Merge pull request #600 from aboch/br
Bridge driver changes to support IPAM model
This commit is contained in:
commit
82660a9d6f
|
@ -5,6 +5,7 @@ package bitseq
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
@ -392,6 +393,38 @@ func (h *Handle) String() string {
|
||||||
h.app, h.id, h.dbIndex, h.bits, h.unselected, h.head.toString())
|
h.app, h.id, h.dbIndex, h.bits, h.unselected, h.head.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MarshalJSON encodes Handle into json message
|
||||||
|
func (h *Handle) MarshalJSON() ([]byte, error) {
|
||||||
|
m := map[string]interface{}{
|
||||||
|
"id": h.id,
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := h.ToByteArray()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
m["sequence"] = b
|
||||||
|
return json.Marshal(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON decodes json message into Handle
|
||||||
|
func (h *Handle) UnmarshalJSON(data []byte) error {
|
||||||
|
var (
|
||||||
|
m map[string]interface{}
|
||||||
|
b []byte
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if err = json.Unmarshal(data, &m); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
h.id = m["id"].(string)
|
||||||
|
bi, _ := json.Marshal(m["sequence"])
|
||||||
|
if err := json.Unmarshal(bi, &b); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return h.FromByteArray(b)
|
||||||
|
}
|
||||||
|
|
||||||
// getFirstAvailable looks for the first unset bit in passed mask starting from start
|
// getFirstAvailable looks for the first unset bit in passed mask starting from start
|
||||||
func getFirstAvailable(head *sequence, start uint32) (uint32, uint32, error) {
|
func getFirstAvailable(head *sequence, start uint32) (uint32, uint32, error) {
|
||||||
// Find sequence which contains the start bit
|
// Find sequence which contains the start bit
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
|
||||||
"github.com/docker/libnetwork/datastore"
|
"github.com/docker/libnetwork/datastore"
|
||||||
"github.com/docker/libnetwork/types"
|
"github.com/docker/libnetwork/types"
|
||||||
)
|
)
|
||||||
|
@ -25,27 +24,16 @@ func (h *Handle) KeyPrefix() []string {
|
||||||
|
|
||||||
// Value marshals the data to be stored in the KV store
|
// Value marshals the data to be stored in the KV store
|
||||||
func (h *Handle) Value() []byte {
|
func (h *Handle) Value() []byte {
|
||||||
b, err := h.ToByteArray()
|
b, err := json.Marshal(h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("Failed to serialize Handle: %v", err)
|
return nil
|
||||||
b = []byte{}
|
|
||||||
}
|
}
|
||||||
jv, err := json.Marshal(b)
|
return b
|
||||||
if err != nil {
|
|
||||||
log.Warnf("Failed to json encode bitseq handler byte array: %v", err)
|
|
||||||
return []byte{}
|
|
||||||
}
|
|
||||||
return jv
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetValue unmarshals the data from the KV store
|
// SetValue unmarshals the data from the KV store
|
||||||
func (h *Handle) SetValue(value []byte) error {
|
func (h *Handle) SetValue(value []byte) error {
|
||||||
var b []byte
|
return json.Unmarshal(value, h)
|
||||||
if err := json.Unmarshal(value, &b); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.FromByteArray(b)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Index returns the latest DB Index as seen by this object
|
// Index returns the latest DB Index as seen by this object
|
||||||
|
@ -77,7 +65,6 @@ func (h *Handle) New() datastore.KVObject {
|
||||||
|
|
||||||
return &Handle{
|
return &Handle{
|
||||||
app: h.app,
|
app: h.app,
|
||||||
id: h.id,
|
|
||||||
store: h.store,
|
store: h.store,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,10 @@ import (
|
||||||
"github.com/docker/libnetwork/config"
|
"github.com/docker/libnetwork/config"
|
||||||
"github.com/docker/libnetwork/datastore"
|
"github.com/docker/libnetwork/datastore"
|
||||||
"github.com/docker/libnetwork/driverapi"
|
"github.com/docker/libnetwork/driverapi"
|
||||||
|
"github.com/docker/libnetwork/ipamutils"
|
||||||
"github.com/docker/libnetwork/netlabel"
|
"github.com/docker/libnetwork/netlabel"
|
||||||
"github.com/docker/libnetwork/options"
|
"github.com/docker/libnetwork/options"
|
||||||
|
"github.com/docker/libnetwork/types"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -187,7 +189,12 @@ func createDefaultNetwork(c libnetwork.NetworkController) {
|
||||||
}
|
}
|
||||||
createOptions = append(createOptions,
|
createOptions = append(createOptions,
|
||||||
libnetwork.NetworkOptionGeneric(genericOption),
|
libnetwork.NetworkOptionGeneric(genericOption),
|
||||||
libnetwork.NetworkOptionPersist(false))
|
ipamOption(nw))
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := c.NetworkByName(nw); err == nil {
|
||||||
|
logrus.Debugf("Default network %s already present", nw)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
_, err := c.NewNetwork(d, nw, createOptions...)
|
_, err := c.NewNetwork(d, nw, createOptions...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -405,3 +412,15 @@ func encodeData(data interface{}) (*bytes.Buffer, error) {
|
||||||
}
|
}
|
||||||
return params, nil
|
return params, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ipamOption(bridgeName string) libnetwork.NetworkOption {
|
||||||
|
if nw, _, err := ipamutils.ElectInterfaceAddresses(bridgeName); err == nil {
|
||||||
|
ipamV4Conf := &libnetwork.IpamConf{PreferredPool: nw.String()}
|
||||||
|
hip, _ := types.GetHostPartIP(nw.IP, nw.Mask)
|
||||||
|
if hip.IsGlobalUnicast() {
|
||||||
|
ipamV4Conf.Gateway = nw.IP.String()
|
||||||
|
}
|
||||||
|
return libnetwork.NetworkOptionIpam("default", "", []*libnetwork.IpamConf{ipamV4Conf}, nil)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -35,6 +35,13 @@ const (
|
||||||
maxAllocatePortAttempts = 10
|
maxAllocatePortAttempts = 10
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// DefaultGatewayV4AuxKey represents the default-gateway configured by the user
|
||||||
|
DefaultGatewayV4AuxKey = "DefaultGatewayIPv4"
|
||||||
|
// DefaultGatewayV6AuxKey represents the ipv6 default-gateway configured by the user
|
||||||
|
DefaultGatewayV6AuxKey = "DefaultGatewayIPv6"
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ipAllocator *ipallocator.IPAllocator
|
ipAllocator *ipallocator.IPAllocator
|
||||||
)
|
)
|
||||||
|
@ -49,17 +56,17 @@ type configuration struct {
|
||||||
// networkConfiguration for network specific configuration
|
// networkConfiguration for network specific configuration
|
||||||
type networkConfiguration struct {
|
type networkConfiguration struct {
|
||||||
BridgeName string
|
BridgeName string
|
||||||
AddressIPv4 *net.IPNet
|
|
||||||
FixedCIDR *net.IPNet
|
|
||||||
FixedCIDRv6 *net.IPNet
|
|
||||||
EnableIPv6 bool
|
EnableIPv6 bool
|
||||||
EnableIPMasquerade bool
|
EnableIPMasquerade bool
|
||||||
EnableICC bool
|
EnableICC bool
|
||||||
Mtu int
|
Mtu int
|
||||||
DefaultGatewayIPv4 net.IP
|
|
||||||
DefaultGatewayIPv6 net.IP
|
|
||||||
DefaultBindingIP net.IP
|
DefaultBindingIP net.IP
|
||||||
DefaultBridge bool
|
DefaultBridge bool
|
||||||
|
// Internal fields set after ipam data parsing
|
||||||
|
AddressIPv4 *net.IPNet
|
||||||
|
AddressIPv6 *net.IPNet
|
||||||
|
DefaultGatewayIPv4 net.IP
|
||||||
|
DefaultGatewayIPv6 net.IP
|
||||||
}
|
}
|
||||||
|
|
||||||
// endpointConfiguration represents the user specified configuration for the sandbox endpoint
|
// endpointConfiguration represents the user specified configuration for the sandbox endpoint
|
||||||
|
@ -148,19 +155,6 @@ func (c *networkConfiguration) Validate() error {
|
||||||
|
|
||||||
// If bridge v4 subnet is specified
|
// If bridge v4 subnet is specified
|
||||||
if c.AddressIPv4 != nil {
|
if c.AddressIPv4 != nil {
|
||||||
// If Container restricted subnet is specified, it must be a subset of bridge subnet
|
|
||||||
if c.FixedCIDR != nil {
|
|
||||||
// Check Network address
|
|
||||||
if !c.AddressIPv4.Contains(c.FixedCIDR.IP) {
|
|
||||||
return &ErrInvalidContainerSubnet{}
|
|
||||||
}
|
|
||||||
// Check it is effectively a subset
|
|
||||||
brNetLen, _ := c.AddressIPv4.Mask.Size()
|
|
||||||
cnNetLen, _ := c.FixedCIDR.Mask.Size()
|
|
||||||
if brNetLen > cnNetLen {
|
|
||||||
return &ErrInvalidContainerSubnet{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If default gw is specified, it must be part of bridge subnet
|
// If default gw is specified, it must be part of bridge subnet
|
||||||
if c.DefaultGatewayIPv4 != nil {
|
if c.DefaultGatewayIPv4 != nil {
|
||||||
if !c.AddressIPv4.Contains(c.DefaultGatewayIPv4) {
|
if !c.AddressIPv4.Contains(c.DefaultGatewayIPv4) {
|
||||||
|
@ -169,34 +163,39 @@ func (c *networkConfiguration) Validate() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If default v6 gw is specified, FixedCIDRv6 must be specified and gw must belong to FixedCIDRv6 subnet
|
// If default v6 gw is specified, AddressIPv6 must be specified and gw must belong to AddressIPv6 subnet
|
||||||
if c.EnableIPv6 && c.DefaultGatewayIPv6 != nil {
|
if c.EnableIPv6 && c.DefaultGatewayIPv6 != nil {
|
||||||
if c.FixedCIDRv6 == nil || !c.FixedCIDRv6.Contains(c.DefaultGatewayIPv6) {
|
if c.AddressIPv6 == nil || !c.AddressIPv6.Contains(c.DefaultGatewayIPv6) {
|
||||||
return &ErrInvalidGateway{}
|
return &ErrInvalidGateway{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Conflicts check if two NetworkConfiguration objects overlap
|
// Conflicts check if two NetworkConfiguration objects overlap
|
||||||
func (c *networkConfiguration) Conflicts(o *networkConfiguration) bool {
|
func (c *networkConfiguration) Conflicts(o *networkConfiguration) error {
|
||||||
if o == nil {
|
if o == nil {
|
||||||
return false
|
return fmt.Errorf("same configuration")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also empty, becasue only one network with empty name is allowed
|
// Also empty, becasue only one network with empty name is allowed
|
||||||
if c.BridgeName == o.BridgeName {
|
if c.BridgeName == o.BridgeName {
|
||||||
return true
|
return fmt.Errorf("networks have same name")
|
||||||
}
|
}
|
||||||
|
|
||||||
// They must be in different subnets
|
// They must be in different subnets
|
||||||
if (c.AddressIPv4 != nil && o.AddressIPv4 != nil) &&
|
if (c.AddressIPv4 != nil && o.AddressIPv4 != nil) &&
|
||||||
(c.AddressIPv4.Contains(o.AddressIPv4.IP) || o.AddressIPv4.Contains(c.AddressIPv4.IP)) {
|
(c.AddressIPv4.Contains(o.AddressIPv4.IP) || o.AddressIPv4.Contains(c.AddressIPv4.IP)) {
|
||||||
return true
|
return fmt.Errorf("networks have overlapping IPv4")
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
// They must be in different v6 subnets
|
||||||
|
if (c.AddressIPv6 != nil && o.AddressIPv6 != nil) &&
|
||||||
|
(c.AddressIPv6.Contains(o.AddressIPv6.IP) || o.AddressIPv6.Contains(c.AddressIPv6.IP)) {
|
||||||
|
return fmt.Errorf("networks have overlapping IPv6")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// fromMap retrieve the configuration data from the map form.
|
// fromMap retrieve the configuration data from the map form.
|
||||||
|
@ -259,65 +258,6 @@ func (c *networkConfiguration) fromMap(data map[string]interface{}) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if i, ok := data["AddressIPv4"]; ok && i != nil {
|
|
||||||
if s, ok := i.(string); ok {
|
|
||||||
if ip, nw, e := net.ParseCIDR(s); e == nil {
|
|
||||||
nw.IP = ip
|
|
||||||
c.AddressIPv4 = nw
|
|
||||||
} else {
|
|
||||||
return types.BadRequestErrorf("failed to parse AddressIPv4 value")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return types.BadRequestErrorf("invalid type for AddressIPv4 value")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if i, ok := data["FixedCIDR"]; ok && i != nil {
|
|
||||||
if s, ok := i.(string); ok {
|
|
||||||
if ip, nw, e := net.ParseCIDR(s); e == nil {
|
|
||||||
nw.IP = ip
|
|
||||||
c.FixedCIDR = nw
|
|
||||||
} else {
|
|
||||||
return types.BadRequestErrorf("failed to parse FixedCIDR value")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return types.BadRequestErrorf("invalid type for FixedCIDR value")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if i, ok := data["FixedCIDRv6"]; ok && i != nil {
|
|
||||||
if s, ok := i.(string); ok {
|
|
||||||
if ip, nw, e := net.ParseCIDR(s); e == nil {
|
|
||||||
nw.IP = ip
|
|
||||||
c.FixedCIDRv6 = nw
|
|
||||||
} else {
|
|
||||||
return types.BadRequestErrorf("failed to parse FixedCIDRv6 value")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return types.BadRequestErrorf("invalid type for FixedCIDRv6 value")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if i, ok := data["DefaultGatewayIPv4"]; ok && i != nil {
|
|
||||||
if s, ok := i.(string); ok {
|
|
||||||
if c.DefaultGatewayIPv4 = net.ParseIP(s); c.DefaultGatewayIPv4 == nil {
|
|
||||||
return types.BadRequestErrorf("failed to parse DefaultGatewayIPv4 value")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return types.BadRequestErrorf("invalid type for DefaultGatewayIPv4 value")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if i, ok := data["DefaultGatewayIPv6"]; ok && i != nil {
|
|
||||||
if s, ok := i.(string); ok {
|
|
||||||
if c.DefaultGatewayIPv6 = net.ParseIP(s); c.DefaultGatewayIPv6 == nil {
|
|
||||||
return types.BadRequestErrorf("failed to parse DefaultGatewayIPv6 value")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return types.BadRequestErrorf("invalid type for DefaultGatewayIPv6 value")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if i, ok := data["DefaultBindingIP"]; ok && i != nil {
|
if i, ok := data["DefaultBindingIP"]; ok && i != nil {
|
||||||
if s, ok := i.(string); ok {
|
if s, ok := i.(string); ok {
|
||||||
if c.DefaultBindingIP = net.ParseIP(s); c.DefaultBindingIP == nil {
|
if c.DefaultBindingIP = net.ParseIP(s); c.DefaultBindingIP == nil {
|
||||||
|
@ -327,6 +267,7 @@ func (c *networkConfiguration) fromMap(data map[string]interface{}) error {
|
||||||
return types.BadRequestErrorf("invalid type for DefaultBindingIP value")
|
return types.BadRequestErrorf("invalid type for DefaultBindingIP value")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,6 +457,36 @@ func parseNetworkGenericOptions(data interface{}) (*networkConfiguration, error)
|
||||||
return config, err
|
return config, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *networkConfiguration) processIPAM(id string, ipamV4Data, ipamV6Data []driverapi.IPAMData) error {
|
||||||
|
if len(ipamV4Data) > 1 || len(ipamV6Data) > 1 {
|
||||||
|
return types.ForbiddenErrorf("bridge driver doesnt support multiple subnets")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ipamV4Data) == 0 {
|
||||||
|
return types.BadRequestErrorf("bridge network %s requires ipv4 configuration", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ipamV4Data[0].Gateway != nil {
|
||||||
|
c.AddressIPv4 = types.GetIPNetCopy(ipamV4Data[0].Gateway)
|
||||||
|
}
|
||||||
|
|
||||||
|
if gw, ok := ipamV4Data[0].AuxAddresses[DefaultGatewayV4AuxKey]; ok {
|
||||||
|
c.DefaultGatewayIPv4 = gw.IP
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ipamV6Data) > 0 {
|
||||||
|
if ipamV6Data[0].Gateway != nil {
|
||||||
|
c.AddressIPv6 = types.GetIPNetCopy(ipamV6Data[0].Gateway)
|
||||||
|
}
|
||||||
|
|
||||||
|
if gw, ok := ipamV6Data[0].AuxAddresses[DefaultGatewayV6AuxKey]; ok {
|
||||||
|
c.DefaultGatewayIPv6 = gw.IP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func parseNetworkOptions(id string, option options.Generic) (*networkConfiguration, error) {
|
func parseNetworkOptions(id string, option options.Generic) (*networkConfiguration, error) {
|
||||||
var err error
|
var err error
|
||||||
config := &networkConfiguration{}
|
config := &networkConfiguration{}
|
||||||
|
@ -545,10 +516,9 @@ func parseNetworkOptions(id string, option options.Generic) (*networkConfigurati
|
||||||
|
|
||||||
// Returns the non link-local IPv6 subnet for the containers attached to this bridge if found, nil otherwise
|
// Returns the non link-local IPv6 subnet for the containers attached to this bridge if found, nil otherwise
|
||||||
func getV6Network(config *networkConfiguration, i *bridgeInterface) *net.IPNet {
|
func getV6Network(config *networkConfiguration, i *bridgeInterface) *net.IPNet {
|
||||||
if config.FixedCIDRv6 != nil {
|
if config.AddressIPv6 != nil {
|
||||||
return config.FixedCIDRv6
|
return config.AddressIPv6
|
||||||
}
|
}
|
||||||
|
|
||||||
if i.bridgeIPv6 != nil && i.bridgeIPv6.IP != nil && !i.bridgeIPv6.IP.IsLinkLocalUnicast() {
|
if i.bridgeIPv6 != nil && i.bridgeIPv6.IP != nil && !i.bridgeIPv6.IP.IsLinkLocalUnicast() {
|
||||||
return i.bridgeIPv6
|
return i.bridgeIPv6
|
||||||
}
|
}
|
||||||
|
@ -587,13 +557,20 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, ipV4Dat
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = config.processIPAM(id, ipV4Data, ipV6Data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
networkList := d.getNetworks()
|
networkList := d.getNetworks()
|
||||||
for _, nw := range networkList {
|
for _, nw := range networkList {
|
||||||
nw.Lock()
|
nw.Lock()
|
||||||
nwConfig := nw.config
|
nwConfig := nw.config
|
||||||
nw.Unlock()
|
nw.Unlock()
|
||||||
if nwConfig.Conflicts(config) {
|
if err := nwConfig.Conflicts(config); err != nil {
|
||||||
return types.ForbiddenErrorf("conflicts with network %s (%s)", nw.id, nw.config.BridgeName)
|
return types.ForbiddenErrorf("cannot create network %s (%s): conflicts with network %s (%s): %s",
|
||||||
|
nwConfig.BridgeName, id, nw.id, nw.config.BridgeName, err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -654,10 +631,7 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, ipV4Dat
|
||||||
// Even if a bridge exists try to setup IPv4.
|
// Even if a bridge exists try to setup IPv4.
|
||||||
bridgeSetup.queueStep(setupBridgeIPv4)
|
bridgeSetup.queueStep(setupBridgeIPv4)
|
||||||
|
|
||||||
enableIPv6Forwarding := false
|
enableIPv6Forwarding := d.config.EnableIPForwarding && config.AddressIPv6 != nil
|
||||||
if d.config.EnableIPForwarding && config.FixedCIDRv6 != nil {
|
|
||||||
enableIPv6Forwarding = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Conditionally queue setup steps depending on configuration values.
|
// Conditionally queue setup steps depending on configuration values.
|
||||||
for _, step := range []struct {
|
for _, step := range []struct {
|
||||||
|
@ -674,14 +648,6 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, ipV4Dat
|
||||||
// the case of a previously existing device.
|
// the case of a previously existing device.
|
||||||
{bridgeAlreadyExists, setupVerifyAndReconcile},
|
{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
|
// Enable IPv6 Forwarding
|
||||||
{enableIPv6Forwarding, setupIPv6Forwarding},
|
{enableIPv6Forwarding, setupIPv6Forwarding},
|
||||||
|
|
||||||
|
@ -712,8 +678,6 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, ipV4Dat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block bridge IP from being allocated.
|
|
||||||
bridgeSetup.queueStep(allocateBridgeIP)
|
|
||||||
// Apply the prepared list of steps, and abort at the first error.
|
// Apply the prepared list of steps, and abort at the first error.
|
||||||
bridgeSetup.queueStep(setupDeviceUp)
|
bridgeSetup.queueStep(setupDeviceUp)
|
||||||
if err = bridgeSetup.apply(); err != nil {
|
if err = bridgeSetup.apply(); err != nil {
|
||||||
|
@ -790,21 +754,7 @@ func (d *driver) DeleteNetwork(nid string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Programming
|
// Programming
|
||||||
err = netlink.LinkDel(n.bridge.Link)
|
return 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func addToBridge(ifaceName, bridgeName string) error {
|
func addToBridge(ifaceName, bridgeName string) error {
|
||||||
|
@ -862,11 +812,6 @@ func setHairpinMode(link netlink.Link, enable bool) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, epOptions map[string]interface{}) error {
|
func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, epOptions map[string]interface{}) error {
|
||||||
var (
|
|
||||||
ipv6Addr *net.IPNet
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
|
|
||||||
defer osl.InitOSContext()()
|
defer osl.InitOSContext()()
|
||||||
|
|
||||||
if ifInfo == nil {
|
if ifInfo == nil {
|
||||||
|
@ -996,12 +941,11 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// v4 address for the sandbox side pipe interface
|
// Create the sandbox side pipe interface
|
||||||
ip4, err := ipAllocator.RequestIP(n.bridge.bridgeIPv4, nil)
|
endpoint.srcName = containerIfName
|
||||||
if err != nil {
|
endpoint.macAddress = ifInfo.MacAddress()
|
||||||
return err
|
endpoint.addr = ifInfo.Address()
|
||||||
}
|
endpoint.addrv6 = ifInfo.AddressIPv6()
|
||||||
ipv4Addr := &net.IPNet{IP: ip4, Mask: n.bridge.bridgeIPv4.Mask}
|
|
||||||
|
|
||||||
// Down the interface before configuring mac address.
|
// Down the interface before configuring mac address.
|
||||||
if err = netlink.LinkSetDown(sbox); err != nil {
|
if err = netlink.LinkSetDown(sbox); err != nil {
|
||||||
|
@ -1009,51 +953,38 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the sbox's MAC. If specified, use the one configured by user, otherwise generate one based on IP.
|
// Set the sbox's MAC. If specified, use the one configured by user, otherwise generate one based on IP.
|
||||||
mac := electMacAddress(epConfig, ip4)
|
if endpoint.macAddress == nil {
|
||||||
err = netlink.LinkSetHardwareAddr(sbox, mac)
|
endpoint.macAddress = electMacAddress(epConfig, endpoint.addr.IP)
|
||||||
|
if err := ifInfo.SetMacAddress(endpoint.macAddress); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = netlink.LinkSetHardwareAddr(sbox, endpoint.macAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not set mac address for container interface %s: %v", containerIfName, err)
|
return fmt.Errorf("could not set mac address for container interface %s: %v", containerIfName, err)
|
||||||
}
|
}
|
||||||
endpoint.macAddress = mac
|
|
||||||
|
|
||||||
// Up the host interface after finishing all netlink configuration
|
// Up the host interface after finishing all netlink configuration
|
||||||
if err = netlink.LinkSetUp(host); err != nil {
|
if err = netlink.LinkSetUp(host); err != nil {
|
||||||
return fmt.Errorf("could not set link up for host interface %s: %v", hostIfName, err)
|
return fmt.Errorf("could not set link up for host interface %s: %v", hostIfName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// v6 address for the sandbox side pipe interface
|
if endpoint.addrv6 == nil && config.EnableIPv6 {
|
||||||
ipv6Addr = &net.IPNet{}
|
|
||||||
if config.EnableIPv6 {
|
|
||||||
var ip6 net.IP
|
var ip6 net.IP
|
||||||
|
|
||||||
network := n.bridge.bridgeIPv6
|
network := n.bridge.bridgeIPv6
|
||||||
if config.FixedCIDRv6 != nil {
|
|
||||||
network = config.FixedCIDRv6
|
|
||||||
}
|
|
||||||
|
|
||||||
ones, _ := network.Mask.Size()
|
ones, _ := network.Mask.Size()
|
||||||
if ones <= 80 {
|
if ones <= 80 {
|
||||||
ip6 = make(net.IP, len(network.IP))
|
ip6 = make(net.IP, len(network.IP))
|
||||||
copy(ip6, network.IP)
|
copy(ip6, network.IP)
|
||||||
for i, h := range mac {
|
for i, h := range endpoint.macAddress {
|
||||||
ip6[i+10] = h
|
ip6[i+10] = h
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ip6, err := ipAllocator.RequestIP(network, ip6)
|
endpoint.addrv6 = &net.IPNet{IP: ip6, Mask: network.Mask}
|
||||||
if err != nil {
|
if err := ifInfo.SetIPAddress(endpoint.addrv6); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ipv6Addr = &net.IPNet{IP: ip6, Mask: network.Mask}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the sandbox side pipe interface
|
|
||||||
endpoint.srcName = containerIfName
|
|
||||||
endpoint.addr = ipv4Addr
|
|
||||||
|
|
||||||
if config.EnableIPv6 {
|
|
||||||
endpoint.addrv6 = ipv6Addr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Program any required port mapping and store them in the endpoint
|
// Program any required port mapping and store them in the endpoint
|
||||||
|
@ -1062,21 +993,6 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ifInfo.SetMacAddress(endpoint.macAddress)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = ifInfo.SetIPAddress(ipv4Addr)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if config.EnableIPv6 {
|
|
||||||
err = ifInfo.SetIPAddress(ipv6Addr)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1140,22 +1056,6 @@ func (d *driver) DeleteEndpoint(nid, eid string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Lock()
|
|
||||||
config := n.config
|
|
||||||
n.Unlock()
|
|
||||||
|
|
||||||
// Release the v6 address allocated to this endpoint's sandbox interface
|
|
||||||
if config.EnableIPv6 {
|
|
||||||
network := n.bridge.bridgeIPv6
|
|
||||||
if config.FixedCIDRv6 != nil {
|
|
||||||
network = config.FixedCIDRv6
|
|
||||||
}
|
|
||||||
err := ipAllocator.ReleaseIP(network, ep.addrv6.IP)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try removal of link. Discard error: link pair might have
|
// Try removal of link. Discard error: link pair might have
|
||||||
// already been deleted by sandbox delete. Make sure defer
|
// already been deleted by sandbox delete. Make sure defer
|
||||||
// does not see this error either.
|
// does not see this error either.
|
||||||
|
|
|
@ -8,14 +8,27 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/libnetwork/driverapi"
|
"github.com/docker/libnetwork/driverapi"
|
||||||
|
"github.com/docker/libnetwork/ipamutils"
|
||||||
"github.com/docker/libnetwork/iptables"
|
"github.com/docker/libnetwork/iptables"
|
||||||
"github.com/docker/libnetwork/netlabel"
|
"github.com/docker/libnetwork/netlabel"
|
||||||
"github.com/docker/libnetwork/netutils"
|
|
||||||
"github.com/docker/libnetwork/testutils"
|
"github.com/docker/libnetwork/testutils"
|
||||||
"github.com/docker/libnetwork/types"
|
"github.com/docker/libnetwork/types"
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func getIPv4Data(t *testing.T) []driverapi.IPAMData {
|
||||||
|
ipd := driverapi.IPAMData{AddressSpace: "full"}
|
||||||
|
nw, _, err := ipamutils.ElectInterfaceAddresses("")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
ipd.Pool = nw
|
||||||
|
// Set network gateway to X.X.X.1
|
||||||
|
ipd.Gateway = types.GetIPNetCopy(nw)
|
||||||
|
ipd.Gateway.IP[len(ipd.Gateway.IP)-1] = 1
|
||||||
|
return []driverapi.IPAMData{ipd}
|
||||||
|
}
|
||||||
|
|
||||||
func TestCreateFullOptions(t *testing.T) {
|
func TestCreateFullOptions(t *testing.T) {
|
||||||
defer testutils.SetupTestOSContext(t)()
|
defer testutils.SetupTestOSContext(t)()
|
||||||
d := newDriver()
|
d := newDriver()
|
||||||
|
@ -27,20 +40,15 @@ func TestCreateFullOptions(t *testing.T) {
|
||||||
|
|
||||||
// Test this scenario: Default gw address does not belong to
|
// Test this scenario: Default gw address does not belong to
|
||||||
// container network and it's greater than bridge address
|
// container network and it's greater than bridge address
|
||||||
cip, cnw, _ := net.ParseCIDR("172.16.122.0/24")
|
cnw, _ := types.ParseCIDR("172.16.122.0/24")
|
||||||
cnw.IP = cip
|
bnw, _ := types.ParseCIDR("172.16.0.0/24")
|
||||||
ip, nw, _ := net.ParseCIDR("172.16.0.10/16")
|
br, _ := types.ParseCIDR("172.16.0.1/16")
|
||||||
nw.IP = ip
|
defgw, _ := types.ParseCIDR("172.16.0.100/16")
|
||||||
gw := net.ParseIP("172.16.0.1")
|
|
||||||
|
|
||||||
netConfig := &networkConfiguration{
|
netConfig := &networkConfiguration{
|
||||||
BridgeName: DefaultBridgeName,
|
BridgeName: DefaultBridgeName,
|
||||||
AddressIPv4: nw,
|
|
||||||
FixedCIDR: cnw,
|
|
||||||
DefaultGatewayIPv4: gw,
|
|
||||||
EnableIPv6: true,
|
EnableIPv6: true,
|
||||||
}
|
}
|
||||||
_, netConfig.FixedCIDRv6, _ = net.ParseCIDR("2001:db8::/48")
|
|
||||||
genericOption := make(map[string]interface{})
|
genericOption := make(map[string]interface{})
|
||||||
genericOption[netlabel.GenericData] = config
|
genericOption[netlabel.GenericData] = config
|
||||||
|
|
||||||
|
@ -51,14 +59,21 @@ func TestCreateFullOptions(t *testing.T) {
|
||||||
netOption := make(map[string]interface{})
|
netOption := make(map[string]interface{})
|
||||||
netOption[netlabel.GenericData] = netConfig
|
netOption[netlabel.GenericData] = netConfig
|
||||||
|
|
||||||
err := d.CreateNetwork("dummy", netOption, nil, nil)
|
ipdList := []driverapi.IPAMData{
|
||||||
|
driverapi.IPAMData{
|
||||||
|
Pool: bnw,
|
||||||
|
Gateway: br,
|
||||||
|
AuxAddresses: map[string]*net.IPNet{DefaultGatewayV4AuxKey: defgw},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err := d.CreateNetwork("dummy", netOption, ipdList, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create bridge: %v", err)
|
t.Fatalf("Failed to create bridge: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify the IP address allocated for the endpoint belongs to the container network
|
// Verify the IP address allocated for the endpoint belongs to the container network
|
||||||
epOptions := make(map[string]interface{})
|
epOptions := make(map[string]interface{})
|
||||||
te := &testEndpoint{iface: &testInterface{}}
|
te := newTestEndpoint(cnw, 10)
|
||||||
err = d.CreateEndpoint("dummy", "ep1", te.Interface(), epOptions)
|
err = d.CreateEndpoint("dummy", "ep1", te.Interface(), epOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create an endpoint : %s", err.Error())
|
t.Fatalf("Failed to create an endpoint : %s", err.Error())
|
||||||
|
@ -77,7 +92,7 @@ func TestCreateNoConfig(t *testing.T) {
|
||||||
genericOption := make(map[string]interface{})
|
genericOption := make(map[string]interface{})
|
||||||
genericOption[netlabel.GenericData] = netconfig
|
genericOption[netlabel.GenericData] = netconfig
|
||||||
|
|
||||||
if err := d.CreateNetwork("dummy", genericOption, nil, nil); err != nil {
|
if err := d.CreateNetwork("dummy", genericOption, getIPv4Data(t), nil); err != nil {
|
||||||
t.Fatalf("Failed to create bridge: %v", err)
|
t.Fatalf("Failed to create bridge: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,11 +109,11 @@ func TestCreate(t *testing.T) {
|
||||||
genericOption := make(map[string]interface{})
|
genericOption := make(map[string]interface{})
|
||||||
genericOption[netlabel.GenericData] = netconfig
|
genericOption[netlabel.GenericData] = netconfig
|
||||||
|
|
||||||
if err := d.CreateNetwork("dummy", genericOption, nil, nil); err != nil {
|
if err := d.CreateNetwork("dummy", genericOption, getIPv4Data(t), nil); err != nil {
|
||||||
t.Fatalf("Failed to create bridge: %v", err)
|
t.Fatalf("Failed to create bridge: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := d.CreateNetwork("dummy", genericOption, nil, nil)
|
err := d.CreateNetwork("dummy", genericOption, getIPv4Data(t), nil)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("Expected bridge driver to refuse creation of second network with default name")
|
t.Fatalf("Expected bridge driver to refuse creation of second network with default name")
|
||||||
}
|
}
|
||||||
|
@ -127,7 +142,7 @@ func TestCreateFail(t *testing.T) {
|
||||||
genericOption := make(map[string]interface{})
|
genericOption := make(map[string]interface{})
|
||||||
genericOption[netlabel.GenericData] = netconfig
|
genericOption[netlabel.GenericData] = netconfig
|
||||||
|
|
||||||
if err := d.CreateNetwork("dummy", genericOption, nil, nil); err == nil {
|
if err := d.CreateNetwork("dummy", genericOption, getIPv4Data(t), nil); err == nil {
|
||||||
t.Fatal("Bridge creation was expected to fail")
|
t.Fatal("Bridge creation was expected to fail")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,19 +164,19 @@ func TestCreateMultipleNetworks(t *testing.T) {
|
||||||
config1 := &networkConfiguration{BridgeName: "net_test_1"}
|
config1 := &networkConfiguration{BridgeName: "net_test_1"}
|
||||||
genericOption = make(map[string]interface{})
|
genericOption = make(map[string]interface{})
|
||||||
genericOption[netlabel.GenericData] = config1
|
genericOption[netlabel.GenericData] = config1
|
||||||
if err := d.CreateNetwork("1", genericOption, nil, nil); err != nil {
|
if err := d.CreateNetwork("1", genericOption, getIPv4Data(t), nil); err != nil {
|
||||||
t.Fatalf("Failed to create bridge: %v", err)
|
t.Fatalf("Failed to create bridge: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
config2 := &networkConfiguration{BridgeName: "net_test_2"}
|
config2 := &networkConfiguration{BridgeName: "net_test_2"}
|
||||||
genericOption[netlabel.GenericData] = config2
|
genericOption[netlabel.GenericData] = config2
|
||||||
if err := d.CreateNetwork("2", genericOption, nil, nil); err != nil {
|
if err := d.CreateNetwork("2", genericOption, getIPv4Data(t), nil); err != nil {
|
||||||
t.Fatalf("Failed to create bridge: %v", err)
|
t.Fatalf("Failed to create bridge: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
config3 := &networkConfiguration{BridgeName: "net_test_3"}
|
config3 := &networkConfiguration{BridgeName: "net_test_3"}
|
||||||
genericOption[netlabel.GenericData] = config3
|
genericOption[netlabel.GenericData] = config3
|
||||||
if err := d.CreateNetwork("3", genericOption, nil, nil); err != nil {
|
if err := d.CreateNetwork("3", genericOption, getIPv4Data(t), nil); err != nil {
|
||||||
t.Fatalf("Failed to create bridge: %v", err)
|
t.Fatalf("Failed to create bridge: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +185,7 @@ func TestCreateMultipleNetworks(t *testing.T) {
|
||||||
|
|
||||||
config4 := &networkConfiguration{BridgeName: "net_test_4"}
|
config4 := &networkConfiguration{BridgeName: "net_test_4"}
|
||||||
genericOption[netlabel.GenericData] = config4
|
genericOption[netlabel.GenericData] = config4
|
||||||
if err := d.CreateNetwork("4", genericOption, nil, nil); err != nil {
|
if err := d.CreateNetwork("4", genericOption, getIPv4Data(t), nil); err != nil {
|
||||||
t.Fatalf("Failed to create bridge: %v", err)
|
t.Fatalf("Failed to create bridge: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,6 +238,12 @@ type testEndpoint struct {
|
||||||
routes []types.StaticRoute
|
routes []types.StaticRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newTestEndpoint(nw *net.IPNet, ordinal byte) *testEndpoint {
|
||||||
|
addr := types.GetIPNetCopy(nw)
|
||||||
|
addr.IP[len(addr.IP)-1] = ordinal
|
||||||
|
return &testEndpoint{iface: &testInterface{addr: addr}}
|
||||||
|
}
|
||||||
|
|
||||||
func (te *testEndpoint) Interface() driverapi.InterfaceInfo {
|
func (te *testEndpoint) Interface() driverapi.InterfaceInfo {
|
||||||
if te.iface != nil {
|
if te.iface != nil {
|
||||||
return te.iface
|
return te.iface
|
||||||
|
@ -331,7 +352,8 @@ func testQueryEndpointInfo(t *testing.T, ulPxyEnabled bool) {
|
||||||
genericOption = make(map[string]interface{})
|
genericOption = make(map[string]interface{})
|
||||||
genericOption[netlabel.GenericData] = netconfig
|
genericOption[netlabel.GenericData] = netconfig
|
||||||
|
|
||||||
err := d.CreateNetwork("net1", genericOption, nil, nil)
|
ipdList := getIPv4Data(t)
|
||||||
|
err := d.CreateNetwork("net1", genericOption, ipdList, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create bridge: %v", err)
|
t.Fatalf("Failed to create bridge: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -340,7 +362,7 @@ func testQueryEndpointInfo(t *testing.T, ulPxyEnabled bool) {
|
||||||
epOptions := make(map[string]interface{})
|
epOptions := make(map[string]interface{})
|
||||||
epOptions[netlabel.PortMap] = portMappings
|
epOptions[netlabel.PortMap] = portMappings
|
||||||
|
|
||||||
te := &testEndpoint{iface: &testInterface{}}
|
te := newTestEndpoint(ipdList[0].Pool, 11)
|
||||||
err = d.CreateEndpoint("net1", "ep1", te.Interface(), epOptions)
|
err = d.CreateEndpoint("net1", "ep1", te.Interface(), epOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create an endpoint : %s", err.Error())
|
t.Fatalf("Failed to create an endpoint : %s", err.Error())
|
||||||
|
@ -391,7 +413,8 @@ func TestCreateLinkWithOptions(t *testing.T) {
|
||||||
netOptions := make(map[string]interface{})
|
netOptions := make(map[string]interface{})
|
||||||
netOptions[netlabel.GenericData] = netconfig
|
netOptions[netlabel.GenericData] = netconfig
|
||||||
|
|
||||||
err := d.CreateNetwork("net1", netOptions, nil, nil)
|
ipdList := getIPv4Data(t)
|
||||||
|
err := d.CreateNetwork("net1", netOptions, ipdList, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create bridge: %v", err)
|
t.Fatalf("Failed to create bridge: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -400,7 +423,7 @@ func TestCreateLinkWithOptions(t *testing.T) {
|
||||||
epOptions := make(map[string]interface{})
|
epOptions := make(map[string]interface{})
|
||||||
epOptions[netlabel.MacAddress] = mac
|
epOptions[netlabel.MacAddress] = mac
|
||||||
|
|
||||||
te := &testEndpoint{iface: &testInterface{}}
|
te := newTestEndpoint(ipdList[0].Pool, 11)
|
||||||
err = d.CreateEndpoint("net1", "ep", te.Interface(), epOptions)
|
err = d.CreateEndpoint("net1", "ep", te.Interface(), epOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create an endpoint: %s", err.Error())
|
t.Fatalf("Failed to create an endpoint: %s", err.Error())
|
||||||
|
@ -460,7 +483,8 @@ func TestLinkContainers(t *testing.T) {
|
||||||
genericOption = make(map[string]interface{})
|
genericOption = make(map[string]interface{})
|
||||||
genericOption[netlabel.GenericData] = netconfig
|
genericOption[netlabel.GenericData] = netconfig
|
||||||
|
|
||||||
err := d.CreateNetwork("net1", genericOption, nil, nil)
|
ipdList := getIPv4Data(t)
|
||||||
|
err := d.CreateNetwork("net1", genericOption, ipdList, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create bridge: %v", err)
|
t.Fatalf("Failed to create bridge: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -469,7 +493,7 @@ func TestLinkContainers(t *testing.T) {
|
||||||
epOptions := make(map[string]interface{})
|
epOptions := make(map[string]interface{})
|
||||||
epOptions[netlabel.ExposedPorts] = exposedPorts
|
epOptions[netlabel.ExposedPorts] = exposedPorts
|
||||||
|
|
||||||
te1 := &testEndpoint{iface: &testInterface{}}
|
te1 := newTestEndpoint(ipdList[0].Pool, 11)
|
||||||
err = d.CreateEndpoint("net1", "ep1", te1.Interface(), epOptions)
|
err = d.CreateEndpoint("net1", "ep1", te1.Interface(), epOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create an endpoint : %s", err.Error())
|
t.Fatalf("Failed to create an endpoint : %s", err.Error())
|
||||||
|
@ -480,7 +504,7 @@ func TestLinkContainers(t *testing.T) {
|
||||||
t.Fatalf("No Ipv4 address assigned to the endpoint: ep1")
|
t.Fatalf("No Ipv4 address assigned to the endpoint: ep1")
|
||||||
}
|
}
|
||||||
|
|
||||||
te2 := &testEndpoint{iface: &testInterface{}}
|
te2 := newTestEndpoint(ipdList[0].Pool, 22)
|
||||||
err = d.CreateEndpoint("net1", "ep2", te2.Interface(), nil)
|
err = d.CreateEndpoint("net1", "ep2", te2.Interface(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create an endpoint : %s", err.Error())
|
t.Fatalf("Failed to create an endpoint : %s", err.Error())
|
||||||
|
@ -583,38 +607,13 @@ func TestValidateConfig(t *testing.T) {
|
||||||
|
|
||||||
// Bridge network
|
// Bridge network
|
||||||
_, network, _ := net.ParseCIDR("172.28.0.0/16")
|
_, network, _ := net.ParseCIDR("172.28.0.0/16")
|
||||||
|
|
||||||
// Test FixedCIDR
|
|
||||||
_, containerSubnet, _ := net.ParseCIDR("172.27.0.0/16")
|
|
||||||
c = networkConfiguration{
|
c = networkConfiguration{
|
||||||
AddressIPv4: network,
|
AddressIPv4: network,
|
||||||
FixedCIDR: containerSubnet,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.Validate()
|
|
||||||
if err == nil {
|
|
||||||
t.Fatalf("Failed to detect invalid FixedCIDR network")
|
|
||||||
}
|
|
||||||
|
|
||||||
_, containerSubnet, _ = net.ParseCIDR("172.28.0.0/16")
|
|
||||||
c.FixedCIDR = containerSubnet
|
|
||||||
err = c.Validate()
|
err = c.Validate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected validation error on FixedCIDR network")
|
t.Fatal(err)
|
||||||
}
|
|
||||||
|
|
||||||
_, containerSubnet, _ = net.ParseCIDR("172.28.0.0/15")
|
|
||||||
c.FixedCIDR = containerSubnet
|
|
||||||
err = c.Validate()
|
|
||||||
if err == nil {
|
|
||||||
t.Fatalf("Failed to detect invalid FixedCIDR network")
|
|
||||||
}
|
|
||||||
|
|
||||||
_, containerSubnet, _ = net.ParseCIDR("172.28.0.0/17")
|
|
||||||
c.FixedCIDR = containerSubnet
|
|
||||||
err = c.Validate()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Unexpected validation error on FixedCIDR network")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test v4 gw
|
// Test v4 gw
|
||||||
|
@ -631,10 +630,10 @@ func TestValidateConfig(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test v6 gw
|
// Test v6 gw
|
||||||
_, containerSubnet, _ = net.ParseCIDR("2001:1234:ae:b004::/64")
|
_, v6nw, _ := net.ParseCIDR("2001:1234:ae:b004::/64")
|
||||||
c = networkConfiguration{
|
c = networkConfiguration{
|
||||||
EnableIPv6: true,
|
EnableIPv6: true,
|
||||||
FixedCIDRv6: containerSubnet,
|
AddressIPv6: v6nw,
|
||||||
DefaultGatewayIPv6: net.ParseIP("2001:1234:ac:b004::bad:a55"),
|
DefaultGatewayIPv6: net.ParseIP("2001:1234:ac:b004::bad:a55"),
|
||||||
}
|
}
|
||||||
err = c.Validate()
|
err = c.Validate()
|
||||||
|
@ -648,7 +647,13 @@ func TestValidateConfig(t *testing.T) {
|
||||||
t.Fatalf("Unexpected validation error on v6 default gateway")
|
t.Fatalf("Unexpected validation error on v6 default gateway")
|
||||||
}
|
}
|
||||||
|
|
||||||
c.FixedCIDRv6 = nil
|
c.AddressIPv6 = nil
|
||||||
|
err = c.Validate()
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("Failed to detect invalid v6 default gateway")
|
||||||
|
}
|
||||||
|
|
||||||
|
c.AddressIPv6 = nil
|
||||||
err = c.Validate()
|
err = c.Validate()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("Failed to detect invalid v6 default gateway")
|
t.Fatalf("Failed to detect invalid v6 default gateway")
|
||||||
|
@ -665,25 +670,15 @@ func TestSetDefaultGw(t *testing.T) {
|
||||||
|
|
||||||
_, subnetv6, _ := net.ParseCIDR("2001:db8:ea9:9abc:b0c4::/80")
|
_, subnetv6, _ := net.ParseCIDR("2001:db8:ea9:9abc:b0c4::/80")
|
||||||
|
|
||||||
var nw *net.IPNet
|
ipdList := getIPv4Data(t)
|
||||||
for _, n := range bridgeNetworks {
|
gw4 := types.GetIPCopy(ipdList[0].Pool.IP).To4()
|
||||||
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
|
gw4[3] = 254
|
||||||
gw6 := net.ParseIP("2001:db8:ea9:9abc:b0c4::254")
|
gw6 := net.ParseIP("2001:db8:ea9:9abc:b0c4::254")
|
||||||
|
|
||||||
config := &networkConfiguration{
|
config := &networkConfiguration{
|
||||||
BridgeName: DefaultBridgeName,
|
BridgeName: DefaultBridgeName,
|
||||||
EnableIPv6: true,
|
EnableIPv6: true,
|
||||||
FixedCIDRv6: subnetv6,
|
AddressIPv6: subnetv6,
|
||||||
DefaultGatewayIPv4: gw4,
|
DefaultGatewayIPv4: gw4,
|
||||||
DefaultGatewayIPv6: gw6,
|
DefaultGatewayIPv6: gw6,
|
||||||
}
|
}
|
||||||
|
@ -691,12 +686,12 @@ func TestSetDefaultGw(t *testing.T) {
|
||||||
genericOption := make(map[string]interface{})
|
genericOption := make(map[string]interface{})
|
||||||
genericOption[netlabel.GenericData] = config
|
genericOption[netlabel.GenericData] = config
|
||||||
|
|
||||||
err := d.CreateNetwork("dummy", genericOption, nil, nil)
|
err := d.CreateNetwork("dummy", genericOption, ipdList, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create bridge: %v", err)
|
t.Fatalf("Failed to create bridge: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
te := &testEndpoint{iface: &testInterface{}}
|
te := newTestEndpoint(ipdList[0].Pool, 10)
|
||||||
err = d.CreateEndpoint("dummy", "ep", te.Interface(), nil)
|
err = d.CreateEndpoint("dummy", "ep", te.Interface(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create endpoint: %v", err)
|
t.Fatalf("Failed to create endpoint: %v", err)
|
||||||
|
|
|
@ -26,12 +26,13 @@ func TestLinkCreate(t *testing.T) {
|
||||||
genericOption := make(map[string]interface{})
|
genericOption := make(map[string]interface{})
|
||||||
genericOption[netlabel.GenericData] = config
|
genericOption[netlabel.GenericData] = config
|
||||||
|
|
||||||
err := d.CreateNetwork("dummy", genericOption, nil, nil)
|
ipdList := getIPv4Data(t)
|
||||||
|
err := d.CreateNetwork("dummy", genericOption, ipdList, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create bridge: %v", err)
|
t.Fatalf("Failed to create bridge: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
te := &testEndpoint{iface: &testInterface{}}
|
te := newTestEndpoint(ipdList[0].Pool, 10)
|
||||||
err = d.CreateEndpoint("dummy", "", te.Interface(), nil)
|
err = d.CreateEndpoint("dummy", "", te.Interface(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if _, ok := err.(InvalidEndpointIDError); !ok {
|
if _, ok := err.(InvalidEndpointIDError); !ok {
|
||||||
|
@ -63,7 +64,7 @@ func TestLinkCreate(t *testing.T) {
|
||||||
// TODO: if we could get peer name from (sboxLnk.(*netlink.Veth)).PeerName
|
// TODO: if we could get peer name from (sboxLnk.(*netlink.Veth)).PeerName
|
||||||
// then we could check the MTU on hostLnk as well.
|
// then we could check the MTU on hostLnk as well.
|
||||||
|
|
||||||
te1 := &testEndpoint{iface: &testInterface{}}
|
te1 := newTestEndpoint(ipdList[0].Pool, 11)
|
||||||
err = d.CreateEndpoint("dummy", "ep", te1.Interface(), nil)
|
err = d.CreateEndpoint("dummy", "ep", te1.Interface(), nil)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("Failed to detect duplicate endpoint id on same network")
|
t.Fatalf("Failed to detect duplicate endpoint id on same network")
|
||||||
|
@ -117,18 +118,19 @@ func TestLinkCreateTwo(t *testing.T) {
|
||||||
genericOption := make(map[string]interface{})
|
genericOption := make(map[string]interface{})
|
||||||
genericOption[netlabel.GenericData] = config
|
genericOption[netlabel.GenericData] = config
|
||||||
|
|
||||||
err := d.CreateNetwork("dummy", genericOption, nil, nil)
|
ipdList := getIPv4Data(t)
|
||||||
|
err := d.CreateNetwork("dummy", genericOption, ipdList, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create bridge: %v", err)
|
t.Fatalf("Failed to create bridge: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
te1 := &testEndpoint{iface: &testInterface{}}
|
te1 := newTestEndpoint(ipdList[0].Pool, 11)
|
||||||
err = d.CreateEndpoint("dummy", "ep", te1.Interface(), nil)
|
err = d.CreateEndpoint("dummy", "ep", te1.Interface(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create a link: %s", err.Error())
|
t.Fatalf("Failed to create a link: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
te2 := &testEndpoint{iface: &testInterface{}}
|
te2 := newTestEndpoint(ipdList[0].Pool, 12)
|
||||||
err = d.CreateEndpoint("dummy", "ep", te2.Interface(), nil)
|
err = d.CreateEndpoint("dummy", "ep", te2.Interface(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if _, ok := err.(driverapi.ErrEndpointExists); !ok {
|
if _, ok := err.(driverapi.ErrEndpointExists); !ok {
|
||||||
|
@ -152,12 +154,12 @@ func TestLinkCreateNoEnableIPv6(t *testing.T) {
|
||||||
genericOption := make(map[string]interface{})
|
genericOption := make(map[string]interface{})
|
||||||
genericOption[netlabel.GenericData] = config
|
genericOption[netlabel.GenericData] = config
|
||||||
|
|
||||||
err := d.CreateNetwork("dummy", genericOption, nil, nil)
|
ipdList := getIPv4Data(t)
|
||||||
|
err := d.CreateNetwork("dummy", genericOption, ipdList, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create bridge: %v", err)
|
t.Fatalf("Failed to create bridge: %v", err)
|
||||||
}
|
}
|
||||||
|
te := newTestEndpoint(ipdList[0].Pool, 30)
|
||||||
te := &testEndpoint{iface: &testInterface{}}
|
|
||||||
err = d.CreateEndpoint("dummy", "ep", te.Interface(), nil)
|
err = d.CreateEndpoint("dummy", "ep", te.Interface(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create a link: %s", err.Error())
|
t.Fatalf("Failed to create a link: %s", err.Error())
|
||||||
|
@ -187,12 +189,13 @@ func TestLinkDelete(t *testing.T) {
|
||||||
genericOption := make(map[string]interface{})
|
genericOption := make(map[string]interface{})
|
||||||
genericOption[netlabel.GenericData] = config
|
genericOption[netlabel.GenericData] = config
|
||||||
|
|
||||||
err := d.CreateNetwork("dummy", genericOption, nil, nil)
|
ipdList := getIPv4Data(t)
|
||||||
|
err := d.CreateNetwork("dummy", genericOption, ipdList, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create bridge: %v", err)
|
t.Fatalf("Failed to create bridge: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
te := &testEndpoint{iface: &testInterface{}}
|
te := newTestEndpoint(ipdList[0].Pool, 30)
|
||||||
err = d.CreateEndpoint("dummy", "ep1", te.Interface(), nil)
|
err = d.CreateEndpoint("dummy", "ep1", te.Interface(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create a link: %s", err.Error())
|
t.Fatalf("Failed to create a link: %s", err.Error())
|
||||||
|
|
|
@ -44,12 +44,13 @@ func TestPortMappingConfig(t *testing.T) {
|
||||||
netOptions := make(map[string]interface{})
|
netOptions := make(map[string]interface{})
|
||||||
netOptions[netlabel.GenericData] = netConfig
|
netOptions[netlabel.GenericData] = netConfig
|
||||||
|
|
||||||
err := d.CreateNetwork("dummy", netOptions, nil, nil)
|
ipdList := getIPv4Data(t)
|
||||||
|
err := d.CreateNetwork("dummy", netOptions, ipdList, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create bridge: %v", err)
|
t.Fatalf("Failed to create bridge: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
te := &testEndpoint{iface: &testInterface{}}
|
te := newTestEndpoint(ipdList[0].Pool, 11)
|
||||||
err = d.CreateEndpoint("dummy", "ep1", te.Interface(), epOptions)
|
err = d.CreateEndpoint("dummy", "ep1", te.Interface(), epOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create the endpoint: %s", err.Error())
|
t.Fatalf("Failed to create the endpoint: %s", err.Error())
|
||||||
|
|
|
@ -22,7 +22,7 @@ const (
|
||||||
//Gets the IP version in use ( [ipv4], [ipv6] or [ipv4 and ipv6] )
|
//Gets the IP version in use ( [ipv4], [ipv6] or [ipv4 and ipv6] )
|
||||||
func getIPVersion(config *networkConfiguration) ipVersion {
|
func getIPVersion(config *networkConfiguration) ipVersion {
|
||||||
ipVersion := ipv4
|
ipVersion := ipv4
|
||||||
if config.FixedCIDRv6 != nil || config.EnableIPv6 {
|
if config.AddressIPv6 != nil || config.EnableIPv6 {
|
||||||
ipVersion |= ipv6
|
ipVersion |= ipv6
|
||||||
}
|
}
|
||||||
return ipVersion
|
return ipVersion
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
package bridge
|
|
||||||
|
|
||||||
import (
|
|
||||||
log "github.com/Sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
func setupFixedCIDRv4(config *networkConfiguration, i *bridgeInterface) error {
|
|
||||||
addrv4, _, err := i.addresses()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("Using IPv4 subnet: %v", config.FixedCIDR)
|
|
||||||
if err := ipAllocator.RegisterSubnet(addrv4.IPNet, config.FixedCIDR); err != nil {
|
|
||||||
return &FixedCIDRv4Error{Subnet: config.FixedCIDR, Net: addrv4.IPNet, Err: err}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
package bridge
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/libnetwork/testutils"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSetupFixedCIDRv4(t *testing.T) {
|
|
||||||
defer testutils.SetupTestOSContext(t)()
|
|
||||||
|
|
||||||
config := &networkConfiguration{
|
|
||||||
BridgeName: DefaultBridgeName,
|
|
||||||
AddressIPv4: &net.IPNet{IP: net.ParseIP("192.168.1.1"), Mask: net.CIDRMask(16, 32)},
|
|
||||||
FixedCIDR: &net.IPNet{IP: net.ParseIP("192.168.2.0"), Mask: net.CIDRMask(24, 32)}}
|
|
||||||
br := &bridgeInterface{}
|
|
||||||
|
|
||||||
if err := setupDevice(config, br); err != nil {
|
|
||||||
t.Fatalf("Bridge creation failed: %v", err)
|
|
||||||
}
|
|
||||||
if err := setupBridgeIPv4(config, br); err != nil {
|
|
||||||
t.Fatalf("Assign IPv4 to bridge failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := setupFixedCIDRv4(config, br); err != nil {
|
|
||||||
t.Fatalf("Failed to setup bridge FixedCIDRv4: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if ip, err := ipAllocator.RequestIP(config.FixedCIDR, nil); err != nil {
|
|
||||||
t.Fatalf("Failed to request IP to allocator: %v", err)
|
|
||||||
} else if expected := "192.168.2.1"; ip.String() != expected {
|
|
||||||
t.Fatalf("Expected allocated IP %s, got %s", expected, ip)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSetupBadFixedCIDRv4(t *testing.T) {
|
|
||||||
defer testutils.SetupTestOSContext(t)()
|
|
||||||
|
|
||||||
config := &networkConfiguration{
|
|
||||||
BridgeName: DefaultBridgeName,
|
|
||||||
AddressIPv4: &net.IPNet{IP: net.ParseIP("192.168.1.1"), Mask: net.CIDRMask(24, 32)},
|
|
||||||
FixedCIDR: &net.IPNet{IP: net.ParseIP("192.168.2.0"), Mask: net.CIDRMask(24, 32)}}
|
|
||||||
br := &bridgeInterface{}
|
|
||||||
|
|
||||||
if err := setupDevice(config, br); err != nil {
|
|
||||||
t.Fatalf("Bridge creation failed: %v", err)
|
|
||||||
}
|
|
||||||
if err := setupBridgeIPv4(config, br); err != nil {
|
|
||||||
t.Fatalf("Assign IPv4 to bridge failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err := setupFixedCIDRv4(config, br)
|
|
||||||
if err == nil {
|
|
||||||
t.Fatal("Setup bridge FixedCIDRv4 should have failed")
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := err.(*FixedCIDRv4Error); !ok {
|
|
||||||
t.Fatalf("Did not fail with expected error. Actual error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
package bridge
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
|
||||||
"github.com/vishvananda/netlink"
|
|
||||||
)
|
|
||||||
|
|
||||||
func setupFixedCIDRv6(config *networkConfiguration, i *bridgeInterface) error {
|
|
||||||
log.Debugf("Using IPv6 subnet: %v", config.FixedCIDRv6)
|
|
||||||
if err := ipAllocator.RegisterSubnet(config.FixedCIDRv6, config.FixedCIDRv6); err != nil {
|
|
||||||
return &FixedCIDRv6Error{Net: config.FixedCIDRv6, Err: err}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setting route to global IPv6 subnet
|
|
||||||
log.Debugf("Adding route to IPv6 network %s via device %s", config.FixedCIDRv6.String(), config.BridgeName)
|
|
||||||
err := netlink.RouteAdd(&netlink.Route{
|
|
||||||
Scope: netlink.SCOPE_UNIVERSE,
|
|
||||||
LinkIndex: i.Link.Attrs().Index,
|
|
||||||
Dst: config.FixedCIDRv6,
|
|
||||||
})
|
|
||||||
if err != nil && !os.IsExist(err) {
|
|
||||||
log.Errorf("Could not add route to IPv6 network %s via device %s", config.FixedCIDRv6.String(), config.BridgeName)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
package bridge
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/libnetwork/testutils"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSetupFixedCIDRv6(t *testing.T) {
|
|
||||||
defer testutils.SetupTestOSContext(t)()
|
|
||||||
|
|
||||||
config := &networkConfiguration{}
|
|
||||||
br := newInterface(config)
|
|
||||||
|
|
||||||
_, config.FixedCIDRv6, _ = net.ParseCIDR("2002:db8::/48")
|
|
||||||
if err := setupDevice(config, br); err != nil {
|
|
||||||
t.Fatalf("Bridge creation failed: %v", err)
|
|
||||||
}
|
|
||||||
if err := setupBridgeIPv4(config, br); err != nil {
|
|
||||||
t.Fatalf("Assign IPv4 to bridge failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := setupBridgeIPv6(config, br); err != nil {
|
|
||||||
t.Fatalf("Assign IPv4 to bridge failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := setupFixedCIDRv6(config, br); err != nil {
|
|
||||||
t.Fatalf("Failed to setup bridge FixedCIDRv6: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var ip net.IP
|
|
||||||
if ip, err := ipAllocator.RequestIP(config.FixedCIDRv6, nil); err != nil {
|
|
||||||
t.Fatalf("Failed to request IP to allocator: %v", err)
|
|
||||||
} else if expected := "2002:db8::1"; ip.String() != expected {
|
|
||||||
t.Fatalf("Expected allocated IP %s, got %s", expected, ip)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := ipAllocator.ReleaseIP(config.FixedCIDRv6, ip); err != nil {
|
|
||||||
t.Fatalf("Failed to release IP from allocator: %v", err)
|
|
||||||
} else if _, err := ipAllocator.RequestIP(config.FixedCIDRv6, ip); err != nil {
|
|
||||||
t.Fatalf("Failed to request a released IP: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,129 +3,43 @@ package bridge
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
"github.com/docker/libnetwork/netutils"
|
"github.com/docker/libnetwork/types"
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
)
|
)
|
||||||
|
|
||||||
var bridgeNetworks []*net.IPNet
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
// Here we don't follow the convention of using the 1st IP of the range for the gateway.
|
|
||||||
// This is to use the same gateway IPs as the /24 ranges, which predate the /16 ranges.
|
|
||||||
// In theory this shouldn't matter - in practice there's bound to be a few scripts relying
|
|
||||||
// on the internal addressing or other stupid things like that.
|
|
||||||
// They shouldn't, but hey, let's not break them unless we really have to.
|
|
||||||
// Don't use 172.16.0.0/16, it conflicts with EC2 DNS 172.16.0.23
|
|
||||||
|
|
||||||
// 172.[17-31].42.1/16
|
|
||||||
mask := []byte{255, 255, 0, 0}
|
|
||||||
for i := 17; i < 32; i++ {
|
|
||||||
bridgeNetworks = append(bridgeNetworks, &net.IPNet{IP: []byte{172, byte(i), 42, 1}, Mask: mask})
|
|
||||||
}
|
|
||||||
// 10.[0-255].42.1/16
|
|
||||||
for i := 0; i < 256; i++ {
|
|
||||||
bridgeNetworks = append(bridgeNetworks, &net.IPNet{IP: []byte{10, byte(i), 42, 1}, Mask: mask})
|
|
||||||
}
|
|
||||||
// 192.168.[42-44].1/24
|
|
||||||
mask24 := []byte{255, 255, 255, 0}
|
|
||||||
for i := 42; i < 45; i++ {
|
|
||||||
bridgeNetworks = append(bridgeNetworks, &net.IPNet{IP: []byte{192, 168, byte(i), 1}, Mask: mask24})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupBridgeIPv4(config *networkConfiguration, i *bridgeInterface) error {
|
func setupBridgeIPv4(config *networkConfiguration, i *bridgeInterface) error {
|
||||||
addrv4, _, err := i.addresses()
|
addrv4, _, err := i.addresses()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("failed to retrieve bridge interface addresses: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we have an IP address already on the bridge.
|
if !types.CompareIPNet(addrv4.IPNet, config.AddressIPv4) {
|
||||||
if addrv4.IPNet != nil {
|
if addrv4.IPNet != nil {
|
||||||
// Make sure to store bridge network and default gateway before getting out.
|
if err := netlink.AddrDel(i.Link, &addrv4); err != nil {
|
||||||
i.bridgeIPv4 = addrv4.IPNet
|
return fmt.Errorf("failed to remove current ip address from bridge: %v", err)
|
||||||
i.gatewayIPv4 = addrv4.IPNet.IP
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not try to configure IPv4 on a non-default bridge unless you are
|
|
||||||
// specifically asked to do so.
|
|
||||||
if config.BridgeName != DefaultBridgeName && config.DefaultBridge {
|
|
||||||
return NonDefaultBridgeNeedsIPError(config.BridgeName)
|
|
||||||
}
|
}
|
||||||
|
log.Debugf("Assigning address to bridge interface %s: %s", config.BridgeName, config.AddressIPv4)
|
||||||
bridgeIPv4, err := electBridgeIPv4(config)
|
if err := netlink.AddrAdd(i.Link, &netlink.Addr{IPNet: config.AddressIPv4}); err != nil {
|
||||||
if err != nil {
|
return &IPv4AddrAddError{IP: config.AddressIPv4, Err: err}
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store bridge network and default gateway
|
// Store bridge network and default gateway
|
||||||
i.bridgeIPv4 = bridgeIPv4
|
i.bridgeIPv4 = config.AddressIPv4
|
||||||
i.gatewayIPv4 = i.bridgeIPv4.IP
|
i.gatewayIPv4 = config.AddressIPv4.IP
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func allocateBridgeIP(config *networkConfiguration, i *bridgeInterface) error {
|
|
||||||
// Because of the way ipallocator manages the container address space,
|
|
||||||
// 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) {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
func electBridgeIPv4(config *networkConfiguration) (*net.IPNet, error) {
|
|
||||||
// Use the requested IPv4 CIDR when available.
|
|
||||||
if 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, _ := readResolvConf(); resolvConf != nil {
|
|
||||||
nameservers = append(nameservers, getNameserversAsCIDR(resolvConf)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to automatically elect appropriate bridge IPv4 settings.
|
|
||||||
for _, n := range bridgeNetworks {
|
|
||||||
if err := netutils.CheckNameserverOverlaps(nameservers, n); err == nil {
|
|
||||||
if err := netutils.CheckRouteOverlaps(n); err == nil {
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, IPv4AddrRangeError(config.BridgeName)
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupGatewayIPv4(config *networkConfiguration, i *bridgeInterface) error {
|
func setupGatewayIPv4(config *networkConfiguration, i *bridgeInterface) error {
|
||||||
if !i.bridgeIPv4.Contains(config.DefaultGatewayIPv4) {
|
if !i.bridgeIPv4.Contains(config.DefaultGatewayIPv4) {
|
||||||
return &ErrInvalidGateway{}
|
return &ErrInvalidGateway{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Because of the way ipallocator manages the container address space,
|
|
||||||
// reserve default gw address only if it belongs to the container network
|
|
||||||
// (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 fmt.Errorf("failed to reserve default gateway %s: %v", config.DefaultGatewayIPv4.String(), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store requested default gateway
|
// Store requested default gateway
|
||||||
i.gatewayIPv4 = config.DefaultGatewayIPv4
|
i.gatewayIPv4 = config.DefaultGatewayIPv4
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/libnetwork/netutils"
|
|
||||||
"github.com/docker/libnetwork/testutils"
|
"github.com/docker/libnetwork/testutils"
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
)
|
)
|
||||||
|
@ -52,43 +51,6 @@ func TestSetupBridgeIPv4Fixed(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetupBridgeIPv4Auto(t *testing.T) {
|
|
||||||
defer testutils.SetupTestOSContext(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)
|
|
||||||
}
|
|
||||||
|
|
||||||
addrsv4, err := netlink.AddrList(br.Link, netlink.FAMILY_V4)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to list device IPv4 addresses: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var found bool
|
|
||||||
for _, addr := range addrsv4 {
|
|
||||||
if toBeChosen.String() == addr.IPNet.String() {
|
|
||||||
found = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !found {
|
|
||||||
t.Fatalf("Bridge device does not have the automatic IPv4 address %s", toBeChosen.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSetupGatewayIPv4(t *testing.T) {
|
func TestSetupGatewayIPv4(t *testing.T) {
|
||||||
defer testutils.SetupTestOSContext(t)()
|
defer testutils.SetupTestOSContext(t)()
|
||||||
|
|
||||||
|
@ -110,14 +72,3 @@ func TestSetupGatewayIPv4(t *testing.T) {
|
||||||
t.Fatalf("Set Default Gateway failed. Expected %v, Found %v", gw, br.gatewayIPv4)
|
t.Fatalf("Set Default Gateway failed. Expected %v, Found %v", gw, br.gatewayIPv4)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCheckPreallocatedBridgeNetworks(t *testing.T) {
|
|
||||||
// Just make sure the bridge networks are created the way we want (172.17.x.x/16)
|
|
||||||
for i := 0; i < len(bridgeNetworks); i++ {
|
|
||||||
fb := bridgeNetworks[i].IP[0]
|
|
||||||
ones, _ := bridgeNetworks[i].Mask.Size()
|
|
||||||
if ((fb == 172 || fb == 10) && ones != 16) || (fb == 192 && ones != 24) {
|
|
||||||
t.Fatalf("Wrong mask for preallocated bridge network: %s", bridgeNetworks[i].String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
|
@ -57,19 +58,31 @@ func setupBridgeIPv6(config *networkConfiguration, i *bridgeInterface) error {
|
||||||
i.bridgeIPv6 = bridgeIPv6
|
i.bridgeIPv6 = bridgeIPv6
|
||||||
i.gatewayIPv6 = i.bridgeIPv6.IP
|
i.gatewayIPv6 = i.bridgeIPv6.IP
|
||||||
|
|
||||||
|
if config.AddressIPv6 == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setting route to global IPv6 subnet
|
||||||
|
logrus.Debugf("Adding route to IPv6 network %s via device %s", config.AddressIPv6.String(), config.BridgeName)
|
||||||
|
err = netlink.RouteAdd(&netlink.Route{
|
||||||
|
Scope: netlink.SCOPE_UNIVERSE,
|
||||||
|
LinkIndex: i.Link.Attrs().Index,
|
||||||
|
Dst: config.AddressIPv6,
|
||||||
|
})
|
||||||
|
if err != nil && !os.IsExist(err) {
|
||||||
|
logrus.Errorf("Could not add route to IPv6 network %s via device %s", config.AddressIPv6.String(), config.BridgeName)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupGatewayIPv6(config *networkConfiguration, i *bridgeInterface) error {
|
func setupGatewayIPv6(config *networkConfiguration, i *bridgeInterface) error {
|
||||||
if config.FixedCIDRv6 == nil {
|
if config.AddressIPv6 == nil {
|
||||||
return &ErrInvalidContainerSubnet{}
|
return &ErrInvalidContainerSubnet{}
|
||||||
}
|
}
|
||||||
if !config.FixedCIDRv6.Contains(config.DefaultGatewayIPv6) {
|
if !config.AddressIPv6.Contains(config.DefaultGatewayIPv6) {
|
||||||
return &ErrInvalidGateway{}
|
return &ErrInvalidGateway{}
|
||||||
}
|
}
|
||||||
if _, err := ipAllocator.RequestIP(config.FixedCIDRv6, config.DefaultGatewayIPv6); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store requested default gateway
|
// Store requested default gateway
|
||||||
i.gatewayIPv6 = config.DefaultGatewayIPv6
|
i.gatewayIPv6 = config.DefaultGatewayIPv6
|
||||||
|
|
|
@ -55,7 +55,7 @@ func TestSetupGatewayIPv6(t *testing.T) {
|
||||||
|
|
||||||
config := &networkConfiguration{
|
config := &networkConfiguration{
|
||||||
BridgeName: DefaultBridgeName,
|
BridgeName: DefaultBridgeName,
|
||||||
FixedCIDRv6: nw,
|
AddressIPv6: nw,
|
||||||
DefaultGatewayIPv6: gw}
|
DefaultGatewayIPv6: gw}
|
||||||
|
|
||||||
br := &bridgeInterface{}
|
br := &bridgeInterface{}
|
||||||
|
|
|
@ -622,10 +622,14 @@ func (ep *endpoint) assignAddress() error {
|
||||||
ipam ipamapi.Ipam
|
ipam ipamapi.Ipam
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
n := ep.getNetwork()
|
n := ep.getNetwork()
|
||||||
if n.Type() == "host" || n.Type() == "null" || n.Type() == "bridge" {
|
if n.Type() == "host" || n.Type() == "null" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Debugf("Assigning addresses for endpoint %s's interface on network %s", ep.Name(), n.Name())
|
||||||
|
|
||||||
ipam, err = n.getController().getIpamDriver(n.ipamType)
|
ipam, err = n.getController().getIpamDriver(n.ipamType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -680,9 +684,12 @@ func (ep *endpoint) assignAddressVersion(ipVer int, ipam ipamapi.Ipam) error {
|
||||||
|
|
||||||
func (ep *endpoint) releaseAddress() {
|
func (ep *endpoint) releaseAddress() {
|
||||||
n := ep.getNetwork()
|
n := ep.getNetwork()
|
||||||
if n.Type() == "host" || n.Type() == "null" || n.Type() == "bridge" {
|
if n.Type() == "host" || n.Type() == "null" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Debugf("Releasing addresses for endpoint %s's interface on network %s", ep.Name(), n.Name())
|
||||||
|
|
||||||
ipam, err := n.getController().getIpamDriver(n.ipamType)
|
ipam, err := n.getController().getIpamDriver(n.ipamType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("Failed to retrieve ipam driver to release interface address on delete of endpoint %s (%s): %v", ep.Name(), ep.ID(), err)
|
log.Warnf("Failed to retrieve ipam driver to release interface address on delete of endpoint %s (%s): %v", ep.Name(), ep.ID(), err)
|
||||||
|
|
|
@ -102,8 +102,9 @@ func (a *Allocator) updateBitMasks(aSpace *addrSpace) error {
|
||||||
aSpace.Lock()
|
aSpace.Lock()
|
||||||
for k, v := range aSpace.subnets {
|
for k, v := range aSpace.subnets {
|
||||||
if v.Range == nil {
|
if v.Range == nil {
|
||||||
inserterList = append(inserterList,
|
kk := k
|
||||||
func() error { return a.insertBitMask(k, v.Pool) })
|
vv := v
|
||||||
|
inserterList = append(inserterList, func() error { return a.insertBitMask(kk, vv.Pool) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
aSpace.Unlock()
|
aSpace.Unlock()
|
||||||
|
@ -127,6 +128,7 @@ func (a *Allocator) GetDefaultAddressSpaces() (string, string, error) {
|
||||||
|
|
||||||
// RequestPool returns an address pool along with its unique id.
|
// RequestPool returns an address pool along with its unique id.
|
||||||
func (a *Allocator) RequestPool(addressSpace, pool, subPool string, options map[string]string, v6 bool) (string, *net.IPNet, map[string]string, error) {
|
func (a *Allocator) RequestPool(addressSpace, pool, subPool string, options map[string]string, v6 bool) (string, *net.IPNet, map[string]string, error) {
|
||||||
|
log.Debugf("RequestPool(%s, %s, %s, %v, %t)", addressSpace, pool, subPool, options, v6)
|
||||||
k, nw, aw, ipr, err := a.parsePoolRequest(addressSpace, pool, subPool, v6)
|
k, nw, aw, ipr, err := a.parsePoolRequest(addressSpace, pool, subPool, v6)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, nil, ipamapi.ErrInvalidPool
|
return "", nil, nil, ipamapi.ErrInvalidPool
|
||||||
|
@ -160,6 +162,7 @@ retry:
|
||||||
|
|
||||||
// ReleasePool releases the address pool identified by the passed id
|
// ReleasePool releases the address pool identified by the passed id
|
||||||
func (a *Allocator) ReleasePool(poolID string) error {
|
func (a *Allocator) ReleasePool(poolID string) error {
|
||||||
|
log.Debugf("ReleasePool(%s)", poolID)
|
||||||
k := SubnetKey{}
|
k := SubnetKey{}
|
||||||
if err := k.FromString(poolID); err != nil {
|
if err := k.FromString(poolID); err != nil {
|
||||||
return types.BadRequestErrorf("invalid pool id: %s", poolID)
|
return types.BadRequestErrorf("invalid pool id: %s", poolID)
|
||||||
|
@ -343,6 +346,7 @@ func (a *Allocator) getPredefinedPool(as string, ipV6 bool) (*net.IPNet, error)
|
||||||
|
|
||||||
// RequestAddress returns an address from the specified pool ID
|
// RequestAddress returns an address from the specified pool ID
|
||||||
func (a *Allocator) RequestAddress(poolID string, prefAddress net.IP, opts map[string]string) (*net.IPNet, map[string]string, error) {
|
func (a *Allocator) RequestAddress(poolID string, prefAddress net.IP, opts map[string]string) (*net.IPNet, map[string]string, error) {
|
||||||
|
log.Debugf("RequestAddress(%s, %v, %v)", poolID, prefAddress, opts)
|
||||||
k := SubnetKey{}
|
k := SubnetKey{}
|
||||||
if err := k.FromString(poolID); err != nil {
|
if err := k.FromString(poolID); err != nil {
|
||||||
return nil, nil, types.BadRequestErrorf("invalid pool id: %s", poolID)
|
return nil, nil, types.BadRequestErrorf("invalid pool id: %s", poolID)
|
||||||
|
@ -391,6 +395,7 @@ func (a *Allocator) RequestAddress(poolID string, prefAddress net.IP, opts map[s
|
||||||
|
|
||||||
// ReleaseAddress releases the address from the specified pool ID
|
// ReleaseAddress releases the address from the specified pool ID
|
||||||
func (a *Allocator) ReleaseAddress(poolID string, address net.IP) error {
|
func (a *Allocator) ReleaseAddress(poolID string, address net.IP) error {
|
||||||
|
log.Debugf("ReleaseAddress(%s, %v)", poolID, address)
|
||||||
k := SubnetKey{}
|
k := SubnetKey{}
|
||||||
if err := k.FromString(poolID); err != nil {
|
if err := k.FromString(poolID); err != nil {
|
||||||
return types.BadRequestErrorf("invalid pool id: %s", poolID)
|
return types.BadRequestErrorf("invalid pool id: %s", poolID)
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
"github.com/docker/libnetwork/bitseq"
|
"github.com/docker/libnetwork/bitseq"
|
||||||
"github.com/docker/libnetwork/datastore"
|
"github.com/docker/libnetwork/datastore"
|
||||||
"github.com/docker/libnetwork/ipamapi"
|
"github.com/docker/libnetwork/ipamapi"
|
||||||
"github.com/docker/libnetwork/netutils"
|
"github.com/docker/libnetwork/ipamutils"
|
||||||
_ "github.com/docker/libnetwork/testutils"
|
_ "github.com/docker/libnetwork/testutils"
|
||||||
"github.com/docker/libnetwork/types"
|
"github.com/docker/libnetwork/types"
|
||||||
)
|
)
|
||||||
|
@ -461,12 +461,7 @@ func TestPredefinedPool(t *testing.T) {
|
||||||
t.Fatalf("Expected failure for non default addr space")
|
t.Fatalf("Expected failure for non default addr space")
|
||||||
}
|
}
|
||||||
|
|
||||||
i, available, err := getFirstAvailablePool(a, localAddressSpace, 2)
|
exp, err := ipamutils.FindAvailableNetwork(a.predefined[localAddressSpace])
|
||||||
if err != nil {
|
|
||||||
t.Skip(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
pid, _, _, err := a.RequestPool(localAddressSpace, available.String(), "", nil, false)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -475,8 +470,24 @@ func TestPredefinedPool(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if nw != a.predefined[localAddressSpace][i+1] {
|
if !types.CompareIPNet(nw, exp) {
|
||||||
t.Fatalf("Unexpected default network returned: %s", nw)
|
t.Fatalf("Unexpected default network returned: %s. Expected: %s", nw, exp)
|
||||||
|
}
|
||||||
|
|
||||||
|
pid, nw, _, err := a.RequestPool(localAddressSpace, exp.String(), "", nil, false)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !types.CompareIPNet(nw, exp) {
|
||||||
|
t.Fatalf("Unexpected default network returned: %s. Expected: %s", nw, exp)
|
||||||
|
}
|
||||||
|
|
||||||
|
nw2, err := a.getPredefinedPool(localAddressSpace, false)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if types.CompareIPNet(nw, nw2) {
|
||||||
|
t.Fatalf("Unexpected default network returned: %s = %s", nw2, nw)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := a.ReleasePool(pid); err != nil {
|
if err := a.ReleasePool(pid); err != nil {
|
||||||
|
@ -487,25 +498,11 @@ func TestPredefinedPool(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if nw != a.predefined[localAddressSpace][i] {
|
if !types.CompareIPNet(nw, exp) {
|
||||||
t.Fatalf("Unexpected default network returned: %s", nw)
|
t.Fatalf("Unexpected default network returned: %s. Expected %s", nw, exp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getFirstAvailablePool(a *Allocator, as string, atLeast int) (int, *net.IPNet, error) {
|
|
||||||
i := 0
|
|
||||||
for i < len(a.predefined[as])-1 {
|
|
||||||
if err := netutils.CheckRouteOverlaps(a.predefined[as][i]); err == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
if i > len(a.predefined[as])-1-atLeast {
|
|
||||||
return 0, nil, fmt.Errorf("Not enough non-overlapping networks to run the test")
|
|
||||||
}
|
|
||||||
return i, a.predefined[as][i], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAdjustAndCheckSubnet(t *testing.T) {
|
func TestAdjustAndCheckSubnet(t *testing.T) {
|
||||||
_, sub6, _ := net.ParseCIDR("1003:1:2:300::/63")
|
_, sub6, _ := net.ParseCIDR("1003:1:2:300::/63")
|
||||||
_, err := adjustAndCheckSubnetSize(sub6)
|
_, err := adjustAndCheckSubnetSize(sub6)
|
||||||
|
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"github.com/docker/libnetwork/config"
|
"github.com/docker/libnetwork/config"
|
||||||
"github.com/docker/libnetwork/datastore"
|
"github.com/docker/libnetwork/datastore"
|
||||||
"github.com/docker/libnetwork/driverapi"
|
"github.com/docker/libnetwork/driverapi"
|
||||||
|
"github.com/docker/libnetwork/ipamapi"
|
||||||
"github.com/docker/libnetwork/netlabel"
|
"github.com/docker/libnetwork/netlabel"
|
||||||
"github.com/docker/libnetwork/options"
|
"github.com/docker/libnetwork/options"
|
||||||
"github.com/docker/libnetwork/osl"
|
"github.com/docker/libnetwork/osl"
|
||||||
|
@ -82,14 +83,10 @@ func createController() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTestNetwork(networkType, networkName string, netOption options.Generic) (libnetwork.Network, error) {
|
func createTestNetwork(networkType, networkName string, netOption options.Generic, ipamV4Configs, ipamV6Configs []*libnetwork.IpamConf) (libnetwork.Network, error) {
|
||||||
network, err := controller.NewNetwork(networkType, networkName,
|
return controller.NewNetwork(networkType, networkName,
|
||||||
libnetwork.NetworkOptionGeneric(netOption))
|
libnetwork.NetworkOptionGeneric(netOption),
|
||||||
if err != nil {
|
libnetwork.NetworkOptionIpam(ipamapi.DefaultIPAM, "", ipamV4Configs, ipamV6Configs))
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return network, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getEmptyGenericOption() map[string]interface{} {
|
func getEmptyGenericOption() map[string]interface{} {
|
||||||
|
@ -117,7 +114,7 @@ func TestNull(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
network, err := createTestNetwork("null", "testnull", options.Generic{})
|
network, err := createTestNetwork("null", "testnull", options.Generic{}, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -184,7 +181,7 @@ func TestHost(t *testing.T) {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
network, err := createTestNetwork("host", "testhost", options.Generic{})
|
network, err := createTestNetwork("host", "testhost", options.Generic{}, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -270,36 +267,18 @@ func TestBridge(t *testing.T) {
|
||||||
defer testutils.SetupTestOSContext(t)()
|
defer testutils.SetupTestOSContext(t)()
|
||||||
}
|
}
|
||||||
|
|
||||||
subnet, err := types.ParseCIDR("192.168.100.1/24")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cidr, err := types.ParseCIDR("192.168.100.2/28")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cidrv6, err := types.ParseCIDR("fe90::1/96")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debug("Adding a bridge")
|
|
||||||
|
|
||||||
netOption := options.Generic{
|
netOption := options.Generic{
|
||||||
netlabel.GenericData: options.Generic{
|
netlabel.GenericData: options.Generic{
|
||||||
"BridgeName": "testnetwork",
|
"BridgeName": "testnetwork",
|
||||||
"AddressIPv4": subnet,
|
|
||||||
"FixedCIDR": cidr,
|
|
||||||
"FixedCIDRv6": cidrv6,
|
|
||||||
"EnableIPv6": true,
|
"EnableIPv6": true,
|
||||||
"EnableICC": true,
|
"EnableICC": true,
|
||||||
"EnableIPMasquerade": true,
|
"EnableIPMasquerade": true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
ipamV4ConfList := []*libnetwork.IpamConf{&libnetwork.IpamConf{PreferredPool: "192.168.100.0/24", Gateway: "192.168.100.1"}}
|
||||||
|
ipamV6ConfList := []*libnetwork.IpamConf{&libnetwork.IpamConf{PreferredPool: "fe90::/98", Gateway: "fe90::22"}}
|
||||||
|
|
||||||
network, err := createTestNetwork(bridgeNetType, "testnetwork", netOption)
|
network, err := createTestNetwork(bridgeNetType, "testnetwork", netOption, ipamV4ConfList, ipamV6ConfList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -339,7 +318,7 @@ func TestUnknownDriver(t *testing.T) {
|
||||||
defer testutils.SetupTestOSContext(t)()
|
defer testutils.SetupTestOSContext(t)()
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := createTestNetwork("unknowndriver", "testnetwork", options.Generic{})
|
_, err := createTestNetwork("unknowndriver", "testnetwork", options.Generic{}, nil, nil)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("Expected to fail. But instead succeeded")
|
t.Fatal("Expected to fail. But instead succeeded")
|
||||||
}
|
}
|
||||||
|
@ -372,7 +351,7 @@ func TestNetworkName(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := createTestNetwork(bridgeNetType, "", netOption)
|
_, err := createTestNetwork(bridgeNetType, "", netOption, nil, nil)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("Expected to fail. But instead succeeded")
|
t.Fatal("Expected to fail. But instead succeeded")
|
||||||
}
|
}
|
||||||
|
@ -382,7 +361,7 @@ func TestNetworkName(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
networkName := "testnetwork"
|
networkName := "testnetwork"
|
||||||
n, err := createTestNetwork(bridgeNetType, networkName, netOption)
|
n, err := createTestNetwork(bridgeNetType, networkName, netOption, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -408,7 +387,7 @@ func TestNetworkType(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
n, err := createTestNetwork(bridgeNetType, "testnetwork", netOption)
|
n, err := createTestNetwork(bridgeNetType, "testnetwork", netOption, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -434,7 +413,7 @@ func TestNetworkID(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
n, err := createTestNetwork(bridgeNetType, "testnetwork", netOption)
|
n, err := createTestNetwork(bridgeNetType, "testnetwork", netOption, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -461,7 +440,7 @@ func TestDeleteNetworkWithActiveEndpoints(t *testing.T) {
|
||||||
netlabel.GenericData: netOption,
|
netlabel.GenericData: netOption,
|
||||||
}
|
}
|
||||||
|
|
||||||
network, err := createTestNetwork(bridgeNetType, "testnetwork", option)
|
network, err := createTestNetwork(bridgeNetType, "testnetwork", option, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -502,7 +481,7 @@ func TestUnknownNetwork(t *testing.T) {
|
||||||
netlabel.GenericData: netOption,
|
netlabel.GenericData: netOption,
|
||||||
}
|
}
|
||||||
|
|
||||||
network, err := createTestNetwork(bridgeNetType, "testnetwork", option)
|
network, err := createTestNetwork(bridgeNetType, "testnetwork", option, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -527,20 +506,15 @@ func TestUnknownEndpoint(t *testing.T) {
|
||||||
defer testutils.SetupTestOSContext(t)()
|
defer testutils.SetupTestOSContext(t)()
|
||||||
}
|
}
|
||||||
|
|
||||||
subnet, err := types.ParseCIDR("192.168.100.1/24")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
netOption := options.Generic{
|
netOption := options.Generic{
|
||||||
"BridgeName": "testnetwork",
|
"BridgeName": "testnetwork",
|
||||||
"AddressIPv4": subnet,
|
|
||||||
}
|
}
|
||||||
option := options.Generic{
|
option := options.Generic{
|
||||||
netlabel.GenericData: netOption,
|
netlabel.GenericData: netOption,
|
||||||
}
|
}
|
||||||
|
ipamV4ConfList := []*libnetwork.IpamConf{&libnetwork.IpamConf{PreferredPool: "192.168.100.0/24"}}
|
||||||
|
|
||||||
network, err := createTestNetwork(bridgeNetType, "testnetwork", option)
|
network, err := createTestNetwork(bridgeNetType, "testnetwork", option, ipamV4ConfList, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -581,7 +555,7 @@ func TestNetworkEndpointsWalkers(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
net1, err := createTestNetwork(bridgeNetType, "network1", netOption)
|
net1, err := createTestNetwork(bridgeNetType, "network1", netOption, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -653,7 +627,7 @@ func TestNetworkEndpointsWalkers(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
net2, err := createTestNetwork(bridgeNetType, "network2", netOption)
|
net2, err := createTestNetwork(bridgeNetType, "network2", netOption, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -709,7 +683,7 @@ func TestDuplicateEndpoint(t *testing.T) {
|
||||||
"BridgeName": "testnetwork",
|
"BridgeName": "testnetwork",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
n, err := createTestNetwork(bridgeNetType, "testnetwork", netOption)
|
n, err := createTestNetwork(bridgeNetType, "testnetwork", netOption, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -759,7 +733,7 @@ func TestControllerQuery(t *testing.T) {
|
||||||
"BridgeName": "network1",
|
"BridgeName": "network1",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
net1, err := createTestNetwork(bridgeNetType, "network1", netOption)
|
net1, err := createTestNetwork(bridgeNetType, "network1", netOption, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -775,7 +749,7 @@ func TestControllerQuery(t *testing.T) {
|
||||||
"BridgeName": "network2",
|
"BridgeName": "network2",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
net2, err := createTestNetwork(bridgeNetType, "network2", netOption)
|
net2, err := createTestNetwork(bridgeNetType, "network2", netOption, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -861,7 +835,7 @@ func TestNetworkQuery(t *testing.T) {
|
||||||
"BridgeName": "network1",
|
"BridgeName": "network1",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
net1, err := createTestNetwork(bridgeNetType, "network1", netOption)
|
net1, err := createTestNetwork(bridgeNetType, "network1", netOption, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -981,7 +955,7 @@ func TestEndpointJoin(t *testing.T) {
|
||||||
netlabel.GenericData: options.Generic{
|
netlabel.GenericData: options.Generic{
|
||||||
"BridgeName": "testnetwork1",
|
"BridgeName": "testnetwork1",
|
||||||
},
|
},
|
||||||
})
|
}, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -1090,7 +1064,7 @@ func TestEndpointJoin(t *testing.T) {
|
||||||
netlabel.GenericData: options.Generic{
|
netlabel.GenericData: options.Generic{
|
||||||
"BridgeName": "testnetwork2",
|
"BridgeName": "testnetwork2",
|
||||||
},
|
},
|
||||||
})
|
}, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -1181,7 +1155,7 @@ func externalKeyTest(t *testing.T, reexec bool) {
|
||||||
netlabel.GenericData: options.Generic{
|
netlabel.GenericData: options.Generic{
|
||||||
"BridgeName": "testnetwork",
|
"BridgeName": "testnetwork",
|
||||||
},
|
},
|
||||||
})
|
}, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -1330,7 +1304,7 @@ func TestEndpointDeleteWithActiveContainer(t *testing.T) {
|
||||||
netlabel.GenericData: options.Generic{
|
netlabel.GenericData: options.Generic{
|
||||||
"BridgeName": "testnetwork",
|
"BridgeName": "testnetwork",
|
||||||
},
|
},
|
||||||
})
|
}, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -1393,7 +1367,7 @@ func TestEndpointMultipleJoins(t *testing.T) {
|
||||||
netlabel.GenericData: options.Generic{
|
netlabel.GenericData: options.Generic{
|
||||||
"BridgeName": "testmultiple",
|
"BridgeName": "testmultiple",
|
||||||
},
|
},
|
||||||
})
|
}, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -1464,7 +1438,7 @@ func TestLeaveAll(t *testing.T) {
|
||||||
netlabel.GenericData: options.Generic{
|
netlabel.GenericData: options.Generic{
|
||||||
"BridgeName": "testnetwork",
|
"BridgeName": "testnetwork",
|
||||||
},
|
},
|
||||||
})
|
}, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -1517,7 +1491,7 @@ func TestontainerInvalidLeave(t *testing.T) {
|
||||||
netlabel.GenericData: options.Generic{
|
netlabel.GenericData: options.Generic{
|
||||||
"BridgeName": "testnetwork",
|
"BridgeName": "testnetwork",
|
||||||
},
|
},
|
||||||
})
|
}, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -1583,7 +1557,7 @@ func TestEndpointUpdateParent(t *testing.T) {
|
||||||
netlabel.GenericData: options.Generic{
|
netlabel.GenericData: options.Generic{
|
||||||
"BridgeName": "testnetwork",
|
"BridgeName": "testnetwork",
|
||||||
},
|
},
|
||||||
})
|
}, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -1661,20 +1635,15 @@ func TestEnableIPv6(t *testing.T) {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
cidrv6, err := types.ParseCIDR("fe80::1/64")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
netOption := options.Generic{
|
netOption := options.Generic{
|
||||||
netlabel.EnableIPv6: true,
|
netlabel.EnableIPv6: true,
|
||||||
netlabel.GenericData: options.Generic{
|
netlabel.GenericData: options.Generic{
|
||||||
"BridgeName": "testnetwork",
|
"BridgeName": "testnetwork",
|
||||||
"FixedCIDRv6": cidrv6,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
ipamV6ConfList := []*libnetwork.IpamConf{&libnetwork.IpamConf{PreferredPool: "fe80::/98"}}
|
||||||
|
|
||||||
n, err := createTestNetwork("bridge", "testnetwork", netOption)
|
n, err := createTestNetwork("bridge", "testnetwork", netOption, nil, ipamV6ConfList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -1832,7 +1801,7 @@ func TestResolvConf(t *testing.T) {
|
||||||
"BridgeName": "testnetwork",
|
"BridgeName": "testnetwork",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
n, err := createTestNetwork("bridge", "testnetwork", netOption)
|
n, err := createTestNetwork("bridge", "testnetwork", netOption, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -2102,7 +2071,7 @@ func createGlobalInstance(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
net2, err := createTestNetwork("bridge", "network2", netOption)
|
net2, err := createTestNetwork("bridge", "network2", netOption, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -804,7 +804,7 @@ func (n *network) getController() *controller {
|
||||||
|
|
||||||
func (n *network) ipamAllocate() error {
|
func (n *network) ipamAllocate() error {
|
||||||
// For now also exclude bridge from using new ipam
|
// For now also exclude bridge from using new ipam
|
||||||
if n.Type() == "host" || n.Type() == "null" || n.Type() == "bridge" {
|
if n.Type() == "host" || n.Type() == "null" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -860,7 +860,7 @@ func (n *network) ipamAllocateVersion(ipVer int, ipam ipamapi.Ipam) error {
|
||||||
|
|
||||||
*infoList = make([]*IpamInfo, len(*cfgList))
|
*infoList = make([]*IpamInfo, len(*cfgList))
|
||||||
|
|
||||||
log.Debugf("allocating IPv%d pools for network %s (%s)", ipVer, n.Name(), n.ID())
|
log.Debugf("Allocating IPv%d pools for network %s (%s)", ipVer, n.Name(), n.ID())
|
||||||
|
|
||||||
for i, cfg := range *cfgList {
|
for i, cfg := range *cfgList {
|
||||||
if err = cfg.Validate(); err != nil {
|
if err = cfg.Validate(); err != nil {
|
||||||
|
@ -921,8 +921,8 @@ func (n *network) ipamAllocateVersion(ipVer int, ipam ipamapi.Ipam) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *network) ipamRelease() {
|
func (n *network) ipamRelease() {
|
||||||
// For now also exclude bridge from using new ipam
|
// For now exclude host and null
|
||||||
if n.Type() == "host" || n.Type() == "null" || n.Type() == "bridge" {
|
if n.Type() == "host" || n.Type() == "null" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ipam, err := n.getController().getIpamDriver(n.ipamType)
|
ipam, err := n.getController().getIpamDriver(n.ipamType)
|
||||||
|
|
Loading…
Reference in New Issue