github.com/jfrazelle/docker@v1.1.2-0.20210712172922-bf78e25fe508/libnetwork/drivers/bridge/bridge_test.go (about)

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