mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
WIP - Bridge refactoring
Signed-off-by: Arnaud Porterie <arnaud.porterie@docker.com>
This commit is contained in:
parent
1f3b1febc7
commit
796d58af9e
5 changed files with 83 additions and 50 deletions
|
@ -212,46 +212,6 @@ func createBridge(config *Configuration) (netlink.Addr, []netlink.Addr, error) {
|
||||||
|
|
||||||
return getInterfaceAddrByName(config.BridgeName)
|
return getInterfaceAddrByName(config.BridgeName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkBridgeConfig(iface netlink.Link, config *Configuration) (netlink.Addr, []netlink.Addr, error) {
|
|
||||||
addrv4, addrsv6, err := getInterfaceAddr(iface)
|
|
||||||
if err != nil {
|
|
||||||
return netlink.Addr{}, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// If config dictates a specific IP for the bridge, we have to check if it
|
|
||||||
// corresponds to reality.
|
|
||||||
if config.AddressIPv4 != "" {
|
|
||||||
bridgeIP, _, err := net.ParseCIDR(config.AddressIPv4)
|
|
||||||
if err != nil {
|
|
||||||
return netlink.Addr{}, nil, err
|
|
||||||
}
|
|
||||||
if !addrv4.IP.Equal(bridgeIP) {
|
|
||||||
return netlink.Addr{}, nil, fmt.Errorf("bridge ip (%s) does not match existing configuration %s", addrv4.IP, bridgeIP)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return addrv4, addrsv6, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupIPv6Bridge(iface netlink.Link, config *Configuration) error {
|
|
||||||
procFile := "/proc/sys/net/ipv6/conf/" + config.BridgeName + "/disable_ipv6"
|
|
||||||
if err := ioutil.WriteFile(procFile, []byte{'0', '\n'}, 0644); err != nil {
|
|
||||||
return fmt.Errorf("Unable to enable IPv6 addresses on bridge: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
ip, net, err := net.ParseCIDR(config.AddressIPv6)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Invalid bridge IPv6 address %q: %v", config.AddressIPv6, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
net.IP = ip
|
|
||||||
if err := netlink.AddrAdd(iface, &netlink.Addr{net, ""}); err != nil {
|
|
||||||
return fmt.Errorf("Failed to add address %s to bridge: %v", net, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
type bridgeNetwork struct {
|
type bridgeNetwork struct {
|
||||||
|
|
|
@ -7,8 +7,8 @@ type BridgeSetup struct {
|
||||||
steps []SetupStep
|
steps []SetupStep
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBridgeSetup(b *Interface) *BridgeSetup {
|
func NewBridgeSetup(i *Interface) *BridgeSetup {
|
||||||
return &BridgeSetup{bridge: b}
|
return &BridgeSetup{bridge: i}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BridgeSetup) Apply() error {
|
func (b *BridgeSetup) Apply() error {
|
||||||
|
@ -26,18 +26,18 @@ func (b *BridgeSetup) QueueStep(step SetupStep) {
|
||||||
|
|
||||||
//---------------------------------------------------------------------------//
|
//---------------------------------------------------------------------------//
|
||||||
|
|
||||||
func SetupFixedCIDRv4(b *Interface) error {
|
func SetupFixedCIDRv4(i *Interface) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetupFixedCIDRv6(b *Interface) error {
|
func SetupFixedCIDRv6(i *Interface) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetupIPTables(b *Interface) error {
|
func SetupIPTables(i *Interface) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetupIPForwarding(b *Interface) error {
|
func SetupIPForwarding(i *Interface) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// SetupDevice create a new bridge interface/
|
||||||
func SetupDevice(i *Interface) error {
|
func SetupDevice(i *Interface) error {
|
||||||
// We only attempt to create the bridge when the requested device name is
|
// We only attempt to create the bridge when the requested device name is
|
||||||
// the default one.
|
// the default one.
|
||||||
|
@ -32,9 +33,11 @@ func SetupDevice(i *Interface) error {
|
||||||
log.Debugf("Setting bridge mac address to %s", i.Link.Attrs().HardwareAddr)
|
log.Debugf("Setting bridge mac address to %s", i.Link.Attrs().HardwareAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Call out to netlink to create the device.
|
||||||
return netlink.LinkAdd(i.Link)
|
return netlink.LinkAdd(i.Link)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetupDeviceUp ups the given bridge interface.
|
||||||
func SetupDeviceUp(i *Interface) error {
|
func SetupDeviceUp(i *Interface) error {
|
||||||
return netlink.LinkSetUp(i.Link)
|
return netlink.LinkSetUp(i.Link)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
|
"github.com/docker/docker/pkg/networkfs/resolvconf"
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -56,12 +57,80 @@ func electBridgeIPv4(config *Configuration) (*net.IPNet, error) {
|
||||||
return config.AddressIPv4, nil
|
return config.AddressIPv4, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
nameservers := []string{}
|
||||||
|
if resolvConf, _ := resolvconf.Get(); resolvConf != nil {
|
||||||
|
nameservers = append(nameservers, resolvconf.GetNameserversAsCIDR(resolvConf)...)
|
||||||
|
}
|
||||||
|
|
||||||
// Try to automatically elect appropriate brige IPv4 settings.
|
// Try to automatically elect appropriate brige IPv4 settings.
|
||||||
for _, n := range bridgeNetworks {
|
for _, n := range bridgeNetworks {
|
||||||
// TODO CheckNameserverOverlaps
|
if err := checkNameserverOverlaps(nameservers, n); err == nil {
|
||||||
// TODO CheckRouteOverlaps
|
if err := checkRouteOverlaps(n); err == nil {
|
||||||
return n, nil
|
return n, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("Couldn't find an address range for interface %q", config.BridgeName)
|
return nil, fmt.Errorf("Couldn't find an address range for interface %q", config.BridgeName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkNameserverOverlaps(nameservers []string, toCheck *net.IPNet) error {
|
||||||
|
for _, ns := range nameservers {
|
||||||
|
_, nsNetwork, err := net.ParseCIDR(ns)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if networkOverlaps(toCheck, nsNetwork) {
|
||||||
|
return fmt.Errorf("Requested network %s overlaps with name server")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkRouteOverlaps(toCheck *net.IPNet) error {
|
||||||
|
networks, err := netlink.RouteList(nil, netlink.FAMILY_V4)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, network := range networks {
|
||||||
|
// TODO Is that right?
|
||||||
|
if network.Dst != nil && networkOverlaps(toCheck, network.Dst) {
|
||||||
|
return fmt.Errorf("Requested network %s overlaps with an existing network")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func networkOverlaps(netX *net.IPNet, netY *net.IPNet) bool {
|
||||||
|
if len(netX.IP) == len(netY.IP) {
|
||||||
|
if firstIP, _ := networkRange(netX); netY.Contains(firstIP) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if firstIP, _ := networkRange(netY); netX.Contains(firstIP) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func networkRange(network *net.IPNet) (net.IP, net.IP) {
|
||||||
|
var netIP net.IP
|
||||||
|
if network.IP.To4() != nil {
|
||||||
|
netIP = network.IP.To4()
|
||||||
|
} else if network.IP.To16() != nil {
|
||||||
|
netIP = network.IP.To16()
|
||||||
|
} else {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
lastIP := make([]byte, len(netIP), len(netIP))
|
||||||
|
|
||||||
|
for i := 0; i < len(netIP); i++ {
|
||||||
|
lastIP[i] = netIP[i] | ^network.Mask[i]
|
||||||
|
}
|
||||||
|
return netIP.Mask(network.Mask), net.IP(lastIP)
|
||||||
|
}
|
||||||
|
|
|
@ -10,7 +10,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
_, net, _ := net.ParseCIDR("192.168.100.1/24")
|
ip, net, _ := net.ParseCIDR("192.168.100.1/24")
|
||||||
|
net.IP = ip
|
||||||
|
|
||||||
options := libnetwork.DriverParams{"AddressIPv4": net}
|
options := libnetwork.DriverParams{"AddressIPv4": net}
|
||||||
netw, err := libnetwork.NewNetwork("simplebridge", options)
|
netw, err := libnetwork.NewNetwork("simplebridge", options)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue