فهرست منبع

Merge pull request #2992 from jpoimboe/bridge-create-ioctl

Create the bridge device with ioctl
Michael Crosby 11 سال پیش
والد
کامیت
06379d8bd9
1فایلهای تغییر یافته به همراه25 افزوده شده و 2 حذف شده
  1. 25 2
      network.go

+ 25 - 2
network.go

@@ -12,6 +12,8 @@ import (
 	"net"
 	"strconv"
 	"sync"
+	"syscall"
+	"unsafe"
 )
 
 const (
@@ -19,6 +21,7 @@ const (
 	DisableNetworkBridge = "none"
 	portRangeStart       = 49153
 	portRangeEnd         = 65535
+	siocBRADDBR          = 0x89a0
 )
 
 // Calculates the first and last IP addresses in an IPNet
@@ -149,8 +152,8 @@ func CreateBridgeIface(config *DaemonConfig) error {
 	}
 	utils.Debugf("Creating bridge %s with network %s", config.BridgeIface, ifaceAddr)
 
-	if err := netlink.NetworkLinkAdd(config.BridgeIface, "bridge"); err != nil {
-		return fmt.Errorf("Error creating bridge: %s", err)
+	if err := createBridgeIface(config.BridgeIface); err != nil {
+		return err
 	}
 	iface, err := net.InterfaceByName(config.BridgeIface)
 	if err != nil {
@@ -170,6 +173,26 @@ func CreateBridgeIface(config *DaemonConfig) error {
 	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 {
+	s, err := syscall.Socket(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_IP)
+	if err != nil {
+		return fmt.Errorf("Error creating bridge creation socket: %s", err)
+	}
+	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
+}
+
 // Return the IPv4 address of a network interface
 func getIfaceAddr(name string) (net.Addr, error) {
 	iface, err := net.InterfaceByName(name)