mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #4931 from crosbymichael/gen-mac-addr-for-bridge
Set bridge mac addr on supported kernels
This commit is contained in:
commit
ceed9382d0
3 changed files with 61 additions and 24 deletions
|
@ -5,6 +5,7 @@ package netlink
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
@ -17,10 +18,16 @@ const (
|
||||||
IFLA_INFO_DATA = 2
|
IFLA_INFO_DATA = 2
|
||||||
VETH_INFO_PEER = 1
|
VETH_INFO_PEER = 1
|
||||||
IFLA_NET_NS_FD = 28
|
IFLA_NET_NS_FD = 28
|
||||||
|
SIOC_BRADDBR = 0x89a0
|
||||||
)
|
)
|
||||||
|
|
||||||
var nextSeqNr int
|
var nextSeqNr int
|
||||||
|
|
||||||
|
type ifreqHwaddr struct {
|
||||||
|
IfrnName [16]byte
|
||||||
|
IfruHwaddr syscall.RawSockaddr
|
||||||
|
}
|
||||||
|
|
||||||
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 {
|
||||||
|
@ -808,3 +815,47 @@ func NetworkCreateVethPair(name1, name2 string) error {
|
||||||
}
|
}
|
||||||
return s.HandleAck(wb.Seq)
|
return s.HandleAck(wb.Seq)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create the actual bridge device. This is more backward-compatible than
|
||||||
|
// netlink.NetworkLinkAdd and works on RHEL 6.
|
||||||
|
func CreateBridge(name string, setMacAddr bool) 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)
|
||||||
|
|
||||||
|
nameBytePtr, err := syscall.BytePtrFromString(name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), SIOC_BRADDBR, uintptr(unsafe.Pointer(nameBytePtr))); err != 0 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if setMacAddr {
|
||||||
|
return setBridgeMacAddress(s, name)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func setBridgeMacAddress(s int, name string) error {
|
||||||
|
ifr := ifreqHwaddr{}
|
||||||
|
ifr.IfruHwaddr.Family = syscall.ARPHRD_ETHER
|
||||||
|
copy(ifr.IfrnName[:], name)
|
||||||
|
|
||||||
|
for i := 0; i < 6; i++ {
|
||||||
|
ifr.IfruHwaddr.Data[i] = int8(rand.Intn(255))
|
||||||
|
}
|
||||||
|
|
||||||
|
ifr.IfruHwaddr.Data[0] &^= 0x1 // clear multicast bit
|
||||||
|
ifr.IfruHwaddr.Data[0] |= 0x2 // set local assignment bit (IEEE802)
|
||||||
|
|
||||||
|
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), syscall.SIOCSIFHWADDR, uintptr(unsafe.Pointer(&ifr))); err != 0 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -59,3 +59,7 @@ func NetworkSetMaster(iface, master *net.Interface) error {
|
||||||
func NetworkLinkDown(iface *net.Interface) error {
|
func NetworkLinkDown(iface *net.Interface) error {
|
||||||
return ErrNotImplemented
|
return ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CreateBridge(name string, setMacAddr bool) error {
|
||||||
|
return ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
|
@ -14,13 +14,10 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DefaultNetworkBridge = "docker0"
|
DefaultNetworkBridge = "docker0"
|
||||||
siocBRADDBR = 0x89a0
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Network interface represents the networking stack of a container
|
// Network interface represents the networking stack of a container
|
||||||
|
@ -281,28 +278,13 @@ func createBridge(bridgeIP string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the actual bridge device. This is more backward-compatible than
|
|
||||||
// netlink.NetworkLinkAdd and works on RHEL 6.
|
|
||||||
func createBridgeIface(name string) error {
|
func createBridgeIface(name string) error {
|
||||||
s, err := syscall.Socket(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_IP)
|
kv, err := utils.GetKernelVersion()
|
||||||
if err != nil {
|
// only set the bridge's mac address if the kernel version is > 3.3
|
||||||
utils.Debugf("Bridge socket creation failed IPv6 probably not enabled: %v", err)
|
// before that it was not supported
|
||||||
s, err = syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_IP)
|
setBridgeMacAddr := err == nil && (kv.Kernel >= 3 && kv.Major >= 3)
|
||||||
if err != nil {
|
utils.Debugf("setting bridge mac address = %v", setBridgeMacAddr)
|
||||||
return fmt.Errorf("Error creating bridge creation socket: %s", err)
|
return netlink.CreateBridge(name, setBridgeMacAddr)
|
||||||
}
|
|
||||||
}
|
|
||||||
defer syscall.Close(s)
|
|
||||||
|
|
||||||
nameBytePtr, err := syscall.BytePtrFromString(name)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error converting bridge name %s to byte array: %s", name, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), siocBRADDBR, uintptr(unsafe.Pointer(nameBytePtr))); err != 0 {
|
|
||||||
return fmt.Errorf("Error creating bridge: %s", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate a network interface
|
// Allocate a network interface
|
||||||
|
|
Loading…
Reference in a new issue