From 36151bd1d752288929be21fca07d492abe8ee115 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 21 Dec 2022 17:21:14 +0100 Subject: [PATCH] libnetwork/drivers/bridge: remove "ioctl" fallback code for legacy kernels This code was forked from libcontainer (now runc) in https://github.com/moby/libnetwork/commit/fb6dd9766e0e4241dc0beedb6f3e3d2b4a5807cb From the description of this code: > THIS CODE DOES NOT COMMUNICATE WITH KERNEL VIA RTNETLINK INTERFACE > IT IS HERE FOR BACKWARDS COMPATIBILITY WITH OLDER LINUX KERNELS > WHICH SHIP WITH OLDER NOT ENTIRELY FUNCTIONAL VERSION OF NETLINK That comment was added as part of a refactor in; https://github.com/docker-archive/libcontainer/pull/197/commits/4fe2c7a4db57bcf4b8c337f60b8c7ef53c9facf9 Digging deeper into the code, it describes: > This is more backward-compatible than netlink.NetworkSetMaster and > works on RHEL 6. That comment (and code) moved around a few times; - moved into the libcontainer pkg: 6158ccad97db51e756aafefb096d1163aa4d6439 - moved within the networkdriver pkg: 4cdcea20474a9f42291fe6b6c6dee348343a7c05 - moved into the networkdriver pkg: 90494600d357d01310d8da1310b6ad02f56de22c Ultimately leading to 7a94cdf8edd917899a38a58917cd4439652047a1, which implemented this: > create the bridge device with ioctl > > On RHEL 6, creation of a bridge device with netlink fails. Use the more > backward-compatible ioctl instead. This fixes networking on RHEL 6. So from that information, it looks indeed to support RHEL 6, and Ubuntu 12.04 which are both EOL, and we haven't supported for a long time, so probably time to remove this. Signed-off-by: Sebastiaan van Stijn --- libnetwork/drivers/bridge/bridge.go | 19 +-- .../bridge/netlink_deprecated_linux.go | 122 ------------------ ..._deprecated_linux_rawsockaddr_data_int8.go | 8 -- ...deprecated_linux_rawsockaddr_data_uint8.go | 8 -- .../bridge/netlink_deprecated_unsupported.go | 19 --- libnetwork/drivers/bridge/setup_device.go | 4 +- 6 files changed, 6 insertions(+), 174 deletions(-) delete mode 100644 libnetwork/drivers/bridge/netlink_deprecated_linux.go delete mode 100644 libnetwork/drivers/bridge/netlink_deprecated_linux_rawsockaddr_data_int8.go delete mode 100644 libnetwork/drivers/bridge/netlink_deprecated_linux_rawsockaddr_data_uint8.go delete mode 100644 libnetwork/drivers/bridge/netlink_deprecated_unsupported.go diff --git a/libnetwork/drivers/bridge/bridge.go b/libnetwork/drivers/bridge/bridge.go index e0e50a907b..a9b010b69c 100644 --- a/libnetwork/drivers/bridge/bridge.go +++ b/libnetwork/drivers/bridge/bridge.go @@ -878,24 +878,13 @@ func (d *driver) deleteNetwork(nid string) error { } func addToBridge(nlh *netlink.Handle, ifaceName, bridgeName string) error { - link, err := nlh.LinkByName(ifaceName) + lnk, err := nlh.LinkByName(ifaceName) if err != nil { return fmt.Errorf("could not find interface %s: %v", ifaceName, err) } - if err = nlh.LinkSetMaster(link, - &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: bridgeName}}); err != nil { - logrus.Debugf("Failed to add %s to bridge via netlink.Trying ioctl: %v", ifaceName, err) - iface, err := net.InterfaceByName(ifaceName) - if err != nil { - return fmt.Errorf("could not find network interface %s: %v", ifaceName, err) - } - - master, err := net.InterfaceByName(bridgeName) - if err != nil { - return fmt.Errorf("could not find bridge %s: %v", bridgeName, err) - } - - return ioctlAddToBridge(iface, master) + if err := nlh.LinkSetMaster(lnk, &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: bridgeName}}); err != nil { + logrus.WithError(err).Errorf("Failed to add %s to bridge via netlink", ifaceName) + return err } return nil } diff --git a/libnetwork/drivers/bridge/netlink_deprecated_linux.go b/libnetwork/drivers/bridge/netlink_deprecated_linux.go deleted file mode 100644 index fd25c9f376..0000000000 --- a/libnetwork/drivers/bridge/netlink_deprecated_linux.go +++ /dev/null @@ -1,122 +0,0 @@ -package bridge - -import ( - "fmt" - "net" - "syscall" - "unsafe" -) - -const ( - ifNameSize = 16 - ioctlBrAdd = 0x89a0 - ioctlBrAddIf = 0x89a2 -) - -type ifreqIndex struct { - IfrnName [ifNameSize]byte - IfruIndex int32 -} - -type ifreqHwaddr struct { - IfrnName [ifNameSize]byte - IfruHwaddr syscall.RawSockaddr -} - -// THIS CODE DOES NOT COMMUNICATE WITH KERNEL VIA RTNETLINK INTERFACE -// IT IS HERE FOR BACKWARDS COMPATIBILITY WITH OLDER LINUX KERNELS -// WHICH SHIP WITH OLDER NOT ENTIRELY FUNCTIONAL VERSION OF NETLINK -func getIfSocket() (fd int, err error) { - for _, socket := range []int{ - syscall.AF_INET, - syscall.AF_PACKET, - syscall.AF_INET6, - } { - if fd, err = syscall.Socket(socket, syscall.SOCK_DGRAM, 0); err == nil { - break - } - } - if err == nil { - return fd, nil - } - return -1, err -} - -func ifIoctBridge(iface, master *net.Interface, op uintptr) error { - if len(master.Name) >= ifNameSize { - return fmt.Errorf("Interface name %s too long", master.Name) - } - - s, err := getIfSocket() - if err != nil { - return err - } - defer syscall.Close(s) - - ifr := ifreqIndex{} - copy(ifr.IfrnName[:len(ifr.IfrnName)-1], master.Name) - ifr.IfruIndex = int32(iface.Index) - - if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), op, uintptr(unsafe.Pointer(&ifr))); err != 0 { - return err - } - - return nil -} - -// Add a slave to a bridge device. This is more backward-compatible than -// netlink.NetworkSetMaster and works on RHEL 6. -func ioctlAddToBridge(iface, master *net.Interface) error { - return ifIoctBridge(iface, master, ioctlBrAddIf) -} - -func ioctlSetMacAddress(name, addr string) error { - if len(name) >= ifNameSize { - return fmt.Errorf("Interface name %s too long", name) - } - - hw, err := net.ParseMAC(addr) - if err != nil { - return err - } - - s, err := getIfSocket() - if err != nil { - return err - } - defer syscall.Close(s) - - ifr := ifreqHwaddr{} - ifr.IfruHwaddr.Family = syscall.ARPHRD_ETHER - copy(ifr.IfrnName[:len(ifr.IfrnName)-1], name) - - for i := 0; i < 6; i++ { - ifr.IfruHwaddr.Data[i] = ifrDataByte(hw[i]) - } - - if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), syscall.SIOCSIFHWADDR, uintptr(unsafe.Pointer(&ifr))); err != 0 { - return err - } - return nil -} - -func ioctlCreateBridge(name, macAddr string) error { - if len(name) >= ifNameSize { - return fmt.Errorf("Interface name %s too long", name) - } - - s, err := getIfSocket() - if err != nil { - return err - } - defer syscall.Close(s) - - nameBytePtr, err := syscall.BytePtrFromString(name) - if err != nil { - return err - } - if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), ioctlBrAdd, uintptr(unsafe.Pointer(nameBytePtr))); err != 0 { - return err - } - return ioctlSetMacAddress(name, macAddr) -} diff --git a/libnetwork/drivers/bridge/netlink_deprecated_linux_rawsockaddr_data_int8.go b/libnetwork/drivers/bridge/netlink_deprecated_linux_rawsockaddr_data_int8.go deleted file mode 100644 index 5a0763efdf..0000000000 --- a/libnetwork/drivers/bridge/netlink_deprecated_linux_rawsockaddr_data_int8.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build !arm && !ppc64 && !ppc64le && !riscv64 -// +build !arm,!ppc64,!ppc64le,!riscv64 - -package bridge - -func ifrDataByte(b byte) int8 { - return int8(b) -} diff --git a/libnetwork/drivers/bridge/netlink_deprecated_linux_rawsockaddr_data_uint8.go b/libnetwork/drivers/bridge/netlink_deprecated_linux_rawsockaddr_data_uint8.go deleted file mode 100644 index e177146077..0000000000 --- a/libnetwork/drivers/bridge/netlink_deprecated_linux_rawsockaddr_data_uint8.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build arm || ppc64 || ppc64le || riscv64 -// +build arm ppc64 ppc64le riscv64 - -package bridge - -func ifrDataByte(b byte) uint8 { - return uint8(b) -} diff --git a/libnetwork/drivers/bridge/netlink_deprecated_unsupported.go b/libnetwork/drivers/bridge/netlink_deprecated_unsupported.go deleted file mode 100644 index d4d34bef44..0000000000 --- a/libnetwork/drivers/bridge/netlink_deprecated_unsupported.go +++ /dev/null @@ -1,19 +0,0 @@ -//go:build !linux -// +build !linux - -package bridge - -import ( - "errors" - "net" -) - -// Add a slave to a bridge device. This is more backward-compatible than -// netlink.NetworkSetMaster and works on RHEL 6. -func ioctlAddToBridge(iface, master *net.Interface) error { - return errors.New("not implemented") -} - -func ioctlCreateBridge(name string, setMacAddr bool) error { - return errors.New("not implemented") -} diff --git a/libnetwork/drivers/bridge/setup_device.go b/libnetwork/drivers/bridge/setup_device.go index a9d9bc1fdf..73d8647b0e 100644 --- a/libnetwork/drivers/bridge/setup_device.go +++ b/libnetwork/drivers/bridge/setup_device.go @@ -34,8 +34,8 @@ func setupDevice(config *networkConfiguration, i *bridgeInterface) error { logrus.Debugf("Setting bridge mac address to %s", hwAddr) if err := i.nlh.LinkAdd(i.Link); err != nil { - logrus.Debugf("Failed to create bridge %s via netlink. Trying ioctl", config.BridgeName) - return ioctlCreateBridge(config.BridgeName, hwAddr.String()) + logrus.WithError(err).Errorf("Failed to create bridge %s via netlink", config.BridgeName) + return err } return nil