11 "github.com/docker/libnetwork/netutils"
20 type ifreqIndex struct {
21 IfrnName [ifNameSize]byte
25 type ifreqHwaddr struct {
26 IfrnName [ifNameSize]byte
27 IfruHwaddr syscall.RawSockaddr
30 var rnd = rand.New(rand.NewSource(time.Now().UnixNano()))
32 // THIS CODE DOES NOT COMMUNICATE WITH KERNEL VIA RTNETLINK INTERFACE
33 // IT IS HERE FOR BACKWARDS COMPATIBILITY WITH OLDER LINUX KERNELS
34 // WHICH SHIP WITH OLDER NOT ENTIRELY FUNCTIONAL VERSION OF NETLINK
35 func getIfSocket() (fd int, err error) {
36 for _, socket := range []int{
41 if fd, err = syscall.Socket(socket, syscall.SOCK_DGRAM, 0); err == nil {
51 func ifIoctBridge(iface, master *net.Interface, op uintptr) error {
52 if len(master.Name) >= ifNameSize {
53 return fmt.Errorf("Interface name %s too long", master.Name)
56 s, err := getIfSocket()
60 defer syscall.Close(s)
63 copy(ifr.IfrnName[:len(ifr.IfrnName)-1], master.Name)
64 ifr.IfruIndex = int32(iface.Index)
66 if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), op, uintptr(unsafe.Pointer(&ifr))); err != 0 {
73 // Add a slave to a bridge device. This is more backward-compatible than
74 // netlink.NetworkSetMaster and works on RHEL 6.
75 func ioctlAddToBridge(iface, master *net.Interface) error {
76 return ifIoctBridge(iface, master, ioctlBrAddIf)
79 func ioctlSetMacAddress(name, addr string) error {
80 if len(name) >= ifNameSize {
81 return fmt.Errorf("Interface name %s too long", name)
84 hw, err := net.ParseMAC(addr)
89 s, err := getIfSocket()
93 defer syscall.Close(s)
96 ifr.IfruHwaddr.Family = syscall.ARPHRD_ETHER
97 copy(ifr.IfrnName[:len(ifr.IfrnName)-1], name)
99 for i := 0; i < 6; i++ {
100 ifr.IfruHwaddr.Data[i] = ifrDataByte(hw[i])
103 if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), syscall.SIOCSIFHWADDR, uintptr(unsafe.Pointer(&ifr))); err != 0 {
109 func ioctlCreateBridge(name string, setMacAddr bool) error {
110 if len(name) >= ifNameSize {
111 return fmt.Errorf("Interface name %s too long", name)
114 s, err := getIfSocket()
118 defer syscall.Close(s)
120 nameBytePtr, err := syscall.BytePtrFromString(name)
124 if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), ioctlBrAdd, uintptr(unsafe.Pointer(nameBytePtr))); err != 0 {
128 return ioctlSetMacAddress(name, netutils.GenerateRandomMAC().String())