Browse Source

Merge pull request #1792 from sanimej/mac2

Remove dynamic mac entry from fdb on endpoint deletion
Madhu Venugopal 8 năm trước cách đây
mục cha
commit
54d627c69d
2 tập tin đã thay đổi với 87 bổ sung0 xóa
  1. 70 0
      libnetwork/drivers/overlay/ov_network.go
  2. 17 0
      libnetwork/osl/neigh_linux.go

+ 70 - 0
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

+ 17 - 0
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()