host-device: Bring interfaces up after moving into container

If an interface is not configured with IPAM (because it functions at
layer 2), it will not be brought up otherwise.

Signed-off-by: David Ward <david.ward@ll.mit.edu>
This commit is contained in:
David Ward 2021-12-24 07:53:44 -05:00 committed by Casey Callendrello
parent 27e830b73e
commit 3b2afc93dc
2 changed files with 32 additions and 16 deletions

View File

@ -230,6 +230,10 @@ func moveLinkIn(hostDev netlink.Link, containerNs ns.NetNS, ifName string) (netl
if err := netlink.LinkSetName(contDev, ifName); err != nil {
return fmt.Errorf("failed to rename device %q to %q: %v", hostDev.Attrs().Name, ifName, err)
}
// Bring container device up
if err = netlink.LinkSetUp(contDev); err != nil {
return fmt.Errorf("failed to set %q up: %v", ifName, err)
}
// Retrieve link again to get up-to-date name and attributes
contDev, err = netlink.LinkByName(ifName)
if err != nil {
@ -261,17 +265,21 @@ func moveLinkOut(containerNs ns.NetNS, ifName string) error {
return fmt.Errorf("failed to set %q down: %v", ifName, err)
}
// Rename device to it's original name
defer func() {
// If moving the device to the host namespace fails, set its name back to ifName so that this
// function can be retried. Also bring the device back up, unless it was already down before.
if err != nil {
_ = netlink.LinkSetName(dev, ifName)
if dev.Attrs().Flags & net.FlagUp == net.FlagUp {
_ = netlink.LinkSetUp(dev)
}
}
}()
// Rename the device to its original name from the host namespace
if err = netlink.LinkSetName(dev, dev.Attrs().Alias); err != nil {
return fmt.Errorf("failed to restore %q to original name %q: %v", ifName, dev.Attrs().Alias, err)
}
defer func() {
if err != nil {
// if moving device to host namespace fails, we should revert device name
// to ifName to make sure that device can be found in retries
_ = netlink.LinkSetName(dev, ifName)
}
}()
if err = netlink.LinkSetNsFd(dev, int(defaultNs.Fd())); err != nil {
return fmt.Errorf("failed to move %q to host netns: %v", dev.Attrs().Alias, err)

View File

@ -381,12 +381,13 @@ var _ = Describe("base functionality", func() {
t := newTesterByVersion(ver)
t.expectInterfaces(resI, cniName, origLink.Attrs().HardwareAddr.String(), targetNS.Path())
// assert that dummy0 is now in the target namespace
// assert that dummy0 is now in the target namespace and is up
_ = targetNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()
link, err := netlink.LinkByName(cniName)
Expect(err).NotTo(HaveOccurred())
Expect(link.Attrs().HardwareAddr).To(Equal(origLink.Attrs().HardwareAddr))
Expect(link.Attrs().Flags & net.FlagUp).To(Equal(net.FlagUp))
return nil
})
@ -461,12 +462,13 @@ var _ = Describe("base functionality", func() {
t := newTesterByVersion(ver)
t.expectInterfaces(resI, cniName, origLink.Attrs().HardwareAddr.String(), targetNS.Path())
// assert that dummy0 is now in the target namespace
// assert that dummy0 is now in the target namespace and is up
_ = targetNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()
link, err := netlink.LinkByName(cniName)
Expect(err).NotTo(HaveOccurred())
Expect(link.Attrs().HardwareAddr).To(Equal(origLink.Attrs().HardwareAddr))
Expect(link.Attrs().Flags & net.FlagUp).To(Equal(net.FlagUp))
return nil
})
@ -504,12 +506,13 @@ var _ = Describe("base functionality", func() {
return nil
})
// assert container interface "eth0" still exists in target namespace
// assert container interface "eth0" still exists in target namespace and is up
_ = targetNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()
link, err := netlink.LinkByName(cniName)
Expect(err).NotTo(HaveOccurred())
Expect(link.Attrs().HardwareAddr).To(Equal(origLink.Attrs().HardwareAddr))
Expect(link.Attrs().Flags & net.FlagUp).To(Equal(net.FlagUp))
return nil
})
@ -654,12 +657,13 @@ var _ = Describe("base functionality", func() {
t := newTesterByVersion(ver)
t.expectInterfaces(resI, cniName, origLink.Attrs().HardwareAddr.String(), targetNS.Path())
// assert that dummy0 is now in the target namespace
// assert that dummy0 is now in the target namespace and is up
_ = targetNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()
link, err := netlink.LinkByName(cniName)
Expect(err).NotTo(HaveOccurred())
Expect(link.Attrs().HardwareAddr).To(Equal(origLink.Attrs().HardwareAddr))
Expect(link.Attrs().Flags & net.FlagUp).To(Equal(net.FlagUp))
//get the IP address of the interface in the target namespace
addrs, err := netlink.AddrList(link, netlink.FAMILY_V4)
@ -757,12 +761,13 @@ var _ = Describe("base functionality", func() {
t := newTesterByVersion(ver)
t.expectInterfaces(resI, cniName, origLink.Attrs().HardwareAddr.String(), targetNS.Path())
// assert that dummy0 is now in the target namespace
// assert that dummy0 is now in the target namespace and is up
_ = targetNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()
link, err := netlink.LinkByName(cniName)
Expect(err).NotTo(HaveOccurred())
Expect(link.Attrs().HardwareAddr).To(Equal(origLink.Attrs().HardwareAddr))
Expect(link.Attrs().Flags & net.FlagUp).To(Equal(net.FlagUp))
return nil
})
@ -949,12 +954,13 @@ var _ = Describe("base functionality", func() {
t := newTesterByVersion(ver)
t.expectInterfaces(resI, cniName, origLink.Attrs().HardwareAddr.String(), targetNS.Path())
// assert that dummy0 is now in the target namespace
// assert that dummy0 is now in the target namespace and is up
_ = targetNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()
link, err := netlink.LinkByName(cniName)
Expect(err).NotTo(HaveOccurred())
Expect(link.Attrs().HardwareAddr).To(Equal(origLink.Attrs().HardwareAddr))
Expect(link.Attrs().Flags & net.FlagUp).To(Equal(net.FlagUp))
//get the IP address of the interface in the target namespace
addrs, err := netlink.AddrList(link, netlink.FAMILY_V4)
@ -1063,12 +1069,13 @@ var _ = Describe("base functionality", func() {
t := newTesterByVersion(ver)
t.expectInterfaces(resI, cniName, origLink.Attrs().HardwareAddr.String(), targetNS.Path())
// assert that dummy0 is now in the target namespace
// assert that dummy0 is now in the target namespace and is up
_ = targetNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()
link, err := netlink.LinkByName(cniName)
Expect(err).NotTo(HaveOccurred())
Expect(link.Attrs().HardwareAddr).To(Equal(origLink.Attrs().HardwareAddr))
Expect(link.Attrs().Flags & net.FlagUp).To(Equal(net.FlagUp))
return nil
})
@ -1106,12 +1113,13 @@ var _ = Describe("base functionality", func() {
return nil
})
// assert container interface "eth0" still exists in target namespace
// assert container interface "eth0" still exists in target namespace and is up
err = targetNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()
link, err := netlink.LinkByName(cniName)
Expect(err).NotTo(HaveOccurred())
Expect(link.Attrs().HardwareAddr).To(Equal(origLink.Attrs().HardwareAddr))
Expect(link.Attrs().Flags & net.FlagUp).To(Equal(net.FlagUp))
return nil
})
Expect(err).NotTo(HaveOccurred())