Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove dynamic mac entry from fdb on endpoint deletion #1792

Merged
merged 1 commit into from
Jun 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions drivers/overlay/ov_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ package overlay
import (
"encoding/json"
"fmt"
"io/ioutil"
"net"
"os"
"os/exec"
"path/filepath"
"strconv"
"strings"
"sync"
"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"
Expand Down Expand Up @@ -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 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope this works equally well across multiple Distros.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested Ubuntu 15.10 running 4.2 kernel and 3.19 kernel. And Centos running 3.10.0-327.10.1.el7.x86_64.

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")
}
Expand Down Expand Up @@ -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 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this specific to non-hostMode ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reexec is to avoid calling the potential blocking sysfs mount operations causing the namespace corruption. Its not needed in the hostmode since there is no per overlay network namespace. But in the hostmode also we might have to set the default-vlan, directly from the daemon without a reexec. I will do that in a separate PR after trying out in the 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
Expand Down
17 changes: 17 additions & 0 deletions osl/neigh_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down