diff --git a/common/utils.go b/common/utils.go index 8ea9fdf6..19c0d2dd 100644 --- a/common/utils.go +++ b/common/utils.go @@ -6,7 +6,6 @@ import ( "os" "strings" - "github.com/j-keck/arping" "github.com/vishvananda/netlink" "github.com/vishvananda/netns" @@ -167,20 +166,3 @@ func GetBridgeNetDev(bridgeName string) (NetDev, error) { return linkToNetDev(link) } - -// Do post-attach configuration of all veths we have created -func ConfigureARPforVeths(processID int, prefix string) error { - _, err := FindNetDevs(processID, func(link netlink.Link) bool { - ifName := link.Attrs().Name - if strings.HasPrefix(ifName, prefix) { - weavenet.ConfigureARPCache(ifName) - if addrs, err := netlink.AddrList(link, netlink.FAMILY_V4); err == nil { - for _, addr := range addrs { - arping.GratuitousArpOverIfaceByName(addr.IPNet.IP, ifName) - } - } - } - return false - }) - return err -} diff --git a/net/netns.go b/net/netns.go index 25e956d0..a501f158 100644 --- a/net/netns.go +++ b/net/netns.go @@ -1,7 +1,10 @@ package net import ( + "bytes" "errors" + "fmt" + "os/exec" "runtime" "github.com/vishvananda/netlink" @@ -63,3 +66,27 @@ func WithNetNSLinkByPidUnsafe(pid int, ifName string, work func(link netlink.Lin return WithNetNSLinkUnsafe(ns, ifName, work) } + +// A safe version of WithNetNS* which creates a process executing +// "nsenter --net= weaveutil [args]". +func WithNetNS(nsPath string, cmd string, args ...string) (string, error) { + var stdout, stderr bytes.Buffer + + args = append([]string{"--net=" + nsPath, "weaveutil", cmd}, args...) + c := exec.Command("nsenter", args...) + c.Stdout = &stdout + c.Stderr = &stderr + if err := c.Run(); err != nil { + return "", fmt.Errorf("%s: %s", string(stderr.Bytes()), err) + } + + return string(stdout.Bytes()), nil +} + +func WithNetNSByPid(pid int, cmd string, args ...string) (string, error) { + return WithNetNS(NSPathByPid(pid), cmd, args...) +} + +func NSPathByPid(pid int) string { + return fmt.Sprintf("/proc/%d/ns/net", pid) +} diff --git a/plugin/net/watcher.go b/plugin/net/watcher.go index 3217b646..b9d04f5a 100644 --- a/plugin/net/watcher.go +++ b/plugin/net/watcher.go @@ -4,7 +4,6 @@ import ( "fmt" weaveapi "github.com/weaveworks/weave/api" - "github.com/weaveworks/weave/common" "github.com/weaveworks/weave/common/docker" weavenet "github.com/weaveworks/weave/net" ) @@ -46,7 +45,7 @@ func (w *watcher) ContainerStarted(id string) { if err := w.weave.RegisterWithDNS(id, fqdn, net.IPAddress); err != nil { w.driver.warn("ContainerStarted", "unable to register %s with weaveDNS: %s", id, err) } - if err := common.ConfigureARPforVeths(info.State.Pid, weavenet.VethName); err != nil { + if _, err := weavenet.WithNetNSByPid(info.State.Pid, "configure-arp", weavenet.VethName); err != nil { w.driver.warn("ContainerStarted", "unable to configure interfaces: %s", err) } } diff --git a/prog/weaveutil/main.go b/prog/weaveutil/main.go index 24a6f581..5cf72e46 100644 --- a/prog/weaveutil/main.go +++ b/prog/weaveutil/main.go @@ -23,6 +23,7 @@ func init() { "process-addrs": processAddrs, "attach-container": attach, "detach-container": detach, + "configure-arp": configureARP, } } diff --git a/prog/weaveutil/netdev.go b/prog/weaveutil/netdev.go new file mode 100644 index 00000000..4fee6ee4 --- /dev/null +++ b/prog/weaveutil/netdev.go @@ -0,0 +1,35 @@ +package main + +import ( + "strings" + + "github.com/j-keck/arping" + "github.com/vishvananda/netlink" + + weavenet "github.com/weaveworks/weave/net" +) + +func configureARP(args []string) error { + if len(args) != 1 { + cmdUsage("configure-arp", "") + } + prefix := args[0] + + links, err := netlink.LinkList() + if err != nil { + return err + } + for _, link := range links { + ifName := link.Attrs().Name + if strings.HasPrefix(ifName, prefix) { + weavenet.ConfigureARPCache(ifName) + if addrs, err := netlink.AddrList(link, netlink.FAMILY_V4); err == nil { + for _, addr := range addrs { + arping.GratuitousArpOverIfaceByName(addr.IPNet.IP, ifName) + } + } + } + } + + return nil +}