- Set bridge ipv4 address when bridge is present
- IPv6 changes for bridge
- Convert unit tests to the new model
Signed-off-by: Alessandro Boch <aboch@docker.com>
| ... | ... |
@@ -5,6 +5,7 @@ package bitseq |
| 5 | 5 |
|
| 6 | 6 |
import ( |
| 7 | 7 |
"encoding/binary" |
| 8 |
+ "encoding/json" |
|
| 8 | 9 |
"fmt" |
| 9 | 10 |
"sync" |
| 10 | 11 |
|
| ... | ... |
@@ -392,6 +393,38 @@ func (h *Handle) String() string {
|
| 392 | 392 |
h.app, h.id, h.dbIndex, h.bits, h.unselected, h.head.toString()) |
| 393 | 393 |
} |
| 394 | 394 |
|
| 395 |
+// MarshalJSON encodes Handle into json message |
|
| 396 |
+func (h *Handle) MarshalJSON() ([]byte, error) {
|
|
| 397 |
+ m := map[string]interface{}{
|
|
| 398 |
+ "id": h.id, |
|
| 399 |
+ } |
|
| 400 |
+ |
|
| 401 |
+ b, err := h.ToByteArray() |
|
| 402 |
+ if err != nil {
|
|
| 403 |
+ return nil, err |
|
| 404 |
+ } |
|
| 405 |
+ m["sequence"] = b |
|
| 406 |
+ return json.Marshal(m) |
|
| 407 |
+} |
|
| 408 |
+ |
|
| 409 |
+// UnmarshalJSON decodes json message into Handle |
|
| 410 |
+func (h *Handle) UnmarshalJSON(data []byte) error {
|
|
| 411 |
+ var ( |
|
| 412 |
+ m map[string]interface{}
|
|
| 413 |
+ b []byte |
|
| 414 |
+ err error |
|
| 415 |
+ ) |
|
| 416 |
+ if err = json.Unmarshal(data, &m); err != nil {
|
|
| 417 |
+ return err |
|
| 418 |
+ } |
|
| 419 |
+ h.id = m["id"].(string) |
|
| 420 |
+ bi, _ := json.Marshal(m["sequence"]) |
|
| 421 |
+ if err := json.Unmarshal(bi, &b); err != nil {
|
|
| 422 |
+ return err |
|
| 423 |
+ } |
|
| 424 |
+ return h.FromByteArray(b) |
|
| 425 |
+} |
|
| 426 |
+ |
|
| 395 | 427 |
// getFirstAvailable looks for the first unset bit in passed mask starting from start |
| 396 | 428 |
func getFirstAvailable(head *sequence, start uint32) (uint32, uint32, error) {
|
| 397 | 429 |
// Find sequence which contains the start bit |
| ... | ... |
@@ -4,7 +4,6 @@ import ( |
| 4 | 4 |
"encoding/json" |
| 5 | 5 |
"fmt" |
| 6 | 6 |
|
| 7 |
- log "github.com/Sirupsen/logrus" |
|
| 8 | 7 |
"github.com/docker/libnetwork/datastore" |
| 9 | 8 |
"github.com/docker/libnetwork/types" |
| 10 | 9 |
) |
| ... | ... |
@@ -25,27 +24,16 @@ func (h *Handle) KeyPrefix() []string {
|
| 25 | 25 |
|
| 26 | 26 |
// Value marshals the data to be stored in the KV store |
| 27 | 27 |
func (h *Handle) Value() []byte {
|
| 28 |
- b, err := h.ToByteArray() |
|
| 28 |
+ b, err := json.Marshal(h) |
|
| 29 | 29 |
if err != nil {
|
| 30 |
- log.Warnf("Failed to serialize Handle: %v", err)
|
|
| 31 |
- b = []byte{}
|
|
| 32 |
- } |
|
| 33 |
- jv, err := json.Marshal(b) |
|
| 34 |
- if err != nil {
|
|
| 35 |
- log.Warnf("Failed to json encode bitseq handler byte array: %v", err)
|
|
| 36 |
- return []byte{}
|
|
| 30 |
+ return nil |
|
| 37 | 31 |
} |
| 38 |
- return jv |
|
| 32 |
+ return b |
|
| 39 | 33 |
} |
| 40 | 34 |
|
| 41 | 35 |
// SetValue unmarshals the data from the KV store |
| 42 | 36 |
func (h *Handle) SetValue(value []byte) error {
|
| 43 |
- var b []byte |
|
| 44 |
- if err := json.Unmarshal(value, &b); err != nil {
|
|
| 45 |
- return err |
|
| 46 |
- } |
|
| 47 |
- |
|
| 48 |
- return h.FromByteArray(b) |
|
| 37 |
+ return json.Unmarshal(value, h) |
|
| 49 | 38 |
} |
| 50 | 39 |
|
| 51 | 40 |
// Index returns the latest DB Index as seen by this object |
| ... | ... |
@@ -77,7 +65,6 @@ func (h *Handle) New() datastore.KVObject {
|
| 77 | 77 |
|
| 78 | 78 |
return &Handle{
|
| 79 | 79 |
app: h.app, |
| 80 |
- id: h.id, |
|
| 81 | 80 |
store: h.store, |
| 82 | 81 |
} |
| 83 | 82 |
} |
| ... | ... |
@@ -29,8 +29,10 @@ import ( |
| 29 | 29 |
"github.com/docker/libnetwork/config" |
| 30 | 30 |
"github.com/docker/libnetwork/datastore" |
| 31 | 31 |
"github.com/docker/libnetwork/driverapi" |
| 32 |
+ "github.com/docker/libnetwork/ipamutils" |
|
| 32 | 33 |
"github.com/docker/libnetwork/netlabel" |
| 33 | 34 |
"github.com/docker/libnetwork/options" |
| 35 |
+ "github.com/docker/libnetwork/types" |
|
| 34 | 36 |
"github.com/gorilla/mux" |
| 35 | 37 |
) |
| 36 | 38 |
|
| ... | ... |
@@ -187,7 +189,12 @@ func createDefaultNetwork(c libnetwork.NetworkController) {
|
| 187 | 187 |
} |
| 188 | 188 |
createOptions = append(createOptions, |
| 189 | 189 |
libnetwork.NetworkOptionGeneric(genericOption), |
| 190 |
- libnetwork.NetworkOptionPersist(false)) |
|
| 190 |
+ ipamOption(nw)) |
|
| 191 |
+ } |
|
| 192 |
+ |
|
| 193 |
+ if _, err := c.NetworkByName(nw); err == nil {
|
|
| 194 |
+ logrus.Debugf("Default network %s already present", nw)
|
|
| 195 |
+ return |
|
| 191 | 196 |
} |
| 192 | 197 |
_, err := c.NewNetwork(d, nw, createOptions...) |
| 193 | 198 |
if err != nil {
|
| ... | ... |
@@ -405,3 +412,15 @@ func encodeData(data interface{}) (*bytes.Buffer, error) {
|
| 405 | 405 |
} |
| 406 | 406 |
return params, nil |
| 407 | 407 |
} |
| 408 |
+ |
|
| 409 |
+func ipamOption(bridgeName string) libnetwork.NetworkOption {
|
|
| 410 |
+ if nw, _, err := ipamutils.ElectInterfaceAddresses(bridgeName); err == nil {
|
|
| 411 |
+ ipamV4Conf := &libnetwork.IpamConf{PreferredPool: nw.String()}
|
|
| 412 |
+ hip, _ := types.GetHostPartIP(nw.IP, nw.Mask) |
|
| 413 |
+ if hip.IsGlobalUnicast() {
|
|
| 414 |
+ ipamV4Conf.Gateway = nw.IP.String() |
|
| 415 |
+ } |
|
| 416 |
+ return libnetwork.NetworkOptionIpam("default", "", []*libnetwork.IpamConf{ipamV4Conf}, nil)
|
|
| 417 |
+ } |
|
| 418 |
+ return nil |
|
| 419 |
+} |
| ... | ... |
@@ -56,15 +56,17 @@ type configuration struct {
|
| 56 | 56 |
// networkConfiguration for network specific configuration |
| 57 | 57 |
type networkConfiguration struct {
|
| 58 | 58 |
BridgeName string |
| 59 |
- AddressIPv4 *net.IPNet |
|
| 60 | 59 |
EnableIPv6 bool |
| 61 | 60 |
EnableIPMasquerade bool |
| 62 | 61 |
EnableICC bool |
| 63 | 62 |
Mtu int |
| 64 |
- DefaultGatewayIPv4 net.IP |
|
| 65 |
- DefaultGatewayIPv6 net.IP |
|
| 66 | 63 |
DefaultBindingIP net.IP |
| 67 | 64 |
DefaultBridge bool |
| 65 |
+ // Internal fields set after ipam data parsing |
|
| 66 |
+ AddressIPv4 *net.IPNet |
|
| 67 |
+ AddressIPv6 *net.IPNet |
|
| 68 |
+ DefaultGatewayIPv4 net.IP |
|
| 69 |
+ DefaultGatewayIPv6 net.IP |
|
| 68 | 70 |
} |
| 69 | 71 |
|
| 70 | 72 |
// endpointConfiguration represents the user specified configuration for the sandbox endpoint |
| ... | ... |
@@ -161,27 +163,39 @@ func (c *networkConfiguration) Validate() error {
|
| 161 | 161 |
} |
| 162 | 162 |
} |
| 163 | 163 |
|
| 164 |
+ // If default v6 gw is specified, AddressIPv6 must be specified and gw must belong to AddressIPv6 subnet |
|
| 165 |
+ if c.EnableIPv6 && c.DefaultGatewayIPv6 != nil {
|
|
| 166 |
+ if c.AddressIPv6 == nil || !c.AddressIPv6.Contains(c.DefaultGatewayIPv6) {
|
|
| 167 |
+ return &ErrInvalidGateway{}
|
|
| 168 |
+ } |
|
| 169 |
+ } |
|
| 164 | 170 |
return nil |
| 165 | 171 |
} |
| 166 | 172 |
|
| 167 | 173 |
// Conflicts check if two NetworkConfiguration objects overlap |
| 168 |
-func (c *networkConfiguration) Conflicts(o *networkConfiguration) bool {
|
|
| 174 |
+func (c *networkConfiguration) Conflicts(o *networkConfiguration) error {
|
|
| 169 | 175 |
if o == nil {
|
| 170 |
- return false |
|
| 176 |
+ return fmt.Errorf("same configuration")
|
|
| 171 | 177 |
} |
| 172 | 178 |
|
| 173 | 179 |
// Also empty, becasue only one network with empty name is allowed |
| 174 | 180 |
if c.BridgeName == o.BridgeName {
|
| 175 |
- return true |
|
| 181 |
+ return fmt.Errorf("networks have same name")
|
|
| 176 | 182 |
} |
| 177 | 183 |
|
| 178 | 184 |
// They must be in different subnets |
| 179 | 185 |
if (c.AddressIPv4 != nil && o.AddressIPv4 != nil) && |
| 180 | 186 |
(c.AddressIPv4.Contains(o.AddressIPv4.IP) || o.AddressIPv4.Contains(c.AddressIPv4.IP)) {
|
| 181 |
- return true |
|
| 187 |
+ return fmt.Errorf("networks have overlapping IPv4")
|
|
| 188 |
+ } |
|
| 189 |
+ |
|
| 190 |
+ // They must be in different v6 subnets |
|
| 191 |
+ if (c.AddressIPv6 != nil && o.AddressIPv6 != nil) && |
|
| 192 |
+ (c.AddressIPv6.Contains(o.AddressIPv6.IP) || o.AddressIPv6.Contains(c.AddressIPv6.IP)) {
|
|
| 193 |
+ return fmt.Errorf("networks have overlapping IPv6")
|
|
| 182 | 194 |
} |
| 183 | 195 |
|
| 184 |
- return false |
|
| 196 |
+ return nil |
|
| 185 | 197 |
} |
| 186 | 198 |
|
| 187 | 199 |
// fromMap retrieve the configuration data from the map form. |
| ... | ... |
@@ -456,18 +470,18 @@ func (c *networkConfiguration) processIPAM(id string, ipamV4Data, ipamV6Data []d |
| 456 | 456 |
c.AddressIPv4 = types.GetIPNetCopy(ipamV4Data[0].Gateway) |
| 457 | 457 |
} |
| 458 | 458 |
|
| 459 |
- if c.EnableIPv6 && len(ipamV6Data) == 0 {
|
|
| 460 |
- return types.BadRequestErrorf("bridge network %s requires ipv6 configuration", id)
|
|
| 461 |
- } |
|
| 462 |
- |
|
| 463 |
- gw, ok := ipamV4Data[0].AuxAddresses[DefaultGatewayV4AuxKey] |
|
| 464 |
- if ok {
|
|
| 459 |
+ if gw, ok := ipamV4Data[0].AuxAddresses[DefaultGatewayV4AuxKey]; ok {
|
|
| 465 | 460 |
c.DefaultGatewayIPv4 = gw.IP |
| 466 | 461 |
} |
| 467 | 462 |
|
| 468 |
- gw, ok = ipamV4Data[0].AuxAddresses[DefaultGatewayV6AuxKey] |
|
| 469 |
- if ok {
|
|
| 470 |
- c.DefaultGatewayIPv6 = gw.IP |
|
| 463 |
+ if len(ipamV6Data) > 0 {
|
|
| 464 |
+ if ipamV6Data[0].Gateway != nil {
|
|
| 465 |
+ c.AddressIPv6 = types.GetIPNetCopy(ipamV6Data[0].Gateway) |
|
| 466 |
+ } |
|
| 467 |
+ |
|
| 468 |
+ if gw, ok := ipamV6Data[0].AuxAddresses[DefaultGatewayV6AuxKey]; ok {
|
|
| 469 |
+ c.DefaultGatewayIPv6 = gw.IP |
|
| 470 |
+ } |
|
| 471 | 471 |
} |
| 472 | 472 |
|
| 473 | 473 |
return nil |
| ... | ... |
@@ -502,6 +516,9 @@ func parseNetworkOptions(id string, option options.Generic) (*networkConfigurati |
| 502 | 502 |
|
| 503 | 503 |
// Returns the non link-local IPv6 subnet for the containers attached to this bridge if found, nil otherwise |
| 504 | 504 |
func getV6Network(config *networkConfiguration, i *bridgeInterface) *net.IPNet {
|
| 505 |
+ if config.AddressIPv6 != nil {
|
|
| 506 |
+ return config.AddressIPv6 |
|
| 507 |
+ } |
|
| 505 | 508 |
if i.bridgeIPv6 != nil && i.bridgeIPv6.IP != nil && !i.bridgeIPv6.IP.IsLinkLocalUnicast() {
|
| 506 | 509 |
return i.bridgeIPv6 |
| 507 | 510 |
} |
| ... | ... |
@@ -551,8 +568,9 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, ipV4Dat
|
| 551 | 551 |
nw.Lock() |
| 552 | 552 |
nwConfig := nw.config |
| 553 | 553 |
nw.Unlock() |
| 554 |
- if nwConfig.Conflicts(config) {
|
|
| 555 |
- return types.ForbiddenErrorf("conflicts with network %s (%s)", nw.id, nw.config.BridgeName)
|
|
| 554 |
+ if err := nwConfig.Conflicts(config); err != nil {
|
|
| 555 |
+ return types.ForbiddenErrorf("cannot create network %s (%s): conflicts with network %s (%s): %s",
|
|
| 556 |
+ nwConfig.BridgeName, id, nw.id, nw.config.BridgeName, err.Error()) |
|
| 556 | 557 |
} |
| 557 | 558 |
} |
| 558 | 559 |
|
| ... | ... |
@@ -613,10 +631,7 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, ipV4Dat
|
| 613 | 613 |
// Even if a bridge exists try to setup IPv4. |
| 614 | 614 |
bridgeSetup.queueStep(setupBridgeIPv4) |
| 615 | 615 |
|
| 616 |
- enableIPv6Forwarding := false |
|
| 617 |
- if d.config.EnableIPForwarding {
|
|
| 618 |
- enableIPv6Forwarding = true |
|
| 619 |
- } |
|
| 616 |
+ enableIPv6Forwarding := d.config.EnableIPForwarding && config.AddressIPv6 != nil |
|
| 620 | 617 |
|
| 621 | 618 |
// Conditionally queue setup steps depending on configuration values. |
| 622 | 619 |
for _, step := range []struct {
|
| ... | ... |
@@ -797,11 +812,6 @@ func setHairpinMode(link netlink.Link, enable bool) error {
|
| 797 | 797 |
} |
| 798 | 798 |
|
| 799 | 799 |
func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, epOptions map[string]interface{}) error {
|
| 800 |
- var ( |
|
| 801 |
- ipv6Addr *net.IPNet |
|
| 802 |
- err error |
|
| 803 |
- ) |
|
| 804 |
- |
|
| 805 | 800 |
defer osl.InitOSContext()() |
| 806 | 801 |
|
| 807 | 802 |
if ifInfo == nil {
|
| ... | ... |
@@ -931,7 +941,11 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, |
| 931 | 931 |
} |
| 932 | 932 |
} |
| 933 | 933 |
|
| 934 |
- ipv4Addr := ifInfo.Address() |
|
| 934 |
+ // Create the sandbox side pipe interface |
|
| 935 |
+ endpoint.srcName = containerIfName |
|
| 936 |
+ endpoint.macAddress = ifInfo.MacAddress() |
|
| 937 |
+ endpoint.addr = ifInfo.Address() |
|
| 938 |
+ endpoint.addrv6 = ifInfo.AddressIPv6() |
|
| 935 | 939 |
|
| 936 | 940 |
// Down the interface before configuring mac address. |
| 937 | 941 |
if err = netlink.LinkSetDown(sbox); err != nil {
|
| ... | ... |
@@ -939,28 +953,38 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, |
| 939 | 939 |
} |
| 940 | 940 |
|
| 941 | 941 |
// Set the sbox's MAC. If specified, use the one configured by user, otherwise generate one based on IP. |
| 942 |
- mac := ifInfo.MacAddress() |
|
| 943 |
- if mac == nil {
|
|
| 944 |
- mac = electMacAddress(epConfig, ipv4Addr.IP) |
|
| 942 |
+ if endpoint.macAddress == nil {
|
|
| 943 |
+ endpoint.macAddress = electMacAddress(epConfig, endpoint.addr.IP) |
|
| 944 |
+ if err := ifInfo.SetMacAddress(endpoint.macAddress); err != nil {
|
|
| 945 |
+ return err |
|
| 946 |
+ } |
|
| 945 | 947 |
} |
| 946 |
- err = netlink.LinkSetHardwareAddr(sbox, mac) |
|
| 948 |
+ err = netlink.LinkSetHardwareAddr(sbox, endpoint.macAddress) |
|
| 947 | 949 |
if err != nil {
|
| 948 | 950 |
return fmt.Errorf("could not set mac address for container interface %s: %v", containerIfName, err)
|
| 949 | 951 |
} |
| 950 |
- endpoint.macAddress = mac |
|
| 951 | 952 |
|
| 952 | 953 |
// Up the host interface after finishing all netlink configuration |
| 953 | 954 |
if err = netlink.LinkSetUp(host); err != nil {
|
| 954 | 955 |
return fmt.Errorf("could not set link up for host interface %s: %v", hostIfName, err)
|
| 955 | 956 |
} |
| 956 | 957 |
|
| 957 |
- ipv6Addr = ifInfo.AddressIPv6() |
|
| 958 |
- // Create the sandbox side pipe interface |
|
| 959 |
- endpoint.srcName = containerIfName |
|
| 960 |
- endpoint.addr = ipv4Addr |
|
| 958 |
+ if endpoint.addrv6 == nil && config.EnableIPv6 {
|
|
| 959 |
+ var ip6 net.IP |
|
| 960 |
+ network := n.bridge.bridgeIPv6 |
|
| 961 |
+ ones, _ := network.Mask.Size() |
|
| 962 |
+ if ones <= 80 {
|
|
| 963 |
+ ip6 = make(net.IP, len(network.IP)) |
|
| 964 |
+ copy(ip6, network.IP) |
|
| 965 |
+ for i, h := range endpoint.macAddress {
|
|
| 966 |
+ ip6[i+10] = h |
|
| 967 |
+ } |
|
| 968 |
+ } |
|
| 961 | 969 |
|
| 962 |
- if config.EnableIPv6 {
|
|
| 963 |
- endpoint.addrv6 = ipv6Addr |
|
| 970 |
+ endpoint.addrv6 = &net.IPNet{IP: ip6, Mask: network.Mask}
|
|
| 971 |
+ if err := ifInfo.SetIPAddress(endpoint.addrv6); err != nil {
|
|
| 972 |
+ return err |
|
| 973 |
+ } |
|
| 964 | 974 |
} |
| 965 | 975 |
|
| 966 | 976 |
// Program any required port mapping and store them in the endpoint |
| ... | ... |
@@ -969,13 +993,6 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, |
| 969 | 969 |
return err |
| 970 | 970 |
} |
| 971 | 971 |
|
| 972 |
- if ifInfo.MacAddress() == nil {
|
|
| 973 |
- err = ifInfo.SetMacAddress(endpoint.macAddress) |
|
| 974 |
- if err != nil {
|
|
| 975 |
- return err |
|
| 976 |
- } |
|
| 977 |
- } |
|
| 978 |
- |
|
| 979 | 972 |
return nil |
| 980 | 973 |
} |
| 981 | 974 |
|
| ... | ... |
@@ -8,14 +8,27 @@ import ( |
| 8 | 8 |
"testing" |
| 9 | 9 |
|
| 10 | 10 |
"github.com/docker/libnetwork/driverapi" |
| 11 |
+ "github.com/docker/libnetwork/ipamutils" |
|
| 11 | 12 |
"github.com/docker/libnetwork/iptables" |
| 12 | 13 |
"github.com/docker/libnetwork/netlabel" |
| 13 |
- "github.com/docker/libnetwork/netutils" |
|
| 14 | 14 |
"github.com/docker/libnetwork/testutils" |
| 15 | 15 |
"github.com/docker/libnetwork/types" |
| 16 | 16 |
"github.com/vishvananda/netlink" |
| 17 | 17 |
) |
| 18 | 18 |
|
| 19 |
+func getIPv4Data(t *testing.T) []driverapi.IPAMData {
|
|
| 20 |
+ ipd := driverapi.IPAMData{AddressSpace: "full"}
|
|
| 21 |
+ nw, _, err := ipamutils.ElectInterfaceAddresses("")
|
|
| 22 |
+ if err != nil {
|
|
| 23 |
+ t.Fatal(err) |
|
| 24 |
+ } |
|
| 25 |
+ ipd.Pool = nw |
|
| 26 |
+ // Set network gateway to X.X.X.1 |
|
| 27 |
+ ipd.Gateway = types.GetIPNetCopy(nw) |
|
| 28 |
+ ipd.Gateway.IP[len(ipd.Gateway.IP)-1] = 1 |
|
| 29 |
+ return []driverapi.IPAMData{ipd}
|
|
| 30 |
+} |
|
| 31 |
+ |
|
| 19 | 32 |
func TestCreateFullOptions(t *testing.T) {
|
| 20 | 33 |
defer testutils.SetupTestOSContext(t)() |
| 21 | 34 |
d := newDriver() |
| ... | ... |
@@ -27,17 +40,14 @@ func TestCreateFullOptions(t *testing.T) {
|
| 27 | 27 |
|
| 28 | 28 |
// Test this scenario: Default gw address does not belong to |
| 29 | 29 |
// container network and it's greater than bridge address |
| 30 |
- cip, cnw, _ := net.ParseCIDR("172.16.122.0/24")
|
|
| 31 |
- cnw.IP = cip |
|
| 32 |
- ip, nw, _ := net.ParseCIDR("172.16.0.10/16")
|
|
| 33 |
- nw.IP = ip |
|
| 34 |
- gw := net.ParseIP("172.16.0.1")
|
|
| 30 |
+ cnw, _ := types.ParseCIDR("172.16.122.0/24")
|
|
| 31 |
+ bnw, _ := types.ParseCIDR("172.16.0.0/24")
|
|
| 32 |
+ br, _ := types.ParseCIDR("172.16.0.1/16")
|
|
| 33 |
+ defgw, _ := types.ParseCIDR("172.16.0.100/16")
|
|
| 35 | 34 |
|
| 36 | 35 |
netConfig := &networkConfiguration{
|
| 37 |
- BridgeName: DefaultBridgeName, |
|
| 38 |
- AddressIPv4: nw, |
|
| 39 |
- DefaultGatewayIPv4: gw, |
|
| 40 |
- EnableIPv6: true, |
|
| 36 |
+ BridgeName: DefaultBridgeName, |
|
| 37 |
+ EnableIPv6: true, |
|
| 41 | 38 |
} |
| 42 | 39 |
genericOption := make(map[string]interface{})
|
| 43 | 40 |
genericOption[netlabel.GenericData] = config |
| ... | ... |
@@ -49,14 +59,21 @@ func TestCreateFullOptions(t *testing.T) {
|
| 49 | 49 |
netOption := make(map[string]interface{})
|
| 50 | 50 |
netOption[netlabel.GenericData] = netConfig |
| 51 | 51 |
|
| 52 |
- err := d.CreateNetwork("dummy", netOption, nil, nil)
|
|
| 52 |
+ ipdList := []driverapi.IPAMData{
|
|
| 53 |
+ driverapi.IPAMData{
|
|
| 54 |
+ Pool: bnw, |
|
| 55 |
+ Gateway: br, |
|
| 56 |
+ AuxAddresses: map[string]*net.IPNet{DefaultGatewayV4AuxKey: defgw},
|
|
| 57 |
+ }, |
|
| 58 |
+ } |
|
| 59 |
+ err := d.CreateNetwork("dummy", netOption, ipdList, nil)
|
|
| 53 | 60 |
if err != nil {
|
| 54 | 61 |
t.Fatalf("Failed to create bridge: %v", err)
|
| 55 | 62 |
} |
| 56 | 63 |
|
| 57 | 64 |
// Verify the IP address allocated for the endpoint belongs to the container network |
| 58 | 65 |
epOptions := make(map[string]interface{})
|
| 59 |
- te := &testEndpoint{iface: &testInterface{}}
|
|
| 66 |
+ te := newTestEndpoint(cnw, 10) |
|
| 60 | 67 |
err = d.CreateEndpoint("dummy", "ep1", te.Interface(), epOptions)
|
| 61 | 68 |
if err != nil {
|
| 62 | 69 |
t.Fatalf("Failed to create an endpoint : %s", err.Error())
|
| ... | ... |
@@ -75,7 +92,7 @@ func TestCreateNoConfig(t *testing.T) {
|
| 75 | 75 |
genericOption := make(map[string]interface{})
|
| 76 | 76 |
genericOption[netlabel.GenericData] = netconfig |
| 77 | 77 |
|
| 78 |
- if err := d.CreateNetwork("dummy", genericOption, nil, nil); err != nil {
|
|
| 78 |
+ if err := d.CreateNetwork("dummy", genericOption, getIPv4Data(t), nil); err != nil {
|
|
| 79 | 79 |
t.Fatalf("Failed to create bridge: %v", err)
|
| 80 | 80 |
} |
| 81 | 81 |
} |
| ... | ... |
@@ -92,11 +109,11 @@ func TestCreate(t *testing.T) {
|
| 92 | 92 |
genericOption := make(map[string]interface{})
|
| 93 | 93 |
genericOption[netlabel.GenericData] = netconfig |
| 94 | 94 |
|
| 95 |
- if err := d.CreateNetwork("dummy", genericOption, nil, nil); err != nil {
|
|
| 95 |
+ if err := d.CreateNetwork("dummy", genericOption, getIPv4Data(t), nil); err != nil {
|
|
| 96 | 96 |
t.Fatalf("Failed to create bridge: %v", err)
|
| 97 | 97 |
} |
| 98 | 98 |
|
| 99 |
- err := d.CreateNetwork("dummy", genericOption, nil, nil)
|
|
| 99 |
+ err := d.CreateNetwork("dummy", genericOption, getIPv4Data(t), nil)
|
|
| 100 | 100 |
if err == nil {
|
| 101 | 101 |
t.Fatalf("Expected bridge driver to refuse creation of second network with default name")
|
| 102 | 102 |
} |
| ... | ... |
@@ -125,7 +142,7 @@ func TestCreateFail(t *testing.T) {
|
| 125 | 125 |
genericOption := make(map[string]interface{})
|
| 126 | 126 |
genericOption[netlabel.GenericData] = netconfig |
| 127 | 127 |
|
| 128 |
- if err := d.CreateNetwork("dummy", genericOption, nil, nil); err == nil {
|
|
| 128 |
+ if err := d.CreateNetwork("dummy", genericOption, getIPv4Data(t), nil); err == nil {
|
|
| 129 | 129 |
t.Fatal("Bridge creation was expected to fail")
|
| 130 | 130 |
} |
| 131 | 131 |
} |
| ... | ... |
@@ -147,19 +164,19 @@ func TestCreateMultipleNetworks(t *testing.T) {
|
| 147 | 147 |
config1 := &networkConfiguration{BridgeName: "net_test_1"}
|
| 148 | 148 |
genericOption = make(map[string]interface{})
|
| 149 | 149 |
genericOption[netlabel.GenericData] = config1 |
| 150 |
- if err := d.CreateNetwork("1", genericOption, nil, nil); err != nil {
|
|
| 150 |
+ if err := d.CreateNetwork("1", genericOption, getIPv4Data(t), nil); err != nil {
|
|
| 151 | 151 |
t.Fatalf("Failed to create bridge: %v", err)
|
| 152 | 152 |
} |
| 153 | 153 |
|
| 154 | 154 |
config2 := &networkConfiguration{BridgeName: "net_test_2"}
|
| 155 | 155 |
genericOption[netlabel.GenericData] = config2 |
| 156 |
- if err := d.CreateNetwork("2", genericOption, nil, nil); err != nil {
|
|
| 156 |
+ if err := d.CreateNetwork("2", genericOption, getIPv4Data(t), nil); err != nil {
|
|
| 157 | 157 |
t.Fatalf("Failed to create bridge: %v", err)
|
| 158 | 158 |
} |
| 159 | 159 |
|
| 160 | 160 |
config3 := &networkConfiguration{BridgeName: "net_test_3"}
|
| 161 | 161 |
genericOption[netlabel.GenericData] = config3 |
| 162 |
- if err := d.CreateNetwork("3", genericOption, nil, nil); err != nil {
|
|
| 162 |
+ if err := d.CreateNetwork("3", genericOption, getIPv4Data(t), nil); err != nil {
|
|
| 163 | 163 |
t.Fatalf("Failed to create bridge: %v", err)
|
| 164 | 164 |
} |
| 165 | 165 |
|
| ... | ... |
@@ -168,7 +185,7 @@ func TestCreateMultipleNetworks(t *testing.T) {
|
| 168 | 168 |
|
| 169 | 169 |
config4 := &networkConfiguration{BridgeName: "net_test_4"}
|
| 170 | 170 |
genericOption[netlabel.GenericData] = config4 |
| 171 |
- if err := d.CreateNetwork("4", genericOption, nil, nil); err != nil {
|
|
| 171 |
+ if err := d.CreateNetwork("4", genericOption, getIPv4Data(t), nil); err != nil {
|
|
| 172 | 172 |
t.Fatalf("Failed to create bridge: %v", err)
|
| 173 | 173 |
} |
| 174 | 174 |
|
| ... | ... |
@@ -221,6 +238,12 @@ type testEndpoint struct {
|
| 221 | 221 |
routes []types.StaticRoute |
| 222 | 222 |
} |
| 223 | 223 |
|
| 224 |
+func newTestEndpoint(nw *net.IPNet, ordinal byte) *testEndpoint {
|
|
| 225 |
+ addr := types.GetIPNetCopy(nw) |
|
| 226 |
+ addr.IP[len(addr.IP)-1] = ordinal |
|
| 227 |
+ return &testEndpoint{iface: &testInterface{addr: addr}}
|
|
| 228 |
+} |
|
| 229 |
+ |
|
| 224 | 230 |
func (te *testEndpoint) Interface() driverapi.InterfaceInfo {
|
| 225 | 231 |
if te.iface != nil {
|
| 226 | 232 |
return te.iface |
| ... | ... |
@@ -329,7 +352,8 @@ func testQueryEndpointInfo(t *testing.T, ulPxyEnabled bool) {
|
| 329 | 329 |
genericOption = make(map[string]interface{})
|
| 330 | 330 |
genericOption[netlabel.GenericData] = netconfig |
| 331 | 331 |
|
| 332 |
- err := d.CreateNetwork("net1", genericOption, nil, nil)
|
|
| 332 |
+ ipdList := getIPv4Data(t) |
|
| 333 |
+ err := d.CreateNetwork("net1", genericOption, ipdList, nil)
|
|
| 333 | 334 |
if err != nil {
|
| 334 | 335 |
t.Fatalf("Failed to create bridge: %v", err)
|
| 335 | 336 |
} |
| ... | ... |
@@ -338,7 +362,7 @@ func testQueryEndpointInfo(t *testing.T, ulPxyEnabled bool) {
|
| 338 | 338 |
epOptions := make(map[string]interface{})
|
| 339 | 339 |
epOptions[netlabel.PortMap] = portMappings |
| 340 | 340 |
|
| 341 |
- te := &testEndpoint{iface: &testInterface{}}
|
|
| 341 |
+ te := newTestEndpoint(ipdList[0].Pool, 11) |
|
| 342 | 342 |
err = d.CreateEndpoint("net1", "ep1", te.Interface(), epOptions)
|
| 343 | 343 |
if err != nil {
|
| 344 | 344 |
t.Fatalf("Failed to create an endpoint : %s", err.Error())
|
| ... | ... |
@@ -389,7 +413,8 @@ func TestCreateLinkWithOptions(t *testing.T) {
|
| 389 | 389 |
netOptions := make(map[string]interface{})
|
| 390 | 390 |
netOptions[netlabel.GenericData] = netconfig |
| 391 | 391 |
|
| 392 |
- err := d.CreateNetwork("net1", netOptions, nil, nil)
|
|
| 392 |
+ ipdList := getIPv4Data(t) |
|
| 393 |
+ err := d.CreateNetwork("net1", netOptions, ipdList, nil)
|
|
| 393 | 394 |
if err != nil {
|
| 394 | 395 |
t.Fatalf("Failed to create bridge: %v", err)
|
| 395 | 396 |
} |
| ... | ... |
@@ -398,7 +423,7 @@ func TestCreateLinkWithOptions(t *testing.T) {
|
| 398 | 398 |
epOptions := make(map[string]interface{})
|
| 399 | 399 |
epOptions[netlabel.MacAddress] = mac |
| 400 | 400 |
|
| 401 |
- te := &testEndpoint{iface: &testInterface{}}
|
|
| 401 |
+ te := newTestEndpoint(ipdList[0].Pool, 11) |
|
| 402 | 402 |
err = d.CreateEndpoint("net1", "ep", te.Interface(), epOptions)
|
| 403 | 403 |
if err != nil {
|
| 404 | 404 |
t.Fatalf("Failed to create an endpoint: %s", err.Error())
|
| ... | ... |
@@ -458,7 +483,8 @@ func TestLinkContainers(t *testing.T) {
|
| 458 | 458 |
genericOption = make(map[string]interface{})
|
| 459 | 459 |
genericOption[netlabel.GenericData] = netconfig |
| 460 | 460 |
|
| 461 |
- err := d.CreateNetwork("net1", genericOption, nil, nil)
|
|
| 461 |
+ ipdList := getIPv4Data(t) |
|
| 462 |
+ err := d.CreateNetwork("net1", genericOption, ipdList, nil)
|
|
| 462 | 463 |
if err != nil {
|
| 463 | 464 |
t.Fatalf("Failed to create bridge: %v", err)
|
| 464 | 465 |
} |
| ... | ... |
@@ -467,7 +493,7 @@ func TestLinkContainers(t *testing.T) {
|
| 467 | 467 |
epOptions := make(map[string]interface{})
|
| 468 | 468 |
epOptions[netlabel.ExposedPorts] = exposedPorts |
| 469 | 469 |
|
| 470 |
- te1 := &testEndpoint{iface: &testInterface{}}
|
|
| 470 |
+ te1 := newTestEndpoint(ipdList[0].Pool, 11) |
|
| 471 | 471 |
err = d.CreateEndpoint("net1", "ep1", te1.Interface(), epOptions)
|
| 472 | 472 |
if err != nil {
|
| 473 | 473 |
t.Fatalf("Failed to create an endpoint : %s", err.Error())
|
| ... | ... |
@@ -478,7 +504,7 @@ func TestLinkContainers(t *testing.T) {
|
| 478 | 478 |
t.Fatalf("No Ipv4 address assigned to the endpoint: ep1")
|
| 479 | 479 |
} |
| 480 | 480 |
|
| 481 |
- te2 := &testEndpoint{iface: &testInterface{}}
|
|
| 481 |
+ te2 := newTestEndpoint(ipdList[0].Pool, 22) |
|
| 482 | 482 |
err = d.CreateEndpoint("net1", "ep2", te2.Interface(), nil)
|
| 483 | 483 |
if err != nil {
|
| 484 | 484 |
t.Fatalf("Failed to create an endpoint : %s", err.Error())
|
| ... | ... |
@@ -581,6 +607,14 @@ func TestValidateConfig(t *testing.T) {
|
| 581 | 581 |
|
| 582 | 582 |
// Bridge network |
| 583 | 583 |
_, network, _ := net.ParseCIDR("172.28.0.0/16")
|
| 584 |
+ c = networkConfiguration{
|
|
| 585 |
+ AddressIPv4: network, |
|
| 586 |
+ } |
|
| 587 |
+ |
|
| 588 |
+ err = c.Validate() |
|
| 589 |
+ if err != nil {
|
|
| 590 |
+ t.Fatal(err) |
|
| 591 |
+ } |
|
| 584 | 592 |
|
| 585 | 593 |
// Test v4 gw |
| 586 | 594 |
c.DefaultGatewayIPv4 = net.ParseIP("172.27.30.234")
|
| ... | ... |
@@ -596,9 +630,10 @@ func TestValidateConfig(t *testing.T) {
|
| 596 | 596 |
} |
| 597 | 597 |
|
| 598 | 598 |
// Test v6 gw |
| 599 |
- _, containerSubnet, _ = net.ParseCIDR("2001:1234:ae:b004::/64")
|
|
| 599 |
+ _, v6nw, _ := net.ParseCIDR("2001:1234:ae:b004::/64")
|
|
| 600 | 600 |
c = networkConfiguration{
|
| 601 | 601 |
EnableIPv6: true, |
| 602 |
+ AddressIPv6: v6nw, |
|
| 602 | 603 |
DefaultGatewayIPv6: net.ParseIP("2001:1234:ac:b004::bad:a55"),
|
| 603 | 604 |
} |
| 604 | 605 |
err = c.Validate() |
| ... | ... |
@@ -611,6 +646,18 @@ func TestValidateConfig(t *testing.T) {
|
| 611 | 611 |
if err != nil {
|
| 612 | 612 |
t.Fatalf("Unexpected validation error on v6 default gateway")
|
| 613 | 613 |
} |
| 614 |
+ |
|
| 615 |
+ c.AddressIPv6 = nil |
|
| 616 |
+ err = c.Validate() |
|
| 617 |
+ if err == nil {
|
|
| 618 |
+ t.Fatalf("Failed to detect invalid v6 default gateway")
|
|
| 619 |
+ } |
|
| 620 |
+ |
|
| 621 |
+ c.AddressIPv6 = nil |
|
| 622 |
+ err = c.Validate() |
|
| 623 |
+ if err == nil {
|
|
| 624 |
+ t.Fatalf("Failed to detect invalid v6 default gateway")
|
|
| 625 |
+ } |
|
| 614 | 626 |
} |
| 615 | 627 |
|
| 616 | 628 |
func TestSetDefaultGw(t *testing.T) {
|
| ... | ... |
@@ -623,24 +670,15 @@ func TestSetDefaultGw(t *testing.T) {
|
| 623 | 623 |
|
| 624 | 624 |
_, subnetv6, _ := net.ParseCIDR("2001:db8:ea9:9abc:b0c4::/80")
|
| 625 | 625 |
|
| 626 |
- var nw *net.IPNet |
|
| 627 |
- for _, n := range bridgeNetworks {
|
|
| 628 |
- if err := netutils.CheckRouteOverlaps(n); err == nil {
|
|
| 629 |
- nw = n |
|
| 630 |
- break |
|
| 631 |
- } |
|
| 632 |
- } |
|
| 633 |
- if nw == nil {
|
|
| 634 |
- t.Skipf("Skip as no more automatic networks available")
|
|
| 635 |
- } |
|
| 636 |
- |
|
| 637 |
- gw4 := types.GetIPCopy(nw.IP).To4() |
|
| 626 |
+ ipdList := getIPv4Data(t) |
|
| 627 |
+ gw4 := types.GetIPCopy(ipdList[0].Pool.IP).To4() |
|
| 638 | 628 |
gw4[3] = 254 |
| 639 | 629 |
gw6 := net.ParseIP("2001:db8:ea9:9abc:b0c4::254")
|
| 640 | 630 |
|
| 641 | 631 |
config := &networkConfiguration{
|
| 642 | 632 |
BridgeName: DefaultBridgeName, |
| 643 | 633 |
EnableIPv6: true, |
| 634 |
+ AddressIPv6: subnetv6, |
|
| 644 | 635 |
DefaultGatewayIPv4: gw4, |
| 645 | 636 |
DefaultGatewayIPv6: gw6, |
| 646 | 637 |
} |
| ... | ... |
@@ -648,12 +686,12 @@ func TestSetDefaultGw(t *testing.T) {
|
| 648 | 648 |
genericOption := make(map[string]interface{})
|
| 649 | 649 |
genericOption[netlabel.GenericData] = config |
| 650 | 650 |
|
| 651 |
- err := d.CreateNetwork("dummy", genericOption, nil, nil)
|
|
| 651 |
+ err := d.CreateNetwork("dummy", genericOption, ipdList, nil)
|
|
| 652 | 652 |
if err != nil {
|
| 653 | 653 |
t.Fatalf("Failed to create bridge: %v", err)
|
| 654 | 654 |
} |
| 655 | 655 |
|
| 656 |
- te := &testEndpoint{iface: &testInterface{}}
|
|
| 656 |
+ te := newTestEndpoint(ipdList[0].Pool, 10) |
|
| 657 | 657 |
err = d.CreateEndpoint("dummy", "ep", te.Interface(), nil)
|
| 658 | 658 |
if err != nil {
|
| 659 | 659 |
t.Fatalf("Failed to create endpoint: %v", err)
|
| ... | ... |
@@ -26,12 +26,13 @@ func TestLinkCreate(t *testing.T) {
|
| 26 | 26 |
genericOption := make(map[string]interface{})
|
| 27 | 27 |
genericOption[netlabel.GenericData] = config |
| 28 | 28 |
|
| 29 |
- err := d.CreateNetwork("dummy", genericOption, nil, nil)
|
|
| 29 |
+ ipdList := getIPv4Data(t) |
|
| 30 |
+ err := d.CreateNetwork("dummy", genericOption, ipdList, nil)
|
|
| 30 | 31 |
if err != nil {
|
| 31 | 32 |
t.Fatalf("Failed to create bridge: %v", err)
|
| 32 | 33 |
} |
| 33 | 34 |
|
| 34 |
- te := &testEndpoint{iface: &testInterface{}}
|
|
| 35 |
+ te := newTestEndpoint(ipdList[0].Pool, 10) |
|
| 35 | 36 |
err = d.CreateEndpoint("dummy", "", te.Interface(), nil)
|
| 36 | 37 |
if err != nil {
|
| 37 | 38 |
if _, ok := err.(InvalidEndpointIDError); !ok {
|
| ... | ... |
@@ -63,7 +64,7 @@ func TestLinkCreate(t *testing.T) {
|
| 63 | 63 |
// TODO: if we could get peer name from (sboxLnk.(*netlink.Veth)).PeerName |
| 64 | 64 |
// then we could check the MTU on hostLnk as well. |
| 65 | 65 |
|
| 66 |
- te1 := &testEndpoint{iface: &testInterface{}}
|
|
| 66 |
+ te1 := newTestEndpoint(ipdList[0].Pool, 11) |
|
| 67 | 67 |
err = d.CreateEndpoint("dummy", "ep", te1.Interface(), nil)
|
| 68 | 68 |
if err == nil {
|
| 69 | 69 |
t.Fatalf("Failed to detect duplicate endpoint id on same network")
|
| ... | ... |
@@ -117,18 +118,19 @@ func TestLinkCreateTwo(t *testing.T) {
|
| 117 | 117 |
genericOption := make(map[string]interface{})
|
| 118 | 118 |
genericOption[netlabel.GenericData] = config |
| 119 | 119 |
|
| 120 |
- err := d.CreateNetwork("dummy", genericOption, nil, nil)
|
|
| 120 |
+ ipdList := getIPv4Data(t) |
|
| 121 |
+ err := d.CreateNetwork("dummy", genericOption, ipdList, nil)
|
|
| 121 | 122 |
if err != nil {
|
| 122 | 123 |
t.Fatalf("Failed to create bridge: %v", err)
|
| 123 | 124 |
} |
| 124 | 125 |
|
| 125 |
- te1 := &testEndpoint{iface: &testInterface{}}
|
|
| 126 |
+ te1 := newTestEndpoint(ipdList[0].Pool, 11) |
|
| 126 | 127 |
err = d.CreateEndpoint("dummy", "ep", te1.Interface(), nil)
|
| 127 | 128 |
if err != nil {
|
| 128 | 129 |
t.Fatalf("Failed to create a link: %s", err.Error())
|
| 129 | 130 |
} |
| 130 | 131 |
|
| 131 |
- te2 := &testEndpoint{iface: &testInterface{}}
|
|
| 132 |
+ te2 := newTestEndpoint(ipdList[0].Pool, 12) |
|
| 132 | 133 |
err = d.CreateEndpoint("dummy", "ep", te2.Interface(), nil)
|
| 133 | 134 |
if err != nil {
|
| 134 | 135 |
if _, ok := err.(driverapi.ErrEndpointExists); !ok {
|
| ... | ... |
@@ -152,12 +154,12 @@ func TestLinkCreateNoEnableIPv6(t *testing.T) {
|
| 152 | 152 |
genericOption := make(map[string]interface{})
|
| 153 | 153 |
genericOption[netlabel.GenericData] = config |
| 154 | 154 |
|
| 155 |
- err := d.CreateNetwork("dummy", genericOption, nil, nil)
|
|
| 155 |
+ ipdList := getIPv4Data(t) |
|
| 156 |
+ err := d.CreateNetwork("dummy", genericOption, ipdList, nil)
|
|
| 156 | 157 |
if err != nil {
|
| 157 | 158 |
t.Fatalf("Failed to create bridge: %v", err)
|
| 158 | 159 |
} |
| 159 |
- |
|
| 160 |
- te := &testEndpoint{iface: &testInterface{}}
|
|
| 160 |
+ te := newTestEndpoint(ipdList[0].Pool, 30) |
|
| 161 | 161 |
err = d.CreateEndpoint("dummy", "ep", te.Interface(), nil)
|
| 162 | 162 |
if err != nil {
|
| 163 | 163 |
t.Fatalf("Failed to create a link: %s", err.Error())
|
| ... | ... |
@@ -187,12 +189,13 @@ func TestLinkDelete(t *testing.T) {
|
| 187 | 187 |
genericOption := make(map[string]interface{})
|
| 188 | 188 |
genericOption[netlabel.GenericData] = config |
| 189 | 189 |
|
| 190 |
- err := d.CreateNetwork("dummy", genericOption, nil, nil)
|
|
| 190 |
+ ipdList := getIPv4Data(t) |
|
| 191 |
+ err := d.CreateNetwork("dummy", genericOption, ipdList, nil)
|
|
| 191 | 192 |
if err != nil {
|
| 192 | 193 |
t.Fatalf("Failed to create bridge: %v", err)
|
| 193 | 194 |
} |
| 194 | 195 |
|
| 195 |
- te := &testEndpoint{iface: &testInterface{}}
|
|
| 196 |
+ te := newTestEndpoint(ipdList[0].Pool, 30) |
|
| 196 | 197 |
err = d.CreateEndpoint("dummy", "ep1", te.Interface(), nil)
|
| 197 | 198 |
if err != nil {
|
| 198 | 199 |
t.Fatalf("Failed to create a link: %s", err.Error())
|
| ... | ... |
@@ -44,12 +44,13 @@ func TestPortMappingConfig(t *testing.T) {
|
| 44 | 44 |
netOptions := make(map[string]interface{})
|
| 45 | 45 |
netOptions[netlabel.GenericData] = netConfig |
| 46 | 46 |
|
| 47 |
- err := d.CreateNetwork("dummy", netOptions, nil, nil)
|
|
| 47 |
+ ipdList := getIPv4Data(t) |
|
| 48 |
+ err := d.CreateNetwork("dummy", netOptions, ipdList, nil)
|
|
| 48 | 49 |
if err != nil {
|
| 49 | 50 |
t.Fatalf("Failed to create bridge: %v", err)
|
| 50 | 51 |
} |
| 51 | 52 |
|
| 52 |
- te := &testEndpoint{iface: &testInterface{}}
|
|
| 53 |
+ te := newTestEndpoint(ipdList[0].Pool, 11) |
|
| 53 | 54 |
err = d.CreateEndpoint("dummy", "ep1", te.Interface(), epOptions)
|
| 54 | 55 |
if err != nil {
|
| 55 | 56 |
t.Fatalf("Failed to create the endpoint: %s", err.Error())
|
| ... | ... |
@@ -22,7 +22,7 @@ const ( |
| 22 | 22 |
//Gets the IP version in use ( [ipv4], [ipv6] or [ipv4 and ipv6] ) |
| 23 | 23 |
func getIPVersion(config *networkConfiguration) ipVersion {
|
| 24 | 24 |
ipVersion := ipv4 |
| 25 |
- if config.EnableIPv6 {
|
|
| 25 |
+ if config.AddressIPv6 != nil || config.EnableIPv6 {
|
|
| 26 | 26 |
ipVersion |= ipv6 |
| 27 | 27 |
} |
| 28 | 28 |
return ipVersion |
| ... | ... |
@@ -3,103 +3,38 @@ package bridge |
| 3 | 3 |
import ( |
| 4 | 4 |
"fmt" |
| 5 | 5 |
"io/ioutil" |
| 6 |
- "net" |
|
| 7 | 6 |
"path/filepath" |
| 8 | 7 |
|
| 9 | 8 |
log "github.com/Sirupsen/logrus" |
| 10 |
- "github.com/docker/libnetwork/netutils" |
|
| 9 |
+ "github.com/docker/libnetwork/types" |
|
| 11 | 10 |
"github.com/vishvananda/netlink" |
| 12 | 11 |
) |
| 13 | 12 |
|
| 14 |
-var bridgeNetworks []*net.IPNet |
|
| 15 |
- |
|
| 16 |
-func init() {
|
|
| 17 |
- // Here we don't follow the convention of using the 1st IP of the range for the gateway. |
|
| 18 |
- // This is to use the same gateway IPs as the /24 ranges, which predate the /16 ranges. |
|
| 19 |
- // In theory this shouldn't matter - in practice there's bound to be a few scripts relying |
|
| 20 |
- // on the internal addressing or other stupid things like that. |
|
| 21 |
- // They shouldn't, but hey, let's not break them unless we really have to. |
|
| 22 |
- // Don't use 172.16.0.0/16, it conflicts with EC2 DNS 172.16.0.23 |
|
| 23 |
- |
|
| 24 |
- // 172.[17-31].42.1/16 |
|
| 25 |
- mask := []byte{255, 255, 0, 0}
|
|
| 26 |
- for i := 17; i < 32; i++ {
|
|
| 27 |
- bridgeNetworks = append(bridgeNetworks, &net.IPNet{IP: []byte{172, byte(i), 42, 1}, Mask: mask})
|
|
| 28 |
- } |
|
| 29 |
- // 10.[0-255].42.1/16 |
|
| 30 |
- for i := 0; i < 256; i++ {
|
|
| 31 |
- bridgeNetworks = append(bridgeNetworks, &net.IPNet{IP: []byte{10, byte(i), 42, 1}, Mask: mask})
|
|
| 32 |
- } |
|
| 33 |
- // 192.168.[42-44].1/24 |
|
| 34 |
- mask24 := []byte{255, 255, 255, 0}
|
|
| 35 |
- for i := 42; i < 45; i++ {
|
|
| 36 |
- bridgeNetworks = append(bridgeNetworks, &net.IPNet{IP: []byte{192, 168, byte(i), 1}, Mask: mask24})
|
|
| 37 |
- } |
|
| 38 |
-} |
|
| 39 |
- |
|
| 40 | 13 |
func setupBridgeIPv4(config *networkConfiguration, i *bridgeInterface) error {
|
| 41 | 14 |
addrv4, _, err := i.addresses() |
| 42 | 15 |
if err != nil {
|
| 43 |
- return err |
|
| 44 |
- } |
|
| 45 |
- |
|
| 46 |
- // Check if we have an IP address already on the bridge. |
|
| 47 |
- if addrv4.IPNet != nil {
|
|
| 48 |
- // Make sure to store bridge network and default gateway before getting out. |
|
| 49 |
- i.bridgeIPv4 = addrv4.IPNet |
|
| 50 |
- i.gatewayIPv4 = addrv4.IPNet.IP |
|
| 51 |
- return nil |
|
| 52 |
- } |
|
| 53 |
- |
|
| 54 |
- // Do not try to configure IPv4 on a non-default bridge unless you are |
|
| 55 |
- // specifically asked to do so. |
|
| 56 |
- if config.BridgeName != DefaultBridgeName && config.DefaultBridge {
|
|
| 57 |
- return NonDefaultBridgeNeedsIPError(config.BridgeName) |
|
| 58 |
- } |
|
| 59 |
- |
|
| 60 |
- bridgeIPv4, err := electBridgeIPv4(config) |
|
| 61 |
- if err != nil {
|
|
| 62 |
- return err |
|
| 16 |
+ return fmt.Errorf("failed to retrieve bridge interface addresses: %v", err)
|
|
| 63 | 17 |
} |
| 64 | 18 |
|
| 65 |
- log.Debugf("Creating bridge interface %s with network %s", config.BridgeName, bridgeIPv4)
|
|
| 66 |
- if err := netlink.AddrAdd(i.Link, &netlink.Addr{IPNet: bridgeIPv4}); err != nil {
|
|
| 67 |
- return &IPv4AddrAddError{IP: bridgeIPv4, Err: err}
|
|
| 19 |
+ if !types.CompareIPNet(addrv4.IPNet, config.AddressIPv4) {
|
|
| 20 |
+ if addrv4.IPNet != nil {
|
|
| 21 |
+ if err := netlink.AddrDel(i.Link, &addrv4); err != nil {
|
|
| 22 |
+ return fmt.Errorf("failed to remove current ip address from bridge: %v", err)
|
|
| 23 |
+ } |
|
| 24 |
+ } |
|
| 25 |
+ log.Debugf("Assigning address to bridge interface %s: %s", config.BridgeName, config.AddressIPv4)
|
|
| 26 |
+ if err := netlink.AddrAdd(i.Link, &netlink.Addr{IPNet: config.AddressIPv4}); err != nil {
|
|
| 27 |
+ return &IPv4AddrAddError{IP: config.AddressIPv4, Err: err}
|
|
| 28 |
+ } |
|
| 68 | 29 |
} |
| 69 | 30 |
|
| 70 | 31 |
// Store bridge network and default gateway |
| 71 |
- i.bridgeIPv4 = bridgeIPv4 |
|
| 72 |
- i.gatewayIPv4 = i.bridgeIPv4.IP |
|
| 32 |
+ i.bridgeIPv4 = config.AddressIPv4 |
|
| 33 |
+ i.gatewayIPv4 = config.AddressIPv4.IP |
|
| 73 | 34 |
|
| 74 | 35 |
return nil |
| 75 | 36 |
} |
| 76 | 37 |
|
| 77 |
-func electBridgeIPv4(config *networkConfiguration) (*net.IPNet, error) {
|
|
| 78 |
- // Use the requested IPv4 CIDR when available. |
|
| 79 |
- if config.AddressIPv4 != nil {
|
|
| 80 |
- return config.AddressIPv4, nil |
|
| 81 |
- } |
|
| 82 |
- |
|
| 83 |
- // We don't check for an error here, because we don't really care if we |
|
| 84 |
- // can't read /etc/resolv.conf. So instead we skip the append if resolvConf |
|
| 85 |
- // is nil. It either doesn't exist, or we can't read it for some reason. |
|
| 86 |
- nameservers := []string{}
|
|
| 87 |
- if resolvConf, _ := readResolvConf(); resolvConf != nil {
|
|
| 88 |
- nameservers = append(nameservers, getNameserversAsCIDR(resolvConf)...) |
|
| 89 |
- } |
|
| 90 |
- |
|
| 91 |
- // Try to automatically elect appropriate bridge IPv4 settings. |
|
| 92 |
- for _, n := range bridgeNetworks {
|
|
| 93 |
- if err := netutils.CheckNameserverOverlaps(nameservers, n); err == nil {
|
|
| 94 |
- if err := netutils.CheckRouteOverlaps(n); err == nil {
|
|
| 95 |
- return n, nil |
|
| 96 |
- } |
|
| 97 |
- } |
|
| 98 |
- } |
|
| 99 |
- |
|
| 100 |
- return nil, IPv4AddrRangeError(config.BridgeName) |
|
| 101 |
-} |
|
| 102 |
- |
|
| 103 | 38 |
func setupGatewayIPv4(config *networkConfiguration, i *bridgeInterface) error {
|
| 104 | 39 |
if !i.bridgeIPv4.Contains(config.DefaultGatewayIPv4) {
|
| 105 | 40 |
return &ErrInvalidGateway{}
|
| ... | ... |
@@ -4,7 +4,6 @@ import ( |
| 4 | 4 |
"net" |
| 5 | 5 |
"testing" |
| 6 | 6 |
|
| 7 |
- "github.com/docker/libnetwork/netutils" |
|
| 8 | 7 |
"github.com/docker/libnetwork/testutils" |
| 9 | 8 |
"github.com/vishvananda/netlink" |
| 10 | 9 |
) |
| ... | ... |
@@ -52,43 +51,6 @@ func TestSetupBridgeIPv4Fixed(t *testing.T) {
|
| 52 | 52 |
} |
| 53 | 53 |
} |
| 54 | 54 |
|
| 55 |
-func TestSetupBridgeIPv4Auto(t *testing.T) {
|
|
| 56 |
- defer testutils.SetupTestOSContext(t)() |
|
| 57 |
- |
|
| 58 |
- var toBeChosen *net.IPNet |
|
| 59 |
- for _, n := range bridgeNetworks {
|
|
| 60 |
- if err := netutils.CheckRouteOverlaps(n); err == nil {
|
|
| 61 |
- toBeChosen = n |
|
| 62 |
- break |
|
| 63 |
- } |
|
| 64 |
- } |
|
| 65 |
- if toBeChosen == nil {
|
|
| 66 |
- t.Skipf("Skip as no more automatic networks available")
|
|
| 67 |
- } |
|
| 68 |
- |
|
| 69 |
- config, br := setupTestInterface(t) |
|
| 70 |
- if err := setupBridgeIPv4(config, br); err != nil {
|
|
| 71 |
- t.Fatalf("Failed to setup bridge IPv4: %v", err)
|
|
| 72 |
- } |
|
| 73 |
- |
|
| 74 |
- addrsv4, err := netlink.AddrList(br.Link, netlink.FAMILY_V4) |
|
| 75 |
- if err != nil {
|
|
| 76 |
- t.Fatalf("Failed to list device IPv4 addresses: %v", err)
|
|
| 77 |
- } |
|
| 78 |
- |
|
| 79 |
- var found bool |
|
| 80 |
- for _, addr := range addrsv4 {
|
|
| 81 |
- if toBeChosen.String() == addr.IPNet.String() {
|
|
| 82 |
- found = true |
|
| 83 |
- break |
|
| 84 |
- } |
|
| 85 |
- } |
|
| 86 |
- |
|
| 87 |
- if !found {
|
|
| 88 |
- t.Fatalf("Bridge device does not have the automatic IPv4 address %s", toBeChosen.String())
|
|
| 89 |
- } |
|
| 90 |
-} |
|
| 91 |
- |
|
| 92 | 55 |
func TestSetupGatewayIPv4(t *testing.T) {
|
| 93 | 56 |
defer testutils.SetupTestOSContext(t)() |
| 94 | 57 |
|
| ... | ... |
@@ -110,14 +72,3 @@ func TestSetupGatewayIPv4(t *testing.T) {
|
| 110 | 110 |
t.Fatalf("Set Default Gateway failed. Expected %v, Found %v", gw, br.gatewayIPv4)
|
| 111 | 111 |
} |
| 112 | 112 |
} |
| 113 |
- |
|
| 114 |
-func TestCheckPreallocatedBridgeNetworks(t *testing.T) {
|
|
| 115 |
- // Just make sure the bridge networks are created the way we want (172.17.x.x/16) |
|
| 116 |
- for i := 0; i < len(bridgeNetworks); i++ {
|
|
| 117 |
- fb := bridgeNetworks[i].IP[0] |
|
| 118 |
- ones, _ := bridgeNetworks[i].Mask.Size() |
|
| 119 |
- if ((fb == 172 || fb == 10) && ones != 16) || (fb == 192 && ones != 24) {
|
|
| 120 |
- t.Fatalf("Wrong mask for preallocated bridge network: %s", bridgeNetworks[i].String())
|
|
| 121 |
- } |
|
| 122 |
- } |
|
| 123 |
-} |
| ... | ... |
@@ -4,6 +4,7 @@ import ( |
| 4 | 4 |
"fmt" |
| 5 | 5 |
"io/ioutil" |
| 6 | 6 |
"net" |
| 7 |
+ "os" |
|
| 7 | 8 |
|
| 8 | 9 |
"github.com/Sirupsen/logrus" |
| 9 | 10 |
"github.com/vishvananda/netlink" |
| ... | ... |
@@ -57,12 +58,35 @@ func setupBridgeIPv6(config *networkConfiguration, i *bridgeInterface) error {
|
| 57 | 57 |
i.bridgeIPv6 = bridgeIPv6 |
| 58 | 58 |
i.gatewayIPv6 = i.bridgeIPv6.IP |
| 59 | 59 |
|
| 60 |
+ if config.AddressIPv6 == nil {
|
|
| 61 |
+ return nil |
|
| 62 |
+ } |
|
| 63 |
+ |
|
| 64 |
+ // Setting route to global IPv6 subnet |
|
| 65 |
+ logrus.Debugf("Adding route to IPv6 network %s via device %s", config.AddressIPv6.String(), config.BridgeName)
|
|
| 66 |
+ err = netlink.RouteAdd(&netlink.Route{
|
|
| 67 |
+ Scope: netlink.SCOPE_UNIVERSE, |
|
| 68 |
+ LinkIndex: i.Link.Attrs().Index, |
|
| 69 |
+ Dst: config.AddressIPv6, |
|
| 70 |
+ }) |
|
| 71 |
+ if err != nil && !os.IsExist(err) {
|
|
| 72 |
+ logrus.Errorf("Could not add route to IPv6 network %s via device %s", config.AddressIPv6.String(), config.BridgeName)
|
|
| 73 |
+ } |
|
| 74 |
+ |
|
| 60 | 75 |
return nil |
| 61 | 76 |
} |
| 62 | 77 |
|
| 63 | 78 |
func setupGatewayIPv6(config *networkConfiguration, i *bridgeInterface) error {
|
| 79 |
+ if config.AddressIPv6 == nil {
|
|
| 80 |
+ return &ErrInvalidContainerSubnet{}
|
|
| 81 |
+ } |
|
| 82 |
+ if !config.AddressIPv6.Contains(config.DefaultGatewayIPv6) {
|
|
| 83 |
+ return &ErrInvalidGateway{}
|
|
| 84 |
+ } |
|
| 85 |
+ |
|
| 64 | 86 |
// Store requested default gateway |
| 65 | 87 |
i.gatewayIPv6 = config.DefaultGatewayIPv6 |
| 88 |
+ |
|
| 66 | 89 |
return nil |
| 67 | 90 |
} |
| 68 | 91 |
|
| ... | ... |
@@ -622,10 +622,14 @@ func (ep *endpoint) assignAddress() error {
|
| 622 | 622 |
ipam ipamapi.Ipam |
| 623 | 623 |
err error |
| 624 | 624 |
) |
| 625 |
+ |
|
| 625 | 626 |
n := ep.getNetwork() |
| 626 | 627 |
if n.Type() == "host" || n.Type() == "null" {
|
| 627 | 628 |
return nil |
| 628 | 629 |
} |
| 630 |
+ |
|
| 631 |
+ log.Debugf("Assigning addresses for endpoint %s's interface on network %s", ep.Name(), n.Name())
|
|
| 632 |
+ |
|
| 629 | 633 |
ipam, err = n.getController().getIpamDriver(n.ipamType) |
| 630 | 634 |
if err != nil {
|
| 631 | 635 |
return err |
| ... | ... |
@@ -683,6 +687,9 @@ func (ep *endpoint) releaseAddress() {
|
| 683 | 683 |
if n.Type() == "host" || n.Type() == "null" {
|
| 684 | 684 |
return |
| 685 | 685 |
} |
| 686 |
+ |
|
| 687 |
+ log.Debugf("Releasing addresses for endpoint %s's interface on network %s", ep.Name(), n.Name())
|
|
| 688 |
+ |
|
| 686 | 689 |
ipam, err := n.getController().getIpamDriver(n.ipamType) |
| 687 | 690 |
if err != nil {
|
| 688 | 691 |
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 {
|
| 102 | 102 |
aSpace.Lock() |
| 103 | 103 |
for k, v := range aSpace.subnets {
|
| 104 | 104 |
if v.Range == nil {
|
| 105 |
- inserterList = append(inserterList, |
|
| 106 |
- func() error { return a.insertBitMask(k, v.Pool) })
|
|
| 105 |
+ kk := k |
|
| 106 |
+ vv := v |
|
| 107 |
+ inserterList = append(inserterList, func() error { return a.insertBitMask(kk, vv.Pool) })
|
|
| 107 | 108 |
} |
| 108 | 109 |
} |
| 109 | 110 |
aSpace.Unlock() |
| ... | ... |
@@ -127,6 +128,7 @@ func (a *Allocator) GetDefaultAddressSpaces() (string, string, error) {
|
| 127 | 127 |
|
| 128 | 128 |
// RequestPool returns an address pool along with its unique id. |
| 129 | 129 |
func (a *Allocator) RequestPool(addressSpace, pool, subPool string, options map[string]string, v6 bool) (string, *net.IPNet, map[string]string, error) {
|
| 130 |
+ log.Debugf("RequestPool(%s, %s, %s, %v, %t)", addressSpace, pool, subPool, options, v6)
|
|
| 130 | 131 |
k, nw, aw, ipr, err := a.parsePoolRequest(addressSpace, pool, subPool, v6) |
| 131 | 132 |
if err != nil {
|
| 132 | 133 |
return "", nil, nil, ipamapi.ErrInvalidPool |
| ... | ... |
@@ -160,6 +162,7 @@ retry: |
| 160 | 160 |
|
| 161 | 161 |
// ReleasePool releases the address pool identified by the passed id |
| 162 | 162 |
func (a *Allocator) ReleasePool(poolID string) error {
|
| 163 |
+ log.Debugf("ReleasePool(%s)", poolID)
|
|
| 163 | 164 |
k := SubnetKey{}
|
| 164 | 165 |
if err := k.FromString(poolID); err != nil {
|
| 165 | 166 |
return types.BadRequestErrorf("invalid pool id: %s", poolID)
|
| ... | ... |
@@ -343,6 +346,7 @@ func (a *Allocator) getPredefinedPool(as string, ipV6 bool) (*net.IPNet, error) |
| 343 | 343 |
|
| 344 | 344 |
// RequestAddress returns an address from the specified pool ID |
| 345 | 345 |
func (a *Allocator) RequestAddress(poolID string, prefAddress net.IP, opts map[string]string) (*net.IPNet, map[string]string, error) {
|
| 346 |
+ log.Debugf("RequestAddress(%s, %v, %v)", poolID, prefAddress, opts)
|
|
| 346 | 347 |
k := SubnetKey{}
|
| 347 | 348 |
if err := k.FromString(poolID); err != nil {
|
| 348 | 349 |
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 |
| 391 | 391 |
|
| 392 | 392 |
// ReleaseAddress releases the address from the specified pool ID |
| 393 | 393 |
func (a *Allocator) ReleaseAddress(poolID string, address net.IP) error {
|
| 394 |
+ log.Debugf("ReleaseAddress(%s, %v)", poolID, address)
|
|
| 394 | 395 |
k := SubnetKey{}
|
| 395 | 396 |
if err := k.FromString(poolID); err != nil {
|
| 396 | 397 |
return types.BadRequestErrorf("invalid pool id: %s", poolID)
|
| ... | ... |
@@ -13,7 +13,7 @@ import ( |
| 13 | 13 |
"github.com/docker/libnetwork/bitseq" |
| 14 | 14 |
"github.com/docker/libnetwork/datastore" |
| 15 | 15 |
"github.com/docker/libnetwork/ipamapi" |
| 16 |
- "github.com/docker/libnetwork/netutils" |
|
| 16 |
+ "github.com/docker/libnetwork/ipamutils" |
|
| 17 | 17 |
_ "github.com/docker/libnetwork/testutils" |
| 18 | 18 |
"github.com/docker/libnetwork/types" |
| 19 | 19 |
) |
| ... | ... |
@@ -461,22 +461,33 @@ func TestPredefinedPool(t *testing.T) {
|
| 461 | 461 |
t.Fatalf("Expected failure for non default addr space")
|
| 462 | 462 |
} |
| 463 | 463 |
|
| 464 |
- i, available, err := getFirstAvailablePool(a, localAddressSpace, 2) |
|
| 464 |
+ exp, err := ipamutils.FindAvailableNetwork(a.predefined[localAddressSpace]) |
|
| 465 | 465 |
if err != nil {
|
| 466 |
- t.Skip(err) |
|
| 466 |
+ t.Fatal(err) |
|
| 467 | 467 |
} |
| 468 | 468 |
|
| 469 |
- pid, _, _, err := a.RequestPool(localAddressSpace, available.String(), "", nil, false) |
|
| 469 |
+ nw, err := a.getPredefinedPool(localAddressSpace, false) |
|
| 470 | 470 |
if err != nil {
|
| 471 | 471 |
t.Fatal(err) |
| 472 | 472 |
} |
| 473 |
+ if !types.CompareIPNet(nw, exp) {
|
|
| 474 |
+ t.Fatalf("Unexpected default network returned: %s. Expected: %s", nw, exp)
|
|
| 475 |
+ } |
|
| 473 | 476 |
|
| 474 |
- nw, err := a.getPredefinedPool(localAddressSpace, false) |
|
| 477 |
+ pid, nw, _, err := a.RequestPool(localAddressSpace, exp.String(), "", nil, false) |
|
| 475 | 478 |
if err != nil {
|
| 476 | 479 |
t.Fatal(err) |
| 477 | 480 |
} |
| 478 |
- if nw != a.predefined[localAddressSpace][i+1] {
|
|
| 479 |
- t.Fatalf("Unexpected default network returned: %s", nw)
|
|
| 481 |
+ if !types.CompareIPNet(nw, exp) {
|
|
| 482 |
+ t.Fatalf("Unexpected default network returned: %s. Expected: %s", nw, exp)
|
|
| 483 |
+ } |
|
| 484 |
+ |
|
| 485 |
+ nw2, err := a.getPredefinedPool(localAddressSpace, false) |
|
| 486 |
+ if err != nil {
|
|
| 487 |
+ t.Fatal(err) |
|
| 488 |
+ } |
|
| 489 |
+ if types.CompareIPNet(nw, nw2) {
|
|
| 490 |
+ t.Fatalf("Unexpected default network returned: %s = %s", nw2, nw)
|
|
| 480 | 491 |
} |
| 481 | 492 |
|
| 482 | 493 |
if err := a.ReleasePool(pid); err != nil {
|
| ... | ... |
@@ -487,23 +498,9 @@ func TestPredefinedPool(t *testing.T) {
|
| 487 | 487 |
if err != nil {
|
| 488 | 488 |
t.Fatal(err) |
| 489 | 489 |
} |
| 490 |
- if nw != a.predefined[localAddressSpace][i] {
|
|
| 491 |
- t.Fatalf("Unexpected default network returned: %s", nw)
|
|
| 492 |
- } |
|
| 493 |
-} |
|
| 494 |
- |
|
| 495 |
-func getFirstAvailablePool(a *Allocator, as string, atLeast int) (int, *net.IPNet, error) {
|
|
| 496 |
- i := 0 |
|
| 497 |
- for i < len(a.predefined[as])-1 {
|
|
| 498 |
- if err := netutils.CheckRouteOverlaps(a.predefined[as][i]); err == nil {
|
|
| 499 |
- break |
|
| 500 |
- } |
|
| 501 |
- i++ |
|
| 502 |
- } |
|
| 503 |
- if i > len(a.predefined[as])-1-atLeast {
|
|
| 504 |
- return 0, nil, fmt.Errorf("Not enough non-overlapping networks to run the test")
|
|
| 490 |
+ if !types.CompareIPNet(nw, exp) {
|
|
| 491 |
+ t.Fatalf("Unexpected default network returned: %s. Expected %s", nw, exp)
|
|
| 505 | 492 |
} |
| 506 |
- return i, a.predefined[as][i], nil |
|
| 507 | 493 |
} |
| 508 | 494 |
|
| 509 | 495 |
func TestAdjustAndCheckSubnet(t *testing.T) {
|
| ... | ... |
@@ -23,6 +23,7 @@ import ( |
| 23 | 23 |
"github.com/docker/libnetwork/config" |
| 24 | 24 |
"github.com/docker/libnetwork/datastore" |
| 25 | 25 |
"github.com/docker/libnetwork/driverapi" |
| 26 |
+ "github.com/docker/libnetwork/ipamapi" |
|
| 26 | 27 |
"github.com/docker/libnetwork/netlabel" |
| 27 | 28 |
"github.com/docker/libnetwork/options" |
| 28 | 29 |
"github.com/docker/libnetwork/osl" |
| ... | ... |
@@ -82,14 +83,10 @@ func createController() error {
|
| 82 | 82 |
return nil |
| 83 | 83 |
} |
| 84 | 84 |
|
| 85 |
-func createTestNetwork(networkType, networkName string, netOption options.Generic) (libnetwork.Network, error) {
|
|
| 86 |
- network, err := controller.NewNetwork(networkType, networkName, |
|
| 87 |
- libnetwork.NetworkOptionGeneric(netOption)) |
|
| 88 |
- if err != nil {
|
|
| 89 |
- return nil, err |
|
| 90 |
- } |
|
| 91 |
- |
|
| 92 |
- return network, nil |
|
| 85 |
+func createTestNetwork(networkType, networkName string, netOption options.Generic, ipamV4Configs, ipamV6Configs []*libnetwork.IpamConf) (libnetwork.Network, error) {
|
|
| 86 |
+ return controller.NewNetwork(networkType, networkName, |
|
| 87 |
+ libnetwork.NetworkOptionGeneric(netOption), |
|
| 88 |
+ libnetwork.NetworkOptionIpam(ipamapi.DefaultIPAM, "", ipamV4Configs, ipamV6Configs)) |
|
| 93 | 89 |
} |
| 94 | 90 |
|
| 95 | 91 |
func getEmptyGenericOption() map[string]interface{} {
|
| ... | ... |
@@ -117,7 +114,7 @@ func TestNull(t *testing.T) {
|
| 117 | 117 |
t.Fatal(err) |
| 118 | 118 |
} |
| 119 | 119 |
|
| 120 |
- network, err := createTestNetwork("null", "testnull", options.Generic{})
|
|
| 120 |
+ network, err := createTestNetwork("null", "testnull", options.Generic{}, nil, nil)
|
|
| 121 | 121 |
if err != nil {
|
| 122 | 122 |
t.Fatal(err) |
| 123 | 123 |
} |
| ... | ... |
@@ -184,7 +181,7 @@ func TestHost(t *testing.T) {
|
| 184 | 184 |
} |
| 185 | 185 |
}() |
| 186 | 186 |
|
| 187 |
- network, err := createTestNetwork("host", "testhost", options.Generic{})
|
|
| 187 |
+ network, err := createTestNetwork("host", "testhost", options.Generic{}, nil, nil)
|
|
| 188 | 188 |
if err != nil {
|
| 189 | 189 |
t.Fatal(err) |
| 190 | 190 |
} |
| ... | ... |
@@ -270,24 +267,18 @@ func TestBridge(t *testing.T) {
|
| 270 | 270 |
defer testutils.SetupTestOSContext(t)() |
| 271 | 271 |
} |
| 272 | 272 |
|
| 273 |
- subnet, err := types.ParseCIDR("192.168.100.1/24")
|
|
| 274 |
- if err != nil {
|
|
| 275 |
- t.Fatal(err) |
|
| 276 |
- } |
|
| 277 |
- |
|
| 278 |
- log.Debug("Adding a bridge")
|
|
| 279 |
- |
|
| 280 | 273 |
netOption := options.Generic{
|
| 281 | 274 |
netlabel.GenericData: options.Generic{
|
| 282 | 275 |
"BridgeName": "testnetwork", |
| 283 |
- "AddressIPv4": subnet, |
|
| 284 | 276 |
"EnableIPv6": true, |
| 285 | 277 |
"EnableICC": true, |
| 286 | 278 |
"EnableIPMasquerade": true, |
| 287 | 279 |
}, |
| 288 | 280 |
} |
| 281 |
+ ipamV4ConfList := []*libnetwork.IpamConf{&libnetwork.IpamConf{PreferredPool: "192.168.100.0/24", Gateway: "192.168.100.1"}}
|
|
| 282 |
+ ipamV6ConfList := []*libnetwork.IpamConf{&libnetwork.IpamConf{PreferredPool: "fe90::/98", Gateway: "fe90::22"}}
|
|
| 289 | 283 |
|
| 290 |
- network, err := createTestNetwork(bridgeNetType, "testnetwork", netOption) |
|
| 284 |
+ network, err := createTestNetwork(bridgeNetType, "testnetwork", netOption, ipamV4ConfList, ipamV6ConfList) |
|
| 291 | 285 |
if err != nil {
|
| 292 | 286 |
t.Fatal(err) |
| 293 | 287 |
} |
| ... | ... |
@@ -327,7 +318,7 @@ func TestUnknownDriver(t *testing.T) {
|
| 327 | 327 |
defer testutils.SetupTestOSContext(t)() |
| 328 | 328 |
} |
| 329 | 329 |
|
| 330 |
- _, err := createTestNetwork("unknowndriver", "testnetwork", options.Generic{})
|
|
| 330 |
+ _, err := createTestNetwork("unknowndriver", "testnetwork", options.Generic{}, nil, nil)
|
|
| 331 | 331 |
if err == nil {
|
| 332 | 332 |
t.Fatal("Expected to fail. But instead succeeded")
|
| 333 | 333 |
} |
| ... | ... |
@@ -360,7 +351,7 @@ func TestNetworkName(t *testing.T) {
|
| 360 | 360 |
}, |
| 361 | 361 |
} |
| 362 | 362 |
|
| 363 |
- _, err := createTestNetwork(bridgeNetType, "", netOption) |
|
| 363 |
+ _, err := createTestNetwork(bridgeNetType, "", netOption, nil, nil) |
|
| 364 | 364 |
if err == nil {
|
| 365 | 365 |
t.Fatal("Expected to fail. But instead succeeded")
|
| 366 | 366 |
} |
| ... | ... |
@@ -370,7 +361,7 @@ func TestNetworkName(t *testing.T) {
|
| 370 | 370 |
} |
| 371 | 371 |
|
| 372 | 372 |
networkName := "testnetwork" |
| 373 |
- n, err := createTestNetwork(bridgeNetType, networkName, netOption) |
|
| 373 |
+ n, err := createTestNetwork(bridgeNetType, networkName, netOption, nil, nil) |
|
| 374 | 374 |
if err != nil {
|
| 375 | 375 |
t.Fatal(err) |
| 376 | 376 |
} |
| ... | ... |
@@ -396,7 +387,7 @@ func TestNetworkType(t *testing.T) {
|
| 396 | 396 |
}, |
| 397 | 397 |
} |
| 398 | 398 |
|
| 399 |
- n, err := createTestNetwork(bridgeNetType, "testnetwork", netOption) |
|
| 399 |
+ n, err := createTestNetwork(bridgeNetType, "testnetwork", netOption, nil, nil) |
|
| 400 | 400 |
if err != nil {
|
| 401 | 401 |
t.Fatal(err) |
| 402 | 402 |
} |
| ... | ... |
@@ -422,7 +413,7 @@ func TestNetworkID(t *testing.T) {
|
| 422 | 422 |
}, |
| 423 | 423 |
} |
| 424 | 424 |
|
| 425 |
- n, err := createTestNetwork(bridgeNetType, "testnetwork", netOption) |
|
| 425 |
+ n, err := createTestNetwork(bridgeNetType, "testnetwork", netOption, nil, nil) |
|
| 426 | 426 |
if err != nil {
|
| 427 | 427 |
t.Fatal(err) |
| 428 | 428 |
} |
| ... | ... |
@@ -449,7 +440,7 @@ func TestDeleteNetworkWithActiveEndpoints(t *testing.T) {
|
| 449 | 449 |
netlabel.GenericData: netOption, |
| 450 | 450 |
} |
| 451 | 451 |
|
| 452 |
- network, err := createTestNetwork(bridgeNetType, "testnetwork", option) |
|
| 452 |
+ network, err := createTestNetwork(bridgeNetType, "testnetwork", option, nil, nil) |
|
| 453 | 453 |
if err != nil {
|
| 454 | 454 |
t.Fatal(err) |
| 455 | 455 |
} |
| ... | ... |
@@ -490,7 +481,7 @@ func TestUnknownNetwork(t *testing.T) {
|
| 490 | 490 |
netlabel.GenericData: netOption, |
| 491 | 491 |
} |
| 492 | 492 |
|
| 493 |
- network, err := createTestNetwork(bridgeNetType, "testnetwork", option) |
|
| 493 |
+ network, err := createTestNetwork(bridgeNetType, "testnetwork", option, nil, nil) |
|
| 494 | 494 |
if err != nil {
|
| 495 | 495 |
t.Fatal(err) |
| 496 | 496 |
} |
| ... | ... |
@@ -515,20 +506,15 @@ func TestUnknownEndpoint(t *testing.T) {
|
| 515 | 515 |
defer testutils.SetupTestOSContext(t)() |
| 516 | 516 |
} |
| 517 | 517 |
|
| 518 |
- subnet, err := types.ParseCIDR("192.168.100.1/24")
|
|
| 519 |
- if err != nil {
|
|
| 520 |
- t.Fatal(err) |
|
| 521 |
- } |
|
| 522 |
- |
|
| 523 | 518 |
netOption := options.Generic{
|
| 524 |
- "BridgeName": "testnetwork", |
|
| 525 |
- "AddressIPv4": subnet, |
|
| 519 |
+ "BridgeName": "testnetwork", |
|
| 526 | 520 |
} |
| 527 | 521 |
option := options.Generic{
|
| 528 | 522 |
netlabel.GenericData: netOption, |
| 529 | 523 |
} |
| 524 |
+ ipamV4ConfList := []*libnetwork.IpamConf{&libnetwork.IpamConf{PreferredPool: "192.168.100.0/24"}}
|
|
| 530 | 525 |
|
| 531 |
- network, err := createTestNetwork(bridgeNetType, "testnetwork", option) |
|
| 526 |
+ network, err := createTestNetwork(bridgeNetType, "testnetwork", option, ipamV4ConfList, nil) |
|
| 532 | 527 |
if err != nil {
|
| 533 | 528 |
t.Fatal(err) |
| 534 | 529 |
} |
| ... | ... |
@@ -569,7 +555,7 @@ func TestNetworkEndpointsWalkers(t *testing.T) {
|
| 569 | 569 |
}, |
| 570 | 570 |
} |
| 571 | 571 |
|
| 572 |
- net1, err := createTestNetwork(bridgeNetType, "network1", netOption) |
|
| 572 |
+ net1, err := createTestNetwork(bridgeNetType, "network1", netOption, nil, nil) |
|
| 573 | 573 |
if err != nil {
|
| 574 | 574 |
t.Fatal(err) |
| 575 | 575 |
} |
| ... | ... |
@@ -641,7 +627,7 @@ func TestNetworkEndpointsWalkers(t *testing.T) {
|
| 641 | 641 |
}, |
| 642 | 642 |
} |
| 643 | 643 |
|
| 644 |
- net2, err := createTestNetwork(bridgeNetType, "network2", netOption) |
|
| 644 |
+ net2, err := createTestNetwork(bridgeNetType, "network2", netOption, nil, nil) |
|
| 645 | 645 |
if err != nil {
|
| 646 | 646 |
t.Fatal(err) |
| 647 | 647 |
} |
| ... | ... |
@@ -697,7 +683,7 @@ func TestDuplicateEndpoint(t *testing.T) {
|
| 697 | 697 |
"BridgeName": "testnetwork", |
| 698 | 698 |
}, |
| 699 | 699 |
} |
| 700 |
- n, err := createTestNetwork(bridgeNetType, "testnetwork", netOption) |
|
| 700 |
+ n, err := createTestNetwork(bridgeNetType, "testnetwork", netOption, nil, nil) |
|
| 701 | 701 |
if err != nil {
|
| 702 | 702 |
t.Fatal(err) |
| 703 | 703 |
} |
| ... | ... |
@@ -747,7 +733,7 @@ func TestControllerQuery(t *testing.T) {
|
| 747 | 747 |
"BridgeName": "network1", |
| 748 | 748 |
}, |
| 749 | 749 |
} |
| 750 |
- net1, err := createTestNetwork(bridgeNetType, "network1", netOption) |
|
| 750 |
+ net1, err := createTestNetwork(bridgeNetType, "network1", netOption, nil, nil) |
|
| 751 | 751 |
if err != nil {
|
| 752 | 752 |
t.Fatal(err) |
| 753 | 753 |
} |
| ... | ... |
@@ -763,7 +749,7 @@ func TestControllerQuery(t *testing.T) {
|
| 763 | 763 |
"BridgeName": "network2", |
| 764 | 764 |
}, |
| 765 | 765 |
} |
| 766 |
- net2, err := createTestNetwork(bridgeNetType, "network2", netOption) |
|
| 766 |
+ net2, err := createTestNetwork(bridgeNetType, "network2", netOption, nil, nil) |
|
| 767 | 767 |
if err != nil {
|
| 768 | 768 |
t.Fatal(err) |
| 769 | 769 |
} |
| ... | ... |
@@ -849,7 +835,7 @@ func TestNetworkQuery(t *testing.T) {
|
| 849 | 849 |
"BridgeName": "network1", |
| 850 | 850 |
}, |
| 851 | 851 |
} |
| 852 |
- net1, err := createTestNetwork(bridgeNetType, "network1", netOption) |
|
| 852 |
+ net1, err := createTestNetwork(bridgeNetType, "network1", netOption, nil, nil) |
|
| 853 | 853 |
if err != nil {
|
| 854 | 854 |
t.Fatal(err) |
| 855 | 855 |
} |
| ... | ... |
@@ -969,7 +955,7 @@ func TestEndpointJoin(t *testing.T) {
|
| 969 | 969 |
netlabel.GenericData: options.Generic{
|
| 970 | 970 |
"BridgeName": "testnetwork1", |
| 971 | 971 |
}, |
| 972 |
- }) |
|
| 972 |
+ }, nil, nil) |
|
| 973 | 973 |
if err != nil {
|
| 974 | 974 |
t.Fatal(err) |
| 975 | 975 |
} |
| ... | ... |
@@ -1078,7 +1064,7 @@ func TestEndpointJoin(t *testing.T) {
|
| 1078 | 1078 |
netlabel.GenericData: options.Generic{
|
| 1079 | 1079 |
"BridgeName": "testnetwork2", |
| 1080 | 1080 |
}, |
| 1081 |
- }) |
|
| 1081 |
+ }, nil, nil) |
|
| 1082 | 1082 |
if err != nil {
|
| 1083 | 1083 |
t.Fatal(err) |
| 1084 | 1084 |
} |
| ... | ... |
@@ -1169,7 +1155,7 @@ func externalKeyTest(t *testing.T, reexec bool) {
|
| 1169 | 1169 |
netlabel.GenericData: options.Generic{
|
| 1170 | 1170 |
"BridgeName": "testnetwork", |
| 1171 | 1171 |
}, |
| 1172 |
- }) |
|
| 1172 |
+ }, nil, nil) |
|
| 1173 | 1173 |
if err != nil {
|
| 1174 | 1174 |
t.Fatal(err) |
| 1175 | 1175 |
} |
| ... | ... |
@@ -1318,7 +1304,7 @@ func TestEndpointDeleteWithActiveContainer(t *testing.T) {
|
| 1318 | 1318 |
netlabel.GenericData: options.Generic{
|
| 1319 | 1319 |
"BridgeName": "testnetwork", |
| 1320 | 1320 |
}, |
| 1321 |
- }) |
|
| 1321 |
+ }, nil, nil) |
|
| 1322 | 1322 |
if err != nil {
|
| 1323 | 1323 |
t.Fatal(err) |
| 1324 | 1324 |
} |
| ... | ... |
@@ -1381,7 +1367,7 @@ func TestEndpointMultipleJoins(t *testing.T) {
|
| 1381 | 1381 |
netlabel.GenericData: options.Generic{
|
| 1382 | 1382 |
"BridgeName": "testmultiple", |
| 1383 | 1383 |
}, |
| 1384 |
- }) |
|
| 1384 |
+ }, nil, nil) |
|
| 1385 | 1385 |
if err != nil {
|
| 1386 | 1386 |
t.Fatal(err) |
| 1387 | 1387 |
} |
| ... | ... |
@@ -1452,7 +1438,7 @@ func TestLeaveAll(t *testing.T) {
|
| 1452 | 1452 |
netlabel.GenericData: options.Generic{
|
| 1453 | 1453 |
"BridgeName": "testnetwork", |
| 1454 | 1454 |
}, |
| 1455 |
- }) |
|
| 1455 |
+ }, nil, nil) |
|
| 1456 | 1456 |
if err != nil {
|
| 1457 | 1457 |
t.Fatal(err) |
| 1458 | 1458 |
} |
| ... | ... |
@@ -1505,7 +1491,7 @@ func TestontainerInvalidLeave(t *testing.T) {
|
| 1505 | 1505 |
netlabel.GenericData: options.Generic{
|
| 1506 | 1506 |
"BridgeName": "testnetwork", |
| 1507 | 1507 |
}, |
| 1508 |
- }) |
|
| 1508 |
+ }, nil, nil) |
|
| 1509 | 1509 |
if err != nil {
|
| 1510 | 1510 |
t.Fatal(err) |
| 1511 | 1511 |
} |
| ... | ... |
@@ -1571,7 +1557,7 @@ func TestEndpointUpdateParent(t *testing.T) {
|
| 1571 | 1571 |
netlabel.GenericData: options.Generic{
|
| 1572 | 1572 |
"BridgeName": "testnetwork", |
| 1573 | 1573 |
}, |
| 1574 |
- }) |
|
| 1574 |
+ }, nil, nil) |
|
| 1575 | 1575 |
if err != nil {
|
| 1576 | 1576 |
t.Fatal(err) |
| 1577 | 1577 |
} |
| ... | ... |
@@ -1655,8 +1641,9 @@ func TestEnableIPv6(t *testing.T) {
|
| 1655 | 1655 |
"BridgeName": "testnetwork", |
| 1656 | 1656 |
}, |
| 1657 | 1657 |
} |
| 1658 |
+ ipamV6ConfList := []*libnetwork.IpamConf{&libnetwork.IpamConf{PreferredPool: "fe80::/98"}}
|
|
| 1658 | 1659 |
|
| 1659 |
- n, err := createTestNetwork("bridge", "testnetwork", netOption)
|
|
| 1660 |
+ n, err := createTestNetwork("bridge", "testnetwork", netOption, nil, ipamV6ConfList)
|
|
| 1660 | 1661 |
if err != nil {
|
| 1661 | 1662 |
t.Fatal(err) |
| 1662 | 1663 |
} |
| ... | ... |
@@ -1814,7 +1801,7 @@ func TestResolvConf(t *testing.T) {
|
| 1814 | 1814 |
"BridgeName": "testnetwork", |
| 1815 | 1815 |
}, |
| 1816 | 1816 |
} |
| 1817 |
- n, err := createTestNetwork("bridge", "testnetwork", netOption)
|
|
| 1817 |
+ n, err := createTestNetwork("bridge", "testnetwork", netOption, nil, nil)
|
|
| 1818 | 1818 |
if err != nil {
|
| 1819 | 1819 |
t.Fatal(err) |
| 1820 | 1820 |
} |
| ... | ... |
@@ -2084,7 +2071,7 @@ func createGlobalInstance(t *testing.T) {
|
| 2084 | 2084 |
t.Fatal(err) |
| 2085 | 2085 |
} |
| 2086 | 2086 |
|
| 2087 |
- net2, err := createTestNetwork("bridge", "network2", netOption)
|
|
| 2087 |
+ net2, err := createTestNetwork("bridge", "network2", netOption, nil, nil)
|
|
| 2088 | 2088 |
if err != nil {
|
| 2089 | 2089 |
t.Fatal(err) |
| 2090 | 2090 |
} |
| ... | ... |
@@ -852,7 +852,7 @@ func (n *network) ipamAllocateVersion(ipVer int, ipam ipamapi.Ipam) error {
|
| 852 | 852 |
|
| 853 | 853 |
*infoList = make([]*IpamInfo, len(*cfgList)) |
| 854 | 854 |
|
| 855 |
- log.Debugf("allocating IPv%d pools for network %s (%s)", ipVer, n.Name(), n.ID())
|
|
| 855 |
+ log.Debugf("Allocating IPv%d pools for network %s (%s)", ipVer, n.Name(), n.ID())
|
|
| 856 | 856 |
|
| 857 | 857 |
for i, cfg := range *cfgList {
|
| 858 | 858 |
if err = cfg.Validate(); err != nil {
|