// Assert function which pushes chains based on bridge config parameters. func assertBridgeConfig(config *networkConfiguration, br *bridgeInterface, t *testing.T) { nw := bridgeNetwork{portMapper: portmapper.New()} // Attempt programming of ip tables. err := nw.setupIPTables(config, br) if err != nil { t.Fatalf("%v", err) } }
// Create a new network using bridge plugin func (d *driver) CreateNetwork(id types.UUID, option map[string]interface{}) error { var err error defer sandbox.InitOSContext()() // Sanity checks d.Lock() if _, ok := d.networks[id]; ok { d.Unlock() return types.ForbiddenErrorf("network %s exists", id) } d.Unlock() // Parse and validate the config. It should not conflict with existing networks' config config, err := parseNetworkOptions(option) if err != nil { return err } networkList := d.getNetworks() for _, nw := range networkList { nw.Lock() nwConfig := nw.config nw.Unlock() if nwConfig.Conflicts(config) { return types.ForbiddenErrorf("conflicts with network %s (%s)", nw.id, nw.config.BridgeName) } } // Create and set network handler in driver network := &bridgeNetwork{ id: id, endpoints: make(map[types.UUID]*bridgeEndpoint), config: config, portMapper: portmapper.New(), } d.Lock() d.networks[id] = network d.Unlock() // On failure make sure to reset driver network handler to nil defer func() { if err != nil { d.Lock() delete(d.networks, id) d.Unlock() } }() // Create or retrieve the bridge L3 interface bridgeIface := newInterface(config) network.bridge = bridgeIface // Verify the network configuration does not conflict with previously installed // networks. This step is needed now because driver might have now set the bridge // name on this config struct. And because we need to check for possible address // conflicts, so we need to check against operationa lnetworks. if err = config.conflictsWithNetworks(id, networkList); err != nil { return err } setupNetworkIsolationRules := func(config *networkConfiguration, i *bridgeInterface) error { if err := network.isolateNetwork(networkList, true); err != nil { if err := network.isolateNetwork(networkList, false); err != nil { logrus.Warnf("Failed on removing the inter-network iptables rules on cleanup: %v", err) } return err } return nil } // Prepare the bridge setup configuration bridgeSetup := newBridgeSetup(config, bridgeIface) // If the bridge interface doesn't exist, we need to start the setup steps // by creating a new device and assigning it an IPv4 address. bridgeAlreadyExists := bridgeIface.exists() if !bridgeAlreadyExists { bridgeSetup.queueStep(setupDevice) } // Even if a bridge exists try to setup IPv4. bridgeSetup.queueStep(setupBridgeIPv4) enableIPv6Forwarding := false if d.config != nil && d.config.EnableIPForwarding && config.FixedCIDRv6 != nil { enableIPv6Forwarding = true } // Conditionally queue setup steps depending on configuration values. for _, step := range []struct { Condition bool Fn setupStep }{ // Enable IPv6 on the bridge if required. We do this even for a // previously existing bridge, as it may be here from a previous // installation where IPv6 wasn't supported yet and needs to be // assigned an IPv6 link-local address. {config.EnableIPv6, setupBridgeIPv6}, // We ensure that the bridge has the expectedIPv4 and IPv6 addresses in // the case of a previously existing device. {bridgeAlreadyExists, setupVerifyAndReconcile}, // Setup the bridge to allocate containers IPv4 addresses in the // specified subnet. {config.FixedCIDR != nil, setupFixedCIDRv4}, // Setup the bridge to allocate containers global IPv6 addresses in the // specified subnet. {config.FixedCIDRv6 != nil, setupFixedCIDRv6}, // Enable IPv6 Forwarding {enableIPv6Forwarding, setupIPv6Forwarding}, // Setup Loopback Adresses Routing {!config.EnableUserlandProxy, setupLoopbackAdressesRouting}, // Setup IPTables. {config.EnableIPTables, network.setupIPTables}, //We want to track firewalld configuration so that //if it is started/reloaded, the rules can be applied correctly {config.EnableIPTables, network.setupFirewalld}, // Setup DefaultGatewayIPv4 {config.DefaultGatewayIPv4 != nil, setupGatewayIPv4}, // Setup DefaultGatewayIPv6 {config.DefaultGatewayIPv6 != nil, setupGatewayIPv6}, // Add inter-network communication rules. {config.EnableIPTables, setupNetworkIsolationRules}, //Configure bridge networking filtering if ICC is off and IP tables are enabled {!config.EnableICC && config.EnableIPTables, setupBridgeNetFiltering}, } { if step.Condition { bridgeSetup.queueStep(step.Fn) } } // Block bridge IP from being allocated. bridgeSetup.queueStep(allocateBridgeIP) // Apply the prepared list of steps, and abort at the first error. bridgeSetup.queueStep(setupDeviceUp) if err = bridgeSetup.apply(); err != nil { return err } return nil }
func init() { ipAllocator = ipallocator.New() portMapper = portmapper.New() }
func (d *driver) createNetwork(config *networkConfiguration) error { var err error defer osl.InitOSContext()() networkList := d.getNetworks() for i, nw := range networkList { nw.Lock() nwConfig := nw.config nw.Unlock() if err := nwConfig.Conflicts(config); err != nil { if config.DefaultBridge { // We encountered and identified a stale default network // We must delete it as libnetwork is the source of thruth // The default network being created must be the only one // This can happen only from docker 1.12 on ward logrus.Infof("Removing stale default bridge network %s (%s)", nwConfig.ID, nwConfig.BridgeName) if err := d.DeleteNetwork(nwConfig.ID); err != nil { logrus.Warnf("Failed to remove stale default network: %s (%s): %v. Will remove from store.", nwConfig.ID, nwConfig.BridgeName, err) d.storeDelete(nwConfig) } networkList = append(networkList[:i], networkList[i+1:]...) } else { return types.ForbiddenErrorf("cannot create network %s (%s): conflicts with network %s (%s): %s", config.ID, config.BridgeName, nwConfig.ID, nwConfig.BridgeName, err.Error()) } } } // Create and set network handler in driver network := &bridgeNetwork{ id: config.ID, endpoints: make(map[string]*bridgeEndpoint), config: config, portMapper: portmapper.New(), driver: d, } d.Lock() d.networks[config.ID] = network d.Unlock() // On failure make sure to reset driver network handler to nil defer func() { if err != nil { d.Lock() delete(d.networks, config.ID) d.Unlock() } }() // Initialize handle when needed d.Lock() if d.nlh == nil { d.nlh = ns.NlHandle() } d.Unlock() // Create or retrieve the bridge L3 interface bridgeIface := newInterface(d.nlh, config) network.bridge = bridgeIface // Verify the network configuration does not conflict with previously installed // networks. This step is needed now because driver might have now set the bridge // name on this config struct. And because we need to check for possible address // conflicts, so we need to check against operationa lnetworks. if err = config.conflictsWithNetworks(config.ID, networkList); err != nil { return err } setupNetworkIsolationRules := func(config *networkConfiguration, i *bridgeInterface) error { if err := network.isolateNetwork(networkList, true); err != nil { if err := network.isolateNetwork(networkList, false); err != nil { logrus.Warnf("Failed on removing the inter-network iptables rules on cleanup: %v", err) } return err } network.registerIptCleanFunc(func() error { nwList := d.getNetworks() return network.isolateNetwork(nwList, false) }) return nil } // Prepare the bridge setup configuration bridgeSetup := newBridgeSetup(config, bridgeIface) // If the bridge interface doesn't exist, we need to start the setup steps // by creating a new device and assigning it an IPv4 address. bridgeAlreadyExists := bridgeIface.exists() if !bridgeAlreadyExists { bridgeSetup.queueStep(setupDevice) } // Even if a bridge exists try to setup IPv4. bridgeSetup.queueStep(setupBridgeIPv4) enableIPv6Forwarding := d.config.EnableIPForwarding && config.AddressIPv6 != nil // Conditionally queue setup steps depending on configuration values. for _, step := range []struct { Condition bool Fn setupStep }{ // Enable IPv6 on the bridge if required. We do this even for a // previously existing bridge, as it may be here from a previous // installation where IPv6 wasn't supported yet and needs to be // assigned an IPv6 link-local address. {config.EnableIPv6, setupBridgeIPv6}, // We ensure that the bridge has the expectedIPv4 and IPv6 addresses in // the case of a previously existing device. {bridgeAlreadyExists, setupVerifyAndReconcile}, // Enable IPv6 Forwarding {enableIPv6Forwarding, setupIPv6Forwarding}, // Setup Loopback Adresses Routing {!d.config.EnableUserlandProxy, setupLoopbackAdressesRouting}, // Setup IPTables. {d.config.EnableIPTables, network.setupIPTables}, //We want to track firewalld configuration so that //if it is started/reloaded, the rules can be applied correctly {d.config.EnableIPTables, network.setupFirewalld}, // Setup DefaultGatewayIPv4 {config.DefaultGatewayIPv4 != nil, setupGatewayIPv4}, // Setup DefaultGatewayIPv6 {config.DefaultGatewayIPv6 != nil, setupGatewayIPv6}, // Add inter-network communication rules. {d.config.EnableIPTables, setupNetworkIsolationRules}, //Configure bridge networking filtering if ICC is off and IP tables are enabled {!config.EnableICC && d.config.EnableIPTables, setupBridgeNetFiltering}, } { if step.Condition { bridgeSetup.queueStep(step.Fn) } } // Apply the prepared list of steps, and abort at the first error. bridgeSetup.queueStep(setupDeviceUp) if err = bridgeSetup.apply(); err != nil { return err } return nil }
func (d *driver) createNetwork(config *networkConfiguration) error { var err error logrus.Infof("Creating bridge network: %s %s %s", config.ID, config.BridgeName, config.AddressIPv4) networkList := d.getNetworks() for i, nw := range networkList { nw.Lock() nwConfig := nw.config nw.Unlock() if err := nwConfig.Conflicts(config); err != nil { if config.DefaultBridge { // We encountered and identified a stale default network // We must delete it as libnetwork is the source of thruth // The default network being created must be the only one // This can happen only from docker 1.12 on ward logrus.Infof("Removing stale default bridge network %s (%s)", nwConfig.ID, nwConfig.BridgeName) if err := d.DeleteNetwork(nwConfig.ID); err != nil { logrus.Warnf("Failed to remove stale default network: %s (%s): %v. Will remove from store.", nwConfig.ID, nwConfig.BridgeName, err) d.storeDelete(nwConfig) } networkList = append(networkList[:i], networkList[i+1:]...) } else { return types.ForbiddenErrorf( "cannot create network %s (%s): "+ "conflicts with network %s (%s): %s", nwConfig.BridgeName, config.ID, nw.id, nw.config.BridgeName, err.Error()) } } } if config.DefaultBindingIP == nil || config.DefaultBindingIP.IsUnspecified() { config.DefaultBindingIP = d.defrouteIP } // Create and set network handler in driver network := &bridgeNetwork{ id: config.ID, endpoints: make(map[string]*bridgeEndpoint), config: config, portMapper: portmapper.New(""), driver: d, } d.Lock() d.networks[config.ID] = network d.Unlock() // On failure make sure to reset driver network handler to nil defer func() { if err != nil { d.Lock() delete(d.networks, config.ID) d.Unlock() } }() // Create or retrieve the bridge L3 interface bridgeIface := newInterface(config) network.bridge = bridgeIface // Verify the network configuration does not conflict with previously installed // networks. This step is needed now because driver might have now set the bridge // name on this config struct. And because we need to check for possible address // conflicts, so we need to check against operational networks. if err = config.conflictsWithNetworks(config.ID, networkList); err != nil { return err } // We only attempt to create the bridge when the requested device name is // the default one. if config.BridgeName != DefaultBridgeName && config.DefaultBridge { return NonDefaultBridgeExistError(config.BridgeName) } bridgeCleanup(config, false) err = bridgeSetup(config) if err != nil { return err } return nil }