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:
Alexander Larsson 2013-09-19 10:57:11 +02:00 коммит произвёл Victor Vieux
Родитель 607c1a520e
Коммит 494cd07f72
2 изменённых файлов: 27 добавлений и 52 удалений

Просмотреть файл

@ -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 {