зеркало из https://github.com/microsoft/docker.git
network: Stop shelling out to /sbin/ip
We have our own netlink version of all the required calls now, so we can just skip the /sbin/ip dependency.
This commit is contained in:
Родитель
607c1a520e
Коммит
494cd07f72
66
network.go
66
network.go
|
@ -6,12 +6,11 @@ import (
|
|||
"fmt"
|
||||
"github.com/dotcloud/docker/iptables"
|
||||
"github.com/dotcloud/docker/proxy"
|
||||
"github.com/dotcloud/docker/netlink"
|
||||
"github.com/dotcloud/docker/utils"
|
||||
"log"
|
||||
"net"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
|
@ -68,42 +67,10 @@ func networkSize(mask net.IPMask) int32 {
|
|||
return int32(binary.BigEndian.Uint32(m)) + 1
|
||||
}
|
||||
|
||||
//Wrapper around the ip command
|
||||
func ip(args ...string) (string, error) {
|
||||
path, err := exec.LookPath("ip")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("command not found: ip")
|
||||
}
|
||||
output, err := exec.Command(path, args...).CombinedOutput()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("ip failed: ip %v", strings.Join(args, " "))
|
||||
}
|
||||
return string(output), nil
|
||||
}
|
||||
|
||||
func checkRouteOverlaps(routes string, dockerNetwork *net.IPNet) error {
|
||||
utils.Debugf("Routes:\n\n%s", routes)
|
||||
for _, line := range strings.Split(routes, "\n") {
|
||||
if strings.Trim(line, "\r\n\t ") == "" || strings.Contains(line, "default") {
|
||||
continue
|
||||
}
|
||||
_, network, err := net.ParseCIDR(strings.Split(line, " ")[0])
|
||||
if err != nil {
|
||||
// is this a mask-less IP address?
|
||||
if ip := net.ParseIP(strings.Split(line, " ")[0]); ip == nil {
|
||||
// fail only if it's neither a network nor a mask-less IP address
|
||||
return fmt.Errorf("Unexpected ip route output: %s (%s)", err, line)
|
||||
} else {
|
||||
_, network, err = net.ParseCIDR(ip.String() + "/32")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
if err == nil && network != nil {
|
||||
if networkOverlaps(dockerNetwork, network) {
|
||||
return fmt.Errorf("Network %s is already routed: '%s'", dockerNetwork, line)
|
||||
}
|
||||
func checkRouteOverlaps(networks []*net.IPNet, dockerNetwork *net.IPNet) error {
|
||||
for _, network := range networks {
|
||||
if networkOverlaps(dockerNetwork, network) {
|
||||
return fmt.Errorf("Network %s is already routed: '%s'", dockerNetwork, network)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -139,7 +106,7 @@ func CreateBridgeIface(config *DaemonConfig) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
routes, err := ip("route")
|
||||
routes, err := netlink.NetworkGetRoutes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -155,15 +122,22 @@ func CreateBridgeIface(config *DaemonConfig) error {
|
|||
}
|
||||
utils.Debugf("Creating bridge %s with network %s", config.BridgeIface, ifaceAddr)
|
||||
|
||||
if output, err := ip("link", "add", config.BridgeIface, "type", "bridge"); err != nil {
|
||||
return fmt.Errorf("Error creating bridge: %s (output: %s)", err, output)
|
||||
if err := netlink.NetworkLinkAdd(config.BridgeIface, "bridge"); err != nil {
|
||||
return fmt.Errorf("Error creating bridge: %s", err)
|
||||
}
|
||||
|
||||
if output, err := ip("addr", "add", ifaceAddr, "dev", config.BridgeIface); err != nil {
|
||||
return fmt.Errorf("Unable to add private network: %s (%s)", err, output)
|
||||
iface, err := net.InterfaceByName(config.BridgeIface)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if output, err := ip("link", "set", config.BridgeIface, "up"); err != nil {
|
||||
return fmt.Errorf("Unable to start network bridge: %s (%s)", err, output)
|
||||
ipAddr, ipNet, err := net.ParseCIDR(ifaceAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if netlink.NetworkLinkAddIp(iface, ipAddr, ipNet); err != nil {
|
||||
return fmt.Errorf("Unable to add private network: %s", err)
|
||||
}
|
||||
if err := netlink.NetworkLinkUp(iface); err != nil {
|
||||
return fmt.Errorf("Unable to start network bridge: %s", err)
|
||||
}
|
||||
|
||||
if config.EnableIptables {
|
||||
|
|
|
@ -277,12 +277,13 @@ func TestNetworkOverlaps(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCheckRouteOverlaps(t *testing.T) {
|
||||
routes := `default via 10.0.2.2 dev eth0
|
||||
10.0.2.0 dev eth0 proto kernel scope link src 10.0.2.15
|
||||
10.0.3.0/24 dev lxcbr0 proto kernel scope link src 10.0.3.1
|
||||
10.0.42.0/24 dev testdockbr0 proto kernel scope link src 10.0.42.1
|
||||
172.16.42.0/24 dev docker0 proto kernel scope link src 172.16.42.1
|
||||
192.168.142.0/24 dev eth1 proto kernel scope link src 192.168.142.142`
|
||||
routesData := []string{"10.0.2.0/32", "10.0.3.0/24", "10.0.42.0/24", "172.16.42.0/24", "192.168.142.0/24"}
|
||||
|
||||
routes := []*net.IPNet{}
|
||||
for _, addr := range routesData {
|
||||
_, netX, _ := net.ParseCIDR(addr)
|
||||
routes = append(routes, netX)
|
||||
}
|
||||
|
||||
_, netX, _ := net.ParseCIDR("172.16.0.1/24")
|
||||
if err := checkRouteOverlaps(routes, netX); err != nil {
|
||||
|
|
Загрузка…
Ссылка в новой задаче