mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Fixes ip allocation for multi bridge networks
- Do not discard errors on ip allocation for gw and bridge - Release addresses on network delete - Add some context on top of ipallocator returned error - Create ip allocator instance at driver creation, not at package init, otherwise this affects bridge test code where ip db is carried over test functions Signed-off-by: Alessandro Boch <aboch@docker.com>
This commit is contained in:
parent
b236fa5cfb
commit
cd3fbc2a95
4 changed files with 44 additions and 10 deletions
|
@ -104,12 +104,9 @@ type driver struct {
|
|||
sync.Mutex
|
||||
}
|
||||
|
||||
func init() {
|
||||
ipAllocator = ipallocator.New()
|
||||
}
|
||||
|
||||
// New constructs a new bridge driver
|
||||
func newDriver() driverapi.Driver {
|
||||
ipAllocator = ipallocator.New()
|
||||
return &driver{networks: map[string]*bridgeNetwork{}}
|
||||
}
|
||||
|
||||
|
@ -786,6 +783,18 @@ func (d *driver) DeleteNetwork(nid string) error {
|
|||
// Programming
|
||||
err = netlink.LinkDel(n.bridge.Link)
|
||||
|
||||
// Release ip addresses (ignore errors)
|
||||
if config.FixedCIDR == nil || config.FixedCIDR.Contains(config.DefaultGatewayIPv4) {
|
||||
if e := ipAllocator.ReleaseIP(n.bridge.bridgeIPv4, n.bridge.gatewayIPv4); e != nil {
|
||||
logrus.Warnf("Failed to release default gateway address %s: %v", n.bridge.gatewayIPv4.String(), e)
|
||||
}
|
||||
}
|
||||
if config.FixedCIDR == nil || config.FixedCIDR.Contains(n.bridge.bridgeIPv4.IP) {
|
||||
if e := ipAllocator.ReleaseIP(n.bridge.bridgeIPv4, n.bridge.bridgeIPv4.IP); e != nil {
|
||||
logrus.Warnf("Failed to release bridge IP %s: %v", n.bridge.bridgeIPv4.IP.String(), e)
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -637,7 +637,19 @@ func TestSetDefaultGw(t *testing.T) {
|
|||
}
|
||||
|
||||
_, subnetv6, _ := net.ParseCIDR("2001:db8:ea9:9abc:b0c4::/80")
|
||||
gw4 := bridgeNetworks[0].IP.To4()
|
||||
|
||||
var nw *net.IPNet
|
||||
for _, n := range bridgeNetworks {
|
||||
if err := netutils.CheckRouteOverlaps(n); err == nil {
|
||||
nw = n
|
||||
break
|
||||
}
|
||||
}
|
||||
if nw == nil {
|
||||
t.Skipf("Skip as no more automatic networks available")
|
||||
}
|
||||
|
||||
gw4 := types.GetIPCopy(nw.IP).To4()
|
||||
gw4[3] = 254
|
||||
gw6 := net.ParseIP("2001:db8:ea9:9abc:b0c4::254")
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ func setupBridgeIPv4(config *networkConfiguration, i *bridgeInterface) error {
|
|||
return err
|
||||
}
|
||||
|
||||
log.Debugf("Creating bridge interface %q with network %s", config.BridgeName, bridgeIPv4)
|
||||
log.Debugf("Creating bridge interface %s with network %s", config.BridgeName, bridgeIPv4)
|
||||
if err := netlink.AddrAdd(i.Link, &netlink.Addr{IPNet: bridgeIPv4}); err != nil {
|
||||
return &IPv4AddrAddError{IP: bridgeIPv4, Err: err}
|
||||
}
|
||||
|
@ -79,7 +79,9 @@ func allocateBridgeIP(config *networkConfiguration, i *bridgeInterface) error {
|
|||
// reserve bridge address only if it belongs to the container network
|
||||
// (if defined), no need otherwise
|
||||
if config.FixedCIDR == nil || config.FixedCIDR.Contains(i.bridgeIPv4.IP) {
|
||||
ipAllocator.RequestIP(i.bridgeIPv4, i.bridgeIPv4.IP)
|
||||
if _, err := ipAllocator.RequestIP(i.bridgeIPv4, i.bridgeIPv4.IP); err != nil {
|
||||
return fmt.Errorf("failed to reserve bridge IP %s: %v", i.bridgeIPv4.IP.String(), err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -120,7 +122,7 @@ func setupGatewayIPv4(config *networkConfiguration, i *bridgeInterface) error {
|
|||
// (if defined), no need otherwise
|
||||
if config.FixedCIDR == nil || config.FixedCIDR.Contains(config.DefaultGatewayIPv4) {
|
||||
if _, err := ipAllocator.RequestIP(i.bridgeIPv4, config.DefaultGatewayIPv4); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("failed to reserve default gateway %s: %v", config.DefaultGatewayIPv4.String(), err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,17 @@ func TestSetupBridgeIPv4Fixed(t *testing.T) {
|
|||
func TestSetupBridgeIPv4Auto(t *testing.T) {
|
||||
defer netutils.SetupTestNetNS(t)()
|
||||
|
||||
var toBeChosen *net.IPNet
|
||||
for _, n := range bridgeNetworks {
|
||||
if err := netutils.CheckRouteOverlaps(n); err == nil {
|
||||
toBeChosen = n
|
||||
break
|
||||
}
|
||||
}
|
||||
if toBeChosen == nil {
|
||||
t.Skipf("Skip as no more automatic networks available")
|
||||
}
|
||||
|
||||
config, br := setupTestInterface(t)
|
||||
if err := setupBridgeIPv4(config, br); err != nil {
|
||||
t.Fatalf("Failed to setup bridge IPv4: %v", err)
|
||||
|
@ -66,14 +77,14 @@ func TestSetupBridgeIPv4Auto(t *testing.T) {
|
|||
|
||||
var found bool
|
||||
for _, addr := range addrsv4 {
|
||||
if bridgeNetworks[0].String() == addr.IPNet.String() {
|
||||
if toBeChosen.String() == addr.IPNet.String() {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
t.Fatalf("Bridge device does not have the automatic IPv4 address %v", bridgeNetworks[0].String())
|
||||
t.Fatalf("Bridge device does not have the automatic IPv4 address %s", toBeChosen.String())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue