libnetwork/drivers/bridge: remove "ioctl" fallback code for legacy kernels

This code was forked from libcontainer (now runc) in
fb6dd9766e

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;
4fe2c7a4db

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: 6158ccad97
- moved within the networkdriver pkg: 4cdcea2047
- moved into the networkdriver pkg: 90494600d3

Ultimately leading to 7a94cdf8ed, 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 <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2022-12-21 17:21:14 +01:00
parent 298d3aa8b8
commit 36151bd1d7
No known key found for this signature in database
GPG key ID: 76698F39D527CE8C
6 changed files with 6 additions and 174 deletions

View file

@ -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
}

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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")
}

View file

@ -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