github.com/pwn-term/docker@v0.0.0-20210616085119-6e977cce2565/libnetwork/drivers/bridge/bridge_test.go (about)

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