github.com/adityamillind98/moby@v23.0.0-rc.4+incompatible/libnetwork/drivers/bridge/bridge_test.go (about)

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