diff --git a/libnetwork/osl/interface_linux.go b/libnetwork/osl/interface_linux.go index 765f7f96be..7ec9cdcf0a 100644 --- a/libnetwork/osl/interface_linux.go +++ b/libnetwork/osl/interface_linux.go @@ -804,20 +804,24 @@ func (n *Namespace) prepAdvertiseAddrs(ctx context.Context, i *Interface, ifInde // original name and moving it out of the sandbox. func (n *Namespace) RemoveInterface(i *Interface) error { close(i.stopCh) + n.mu.Lock() + isDefault := n.isDefault + nlh := n.nlHandle + n.mu.Unlock() // Find the network interface identified by the DstName attribute. - iface, err := n.nlHandle.LinkByName(i.DstName()) + iface, err := nlh.LinkByName(i.DstName()) if err != nil { return err } // Down the interface before configuring - if err := n.nlHandle.LinkSetDown(iface); err != nil { + if err := nlh.LinkSetDown(iface); err != nil { return err } // TODO(aker): Why are we doing this? This would fail if the initial interface set up failed before the "dest interface" was moved into its own namespace; see https://github.com/moby/moby/pull/46315/commits/108595c2fe852a5264b78e96f9e63cda284990a6#r1331253578 - err = n.nlHandle.LinkSetName(iface, i.SrcName()) + err = nlh.LinkSetName(iface, i.SrcName()) if err != nil { log.G(context.TODO()).Debugf("LinkSetName failed for interface %s: %v", i.SrcName(), err) return err @@ -825,13 +829,13 @@ func (n *Namespace) RemoveInterface(i *Interface) error { // if it is a bridge just delete it. if i.Bridge() { - if err := n.nlHandle.LinkDel(iface); err != nil { + if err := nlh.LinkDel(iface); err != nil { return fmt.Errorf("failed deleting bridge %q: %v", i.SrcName(), err) } - } else if !n.isDefault { + } else if !isDefault { // Move the network interface to caller namespace. // TODO(aker): What's this really doing? There are no calls to LinkDel in this package: is this code really used? (Interface.Remove() has 3 callers); see https://github.com/moby/moby/pull/46315/commits/108595c2fe852a5264b78e96f9e63cda284990a6#r1331265335 - if err := n.nlHandle.LinkSetNsFd(iface, ns.ParseHandlerInt()); err != nil { + if err := nlh.LinkSetNsFd(iface, ns.ParseHandlerInt()); err != nil { log.G(context.TODO()).Debugf("LinkSetNsFd failed for interface %s: %v", i.SrcName(), err) return err } diff --git a/libnetwork/osl/neigh_linux.go b/libnetwork/osl/neigh_linux.go index d08a5aca99..7ed9f84a13 100644 --- a/libnetwork/osl/neigh_linux.go +++ b/libnetwork/osl/neigh_linux.go @@ -51,9 +51,13 @@ func (n *Namespace) DeleteNeighbor(dstIP net.IP, dstMac net.HardwareAddr) error return NeighborSearchError{dstIP, dstMac, false} } + n.mu.Lock() + nlh := n.nlHandle + n.mu.Unlock() + var linkIndex int if nh.linkDst != "" { - iface, err := n.nlHandle.LinkByName(nh.linkDst) + iface, err := nlh.LinkByName(nh.linkDst) if err != nil { return fmt.Errorf("could not find interface with destination name %s: %v", nh.linkDst, err) } @@ -75,13 +79,13 @@ func (n *Namespace) DeleteNeighbor(dstIP net.IP, dstMac net.HardwareAddr) error // If the kernel deletion fails for the neighbor entry still remove it // from the namespace cache, otherwise kernel update can fail if the // neighbor moves back to the same host again. - if err := n.nlHandle.NeighDel(nlnh); err != nil && !errors.Is(err, os.ErrNotExist) { + if err := nlh.NeighDel(nlnh); err != nil && !errors.Is(err, os.ErrNotExist) { log.G(context.TODO()).Warnf("Deleting neighbor IP %s, mac %s failed, %v", dstIP, dstMac, err) } // Delete the dynamic entry in the bridge if nh.family > 0 { - if err := n.nlHandle.NeighDel(&netlink.Neigh{ + if err := nlh.NeighDel(&netlink.Neigh{ LinkIndex: linkIndex, IP: dstIP, Family: nh.family, @@ -120,6 +124,10 @@ func (n *Namespace) AddNeighbor(dstIP net.IP, dstMac net.HardwareAddr, options . nh.processNeighOptions(options...) + n.mu.Lock() + nlh := n.nlHandle + n.mu.Unlock() + nlnh := &netlink.Neigh{ IP: dstIP, HardwareAddr: dstMac, @@ -137,14 +145,14 @@ func (n *Namespace) AddNeighbor(dstIP net.IP, dstMac net.HardwareAddr, options . return fmt.Errorf("could not find the interface with name %s", nh.linkName) } - iface, err := n.nlHandle.LinkByName(nh.linkDst) + iface, err := nlh.LinkByName(nh.linkDst) if err != nil { return fmt.Errorf("could not find interface with destination name %s: %v", nh.linkDst, err) } nlnh.LinkIndex = iface.Attrs().Index } - if err := n.nlHandle.NeighSet(nlnh); err != nil { + if err := nlh.NeighSet(nlnh); err != nil { return fmt.Errorf("could not add neighbor entry:%+v error:%v", nlnh, err) }