diff --git a/libnetwork/drivers/bridge/bridge.go b/libnetwork/drivers/bridge/bridge.go index b617ea7bc4..5e38e5f60e 100644 --- a/libnetwork/drivers/bridge/bridge.go +++ b/libnetwork/drivers/bridge/bridge.go @@ -68,6 +68,7 @@ type networkConfiguration struct { EnableIPv6 bool EnableIPMasquerade bool EnableICC bool + InhibitIPv4 bool Mtu int DefaultBindingIP net.IP DefaultBridge bool @@ -243,6 +244,10 @@ func (c *networkConfiguration) fromLabels(labels map[string]string) error { if c.EnableICC, err = strconv.ParseBool(value); err != nil { return parseErr(label, value, err.Error()) } + case InhibitIPv4: + if c.InhibitIPv4, err = strconv.ParseBool(value); err != nil { + return parseErr(label, value, err.Error()) + } case DefaultBridge: if c.DefaultBridge, err = strconv.ParseBool(value); err != nil { return parseErr(label, value, err.Error()) @@ -699,7 +704,7 @@ func (d *driver) createNetwork(config *networkConfiguration) (err error) { // We ensure that the bridge has the expectedIPv4 and IPv6 addresses in // the case of a previously existing device. - {bridgeAlreadyExists, setupVerifyAndReconcile}, + {bridgeAlreadyExists && !config.InhibitIPv4, setupVerifyAndReconcile}, // Enable IPv6 Forwarding {enableIPv6Forwarding, setupIPv6Forwarding}, diff --git a/libnetwork/drivers/bridge/bridge_store.go b/libnetwork/drivers/bridge/bridge_store.go index 2988c34fa5..67af774e7c 100644 --- a/libnetwork/drivers/bridge/bridge_store.go +++ b/libnetwork/drivers/bridge/bridge_store.go @@ -137,6 +137,7 @@ func (ncfg *networkConfiguration) MarshalJSON() ([]byte, error) { nMap["EnableIPv6"] = ncfg.EnableIPv6 nMap["EnableIPMasquerade"] = ncfg.EnableIPMasquerade nMap["EnableICC"] = ncfg.EnableICC + nMap["InhibitIPv4"] = ncfg.InhibitIPv4 nMap["Mtu"] = ncfg.Mtu nMap["Internal"] = ncfg.Internal nMap["DefaultBridge"] = ncfg.DefaultBridge @@ -192,6 +193,7 @@ func (ncfg *networkConfiguration) UnmarshalJSON(b []byte) error { ncfg.EnableIPv6 = nMap["EnableIPv6"].(bool) ncfg.EnableIPMasquerade = nMap["EnableIPMasquerade"].(bool) ncfg.EnableICC = nMap["EnableICC"].(bool) + ncfg.InhibitIPv4 = nMap["InhibitIPv4"].(bool) ncfg.Mtu = int(nMap["Mtu"].(float64)) if v, ok := nMap["Internal"]; ok { ncfg.Internal = v.(bool) diff --git a/libnetwork/drivers/bridge/labels.go b/libnetwork/drivers/bridge/labels.go index 7447bd3f93..b938a75477 100644 --- a/libnetwork/drivers/bridge/labels.go +++ b/libnetwork/drivers/bridge/labels.go @@ -10,6 +10,9 @@ const ( // EnableICC label EnableICC = "com.docker.network.bridge.enable_icc" + // InhibitIPv4 label + InhibitIPv4 = "com.docker.network.bridge.inhibit_ipv4" + // DefaultBindingIP label DefaultBindingIP = "com.docker.network.bridge.host_binding_ipv4" diff --git a/libnetwork/drivers/bridge/setup_ipv4.go b/libnetwork/drivers/bridge/setup_ipv4.go index 983669f324..e4e47a1af1 100644 --- a/libnetwork/drivers/bridge/setup_ipv4.go +++ b/libnetwork/drivers/bridge/setup_ipv4.go @@ -27,22 +27,24 @@ func selectIPv4Address(addresses []netlink.Addr, selector *net.IPNet) (netlink.A } func setupBridgeIPv4(config *networkConfiguration, i *bridgeInterface) error { - addrv4List, _, err := i.addresses() - if err != nil { - return fmt.Errorf("failed to retrieve bridge interface addresses: %v", err) - } - - addrv4, _ := selectIPv4Address(addrv4List, config.AddressIPv4) - - if !types.CompareIPNet(addrv4.IPNet, config.AddressIPv4) { - if addrv4.IPNet != nil { - if err := i.nlh.AddrDel(i.Link, &addrv4); err != nil { - return fmt.Errorf("failed to remove current ip address from bridge: %v", err) - } + if !config.InhibitIPv4 { + addrv4List, _, err := i.addresses() + if err != nil { + return fmt.Errorf("failed to retrieve bridge interface addresses: %v", err) } - logrus.Debugf("Assigning address to bridge interface %s: %s", config.BridgeName, config.AddressIPv4) - if err := i.nlh.AddrAdd(i.Link, &netlink.Addr{IPNet: config.AddressIPv4}); err != nil { - return &IPv4AddrAddError{IP: config.AddressIPv4, Err: err} + + addrv4, _ := selectIPv4Address(addrv4List, config.AddressIPv4) + + if !types.CompareIPNet(addrv4.IPNet, config.AddressIPv4) { + if addrv4.IPNet != nil { + if err := i.nlh.AddrDel(i.Link, &addrv4); err != nil { + return fmt.Errorf("failed to remove current ip address from bridge: %v", err) + } + } + logrus.Debugf("Assigning address to bridge interface %s: %s", config.BridgeName, config.AddressIPv4) + if err := i.nlh.AddrAdd(i.Link, &netlink.Addr{IPNet: config.AddressIPv4}); err != nil { + return &IPv4AddrAddError{IP: config.AddressIPv4, Err: err} + } } }