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