github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/libnetwork/drivers/bridge/bridge_linux_test.go (about)

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