From e49955988ae1996c1ef966cb9b20b3e19817f526 Mon Sep 17 00:00:00 2001 From: Santhosh Manohar Date: Thu, 1 Jun 2017 12:20:46 -0700 Subject: [PATCH] Remove dynamic mac entry from fdb on endpoint deletion Signed-off-by: Santhosh Manohar --- libnetwork/drivers/overlay/ov_network.go | 70 ++++++++++++++++++++++++ libnetwork/osl/neigh_linux.go | 17 ++++++ 2 files changed, 87 insertions(+) diff --git a/libnetwork/drivers/overlay/ov_network.go b/libnetwork/drivers/overlay/ov_network.go index 64e5744403..f24390ec7c 100644 --- a/libnetwork/drivers/overlay/ov_network.go +++ b/libnetwork/drivers/overlay/ov_network.go @@ -3,8 +3,10 @@ package overlay import ( "encoding/json" "fmt" + "io/ioutil" "net" "os" + "os/exec" "path/filepath" "strconv" "strings" @@ -12,6 +14,7 @@ import ( "syscall" "github.com/Sirupsen/logrus" + "github.com/docker/docker/pkg/reexec" "github.com/docker/libnetwork/datastore" "github.com/docker/libnetwork/driverapi" "github.com/docker/libnetwork/netlabel" @@ -67,6 +70,54 @@ type network struct { sync.Mutex } +func init() { + reexec.Register("set-default-vlan", setDefaultVlan) +} + +func setDefaultVlan() { + if len(os.Args) < 3 { + logrus.Error("insufficient number of arguments") + os.Exit(1) + } + nsPath := os.Args[1] + ns, err := netns.GetFromPath(nsPath) + if err != nil { + logrus.Errorf("overlay namespace get failed, %v", err) + os.Exit(1) + } + if err = netns.Set(ns); err != nil { + logrus.Errorf("setting into overlay namespace failed, %v", err) + os.Exit(1) + } + + // make sure the sysfs mount doesn't propagate back + if err = syscall.Unshare(syscall.CLONE_NEWNS); err != nil { + logrus.Errorf("unshare failed, %v", err) + os.Exit(1) + } + + flag := syscall.MS_PRIVATE | syscall.MS_REC + if err = syscall.Mount("", "/", "", uintptr(flag), ""); err != nil { + logrus.Errorf("root mount failed, %v", err) + os.Exit(1) + } + + if err = syscall.Mount("sysfs", "/sys", "sysfs", 0, ""); err != nil { + logrus.Errorf("mounting sysfs failed, %v", err) + os.Exit(1) + } + + brName := os.Args[2] + path := filepath.Join("/sys/class/net", brName, "bridge/default_pvid") + data := []byte{'0', '\n'} + + if err = ioutil.WriteFile(path, data, 0644); err != nil { + logrus.Errorf("endbling default vlan on bridge %s failed %v", brName, err) + os.Exit(1) + } + os.Exit(0) +} + func (d *driver) NetworkAllocate(id string, option map[string]string, ipV4Data, ipV6Data []driverapi.IPAMData) (map[string]string, error) { return nil, types.NotImplementedErrorf("not implemented") } @@ -505,6 +556,25 @@ func (n *network) setupSubnetSandbox(s *subnet, brName, vxlanName string) error return fmt.Errorf("vxlan interface creation failed for subnet %q: %v", s.subnetIP.String(), err) } + if !hostMode { + var name string + for _, i := range sbox.Info().Interfaces() { + if i.Bridge() { + name = i.DstName() + } + } + cmd := &exec.Cmd{ + Path: reexec.Self(), + Args: []string{"set-default-vlan", sbox.Key(), name}, + Stdout: os.Stdout, + Stderr: os.Stderr, + } + if err := cmd.Run(); err != nil { + // not a fatal error + logrus.Errorf("reexec to set bridge default vlan failed %v", err) + } + } + if hostMode { if err := addFilters(n.id[:12], brName); err != nil { return err diff --git a/libnetwork/osl/neigh_linux.go b/libnetwork/osl/neigh_linux.go index 81b6cd9c1c..161ffa7beb 100644 --- a/libnetwork/osl/neigh_linux.go +++ b/libnetwork/osl/neigh_linux.go @@ -78,6 +78,23 @@ func (n *networkNamespace) DeleteNeighbor(dstIP net.IP, dstMac net.HardwareAddr, if err := nlh.NeighDel(nlnh); err != nil { logrus.Warnf("Deleting neighbor IP %s, mac %s failed, %v", dstIP, dstMac, err) } + + // Delete the dynamic entry in the bridge + if nlnh.Family > 0 { + nlnh := &netlink.Neigh{ + IP: dstIP, + Family: nh.family, + } + + nlnh.HardwareAddr = dstMac + nlnh.Flags = netlink.NTF_MASTER + if nh.linkDst != "" { + nlnh.LinkIndex = iface.Attrs().Index + } + if err := nlh.NeighDel(nlnh); err != nil { + logrus.Warnf("Deleting bridge mac mac %s failed, %v", dstMac, err) + } + } } n.Lock()