func GetDefaultMtu() (int, error) { routes, err := netlink.NetworkGetRoutes() if err != nil { return -1, err } for _, r := range routes { if r.Default { return r.Iface.MTU, nil } } return -1, ErrNoDefaultRoute }
// RegisterNetwork registers a new network with the allocator // and validates that it contains a valid ip that does not overlap // with existing routes and nameservers func RegisterNetwork(network *net.IPNet, nameservers []string) error { lock.Lock() defer lock.Unlock() if err := checkExistingNetworkOverlaps(network); err != nil { return err } routes, err := netlink.NetworkGetRoutes() if err != nil { return err } if err := checkRouteOverlaps(routes, network); err != nil { return err } if err := checkNameserverOverlaps(nameservers, network); err != nil { return err } return RegisterExistingNetwork(network) }
// CreateBridgeIface creates a network bridge interface on the host system with the name `ifaceName`, // and attempts to configure it with an address which doesn't conflict with any other interface on the host. // If it can't find an address which doesn't conflict, it will return an error. func CreateBridgeIface(config *DaemonConfig) error { addrs := []string{ // Here we don't follow the convention of using the 1st IP of the range for the gateway. // This is to use the same gateway IPs as the /24 ranges, which predate the /16 ranges. // In theory this shouldn't matter - in practice there's bound to be a few scripts relying // on the internal addressing or other stupid things like that. // The shouldn't, but hey, let's not break them unless we really have to. "172.17.42.1/16", // Don't use 172.16.0.0/16, it conflicts with EC2 DNS 172.16.0.23 "10.0.42.1/16", // Don't even try using the entire /8, that's too intrusive "10.1.42.1/16", "10.42.42.1/16", "172.16.42.1/24", "172.16.43.1/24", "172.16.44.1/24", "10.0.42.1/24", "10.0.43.1/24", "192.168.42.1/24", "192.168.43.1/24", "192.168.44.1/24", } nameservers := []string{} resolvConf, _ := utils.GetResolvConf() // we don't check for an error here, because we don't really care // if we can't read /etc/resolv.conf. So instead we skip the append // if resolvConf is nil. It either doesn't exist, or we can't read it // for some reason. if resolvConf != nil { nameservers = append(nameservers, utils.GetNameserversAsCIDR(resolvConf)...) } var ifaceAddr string if len(config.BridgeIp) != 0 { _, _, err := net.ParseCIDR(config.BridgeIp) if err != nil { return err } ifaceAddr = config.BridgeIp } else { for _, addr := range addrs { _, dockerNetwork, err := net.ParseCIDR(addr) if err != nil { return err } routes, err := netlink.NetworkGetRoutes() if err != nil { return err } if err := checkRouteOverlaps(routes, dockerNetwork); err == nil { if err := checkNameserverOverlaps(nameservers, dockerNetwork); err == nil { ifaceAddr = addr break } } else { utils.Debugf("%s: %s", addr, err) } } } if ifaceAddr == "" { return fmt.Errorf("Could not find a free IP address range for interface '%s'. Please configure its address manually and run 'docker -b %s'", config.BridgeIface, config.BridgeIface) } utils.Debugf("Creating bridge %s with network %s", config.BridgeIface, ifaceAddr) if err := createBridgeIface(config.BridgeIface); err != nil { return err } iface, err := net.InterfaceByName(config.BridgeIface) if err != nil { return err } 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) } return nil }