mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
When encountering an error while deleting an ip in sandbox networking mode, check the ip is still on the interface
When multiple ipv4 ips are added on interfaces, gvisor fails to delete the additional ips from the interface in sandbox networking mode with the following error: starting container: setting up network: creating interfaces from net namespace "/proc/909056/ns/net": removing address 10.0.2.101/24 from device "tun0": cannot assign requested address This is due to the fact that additional ips on these interfaces are tagged as secondary ips. When gvisor deletes the primary ip, secondary ips get deleted at the same time and cease to exist on the interface.
This commit is contained in:
@@ -264,6 +264,13 @@ func createInterfacesAndRoutesFromNS(conn *urpc.Client, nsPath string, hardwareG
|
||||
|
||||
// Steal IP address from NIC.
|
||||
if err := removeAddress(ifaceLink, addr.String()); err != nil {
|
||||
// If we encounter an error while deleting the ip,
|
||||
// verify the ip is still present on the interface.
|
||||
if present, err := isAddressOnInterface(iface.Name, addr); err != nil {
|
||||
return fmt.Errorf("checking if address %v is on interface %q: %w", addr, iface.Name, err)
|
||||
} else if !present {
|
||||
continue
|
||||
}
|
||||
return fmt.Errorf("removing address %v from device %q: %w", addr, iface.Name, err)
|
||||
}
|
||||
}
|
||||
@@ -278,6 +285,29 @@ func createInterfacesAndRoutesFromNS(conn *urpc.Client, nsPath string, hardwareG
|
||||
return nil
|
||||
}
|
||||
|
||||
// isAddressOnInterface checks if an address is on an interface
|
||||
func isAddressOnInterface(ifaceName string, addr *net.IPNet) (bool, error) {
|
||||
iface, err := net.InterfaceByName(ifaceName)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("getting interface by name %q: %w", ifaceName, err)
|
||||
}
|
||||
ifaceAddrs, err := iface.Addrs()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("fetching interface addresses for %q: %w", iface.Name, err)
|
||||
}
|
||||
for _, ifaceAddr := range ifaceAddrs {
|
||||
ipNet, ok := ifaceAddr.(*net.IPNet)
|
||||
if !ok {
|
||||
log.Warningf("Can't cast address to *net.IPNet, skipping: %+v", ifaceAddr)
|
||||
continue
|
||||
}
|
||||
if ipNet.String() == addr.String() {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
type socketEntry struct {
|
||||
deviceFile *os.File
|
||||
gsoMaxSize uint32
|
||||
|
||||
Reference in New Issue
Block a user