github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/libnetwork/drivers/bridge/bridge_test.go (about)

     1  package bridge
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"net"
     8  	"regexp"
     9  	"testing"
    10  
    11  	"github.com/docker/libnetwork/driverapi"
    12  	"github.com/docker/libnetwork/ipamutils"
    13  	"github.com/docker/libnetwork/iptables"
    14  	"github.com/docker/libnetwork/netlabel"
    15  	"github.com/docker/libnetwork/netutils"
    16  	"github.com/docker/libnetwork/options"
    17  	"github.com/docker/libnetwork/testutils"
    18  	"github.com/docker/libnetwork/types"
    19  	"github.com/vishvananda/netlink"
    20  )
    21  
    22  func init() {
    23  	ipamutils.InitNetworks()
    24  }
    25  
    26  func TestEndpointMarshalling(t *testing.T) {
    27  	ip1, _ := types.ParseCIDR("172.22.0.9/16")
    28  	ip2, _ := types.ParseCIDR("2001:db8::9")
    29  	mac, _ := net.ParseMAC("ac:bd:24:57:66:77")
    30  	e := &bridgeEndpoint{
    31  		id:         "d2c015a1fe5930650cbcd50493efba0500bcebd8ee1f4401a16319f8a567de33",
    32  		nid:        "ee33fbb43c323f1920b6b35a0101552ac22ede960d0e5245e9738bccc68b2415",
    33  		addr:       ip1,
    34  		addrv6:     ip2,
    35  		macAddress: mac,
    36  		srcName:    "veth123456",
    37  		config:     &endpointConfiguration{MacAddress: mac},
    38  		containerConfig: &containerConfiguration{
    39  			ParentEndpoints: []string{"one", "due", "three"},
    40  			ChildEndpoints:  []string{"four", "five", "six"},
    41  		},
    42  		extConnConfig: &connectivityConfiguration{
    43  			ExposedPorts: []types.TransportPort{
    44  				{
    45  					Proto: 6,
    46  					Port:  uint16(18),
    47  				},
    48  			},
    49  			PortBindings: []types.PortBinding{
    50  				{
    51  					Proto:       6,
    52  					IP:          net.ParseIP("17210.33.9.56"),
    53  					Port:        uint16(18),
    54  					HostPort:    uint16(3000),
    55  					HostPortEnd: uint16(14000),
    56  				},
    57  			},
    58  		},
    59  		portMapping: []types.PortBinding{
    60  			{
    61  				Proto:       17,
    62  				IP:          net.ParseIP("172.33.9.56"),
    63  				Port:        uint16(99),
    64  				HostIP:      net.ParseIP("10.10.100.2"),
    65  				HostPort:    uint16(9900),
    66  				HostPortEnd: uint16(10000),
    67  			},
    68  			{
    69  				Proto:       6,
    70  				IP:          net.ParseIP("171.33.9.56"),
    71  				Port:        uint16(55),
    72  				HostIP:      net.ParseIP("10.11.100.2"),
    73  				HostPort:    uint16(5500),
    74  				HostPortEnd: uint16(55000),
    75  			},
    76  		},
    77  	}
    78  
    79  	b, err := json.Marshal(e)
    80  	if err != nil {
    81  		t.Fatal(err)
    82  	}
    83  
    84  	ee := &bridgeEndpoint{}
    85  	err = json.Unmarshal(b, ee)
    86  	if err != nil {
    87  		t.Fatal(err)
    88  	}
    89  
    90  	if e.id != ee.id || e.nid != ee.nid || e.srcName != ee.srcName || !bytes.Equal(e.macAddress, ee.macAddress) ||
    91  		!types.CompareIPNet(e.addr, ee.addr) || !types.CompareIPNet(e.addrv6, ee.addrv6) ||
    92  		!compareEpConfig(e.config, ee.config) ||
    93  		!compareContainerConfig(e.containerConfig, ee.containerConfig) ||
    94  		!compareConnConfig(e.extConnConfig, ee.extConnConfig) ||
    95  		!compareBindings(e.portMapping, ee.portMapping) {
    96  		t.Fatalf("JSON marsh/unmarsh failed.\nOriginal:\n%#v\nDecoded:\n%#v", e, ee)
    97  	}
    98  }
    99  
   100  func compareEpConfig(a, b *endpointConfiguration) bool {
   101  	if a == b {
   102  		return true
   103  	}
   104  	if a == nil || b == nil {
   105  		return false
   106  	}
   107  	return bytes.Equal(a.MacAddress, b.MacAddress)
   108  }
   109  
   110  func compareContainerConfig(a, b *containerConfiguration) bool {
   111  	if a == b {
   112  		return true
   113  	}
   114  	if a == nil || b == nil {
   115  		return false
   116  	}
   117  	if len(a.ParentEndpoints) != len(b.ParentEndpoints) ||
   118  		len(a.ChildEndpoints) != len(b.ChildEndpoints) {
   119  		return false
   120  	}
   121  	for i := 0; i < len(a.ParentEndpoints); i++ {
   122  		if a.ParentEndpoints[i] != b.ParentEndpoints[i] {
   123  			return false
   124  		}
   125  	}
   126  	for i := 0; i < len(a.ChildEndpoints); i++ {
   127  		if a.ChildEndpoints[i] != b.ChildEndpoints[i] {
   128  			return false
   129  		}
   130  	}
   131  	return true
   132  }
   133  
   134  func compareConnConfig(a, b *connectivityConfiguration) bool {
   135  	if a == b {
   136  		return true
   137  	}
   138  	if a == nil || b == nil {
   139  		return false
   140  	}
   141  	if len(a.ExposedPorts) != len(b.ExposedPorts) ||
   142  		len(a.PortBindings) != len(b.PortBindings) {
   143  		return false
   144  	}
   145  	for i := 0; i < len(a.ExposedPorts); i++ {
   146  		if !a.ExposedPorts[i].Equal(&b.ExposedPorts[i]) {
   147  			return false
   148  		}
   149  	}
   150  	for i := 0; i < len(a.PortBindings); i++ {
   151  		if !a.PortBindings[i].Equal(&b.PortBindings[i]) {
   152  			return false
   153  		}
   154  	}
   155  	return true
   156  }
   157  
   158  func compareBindings(a, b []types.PortBinding) bool {
   159  	if len(a) != len(b) {
   160  		return false
   161  	}
   162  	for i := 0; i < len(a); i++ {
   163  		if !a[i].Equal(&b[i]) {
   164  			return false
   165  		}
   166  	}
   167  	return true
   168  }
   169  
   170  func getIPv4Data(t *testing.T, iface string) []driverapi.IPAMData {
   171  	ipd := driverapi.IPAMData{AddressSpace: "full"}
   172  	nw, _, err := netutils.ElectInterfaceAddresses(iface)
   173  	if err != nil {
   174  		t.Fatal(err)
   175  	}
   176  	ipd.Pool = nw
   177  	// Set network gateway to X.X.X.1
   178  	ipd.Gateway = types.GetIPNetCopy(nw)
   179  	ipd.Gateway.IP[len(ipd.Gateway.IP)-1] = 1
   180  	return []driverapi.IPAMData{ipd}
   181  }
   182  
   183  func TestCreateFullOptions(t *testing.T) {
   184  	defer testutils.SetupTestOSContext(t)()
   185  	d := newDriver()
   186  
   187  	config := &configuration{
   188  		EnableIPForwarding: true,
   189  		EnableIPTables:     true,
   190  	}
   191  
   192  	// Test this scenario: Default gw address does not belong to
   193  	// container network and it's greater than bridge address
   194  	cnw, _ := types.ParseCIDR("172.16.122.0/24")
   195  	bnw, _ := types.ParseCIDR("172.16.0.0/24")
   196  	br, _ := types.ParseCIDR("172.16.0.1/16")
   197  	defgw, _ := types.ParseCIDR("172.16.0.100/16")
   198  
   199  	genericOption := make(map[string]interface{})
   200  	genericOption[netlabel.GenericData] = config
   201  
   202  	if err := d.configure(genericOption); err != nil {
   203  		t.Fatalf("Failed to setup driver config: %v", err)
   204  	}
   205  
   206  	netOption := make(map[string]interface{})
   207  	netOption[netlabel.EnableIPv6] = true
   208  	netOption[netlabel.GenericData] = &networkConfiguration{
   209  		BridgeName: DefaultBridgeName,
   210  	}
   211  
   212  	ipdList := []driverapi.IPAMData{
   213  		{
   214  			Pool:         bnw,
   215  			Gateway:      br,
   216  			AuxAddresses: map[string]*net.IPNet{DefaultGatewayV4AuxKey: defgw},
   217  		},
   218  	}
   219  	err := d.CreateNetwork("dummy", netOption, nil, ipdList, nil)
   220  	if err != nil {
   221  		t.Fatalf("Failed to create bridge: %v", err)
   222  	}
   223  
   224  	// Verify the IP address allocated for the endpoint belongs to the container network
   225  	epOptions := make(map[string]interface{})
   226  	te := newTestEndpoint(cnw, 10)
   227  	err = d.CreateEndpoint("dummy", "ep1", te.Interface(), epOptions)
   228  	if err != nil {
   229  		t.Fatalf("Failed to create an endpoint : %s", err.Error())
   230  	}
   231  
   232  	if !cnw.Contains(te.Interface().Address().IP) {
   233  		t.Fatalf("endpoint got assigned address outside of container network(%s): %s", cnw.String(), te.Interface().Address())
   234  	}
   235  }
   236  
   237  func TestCreateNoConfig(t *testing.T) {
   238  	if !testutils.IsRunningInContainer() {
   239  		defer testutils.SetupTestOSContext(t)()
   240  	}
   241  	d := newDriver()
   242  
   243  	netconfig := &networkConfiguration{BridgeName: DefaultBridgeName}
   244  	genericOption := make(map[string]interface{})
   245  	genericOption[netlabel.GenericData] = netconfig
   246  
   247  	if err := d.CreateNetwork("dummy", genericOption, nil, getIPv4Data(t, ""), nil); err != nil {
   248  		t.Fatalf("Failed to create bridge: %v", err)
   249  	}
   250  }
   251  
   252  func TestCreateFullOptionsLabels(t *testing.T) {
   253  	if !testutils.IsRunningInContainer() {
   254  		defer testutils.SetupTestOSContext(t)()
   255  	}
   256  	d := newDriver()
   257  
   258  	config := &configuration{
   259  		EnableIPForwarding: true,
   260  	}
   261  	genericOption := make(map[string]interface{})
   262  	genericOption[netlabel.GenericData] = config
   263  
   264  	if err := d.configure(genericOption); err != nil {
   265  		t.Fatalf("Failed to setup driver config: %v", err)
   266  	}
   267  
   268  	bndIPs := "127.0.0.1"
   269  	nwV6s := "2001:db8:2600:2700:2800::/80"
   270  	gwV6s := "2001:db8:2600:2700:2800::25/80"
   271  	nwV6, _ := types.ParseCIDR(nwV6s)
   272  	gwV6, _ := types.ParseCIDR(gwV6s)
   273  
   274  	labels := map[string]string{
   275  		BridgeName:         DefaultBridgeName,
   276  		DefaultBridge:      "true",
   277  		EnableICC:          "true",
   278  		EnableIPMasquerade: "true",
   279  		DefaultBindingIP:   bndIPs,
   280  	}
   281  
   282  	netOption := make(map[string]interface{})
   283  	netOption[netlabel.EnableIPv6] = true
   284  	netOption[netlabel.GenericData] = labels
   285  
   286  	ipdList := getIPv4Data(t, "")
   287  	ipd6List := []driverapi.IPAMData{
   288  		{
   289  			Pool: nwV6,
   290  			AuxAddresses: map[string]*net.IPNet{
   291  				DefaultGatewayV6AuxKey: gwV6,
   292  			},
   293  		},
   294  	}
   295  
   296  	err := d.CreateNetwork("dummy", netOption, nil, ipdList, ipd6List)
   297  	if err != nil {
   298  		t.Fatalf("Failed to create bridge: %v", err)
   299  	}
   300  
   301  	nw, ok := d.networks["dummy"]
   302  	if !ok {
   303  		t.Fatalf("Cannot find dummy network in bridge driver")
   304  	}
   305  
   306  	if nw.config.BridgeName != DefaultBridgeName {
   307  		t.Fatalf("incongruent name in bridge network")
   308  	}
   309  
   310  	if !nw.config.EnableIPv6 {
   311  		t.Fatalf("incongruent EnableIPv6 in bridge network")
   312  	}
   313  
   314  	if !nw.config.EnableICC {
   315  		t.Fatalf("incongruent EnableICC in bridge network")
   316  	}
   317  
   318  	if !nw.config.EnableIPMasquerade {
   319  		t.Fatalf("incongruent EnableIPMasquerade in bridge network")
   320  	}
   321  
   322  	bndIP := net.ParseIP(bndIPs)
   323  	if !bndIP.Equal(nw.config.DefaultBindingIP) {
   324  		t.Fatalf("Unexpected: %v", nw.config.DefaultBindingIP)
   325  	}
   326  
   327  	if !types.CompareIPNet(nw.config.AddressIPv6, nwV6) {
   328  		t.Fatalf("Unexpected: %v", nw.config.AddressIPv6)
   329  	}
   330  
   331  	if !gwV6.IP.Equal(nw.config.DefaultGatewayIPv6) {
   332  		t.Fatalf("Unexpected: %v", nw.config.DefaultGatewayIPv6)
   333  	}
   334  
   335  	// In short here we are testing --fixed-cidr-v6 daemon option
   336  	// plus --mac-address run option
   337  	mac, _ := net.ParseMAC("aa:bb:cc:dd:ee:ff")
   338  	epOptions := map[string]interface{}{netlabel.MacAddress: mac}
   339  	te := newTestEndpoint(ipdList[0].Pool, 20)
   340  	err = d.CreateEndpoint("dummy", "ep1", te.Interface(), epOptions)
   341  	if err != nil {
   342  		t.Fatal(err)
   343  	}
   344  
   345  	if !nwV6.Contains(te.Interface().AddressIPv6().IP) {
   346  		t.Fatalf("endpoint got assigned address outside of container network(%s): %s", nwV6.String(), te.Interface().AddressIPv6())
   347  	}
   348  	if te.Interface().AddressIPv6().IP.String() != "2001:db8:2600:2700:2800:aabb:ccdd:eeff" {
   349  		t.Fatalf("Unexpected endpoint IPv6 address: %v", te.Interface().AddressIPv6().IP)
   350  	}
   351  }
   352  
   353  func TestCreate(t *testing.T) {
   354  	if !testutils.IsRunningInContainer() {
   355  		defer testutils.SetupTestOSContext(t)()
   356  	}
   357  
   358  	d := newDriver()
   359  
   360  	if err := d.configure(nil); err != nil {
   361  		t.Fatalf("Failed to setup driver config: %v", err)
   362  	}
   363  
   364  	netconfig := &networkConfiguration{BridgeName: DefaultBridgeName}
   365  	genericOption := make(map[string]interface{})
   366  	genericOption[netlabel.GenericData] = netconfig
   367  
   368  	if err := d.CreateNetwork("dummy", genericOption, nil, getIPv4Data(t, ""), nil); err != nil {
   369  		t.Fatalf("Failed to create bridge: %v", err)
   370  	}
   371  
   372  	err := d.CreateNetwork("dummy", genericOption, nil, getIPv4Data(t, ""), nil)
   373  	if err == nil {
   374  		t.Fatalf("Expected bridge driver to refuse creation of second network with default name")
   375  	}
   376  	if _, ok := err.(types.ForbiddenError); !ok {
   377  		t.Fatalf("Creation of second network with default name failed with unexpected error type")
   378  	}
   379  }
   380  
   381  func TestCreateFail(t *testing.T) {
   382  	if !testutils.IsRunningInContainer() {
   383  		defer testutils.SetupTestOSContext(t)()
   384  	}
   385  
   386  	d := newDriver()
   387  
   388  	if err := d.configure(nil); err != nil {
   389  		t.Fatalf("Failed to setup driver config: %v", err)
   390  	}
   391  
   392  	netconfig := &networkConfiguration{BridgeName: "dummy0", DefaultBridge: true}
   393  	genericOption := make(map[string]interface{})
   394  	genericOption[netlabel.GenericData] = netconfig
   395  
   396  	if err := d.CreateNetwork("dummy", genericOption, nil, getIPv4Data(t, ""), nil); err == nil {
   397  		t.Fatal("Bridge creation was expected to fail")
   398  	}
   399  }
   400  
   401  func TestCreateMultipleNetworks(t *testing.T) {
   402  	if !testutils.IsRunningInContainer() {
   403  		defer testutils.SetupTestOSContext(t)()
   404  	}
   405  
   406  	d := newDriver()
   407  
   408  	config := &configuration{
   409  		EnableIPTables: true,
   410  	}
   411  	genericOption := make(map[string]interface{})
   412  	genericOption[netlabel.GenericData] = config
   413  
   414  	if err := d.configure(genericOption); err != nil {
   415  		t.Fatalf("Failed to setup driver config: %v", err)
   416  	}
   417  
   418  	config1 := &networkConfiguration{BridgeName: "net_test_1"}
   419  	genericOption = make(map[string]interface{})
   420  	genericOption[netlabel.GenericData] = config1
   421  	if err := d.CreateNetwork("1", genericOption, nil, getIPv4Data(t, ""), nil); err != nil {
   422  		t.Fatalf("Failed to create bridge: %v", err)
   423  	}
   424  
   425  	config2 := &networkConfiguration{BridgeName: "net_test_2"}
   426  	genericOption[netlabel.GenericData] = config2
   427  	if err := d.CreateNetwork("2", genericOption, nil, getIPv4Data(t, ""), nil); err != nil {
   428  		t.Fatalf("Failed to create bridge: %v", err)
   429  	}
   430  
   431  	// Verify the network isolation rules are installed, each network subnet should appear 2 times
   432  	verifyV4INCEntries(d.networks, 2, t)
   433  
   434  	config3 := &networkConfiguration{BridgeName: "net_test_3"}
   435  	genericOption[netlabel.GenericData] = config3
   436  	if err := d.CreateNetwork("3", genericOption, nil, getIPv4Data(t, ""), nil); err != nil {
   437  		t.Fatalf("Failed to create bridge: %v", err)
   438  	}
   439  
   440  	// Verify the network isolation rules are installed, each network subnet should appear 4 times
   441  	verifyV4INCEntries(d.networks, 6, t)
   442  
   443  	config4 := &networkConfiguration{BridgeName: "net_test_4"}
   444  	genericOption[netlabel.GenericData] = config4
   445  	if err := d.CreateNetwork("4", genericOption, nil, getIPv4Data(t, ""), nil); err != nil {
   446  		t.Fatalf("Failed to create bridge: %v", err)
   447  	}
   448  
   449  	// Now 6 times
   450  	verifyV4INCEntries(d.networks, 12, t)
   451  
   452  	d.DeleteNetwork("1")
   453  	verifyV4INCEntries(d.networks, 6, t)
   454  
   455  	d.DeleteNetwork("2")
   456  	verifyV4INCEntries(d.networks, 2, t)
   457  
   458  	d.DeleteNetwork("3")
   459  	verifyV4INCEntries(d.networks, 0, t)
   460  
   461  	d.DeleteNetwork("4")
   462  	verifyV4INCEntries(d.networks, 0, t)
   463  }
   464  
   465  func verifyV4INCEntries(networks map[string]*bridgeNetwork, numEntries int, t *testing.T) {
   466  	out, err := iptables.Raw("-nvL", IsolationChain)
   467  	if err != nil {
   468  		t.Fatal(err)
   469  	}
   470  
   471  	found := 0
   472  	for _, x := range networks {
   473  		for _, y := range networks {
   474  			if x == y {
   475  				continue
   476  			}
   477  			re := regexp.MustCompile(fmt.Sprintf("%s %s", x.config.BridgeName, y.config.BridgeName))
   478  			matches := re.FindAllString(string(out[:]), -1)
   479  			if len(matches) != 1 {
   480  				t.Fatalf("Cannot find expected inter-network isolation rules in IP Tables:\n%s", string(out[:]))
   481  			}
   482  			found++
   483  		}
   484  	}
   485  
   486  	if found != numEntries {
   487  		t.Fatalf("Cannot find expected number (%d) of inter-network isolation rules in IP Tables:\n%s\nFound %d", numEntries, string(out[:]), found)
   488  	}
   489  }
   490  
   491  type testInterface struct {
   492  	mac     net.HardwareAddr
   493  	addr    *net.IPNet
   494  	addrv6  *net.IPNet
   495  	srcName string
   496  	dstName string
   497  }
   498  
   499  type testEndpoint struct {
   500  	iface          *testInterface
   501  	gw             net.IP
   502  	gw6            net.IP
   503  	hostsPath      string
   504  	resolvConfPath string
   505  	routes         []types.StaticRoute
   506  }
   507  
   508  func newTestEndpoint(nw *net.IPNet, ordinal byte) *testEndpoint {
   509  	addr := types.GetIPNetCopy(nw)
   510  	addr.IP[len(addr.IP)-1] = ordinal
   511  	return &testEndpoint{iface: &testInterface{addr: addr}}
   512  }
   513  
   514  func (te *testEndpoint) Interface() driverapi.InterfaceInfo {
   515  	if te.iface != nil {
   516  		return te.iface
   517  	}
   518  
   519  	return nil
   520  }
   521  
   522  func (i *testInterface) MacAddress() net.HardwareAddr {
   523  	return i.mac
   524  }
   525  
   526  func (i *testInterface) Address() *net.IPNet {
   527  	return i.addr
   528  }
   529  
   530  func (i *testInterface) AddressIPv6() *net.IPNet {
   531  	return i.addrv6
   532  }
   533  
   534  func (i *testInterface) SetMacAddress(mac net.HardwareAddr) error {
   535  	if i.mac != nil {
   536  		return types.ForbiddenErrorf("endpoint interface MAC address present (%s). Cannot be modified with %s.", i.mac, mac)
   537  	}
   538  	if mac == nil {
   539  		return types.BadRequestErrorf("tried to set nil MAC address to endpoint interface")
   540  	}
   541  	i.mac = types.GetMacCopy(mac)
   542  	return nil
   543  }
   544  
   545  func (i *testInterface) SetIPAddress(address *net.IPNet) error {
   546  	if address.IP == nil {
   547  		return types.BadRequestErrorf("tried to set nil IP address to endpoint interface")
   548  	}
   549  	if address.IP.To4() == nil {
   550  		return setAddress(&i.addrv6, address)
   551  	}
   552  	return setAddress(&i.addr, address)
   553  }
   554  
   555  func setAddress(ifaceAddr **net.IPNet, address *net.IPNet) error {
   556  	if *ifaceAddr != nil {
   557  		return types.ForbiddenErrorf("endpoint interface IP present (%s). Cannot be modified with (%s).", *ifaceAddr, address)
   558  	}
   559  	*ifaceAddr = types.GetIPNetCopy(address)
   560  	return nil
   561  }
   562  
   563  func (i *testInterface) SetNames(srcName string, dstName string) error {
   564  	i.srcName = srcName
   565  	i.dstName = dstName
   566  	return nil
   567  }
   568  
   569  func (te *testEndpoint) InterfaceName() driverapi.InterfaceNameInfo {
   570  	if te.iface != nil {
   571  		return te.iface
   572  	}
   573  
   574  	return nil
   575  }
   576  
   577  func (te *testEndpoint) SetGateway(gw net.IP) error {
   578  	te.gw = gw
   579  	return nil
   580  }
   581  
   582  func (te *testEndpoint) SetGatewayIPv6(gw6 net.IP) error {
   583  	te.gw6 = gw6
   584  	return nil
   585  }
   586  
   587  func (te *testEndpoint) AddStaticRoute(destination *net.IPNet, routeType int, nextHop net.IP) error {
   588  	te.routes = append(te.routes, types.StaticRoute{Destination: destination, RouteType: routeType, NextHop: nextHop})
   589  	return nil
   590  }
   591  
   592  func (te *testEndpoint) AddTableEntry(tableName string, key string, value []byte) error {
   593  	return nil
   594  }
   595  
   596  func (te *testEndpoint) DisableGatewayService() {}
   597  
   598  func TestQueryEndpointInfo(t *testing.T) {
   599  	testQueryEndpointInfo(t, true)
   600  }
   601  
   602  func TestQueryEndpointInfoHairpin(t *testing.T) {
   603  	testQueryEndpointInfo(t, false)
   604  }
   605  
   606  func testQueryEndpointInfo(t *testing.T, ulPxyEnabled bool) {
   607  	defer testutils.SetupTestOSContext(t)()
   608  
   609  	d := newDriver()
   610  
   611  	config := &configuration{
   612  		EnableIPTables:      true,
   613  		EnableUserlandProxy: ulPxyEnabled,
   614  	}
   615  	genericOption := make(map[string]interface{})
   616  	genericOption[netlabel.GenericData] = config
   617  
   618  	if err := d.configure(genericOption); err != nil {
   619  		t.Fatalf("Failed to setup driver config: %v", err)
   620  	}
   621  
   622  	netconfig := &networkConfiguration{
   623  		BridgeName: DefaultBridgeName,
   624  		EnableICC:  false,
   625  	}
   626  	genericOption = make(map[string]interface{})
   627  	genericOption[netlabel.GenericData] = netconfig
   628  
   629  	ipdList := getIPv4Data(t, "")
   630  	err := d.CreateNetwork("net1", genericOption, nil, ipdList, nil)
   631  	if err != nil {
   632  		t.Fatalf("Failed to create bridge: %v", err)
   633  	}
   634  
   635  	sbOptions := make(map[string]interface{})
   636  	sbOptions[netlabel.PortMap] = getPortMapping()
   637  
   638  	te := newTestEndpoint(ipdList[0].Pool, 11)
   639  	err = d.CreateEndpoint("net1", "ep1", te.Interface(), nil)
   640  	if err != nil {
   641  		t.Fatalf("Failed to create an endpoint : %s", err.Error())
   642  	}
   643  
   644  	err = d.Join("net1", "ep1", "sbox", te, sbOptions)
   645  	if err != nil {
   646  		t.Fatalf("Failed to join the endpoint: %v", err)
   647  	}
   648  
   649  	err = d.ProgramExternalConnectivity("net1", "ep1", sbOptions)
   650  	if err != nil {
   651  		t.Fatalf("Failed to program external connectivity: %v", err)
   652  	}
   653  
   654  	network, ok := d.networks["net1"]
   655  	if !ok {
   656  		t.Fatalf("Cannot find network %s inside driver", "net1")
   657  	}
   658  	ep, _ := network.endpoints["ep1"]
   659  	data, err := d.EndpointOperInfo(network.id, ep.id)
   660  	if err != nil {
   661  		t.Fatalf("Failed to ask for endpoint operational data:  %v", err)
   662  	}
   663  	pmd, ok := data[netlabel.PortMap]
   664  	if !ok {
   665  		t.Fatalf("Endpoint operational data does not contain port mapping data")
   666  	}
   667  	pm, ok := pmd.([]types.PortBinding)
   668  	if !ok {
   669  		t.Fatalf("Unexpected format for port mapping in endpoint operational data")
   670  	}
   671  	if len(ep.portMapping) != len(pm) {
   672  		t.Fatalf("Incomplete data for port mapping in endpoint operational data")
   673  	}
   674  	for i, pb := range ep.portMapping {
   675  		if !pb.Equal(&pm[i]) {
   676  			t.Fatalf("Unexpected data for port mapping in endpoint operational data")
   677  		}
   678  	}
   679  
   680  	err = d.RevokeExternalConnectivity("net1", "ep1")
   681  	if err != nil {
   682  		t.Fatal(err)
   683  	}
   684  
   685  	// release host mapped ports
   686  	err = d.Leave("net1", "ep1")
   687  	if err != nil {
   688  		t.Fatal(err)
   689  	}
   690  }
   691  
   692  func getExposedPorts() []types.TransportPort {
   693  	return []types.TransportPort{
   694  		{Proto: types.TCP, Port: uint16(5000)},
   695  		{Proto: types.UDP, Port: uint16(400)},
   696  		{Proto: types.TCP, Port: uint16(600)},
   697  	}
   698  }
   699  
   700  func getPortMapping() []types.PortBinding {
   701  	return []types.PortBinding{
   702  		{Proto: types.TCP, Port: uint16(230), HostPort: uint16(23000)},
   703  		{Proto: types.UDP, Port: uint16(200), HostPort: uint16(22000)},
   704  		{Proto: types.TCP, Port: uint16(120), HostPort: uint16(12000)},
   705  	}
   706  }
   707  
   708  func TestLinkContainers(t *testing.T) {
   709  	if !testutils.IsRunningInContainer() {
   710  		defer testutils.SetupTestOSContext(t)()
   711  	}
   712  
   713  	d := newDriver()
   714  
   715  	config := &configuration{
   716  		EnableIPTables: true,
   717  	}
   718  	genericOption := make(map[string]interface{})
   719  	genericOption[netlabel.GenericData] = config
   720  
   721  	if err := d.configure(genericOption); err != nil {
   722  		t.Fatalf("Failed to setup driver config: %v", err)
   723  	}
   724  
   725  	netconfig := &networkConfiguration{
   726  		BridgeName: DefaultBridgeName,
   727  		EnableICC:  false,
   728  	}
   729  	genericOption = make(map[string]interface{})
   730  	genericOption[netlabel.GenericData] = netconfig
   731  
   732  	ipdList := getIPv4Data(t, "")
   733  	err := d.CreateNetwork("net1", genericOption, nil, ipdList, nil)
   734  	if err != nil {
   735  		t.Fatalf("Failed to create bridge: %v", err)
   736  	}
   737  
   738  	te1 := newTestEndpoint(ipdList[0].Pool, 11)
   739  	err = d.CreateEndpoint("net1", "ep1", te1.Interface(), nil)
   740  	if err != nil {
   741  		t.Fatalf("Failed to create an endpoint : %s", err.Error())
   742  	}
   743  
   744  	exposedPorts := getExposedPorts()
   745  	sbOptions := make(map[string]interface{})
   746  	sbOptions[netlabel.ExposedPorts] = exposedPorts
   747  
   748  	err = d.Join("net1", "ep1", "sbox", te1, sbOptions)
   749  	if err != nil {
   750  		t.Fatalf("Failed to join the endpoint: %v", err)
   751  	}
   752  
   753  	err = d.ProgramExternalConnectivity("net1", "ep1", sbOptions)
   754  	if err != nil {
   755  		t.Fatalf("Failed to program external connectivity: %v", err)
   756  	}
   757  
   758  	addr1 := te1.iface.addr
   759  	if addr1.IP.To4() == nil {
   760  		t.Fatalf("No Ipv4 address assigned to the endpoint:  ep1")
   761  	}
   762  
   763  	te2 := newTestEndpoint(ipdList[0].Pool, 22)
   764  	err = d.CreateEndpoint("net1", "ep2", te2.Interface(), nil)
   765  	if err != nil {
   766  		t.Fatalf("Failed to create an endpoint : %s", err.Error())
   767  	}
   768  
   769  	addr2 := te2.iface.addr
   770  	if addr2.IP.To4() == nil {
   771  		t.Fatalf("No Ipv4 address assigned to the endpoint:  ep2")
   772  	}
   773  
   774  	sbOptions = make(map[string]interface{})
   775  	sbOptions[netlabel.GenericData] = options.Generic{
   776  		"ChildEndpoints": []string{"ep1"},
   777  	}
   778  
   779  	err = d.Join("net1", "ep2", "", te2, sbOptions)
   780  	if err != nil {
   781  		t.Fatalf("Failed to link ep1 and ep2")
   782  	}
   783  
   784  	err = d.ProgramExternalConnectivity("net1", "ep2", sbOptions)
   785  	if err != nil {
   786  		t.Fatalf("Failed to program external connectivity: %v", err)
   787  	}
   788  
   789  	out, err := iptables.Raw("-L", DockerChain)
   790  	for _, pm := range exposedPorts {
   791  		regex := fmt.Sprintf("%s dpt:%d", pm.Proto.String(), pm.Port)
   792  		re := regexp.MustCompile(regex)
   793  		matches := re.FindAllString(string(out[:]), -1)
   794  		if len(matches) != 1 {
   795  			t.Fatalf("IP Tables programming failed %s", string(out[:]))
   796  		}
   797  
   798  		regex = fmt.Sprintf("%s spt:%d", pm.Proto.String(), pm.Port)
   799  		matched, _ := regexp.MatchString(regex, string(out[:]))
   800  		if !matched {
   801  			t.Fatalf("IP Tables programming failed %s", string(out[:]))
   802  		}
   803  	}
   804  
   805  	err = d.RevokeExternalConnectivity("net1", "ep2")
   806  	if err != nil {
   807  		t.Fatalf("Failed to revoke external connectivity: %v", err)
   808  	}
   809  
   810  	err = d.Leave("net1", "ep2")
   811  	if err != nil {
   812  		t.Fatalf("Failed to unlink ep1 and ep2")
   813  	}
   814  
   815  	out, err = iptables.Raw("-L", DockerChain)
   816  	for _, pm := range exposedPorts {
   817  		regex := fmt.Sprintf("%s dpt:%d", pm.Proto.String(), pm.Port)
   818  		re := regexp.MustCompile(regex)
   819  		matches := re.FindAllString(string(out[:]), -1)
   820  		if len(matches) != 0 {
   821  			t.Fatalf("Leave should have deleted relevant IPTables rules  %s", string(out[:]))
   822  		}
   823  
   824  		regex = fmt.Sprintf("%s spt:%d", pm.Proto.String(), pm.Port)
   825  		matched, _ := regexp.MatchString(regex, string(out[:]))
   826  		if matched {
   827  			t.Fatalf("Leave should have deleted relevant IPTables rules  %s", string(out[:]))
   828  		}
   829  	}
   830  
   831  	// Error condition test with an invalid endpoint-id "ep4"
   832  	sbOptions = make(map[string]interface{})
   833  	sbOptions[netlabel.GenericData] = options.Generic{
   834  		"ChildEndpoints": []string{"ep1", "ep4"},
   835  	}
   836  
   837  	err = d.Join("net1", "ep2", "", te2, sbOptions)
   838  	if err != nil {
   839  		t.Fatal(err)
   840  	}
   841  	err = d.ProgramExternalConnectivity("net1", "ep2", sbOptions)
   842  	if err != nil {
   843  		out, err = iptables.Raw("-L", DockerChain)
   844  		for _, pm := range exposedPorts {
   845  			regex := fmt.Sprintf("%s dpt:%d", pm.Proto.String(), pm.Port)
   846  			re := regexp.MustCompile(regex)
   847  			matches := re.FindAllString(string(out[:]), -1)
   848  			if len(matches) != 0 {
   849  				t.Fatalf("Error handling should rollback relevant IPTables rules  %s", string(out[:]))
   850  			}
   851  
   852  			regex = fmt.Sprintf("%s spt:%d", pm.Proto.String(), pm.Port)
   853  			matched, _ := regexp.MatchString(regex, string(out[:]))
   854  			if matched {
   855  				t.Fatalf("Error handling should rollback relevant IPTables rules  %s", string(out[:]))
   856  			}
   857  		}
   858  	} else {
   859  		t.Fatalf("Expected Join to fail given link conditions are not satisfied")
   860  	}
   861  }
   862  
   863  func TestValidateConfig(t *testing.T) {
   864  	if !testutils.IsRunningInContainer() {
   865  		defer testutils.SetupTestOSContext(t)()
   866  	}
   867  
   868  	// Test mtu
   869  	c := networkConfiguration{Mtu: -2}
   870  	err := c.Validate()
   871  	if err == nil {
   872  		t.Fatalf("Failed to detect invalid MTU number")
   873  	}
   874  
   875  	c.Mtu = 9000
   876  	err = c.Validate()
   877  	if err != nil {
   878  		t.Fatalf("unexpected validation error on MTU number")
   879  	}
   880  
   881  	// Bridge network
   882  	_, network, _ := net.ParseCIDR("172.28.0.0/16")
   883  	c = networkConfiguration{
   884  		AddressIPv4: network,
   885  	}
   886  
   887  	err = c.Validate()
   888  	if err != nil {
   889  		t.Fatal(err)
   890  	}
   891  
   892  	// Test v4 gw
   893  	c.DefaultGatewayIPv4 = net.ParseIP("172.27.30.234")
   894  	err = c.Validate()
   895  	if err == nil {
   896  		t.Fatalf("Failed to detect invalid default gateway")
   897  	}
   898  
   899  	c.DefaultGatewayIPv4 = net.ParseIP("172.28.30.234")
   900  	err = c.Validate()
   901  	if err != nil {
   902  		t.Fatalf("Unexpected validation error on default gateway")
   903  	}
   904  
   905  	// Test v6 gw
   906  	_, v6nw, _ := net.ParseCIDR("2001:db8:ae:b004::/64")
   907  	c = networkConfiguration{
   908  		EnableIPv6:         true,
   909  		AddressIPv6:        v6nw,
   910  		DefaultGatewayIPv6: net.ParseIP("2001:db8:ac:b004::bad:a55"),
   911  	}
   912  	err = c.Validate()
   913  	if err == nil {
   914  		t.Fatalf("Failed to detect invalid v6 default gateway")
   915  	}
   916  
   917  	c.DefaultGatewayIPv6 = net.ParseIP("2001:db8:ae:b004::bad:a55")
   918  	err = c.Validate()
   919  	if err != nil {
   920  		t.Fatalf("Unexpected validation error on v6 default gateway")
   921  	}
   922  
   923  	c.AddressIPv6 = nil
   924  	err = c.Validate()
   925  	if err == nil {
   926  		t.Fatalf("Failed to detect invalid v6 default gateway")
   927  	}
   928  
   929  	c.AddressIPv6 = nil
   930  	err = c.Validate()
   931  	if err == nil {
   932  		t.Fatalf("Failed to detect invalid v6 default gateway")
   933  	}
   934  }
   935  
   936  func TestSetDefaultGw(t *testing.T) {
   937  	if !testutils.IsRunningInContainer() {
   938  		defer testutils.SetupTestOSContext(t)()
   939  	}
   940  
   941  	d := newDriver()
   942  
   943  	if err := d.configure(nil); err != nil {
   944  		t.Fatalf("Failed to setup driver config: %v", err)
   945  	}
   946  
   947  	_, subnetv6, _ := net.ParseCIDR("2001:db8:ea9:9abc:b0c4::/80")
   948  
   949  	ipdList := getIPv4Data(t, "")
   950  	gw4 := types.GetIPCopy(ipdList[0].Pool.IP).To4()
   951  	gw4[3] = 254
   952  	gw6 := net.ParseIP("2001:db8:ea9:9abc:b0c4::254")
   953  
   954  	config := &networkConfiguration{
   955  		BridgeName:         DefaultBridgeName,
   956  		AddressIPv6:        subnetv6,
   957  		DefaultGatewayIPv4: gw4,
   958  		DefaultGatewayIPv6: gw6,
   959  	}
   960  
   961  	genericOption := make(map[string]interface{})
   962  	genericOption[netlabel.EnableIPv6] = true
   963  	genericOption[netlabel.GenericData] = config
   964  
   965  	err := d.CreateNetwork("dummy", genericOption, nil, ipdList, nil)
   966  	if err != nil {
   967  		t.Fatalf("Failed to create bridge: %v", err)
   968  	}
   969  
   970  	te := newTestEndpoint(ipdList[0].Pool, 10)
   971  	err = d.CreateEndpoint("dummy", "ep", te.Interface(), nil)
   972  	if err != nil {
   973  		t.Fatalf("Failed to create endpoint: %v", err)
   974  	}
   975  
   976  	err = d.Join("dummy", "ep", "sbox", te, nil)
   977  	if err != nil {
   978  		t.Fatalf("Failed to join endpoint: %v", err)
   979  	}
   980  
   981  	if !gw4.Equal(te.gw) {
   982  		t.Fatalf("Failed to configure default gateway. Expected %v. Found %v", gw4, te.gw)
   983  	}
   984  
   985  	if !gw6.Equal(te.gw6) {
   986  		t.Fatalf("Failed to configure default gateway. Expected %v. Found %v", gw6, te.gw6)
   987  	}
   988  }
   989  
   990  func TestCleanupIptableRules(t *testing.T) {
   991  	defer testutils.SetupTestOSContext(t)()
   992  	bridgeChain := []iptables.ChainInfo{
   993  		{Name: DockerChain, Table: iptables.Nat},
   994  		{Name: DockerChain, Table: iptables.Filter},
   995  		{Name: IsolationChain, Table: iptables.Filter},
   996  	}
   997  	if _, _, _, err := setupIPChains(&configuration{EnableIPTables: true}); err != nil {
   998  		t.Fatalf("Error setting up ip chains: %v", err)
   999  	}
  1000  	for _, chainInfo := range bridgeChain {
  1001  		if !iptables.ExistChain(chainInfo.Name, chainInfo.Table) {
  1002  			t.Fatalf("iptables chain %s of %s table should have been created", chainInfo.Name, chainInfo.Table)
  1003  		}
  1004  	}
  1005  	removeIPChains()
  1006  	for _, chainInfo := range bridgeChain {
  1007  		if iptables.ExistChain(chainInfo.Name, chainInfo.Table) {
  1008  			t.Fatalf("iptables chain %s of %s table should have been deleted", chainInfo.Name, chainInfo.Table)
  1009  		}
  1010  	}
  1011  }
  1012  
  1013  func TestCreateWithExistingBridge(t *testing.T) {
  1014  	defer testutils.SetupTestOSContext(t)()
  1015  	d := newDriver()
  1016  
  1017  	if err := d.configure(nil); err != nil {
  1018  		t.Fatalf("Failed to setup driver config: %v", err)
  1019  	}
  1020  
  1021  	brName := "br111"
  1022  	br := &netlink.Bridge{
  1023  		LinkAttrs: netlink.LinkAttrs{
  1024  			Name: brName,
  1025  		},
  1026  	}
  1027  	if err := netlink.LinkAdd(br); err != nil {
  1028  		t.Fatalf("Failed to create bridge interface: %v", err)
  1029  	}
  1030  	defer netlink.LinkDel(br)
  1031  	if err := netlink.LinkSetUp(br); err != nil {
  1032  		t.Fatalf("Failed to set bridge interface up: %v", err)
  1033  	}
  1034  
  1035  	ip := net.IP{192, 168, 122, 1}
  1036  	addr := &netlink.Addr{IPNet: &net.IPNet{
  1037  		IP:   ip,
  1038  		Mask: net.IPv4Mask(255, 255, 255, 0),
  1039  	}}
  1040  	if err := netlink.AddrAdd(br, addr); err != nil {
  1041  		t.Fatalf("Failed to add IP address to bridge: %v", err)
  1042  	}
  1043  
  1044  	netconfig := &networkConfiguration{BridgeName: brName}
  1045  	genericOption := make(map[string]interface{})
  1046  	genericOption[netlabel.GenericData] = netconfig
  1047  
  1048  	if err := d.CreateNetwork(brName, genericOption, nil, getIPv4Data(t, brName), nil); err != nil {
  1049  		t.Fatalf("Failed to create bridge network: %v", err)
  1050  	}
  1051  
  1052  	nw, err := d.getNetwork(brName)
  1053  	if err != nil {
  1054  		t.Fatalf("Failed to getNetwork(%s): %v", brName, err)
  1055  	}
  1056  
  1057  	addr4, _, err := nw.bridge.addresses()
  1058  	if err != nil {
  1059  		t.Fatalf("Failed to get the bridge network's address: %v", err)
  1060  	}
  1061  
  1062  	if !addr4.IP.Equal(ip) {
  1063  		t.Fatal("Creating bridge network with existing bridge interface unexpectedly modified the IP address of the bridge")
  1064  	}
  1065  
  1066  	if err := d.DeleteNetwork(brName); err != nil {
  1067  		t.Fatalf("Failed to delete network %s: %v", brName, err)
  1068  	}
  1069  
  1070  	if _, err := netlink.LinkByName(brName); err != nil {
  1071  		t.Fatalf("Deleting bridge network that using existing bridge interface unexpectedly deleted the bridge interface")
  1072  	}
  1073  }