Skip to content
This repository has been archived by the owner on Jun 20, 2024. It is now read-only.

Disable accept_ra on Weave Net interfaces #3801

Merged
merged 3 commits into from
May 22, 2020
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
26 changes: 15 additions & 11 deletions net/bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ const (
)

type Bridge interface {
init(config *BridgeConfig) error // create and initialise bridge device(s)
attach(veth *netlink.Veth) error // attach veth to bridge
IsFastdp() bool // does this bridge use fastdp?
String() string // human-readable type string
init(procPath string, config *BridgeConfig) error // create and initialise bridge device(s)
attach(veth *netlink.Veth) error // attach veth to bridge
IsFastdp() bool // does this bridge use fastdp?
String() string // human-readable type string
}

// Used to indicate a fallback to the Bridge type
Expand Down Expand Up @@ -250,7 +250,7 @@ func EnsureBridge(procPath string, config *BridgeConfig, log *logrus.Logger, ips
}

for {
if err := bridgeType.init(config); err != nil {
if err := bridgeType.init(procPath, config); err != nil {
if errors.Cause(err) == errBridgeNotSupported {
log.Warnf("Skipping bridge creation of %q due to: %s", bridgeType, err)
bridgeType = bridgeImpl{}
Expand Down Expand Up @@ -279,6 +279,10 @@ func EnsureBridge(procPath string, config *BridgeConfig, log *logrus.Logger, ips
return bridgeType, errors.Wrap(err, "setting proxy_arp")
}
}
// No ipv6 router advertisments please
if err := sysctl(procPath, "net/ipv6/conf/"+config.WeaveBridgeName+"/accept_ra", "0"); err != nil {
return bridgeType, errors.Wrap(err, "setting accept_ra to 0")
}

if err := linkSetUpByName(config.WeaveBridgeName); err != nil {
return bridgeType, err
Expand Down Expand Up @@ -345,11 +349,11 @@ func (b bridgeImpl) initPrep(config *BridgeConfig) error {
return nil
}

func (b bridgeImpl) init(config *BridgeConfig) error {
func (b bridgeImpl) init(procPath string, config *BridgeConfig) error {
if err := b.initPrep(config); err != nil {
return err
}
if _, err := CreateAndAttachVeth(BridgeIfName, PcapIfName, config.WeaveBridgeName, config.MTU, true, false, func(veth netlink.Link) error {
if _, err := CreateAndAttachVeth(procPath, BridgeIfName, PcapIfName, config.WeaveBridgeName, config.MTU, true, false, func(veth netlink.Link) error {
return netlink.LinkSetUp(veth)
}); err != nil {
return errors.Wrap(err, "creating pcap veth pair")
Expand All @@ -361,7 +365,7 @@ func (b bridgeImpl) init(config *BridgeConfig) error {
return nil
}

func (f fastdpImpl) init(config *BridgeConfig) error {
func (f fastdpImpl) init(procPath string, config *BridgeConfig) error {
odpSupported, err := odp.CreateDatapath(f.datapathName)
if !odpSupported {
msg := ""
Expand Down Expand Up @@ -392,14 +396,14 @@ func (f fastdpImpl) init(config *BridgeConfig) error {
return nil
}

func (bf bridgedFastdpImpl) init(config *BridgeConfig) error {
if err := bf.fastdpImpl.init(config); err != nil {
func (bf bridgedFastdpImpl) init(procPath string, config *BridgeConfig) error {
if err := bf.fastdpImpl.init(procPath, config); err != nil {
return err
}
if err := bf.bridgeImpl.initPrep(config); err != nil {
return err
}
if _, err := CreateAndAttachVeth(BridgeIfName, DatapathIfName, config.WeaveBridgeName, config.MTU, true, false, func(veth netlink.Link) error {
if _, err := CreateAndAttachVeth(procPath, BridgeIfName, DatapathIfName, config.WeaveBridgeName, config.MTU, true, false, func(veth netlink.Link) error {
if err := netlink.LinkSetUp(veth); err != nil {
return errors.Wrapf(err, "setting link up on %q", veth.Attrs().Name)
}
Expand Down
6 changes: 3 additions & 3 deletions net/netns.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ func WithNetNSByPath(path string, work func() error) error {
}

func NSPathByPid(pid int) string {
return NSPathByPidWithRoot("/", pid)
return NSPathByPidWithProc("/proc", pid)
}

func NSPathByPidWithRoot(root string, pid int) string {
return filepath.Join(root, fmt.Sprintf("/proc/%d/ns/net", pid))
func NSPathByPidWithProc(procPath string, pid int) string {
return filepath.Join(procPath, fmt.Sprint(pid), "/ns/net")
}
25 changes: 17 additions & 8 deletions net/veth.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
)

// create and attach a veth to the Weave bridge
func CreateAndAttachVeth(name, peerName, bridgeName string, mtu int, keepTXOn bool, errIfLinkExist bool, init func(peer netlink.Link) error) (*netlink.Veth, error) {
func CreateAndAttachVeth(procPath, name, peerName, bridgeName string, mtu int, keepTXOn bool, errIfLinkExist bool, init func(peer netlink.Link) error) (*netlink.Veth, error) {
bridge, err := netlink.LinkByName(bridgeName)
if err != nil {
return nil, fmt.Errorf(`bridge "%s" not present; did you launch weave?`, bridgeName)
Expand Down Expand Up @@ -49,6 +49,13 @@ func CreateAndAttachVeth(name, peerName, bridgeName string, mtu int, keepTXOn bo
if err := bridgeType.attach(veth); err != nil {
return cleanup("attaching veth %q to %q: %s", name, bridgeName, err)
}
// No ipv6 router advertisments please
if err := sysctl(procPath, "net/ipv6/conf/"+name+"/accept_ra", "0"); err != nil {
saada marked this conversation as resolved.
Show resolved Hide resolved
return cleanup("setting accept_ra to 0: %s", err)
}
if err := sysctl(procPath, "net/ipv6/conf/"+peerName+"/accept_ra", "0"); err != nil {
return cleanup("setting accept_ra to 0: %s", err)
}
if !bridgeType.IsFastdp() && !keepTXOn {
if err := EthtoolTXOff(veth.PeerName); err != nil {
return cleanup(`unable to set tx off on %q: %s`, peerName, err)
Expand Down Expand Up @@ -112,6 +119,9 @@ func interfaceExistsInNamespace(netNSPath string, ifName string) bool {
}

func AttachContainer(netNSPath, id, ifName, bridgeName string, mtu int, withMulticastRoute bool, cidrs []*net.IPNet, keepTXOn bool, hairpinMode bool) error {
// AttachContainer expects to be called in host pid namespace
const procPath = "/proc"

ns, err := netns.GetFromPath(netNSPath)
if err != nil {
return err
Expand All @@ -124,12 +134,12 @@ func AttachContainer(netNSPath, id, ifName, bridgeName string, mtu int, withMult
id = id[:maxIDLen] // trim passed ID if too long
}
name, peerName := vethPrefix+"pl"+id, vethPrefix+"pg"+id
veth, err := CreateAndAttachVeth(name, peerName, bridgeName, mtu, keepTXOn, true, func(veth netlink.Link) error {
veth, err := CreateAndAttachVeth(procPath, name, peerName, bridgeName, mtu, keepTXOn, true, func(veth netlink.Link) error {
if err := netlink.LinkSetNsFd(veth, int(ns)); err != nil {
return fmt.Errorf("failed to move veth to container netns: %s", err)
}
if err := WithNetNS(ns, func() error {
return setupIface(peerName, ifName)
return setupIface(procPath, peerName, ifName)
}); err != nil {
return fmt.Errorf("error setting up interface: %s", err)
}
Expand Down Expand Up @@ -206,7 +216,7 @@ func setupIfaceAddrs(veth netlink.Link, withMulticastRoute bool, cidrs []*net.IP
}

// setupIface expects to be called in the container's netns
func setupIface(ifaceName, newIfName string) error {
func setupIface(procPath, ifaceName, newIfName string) error {
ipt, err := iptables.New()
if err != nil {
return err
Expand All @@ -219,23 +229,22 @@ func setupIface(ifaceName, newIfName string) error {
if err := netlink.LinkSetName(link, newIfName); err != nil {
return err
}
// This is only called by AttachContainer which is only called in host pid namespace
if err := configureARPCache("/proc", newIfName); err != nil {
if err := configureARPCache(procPath, newIfName); err != nil {
return err
}
return ipt.Append("filter", "INPUT", "-i", newIfName, "-d", "224.0.0.0/4", "-j", "DROP")
}

// configureARP is a helper for the Docker plugin which doesn't set the addresses itself
func ConfigureARP(prefix, rootPath string) error {
func ConfigureARP(prefix, procPath string) error {
links, err := netlink.LinkList()
if err != nil {
return err
}
for _, link := range links {
ifName := link.Attrs().Name
if strings.HasPrefix(ifName, prefix) {
configureARPCache(rootPath+"/proc", ifName)
configureARPCache(procPath, ifName)
if addrs, err := netlink.AddrList(link, netlink.FAMILY_V4); err == nil {
for _, addr := range addrs {
arping.GratuitousArpOverIfaceByName(addr.IPNet.IP, ifName)
Expand Down
6 changes: 4 additions & 2 deletions plugin/net/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ type driver struct {
// used only by plugin-v2
forceMulticast bool
networks map[string]network
procPath string
}

func New(client *docker.Client, weave *weaveapi.Client, name, scope string, dns, isPluginV2, forceMulticast bool) (skel.Driver, error) {
func New(client *docker.Client, weave *weaveapi.Client, name, scope string, dns, isPluginV2, forceMulticast bool, procPath string) (skel.Driver, error) {
driver := &driver{
name: name,
scope: scope,
Expand All @@ -51,6 +52,7 @@ func New(client *docker.Client, weave *weaveapi.Client, name, scope string, dns,
// make sure that it's used only by plugin-v2
forceMulticast: isPluginV2 && forceMulticast,
networks: make(map[string]network),
procPath: procPath,
}

// Do not start watcher in the case of plugin v2, which prevents us from
Expand Down Expand Up @@ -134,7 +136,7 @@ func (driver *driver) CreateEndpoint(create *api.CreateEndpointRequest) (*api.Cr

// create veths. note we assume endpoint IDs are unique in the first 9 chars
name, peerName := vethPair(create.EndpointID)
if _, err := weavenet.CreateAndAttachVeth(name, peerName, weavenet.WeaveBridgeName, 0, false, true, nil); err != nil {
if _, err := weavenet.CreateAndAttachVeth(driver.procPath, name, peerName, weavenet.WeaveBridgeName, 0, false, true, nil); err != nil {
return nil, driver.error("JoinEndpoint", "%s", err)
}

Expand Down
9 changes: 2 additions & 7 deletions plugin/net/watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,9 @@ func (w *watcher) ContainerStarted(id string) {
w.driver.warn("ContainerStarted", "unable to register %s with weaveDNS: %s", id, err)
}
}
rootDir := "/"
if w.driver.isPluginV2 {
// We bind mount host's /proc to /host/proc for plugin-v2
rootDir = "/host"
}
netNSPath := weavenet.NSPathByPidWithRoot(rootDir, info.State.Pid)
netNSPath := weavenet.NSPathByPidWithProc(w.driver.procPath, info.State.Pid)
if err := weavenet.WithNetNSByPath(netNSPath, func() error {
return weavenet.ConfigureARP(weavenet.VethName, rootDir)
return weavenet.ConfigureARP(weavenet.VethName, w.driver.procPath)
}); err != nil {
w.driver.warn("ContainerStarted", "unable to configure interfaces: %s", err)
}
Expand Down
9 changes: 5 additions & 4 deletions plugin/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type Config struct {
EnableV2Multicast bool
DNS bool
DefaultSubnet string
ProcPath string // path to reach host /proc filesystem
}

type Plugin struct {
Expand Down Expand Up @@ -62,15 +63,15 @@ func (plugin *Plugin) run(dockerClient *docker.Client, weave *weaveapi.Client, r
endChan := make(chan error, 1)

if plugin.Socket != "" {
globalListener, err := listenAndServe(dockerClient, weave, plugin.Socket, endChan, "global", false, plugin.DNS, plugin.EnableV2, plugin.EnableV2Multicast)
globalListener, err := listenAndServe(dockerClient, weave, plugin.Socket, endChan, "global", false, plugin.DNS, plugin.EnableV2, plugin.EnableV2Multicast, plugin.ProcPath)
if err != nil {
return err
}
defer os.Remove(plugin.Socket)
defer globalListener.Close()
}
if plugin.MeshSocket != "" {
meshListener, err := listenAndServe(dockerClient, weave, plugin.MeshSocket, endChan, "local", true, plugin.DNS, plugin.EnableV2, plugin.EnableV2Multicast)
meshListener, err := listenAndServe(dockerClient, weave, plugin.MeshSocket, endChan, "local", true, plugin.DNS, plugin.EnableV2, plugin.EnableV2Multicast, plugin.ProcPath)
if err != nil {
return err
}
Expand All @@ -87,15 +88,15 @@ func (plugin *Plugin) run(dockerClient *docker.Client, weave *weaveapi.Client, r
return <-endChan
}

func listenAndServe(dockerClient *docker.Client, weave *weaveapi.Client, address string, endChan chan<- error, scope string, withIpam, dns bool, isPluginV2, forceMulticast bool) (net.Listener, error) {
func listenAndServe(dockerClient *docker.Client, weave *weaveapi.Client, address string, endChan chan<- error, scope string, withIpam, dns bool, isPluginV2, forceMulticast bool, procPath string) (net.Listener, error) {
var name string
if isPluginV2 {
name = pluginV2Name
} else {
name = pluginNameFromAddress(address)
}

d, err := netplugin.New(dockerClient, weave, name, scope, dns, isPluginV2, forceMulticast)
d, err := netplugin.New(dockerClient, weave, name, scope, dns, isPluginV2, forceMulticast, procPath)
if err != nil {
return nil, err
}
Expand Down
1 change: 1 addition & 0 deletions prog/weaver/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ func main() {

pluginConfig.DNS = !noDNS
pluginConfig.DefaultSubnet = defaultSubnet.String()
pluginConfig.ProcPath = procPath
plugin := plugin.NewPlugin(pluginConfig)

// The weave script always waits for a status call to succeed,
Expand Down