summaryrefslogtreecommitdiff
path: root/pkg/netlink/netlink_linux.go
diff options
context:
space:
mode:
authorunclejack <unclejack@users.noreply.github.com>2014-04-09 01:56:01 +0300
committerunclejack <unclejack@users.noreply.github.com>2014-04-09 01:56:01 +0300
commite128a606e39fa63c6b4fd6e53a1d88cf00aad868 (patch)
tree199ee7eb6678ffecd2ddad95fce794c795ad5183 /pkg/netlink/netlink_linux.go
parent143c9707a9fafc39e1d9747f528db97b2564f01e (diff)
parentdc9c28f51d669d6b09e81c2381f800f1a33bb659 (diff)
downloaddocker-release-0.10.tar.gz
Merge pull request #5079 from unclejack/bump_v0.10.0release-0.100.10.1-hotfixes
Bump version to v0.10.0
Diffstat (limited to 'pkg/netlink/netlink_linux.go')
-rw-r--r--pkg/netlink/netlink_linux.go51
1 files changed, 51 insertions, 0 deletions
diff --git a/pkg/netlink/netlink_linux.go b/pkg/netlink/netlink_linux.go
index f8bb6bac3c..f4aa92ed34 100644
--- a/pkg/netlink/netlink_linux.go
+++ b/pkg/netlink/netlink_linux.go
@@ -5,6 +5,7 @@ package netlink
import (
"encoding/binary"
"fmt"
+ "math/rand"
"net"
"syscall"
"unsafe"
@@ -17,10 +18,16 @@ const (
IFLA_INFO_DATA = 2
VETH_INFO_PEER = 1
IFLA_NET_NS_FD = 28
+ SIOC_BRADDBR = 0x89a0
)
var nextSeqNr int
+type ifreqHwaddr struct {
+ IfrnName [16]byte
+ IfruHwaddr syscall.RawSockaddr
+}
+
func nativeEndian() binary.ByteOrder {
var x uint32 = 0x01020304
if *(*byte)(unsafe.Pointer(&x)) == 0x01 {
@@ -808,3 +815,47 @@ func NetworkCreateVethPair(name1, name2 string) error {
}
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
+}