|
@@ -98,6 +98,7 @@ type bridgeNetwork struct {
|
|
|
|
|
|
type driver struct {
|
|
type driver struct {
|
|
config *configuration
|
|
config *configuration
|
|
|
|
+ configured bool
|
|
network *bridgeNetwork
|
|
network *bridgeNetwork
|
|
natChain *iptables.ChainInfo
|
|
natChain *iptables.ChainInfo
|
|
filterChain *iptables.ChainInfo
|
|
filterChain *iptables.ChainInfo
|
|
@@ -105,13 +106,10 @@ type driver struct {
|
|
sync.Mutex
|
|
sync.Mutex
|
|
}
|
|
}
|
|
|
|
|
|
-func init() {
|
|
|
|
- ipAllocator = ipallocator.New()
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
// New constructs a new bridge driver
|
|
// New constructs a new bridge driver
|
|
func newDriver() driverapi.Driver {
|
|
func newDriver() driverapi.Driver {
|
|
- return &driver{networks: map[string]*bridgeNetwork{}}
|
|
|
|
|
|
+ ipAllocator = ipallocator.New()
|
|
|
|
+ return &driver{networks: map[string]*bridgeNetwork{}, config: &configuration{}}
|
|
}
|
|
}
|
|
|
|
|
|
// Init registers a new instance of bridge driver
|
|
// Init registers a new instance of bridge driver
|
|
@@ -436,29 +434,26 @@ func (d *driver) Config(option map[string]interface{}) error {
|
|
d.Lock()
|
|
d.Lock()
|
|
defer d.Unlock()
|
|
defer d.Unlock()
|
|
|
|
|
|
- if d.config != nil {
|
|
|
|
|
|
+ if d.configured {
|
|
return &ErrConfigExists{}
|
|
return &ErrConfigExists{}
|
|
}
|
|
}
|
|
|
|
|
|
genericData, ok := option[netlabel.GenericData]
|
|
genericData, ok := option[netlabel.GenericData]
|
|
- if ok && genericData != nil {
|
|
|
|
- switch opt := genericData.(type) {
|
|
|
|
- case options.Generic:
|
|
|
|
- opaqueConfig, err := options.GenerateFromModel(opt, &configuration{})
|
|
|
|
- if err != nil {
|
|
|
|
- return err
|
|
|
|
- }
|
|
|
|
- config = opaqueConfig.(*configuration)
|
|
|
|
- case *configuration:
|
|
|
|
- config = opt
|
|
|
|
- default:
|
|
|
|
- return &ErrInvalidDriverConfig{}
|
|
|
|
- }
|
|
|
|
|
|
+ if !ok || genericData == nil {
|
|
|
|
+ return nil
|
|
|
|
+ }
|
|
|
|
|
|
- d.config = config
|
|
|
|
- } else {
|
|
|
|
- config = &configuration{}
|
|
|
|
- d.config = config
|
|
|
|
|
|
+ switch opt := genericData.(type) {
|
|
|
|
+ case options.Generic:
|
|
|
|
+ opaqueConfig, err := options.GenerateFromModel(opt, &configuration{})
|
|
|
|
+ if err != nil {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+ config = opaqueConfig.(*configuration)
|
|
|
|
+ case *configuration:
|
|
|
|
+ config = opt
|
|
|
|
+ default:
|
|
|
|
+ return &ErrInvalidDriverConfig{}
|
|
}
|
|
}
|
|
|
|
|
|
if config.EnableIPForwarding {
|
|
if config.EnableIPForwarding {
|
|
@@ -470,9 +465,13 @@ func (d *driver) Config(option map[string]interface{}) error {
|
|
|
|
|
|
if config.EnableIPTables {
|
|
if config.EnableIPTables {
|
|
d.natChain, d.filterChain, err = setupIPChains(config)
|
|
d.natChain, d.filterChain, err = setupIPChains(config)
|
|
- return err
|
|
|
|
|
|
+ if err != nil {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ d.configured = true
|
|
|
|
+ d.config = config
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
@@ -569,12 +568,20 @@ func (d *driver) getNetworks() []*bridgeNetwork {
|
|
|
|
|
|
// Create a new network using bridge plugin
|
|
// Create a new network using bridge plugin
|
|
func (d *driver) CreateNetwork(id string, option map[string]interface{}) error {
|
|
func (d *driver) CreateNetwork(id string, option map[string]interface{}) error {
|
|
- var err error
|
|
|
|
|
|
+ var (
|
|
|
|
+ err error
|
|
|
|
+ configLocked bool
|
|
|
|
+ )
|
|
|
|
|
|
defer osl.InitOSContext()()
|
|
defer osl.InitOSContext()()
|
|
|
|
|
|
// Sanity checks
|
|
// Sanity checks
|
|
d.Lock()
|
|
d.Lock()
|
|
|
|
+ if !d.configured {
|
|
|
|
+ configLocked = true
|
|
|
|
+ d.configured = true
|
|
|
|
+ }
|
|
|
|
+
|
|
if _, ok := d.networks[id]; ok {
|
|
if _, ok := d.networks[id]; ok {
|
|
d.Unlock()
|
|
d.Unlock()
|
|
return types.ForbiddenErrorf("network %s exists", id)
|
|
return types.ForbiddenErrorf("network %s exists", id)
|
|
@@ -613,6 +620,10 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}) error {
|
|
defer func() {
|
|
defer func() {
|
|
if err != nil {
|
|
if err != nil {
|
|
d.Lock()
|
|
d.Lock()
|
|
|
|
+ if configLocked {
|
|
|
|
+ d.configured = false
|
|
|
|
+ }
|
|
|
|
+
|
|
delete(d.networks, id)
|
|
delete(d.networks, id)
|
|
d.Unlock()
|
|
d.Unlock()
|
|
}
|
|
}
|
|
@@ -654,7 +665,7 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}) error {
|
|
bridgeSetup.queueStep(setupBridgeIPv4)
|
|
bridgeSetup.queueStep(setupBridgeIPv4)
|
|
|
|
|
|
enableIPv6Forwarding := false
|
|
enableIPv6Forwarding := false
|
|
- if d.config != nil && d.config.EnableIPForwarding && config.FixedCIDRv6 != nil {
|
|
|
|
|
|
+ if d.config.EnableIPForwarding && config.FixedCIDRv6 != nil {
|
|
enableIPv6Forwarding = true
|
|
enableIPv6Forwarding = true
|
|
}
|
|
}
|
|
|
|
|
|
@@ -791,6 +802,18 @@ func (d *driver) DeleteNetwork(nid string) error {
|
|
// Programming
|
|
// Programming
|
|
err = netlink.LinkDel(n.bridge.Link)
|
|
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
|
|
return err
|
|
}
|
|
}
|
|
|
|
|