Fix libcontainer network support on rhel6
It seems that netlink in older kernels, including RHEL6, does not support RTM_SETLINK with IFLA_MASTER. It just silently ignores it, reporting no error, causing netlink.NetworkSetMaster() to not do anything yet return no error. We fix this by introducing and using AddToBridge() in a very similar manner to CreateBridge(), which use the old ioctls directly. This fixes https://github.com/dotcloud/docker/issues/4668 Docker-DCO-1.1-Signed-off-by: Alexander Larsson <alexl@redhat.com> (github: alexlarsson)
This commit is contained in:
parent
2538689b31
commit
db1a117450
3 changed files with 35 additions and 1 deletions
|
@ -50,7 +50,7 @@ func SetInterfaceMaster(name, master string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return netlink.NetworkSetMaster(iface, masterIface)
|
return netlink.AddToBridge(iface, masterIface)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetDefaultGateway(ip string) error {
|
func SetDefaultGateway(ip string) error {
|
||||||
|
|
|
@ -19,6 +19,7 @@ const (
|
||||||
VETH_INFO_PEER = 1
|
VETH_INFO_PEER = 1
|
||||||
IFLA_NET_NS_FD = 28
|
IFLA_NET_NS_FD = 28
|
||||||
SIOC_BRADDBR = 0x89a0
|
SIOC_BRADDBR = 0x89a0
|
||||||
|
SIOC_BRADDIF = 0x89a2
|
||||||
)
|
)
|
||||||
|
|
||||||
var nextSeqNr int
|
var nextSeqNr int
|
||||||
|
@ -28,6 +29,11 @@ type ifreqHwaddr struct {
|
||||||
IfruHwaddr syscall.RawSockaddr
|
IfruHwaddr syscall.RawSockaddr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ifreqIndex struct {
|
||||||
|
IfrnName [16]byte
|
||||||
|
IfruIndex int32
|
||||||
|
}
|
||||||
|
|
||||||
func nativeEndian() binary.ByteOrder {
|
func nativeEndian() binary.ByteOrder {
|
||||||
var x uint32 = 0x01020304
|
var x uint32 = 0x01020304
|
||||||
if *(*byte)(unsafe.Pointer(&x)) == 0x01 {
|
if *(*byte)(unsafe.Pointer(&x)) == 0x01 {
|
||||||
|
@ -842,6 +848,30 @@ func CreateBridge(name string, setMacAddr bool) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add a slave to abridge device. This is more backward-compatible than
|
||||||
|
// netlink.NetworkSetMaster and works on RHEL 6.
|
||||||
|
func AddToBridge(iface, master *net.Interface) error {
|
||||||
|
s, err := syscall.Socket(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_IP)
|
||||||
|
if err != nil {
|
||||||
|
// ipv6 issue, creating with ipv4
|
||||||
|
s, err = syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_IP)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defer syscall.Close(s)
|
||||||
|
|
||||||
|
ifr := ifreqIndex{}
|
||||||
|
copy(ifr.IfrnName[:], master.Name)
|
||||||
|
ifr.IfruIndex = int32(iface.Index)
|
||||||
|
|
||||||
|
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), SIOC_BRADDIF, uintptr(unsafe.Pointer(&ifr))); err != 0 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func setBridgeMacAddress(s int, name string) error {
|
func setBridgeMacAddress(s int, name string) error {
|
||||||
ifr := ifreqHwaddr{}
|
ifr := ifreqHwaddr{}
|
||||||
ifr.IfruHwaddr.Family = syscall.ARPHRD_ETHER
|
ifr.IfruHwaddr.Family = syscall.ARPHRD_ETHER
|
||||||
|
|
|
@ -63,3 +63,7 @@ func NetworkLinkDown(iface *net.Interface) error {
|
||||||
func CreateBridge(name string, setMacAddr bool) error {
|
func CreateBridge(name string, setMacAddr bool) error {
|
||||||
return ErrNotImplemented
|
return ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func AddToBridge(iface, master *net.Interface) error {
|
||||||
|
return ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue