bridge_test.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. package bridge
  2. import (
  3. "bytes"
  4. "fmt"
  5. "net"
  6. "regexp"
  7. "testing"
  8. "github.com/docker/libnetwork/driverapi"
  9. "github.com/docker/libnetwork/iptables"
  10. "github.com/docker/libnetwork/netlabel"
  11. "github.com/docker/libnetwork/netutils"
  12. "github.com/docker/libnetwork/types"
  13. "github.com/vishvananda/netlink"
  14. )
  15. func TestCreateFullOptions(t *testing.T) {
  16. defer netutils.SetupTestNetNS(t)()
  17. d := newDriver()
  18. config := &configuration{
  19. EnableIPForwarding: true,
  20. }
  21. // Test this scenario: Default gw address does not belong to
  22. // container network and it's greater than bridge address
  23. cip, cnw, _ := net.ParseCIDR("172.16.122.0/24")
  24. cnw.IP = cip
  25. ip, nw, _ := net.ParseCIDR("172.16.0.10/16")
  26. nw.IP = ip
  27. gw := net.ParseIP("172.16.0.1")
  28. netConfig := &networkConfiguration{
  29. BridgeName: DefaultBridgeName,
  30. AddressIPv4: nw,
  31. FixedCIDR: cnw,
  32. DefaultGatewayIPv4: gw,
  33. EnableIPv6: true,
  34. EnableIPTables: true,
  35. }
  36. _, netConfig.FixedCIDRv6, _ = net.ParseCIDR("2001:db8::/48")
  37. genericOption := make(map[string]interface{})
  38. genericOption[netlabel.GenericData] = config
  39. if err := d.Config(genericOption); err != nil {
  40. t.Fatalf("Failed to setup driver config: %v", err)
  41. }
  42. netOption := make(map[string]interface{})
  43. netOption[netlabel.GenericData] = netConfig
  44. err := d.CreateNetwork("dummy", netOption)
  45. if err != nil {
  46. t.Fatalf("Failed to create bridge: %v", err)
  47. }
  48. }
  49. func TestCreate(t *testing.T) {
  50. defer netutils.SetupTestNetNS(t)()
  51. d := newDriver()
  52. config := &networkConfiguration{BridgeName: DefaultBridgeName}
  53. genericOption := make(map[string]interface{})
  54. genericOption[netlabel.GenericData] = config
  55. if err := d.CreateNetwork("dummy", genericOption); err != nil {
  56. t.Fatalf("Failed to create bridge: %v", err)
  57. }
  58. err := d.CreateNetwork("dummy", genericOption)
  59. if err == nil {
  60. t.Fatalf("Expected bridge driver to refuse creation of second network with default name")
  61. }
  62. if _, ok := err.(types.ForbiddenError); !ok {
  63. t.Fatalf("Creation of second network with default name failed with unexpected error type")
  64. }
  65. err = d.DeleteNetwork("dummy")
  66. if err == nil {
  67. t.Fatalf("deletion of network with default name should fail on this driver")
  68. }
  69. if _, ok := err.(types.ForbiddenError); !ok {
  70. t.Fatalf("deletion of network with default name failed with unexpected error type")
  71. }
  72. }
  73. func TestCreateFail(t *testing.T) {
  74. defer netutils.SetupTestNetNS(t)()
  75. d := newDriver()
  76. config := &networkConfiguration{BridgeName: "dummy0"}
  77. genericOption := make(map[string]interface{})
  78. genericOption[netlabel.GenericData] = config
  79. if err := d.CreateNetwork("dummy", genericOption); err == nil {
  80. t.Fatal("Bridge creation was expected to fail")
  81. }
  82. }
  83. func TestCreateMultipleNetworks(t *testing.T) {
  84. defer netutils.SetupTestNetNS(t)()
  85. d := newDriver()
  86. dd, _ := d.(*driver)
  87. config1 := &networkConfiguration{BridgeName: "net_test_1", AllowNonDefaultBridge: true, EnableIPTables: true}
  88. genericOption := make(map[string]interface{})
  89. genericOption[netlabel.GenericData] = config1
  90. if err := d.CreateNetwork("1", genericOption); err != nil {
  91. t.Fatalf("Failed to create bridge: %v", err)
  92. }
  93. config2 := &networkConfiguration{BridgeName: "net_test_2", AllowNonDefaultBridge: true, EnableIPTables: true}
  94. genericOption[netlabel.GenericData] = config2
  95. if err := d.CreateNetwork("2", genericOption); err != nil {
  96. t.Fatalf("Failed to create bridge: %v", err)
  97. }
  98. config3 := &networkConfiguration{BridgeName: "net_test_3", AllowNonDefaultBridge: true, EnableIPTables: true}
  99. genericOption[netlabel.GenericData] = config3
  100. if err := d.CreateNetwork("3", genericOption); err != nil {
  101. t.Fatalf("Failed to create bridge: %v", err)
  102. }
  103. // Verify the network isolation rules are installed, each network subnet should appear 4 times
  104. verifyV4INCEntries(dd.networks, 4, t)
  105. config4 := &networkConfiguration{BridgeName: "net_test_4", AllowNonDefaultBridge: true, EnableIPTables: true}
  106. genericOption[netlabel.GenericData] = config4
  107. if err := d.CreateNetwork("4", genericOption); err != nil {
  108. t.Fatalf("Failed to create bridge: %v", err)
  109. }
  110. // Now 6 times
  111. verifyV4INCEntries(dd.networks, 6, t)
  112. d.DeleteNetwork("1")
  113. verifyV4INCEntries(dd.networks, 4, t)
  114. d.DeleteNetwork("2")
  115. verifyV4INCEntries(dd.networks, 2, t)
  116. d.DeleteNetwork("3")
  117. verifyV4INCEntries(dd.networks, 0, t)
  118. d.DeleteNetwork("4")
  119. verifyV4INCEntries(dd.networks, 0, t)
  120. }
  121. func verifyV4INCEntries(networks map[types.UUID]*bridgeNetwork, numEntries int, t *testing.T) {
  122. out, err := iptables.Raw("-L", "FORWARD")
  123. if err != nil {
  124. t.Fatal(err)
  125. }
  126. for _, nw := range networks {
  127. nt := types.GetIPNetCopy(nw.bridge.bridgeIPv4)
  128. nt.IP = nt.IP.Mask(nt.Mask)
  129. re := regexp.MustCompile(nt.String())
  130. matches := re.FindAllString(string(out[:]), -1)
  131. if len(matches) != numEntries {
  132. t.Fatalf("Cannot find expected inter-network isolation rules in IP Tables:\n%s", string(out[:]))
  133. }
  134. }
  135. }
  136. type testInterface struct {
  137. id int
  138. mac net.HardwareAddr
  139. addr net.IPNet
  140. addrv6 net.IPNet
  141. srcName string
  142. dstName string
  143. }
  144. type testEndpoint struct {
  145. ifaces []*testInterface
  146. gw net.IP
  147. gw6 net.IP
  148. hostsPath string
  149. resolvConfPath string
  150. routes []types.StaticRoute
  151. }
  152. func (te *testEndpoint) Interfaces() []driverapi.InterfaceInfo {
  153. iList := make([]driverapi.InterfaceInfo, len(te.ifaces))
  154. for i, iface := range te.ifaces {
  155. iList[i] = iface
  156. }
  157. return iList
  158. }
  159. func (te *testEndpoint) AddInterface(id int, mac net.HardwareAddr, ipv4 net.IPNet, ipv6 net.IPNet) error {
  160. iface := &testInterface{id: id, addr: ipv4, addrv6: ipv6}
  161. te.ifaces = append(te.ifaces, iface)
  162. return nil
  163. }
  164. func (i *testInterface) ID() int {
  165. return i.id
  166. }
  167. func (i *testInterface) MacAddress() net.HardwareAddr {
  168. return i.mac
  169. }
  170. func (i *testInterface) Address() net.IPNet {
  171. return i.addr
  172. }
  173. func (i *testInterface) AddressIPv6() net.IPNet {
  174. return i.addrv6
  175. }
  176. func (i *testInterface) SetNames(srcName string, dstName string) error {
  177. i.srcName = srcName
  178. i.dstName = dstName
  179. return nil
  180. }
  181. func (te *testEndpoint) InterfaceNames() []driverapi.InterfaceNameInfo {
  182. iList := make([]driverapi.InterfaceNameInfo, len(te.ifaces))
  183. for i, iface := range te.ifaces {
  184. iList[i] = iface
  185. }
  186. return iList
  187. }
  188. func (te *testEndpoint) SetGateway(gw net.IP) error {
  189. te.gw = gw
  190. return nil
  191. }
  192. func (te *testEndpoint) SetGatewayIPv6(gw6 net.IP) error {
  193. te.gw6 = gw6
  194. return nil
  195. }
  196. func (te *testEndpoint) SetHostsPath(path string) error {
  197. te.hostsPath = path
  198. return nil
  199. }
  200. func (te *testEndpoint) SetResolvConfPath(path string) error {
  201. te.resolvConfPath = path
  202. return nil
  203. }
  204. func (te *testEndpoint) AddStaticRoute(destination *net.IPNet, routeType int, nextHop net.IP, interfaceID int) error {
  205. te.routes = append(te.routes, types.StaticRoute{Destination: destination, RouteType: routeType, NextHop: nextHop, InterfaceID: interfaceID})
  206. return nil
  207. }
  208. func TestQueryEndpointInfo(t *testing.T) {
  209. testQueryEndpointInfo(t, true)
  210. }
  211. func TestQueryEndpointInfoHairpin(t *testing.T) {
  212. testQueryEndpointInfo(t, false)
  213. }
  214. func testQueryEndpointInfo(t *testing.T, ulPxyEnabled bool) {
  215. defer netutils.SetupTestNetNS(t)()
  216. d := newDriver()
  217. dd, _ := d.(*driver)
  218. config := &networkConfiguration{
  219. BridgeName: DefaultBridgeName,
  220. EnableIPTables: true,
  221. EnableICC: false,
  222. EnableUserlandProxy: ulPxyEnabled,
  223. }
  224. genericOption := make(map[string]interface{})
  225. genericOption[netlabel.GenericData] = config
  226. err := d.CreateNetwork("net1", genericOption)
  227. if err != nil {
  228. t.Fatalf("Failed to create bridge: %v", err)
  229. }
  230. portMappings := getPortMapping()
  231. epOptions := make(map[string]interface{})
  232. epOptions[netlabel.PortMap] = portMappings
  233. te := &testEndpoint{ifaces: []*testInterface{}}
  234. err = d.CreateEndpoint("net1", "ep1", te, epOptions)
  235. if err != nil {
  236. t.Fatalf("Failed to create an endpoint : %s", err.Error())
  237. }
  238. network, ok := dd.networks["net1"]
  239. if !ok {
  240. t.Fatalf("Cannot find network %s inside driver", "net1")
  241. }
  242. ep, _ := network.endpoints["ep1"]
  243. data, err := d.EndpointOperInfo(network.id, ep.id)
  244. if err != nil {
  245. t.Fatalf("Failed to ask for endpoint operational data: %v", err)
  246. }
  247. pmd, ok := data[netlabel.PortMap]
  248. if !ok {
  249. t.Fatalf("Endpoint operational data does not contain port mapping data")
  250. }
  251. pm, ok := pmd.([]types.PortBinding)
  252. if !ok {
  253. t.Fatalf("Unexpected format for port mapping in endpoint operational data")
  254. }
  255. if len(ep.portMapping) != len(pm) {
  256. t.Fatalf("Incomplete data for port mapping in endpoint operational data")
  257. }
  258. for i, pb := range ep.portMapping {
  259. if !pb.Equal(&pm[i]) {
  260. t.Fatalf("Unexpected data for port mapping in endpoint operational data")
  261. }
  262. }
  263. // Cleanup as host ports are there
  264. err = network.releasePorts(ep)
  265. if err != nil {
  266. t.Fatalf("Failed to release mapped ports: %v", err)
  267. }
  268. }
  269. func TestCreateLinkWithOptions(t *testing.T) {
  270. defer netutils.SetupTestNetNS(t)()
  271. d := newDriver()
  272. config := &networkConfiguration{BridgeName: DefaultBridgeName}
  273. netOptions := make(map[string]interface{})
  274. netOptions[netlabel.GenericData] = config
  275. err := d.CreateNetwork("net1", netOptions)
  276. if err != nil {
  277. t.Fatalf("Failed to create bridge: %v", err)
  278. }
  279. mac := net.HardwareAddr([]byte{0x1e, 0x67, 0x66, 0x44, 0x55, 0x66})
  280. epOptions := make(map[string]interface{})
  281. epOptions[netlabel.MacAddress] = mac
  282. te := &testEndpoint{ifaces: []*testInterface{}}
  283. err = d.CreateEndpoint("net1", "ep", te, epOptions)
  284. if err != nil {
  285. t.Fatalf("Failed to create an endpoint: %s", err.Error())
  286. }
  287. err = d.Join("net1", "ep", "sbox", te, nil)
  288. if err != nil {
  289. t.Fatalf("Failed to join the endpoint: %v", err)
  290. }
  291. ifaceName := te.ifaces[0].srcName
  292. veth, err := netlink.LinkByName(ifaceName)
  293. if err != nil {
  294. t.Fatal(err)
  295. }
  296. if !bytes.Equal(mac, veth.Attrs().HardwareAddr) {
  297. t.Fatalf("Failed to parse and program endpoint configuration")
  298. }
  299. }
  300. func getExposedPorts() []types.TransportPort {
  301. return []types.TransportPort{
  302. types.TransportPort{Proto: types.TCP, Port: uint16(5000)},
  303. types.TransportPort{Proto: types.UDP, Port: uint16(400)},
  304. types.TransportPort{Proto: types.TCP, Port: uint16(600)},
  305. }
  306. }
  307. func getPortMapping() []types.PortBinding {
  308. return []types.PortBinding{
  309. types.PortBinding{Proto: types.TCP, Port: uint16(230), HostPort: uint16(23000)},
  310. types.PortBinding{Proto: types.UDP, Port: uint16(200), HostPort: uint16(22000)},
  311. types.PortBinding{Proto: types.TCP, Port: uint16(120), HostPort: uint16(12000)},
  312. }
  313. }
  314. func TestLinkContainers(t *testing.T) {
  315. defer netutils.SetupTestNetNS(t)()
  316. d := newDriver()
  317. config := &networkConfiguration{
  318. BridgeName: DefaultBridgeName,
  319. EnableIPTables: true,
  320. EnableICC: false,
  321. }
  322. genericOption := make(map[string]interface{})
  323. genericOption[netlabel.GenericData] = config
  324. err := d.CreateNetwork("net1", genericOption)
  325. if err != nil {
  326. t.Fatalf("Failed to create bridge: %v", err)
  327. }
  328. exposedPorts := getExposedPorts()
  329. epOptions := make(map[string]interface{})
  330. epOptions[netlabel.ExposedPorts] = exposedPorts
  331. te1 := &testEndpoint{ifaces: []*testInterface{}}
  332. err = d.CreateEndpoint("net1", "ep1", te1, epOptions)
  333. if err != nil {
  334. t.Fatalf("Failed to create an endpoint : %s", err.Error())
  335. }
  336. addr1 := te1.ifaces[0].addr
  337. if addr1.IP.To4() == nil {
  338. t.Fatalf("No Ipv4 address assigned to the endpoint: ep1")
  339. }
  340. te2 := &testEndpoint{ifaces: []*testInterface{}}
  341. err = d.CreateEndpoint("net1", "ep2", te2, nil)
  342. if err != nil {
  343. t.Fatalf("Failed to create an endpoint : %s", err.Error())
  344. }
  345. addr2 := te2.ifaces[0].addr
  346. if addr2.IP.To4() == nil {
  347. t.Fatalf("No Ipv4 address assigned to the endpoint: ep2")
  348. }
  349. ce := []string{"ep1"}
  350. cConfig := &containerConfiguration{ChildEndpoints: ce}
  351. genericOption = make(map[string]interface{})
  352. genericOption[netlabel.GenericData] = cConfig
  353. err = d.Join("net1", "ep2", "", te2, genericOption)
  354. if err != nil {
  355. t.Fatalf("Failed to link ep1 and ep2")
  356. }
  357. out, err := iptables.Raw("-L", DockerChain)
  358. for _, pm := range exposedPorts {
  359. regex := fmt.Sprintf("%s dpt:%d", pm.Proto.String(), pm.Port)
  360. re := regexp.MustCompile(regex)
  361. matches := re.FindAllString(string(out[:]), -1)
  362. if len(matches) != 1 {
  363. t.Fatalf("IP Tables programming failed %s", string(out[:]))
  364. }
  365. regex = fmt.Sprintf("%s spt:%d", pm.Proto.String(), pm.Port)
  366. matched, _ := regexp.MatchString(regex, string(out[:]))
  367. if !matched {
  368. t.Fatalf("IP Tables programming failed %s", string(out[:]))
  369. }
  370. }
  371. err = d.Leave("net1", "ep2")
  372. if err != nil {
  373. t.Fatalf("Failed to unlink ep1 and ep2")
  374. }
  375. out, err = iptables.Raw("-L", DockerChain)
  376. for _, pm := range exposedPorts {
  377. regex := fmt.Sprintf("%s dpt:%d", pm.Proto.String(), pm.Port)
  378. re := regexp.MustCompile(regex)
  379. matches := re.FindAllString(string(out[:]), -1)
  380. if len(matches) != 0 {
  381. t.Fatalf("Leave should have deleted relevant IPTables rules %s", string(out[:]))
  382. }
  383. regex = fmt.Sprintf("%s spt:%d", pm.Proto.String(), pm.Port)
  384. matched, _ := regexp.MatchString(regex, string(out[:]))
  385. if matched {
  386. t.Fatalf("Leave should have deleted relevant IPTables rules %s", string(out[:]))
  387. }
  388. }
  389. // Error condition test with an invalid endpoint-id "ep4"
  390. ce = []string{"ep1", "ep4"}
  391. cConfig = &containerConfiguration{ChildEndpoints: ce}
  392. genericOption = make(map[string]interface{})
  393. genericOption[netlabel.GenericData] = cConfig
  394. err = d.Join("net1", "ep2", "", te2, genericOption)
  395. if err != nil {
  396. out, err = iptables.Raw("-L", DockerChain)
  397. for _, pm := range exposedPorts {
  398. regex := fmt.Sprintf("%s dpt:%d", pm.Proto.String(), pm.Port)
  399. re := regexp.MustCompile(regex)
  400. matches := re.FindAllString(string(out[:]), -1)
  401. if len(matches) != 0 {
  402. t.Fatalf("Error handling should rollback relevant IPTables rules %s", string(out[:]))
  403. }
  404. regex = fmt.Sprintf("%s spt:%d", pm.Proto.String(), pm.Port)
  405. matched, _ := regexp.MatchString(regex, string(out[:]))
  406. if matched {
  407. t.Fatalf("Error handling should rollback relevant IPTables rules %s", string(out[:]))
  408. }
  409. }
  410. } else {
  411. t.Fatalf("Expected Join to fail given link conditions are not satisfied")
  412. }
  413. }
  414. func TestValidateConfig(t *testing.T) {
  415. // Test mtu
  416. c := networkConfiguration{Mtu: -2}
  417. err := c.Validate()
  418. if err == nil {
  419. t.Fatalf("Failed to detect invalid MTU number")
  420. }
  421. c.Mtu = 9000
  422. err = c.Validate()
  423. if err != nil {
  424. t.Fatalf("unexpected validation error on MTU number")
  425. }
  426. // Bridge network
  427. _, network, _ := net.ParseCIDR("172.28.0.0/16")
  428. // Test FixedCIDR
  429. _, containerSubnet, _ := net.ParseCIDR("172.27.0.0/16")
  430. c = networkConfiguration{
  431. AddressIPv4: network,
  432. FixedCIDR: containerSubnet,
  433. }
  434. err = c.Validate()
  435. if err == nil {
  436. t.Fatalf("Failed to detect invalid FixedCIDR network")
  437. }
  438. _, containerSubnet, _ = net.ParseCIDR("172.28.0.0/16")
  439. c.FixedCIDR = containerSubnet
  440. err = c.Validate()
  441. if err != nil {
  442. t.Fatalf("Unexpected validation error on FixedCIDR network")
  443. }
  444. _, containerSubnet, _ = net.ParseCIDR("172.28.0.0/15")
  445. c.FixedCIDR = containerSubnet
  446. err = c.Validate()
  447. if err == nil {
  448. t.Fatalf("Failed to detect invalid FixedCIDR network")
  449. }
  450. _, containerSubnet, _ = net.ParseCIDR("172.28.0.0/17")
  451. c.FixedCIDR = containerSubnet
  452. err = c.Validate()
  453. if err != nil {
  454. t.Fatalf("Unexpected validation error on FixedCIDR network")
  455. }
  456. // Test v4 gw
  457. c.DefaultGatewayIPv4 = net.ParseIP("172.27.30.234")
  458. err = c.Validate()
  459. if err == nil {
  460. t.Fatalf("Failed to detect invalid default gateway")
  461. }
  462. c.DefaultGatewayIPv4 = net.ParseIP("172.28.30.234")
  463. err = c.Validate()
  464. if err != nil {
  465. t.Fatalf("Unexpected validation error on default gateway")
  466. }
  467. // Test v6 gw
  468. _, containerSubnet, _ = net.ParseCIDR("2001:1234:ae:b004::/64")
  469. c = networkConfiguration{
  470. EnableIPv6: true,
  471. FixedCIDRv6: containerSubnet,
  472. DefaultGatewayIPv6: net.ParseIP("2001:1234:ac:b004::bad:a55"),
  473. }
  474. err = c.Validate()
  475. if err == nil {
  476. t.Fatalf("Failed to detect invalid v6 default gateway")
  477. }
  478. c.DefaultGatewayIPv6 = net.ParseIP("2001:1234:ae:b004::bad:a55")
  479. err = c.Validate()
  480. if err != nil {
  481. t.Fatalf("Unexpected validation error on v6 default gateway")
  482. }
  483. c.FixedCIDRv6 = nil
  484. err = c.Validate()
  485. if err == nil {
  486. t.Fatalf("Failed to detect invalid v6 default gateway")
  487. }
  488. }
  489. func TestSetDefaultGw(t *testing.T) {
  490. defer netutils.SetupTestNetNS(t)()
  491. d := newDriver()
  492. _, subnetv6, _ := net.ParseCIDR("2001:db8:ea9:9abc:b0c4::/80")
  493. gw4 := bridgeNetworks[0].IP.To4()
  494. gw4[3] = 254
  495. gw6 := net.ParseIP("2001:db8:ea9:9abc:b0c4::254")
  496. config := &networkConfiguration{
  497. BridgeName: DefaultBridgeName,
  498. EnableIPv6: true,
  499. FixedCIDRv6: subnetv6,
  500. DefaultGatewayIPv4: gw4,
  501. DefaultGatewayIPv6: gw6,
  502. }
  503. genericOption := make(map[string]interface{})
  504. genericOption[netlabel.GenericData] = config
  505. err := d.CreateNetwork("dummy", genericOption)
  506. if err != nil {
  507. t.Fatalf("Failed to create bridge: %v", err)
  508. }
  509. te := &testEndpoint{ifaces: []*testInterface{}}
  510. err = d.CreateEndpoint("dummy", "ep", te, nil)
  511. if err != nil {
  512. t.Fatalf("Failed to create endpoint: %v", err)
  513. }
  514. err = d.Join("dummy", "ep", "sbox", te, nil)
  515. if err != nil {
  516. t.Fatalf("Failed to join endpoint: %v", err)
  517. }
  518. if !gw4.Equal(te.gw) {
  519. t.Fatalf("Failed to configure default gateway. Expected %v. Found %v", gw4, te.gw)
  520. }
  521. if !gw6.Equal(te.gw6) {
  522. t.Fatalf("Failed to configure default gateway. Expected %v. Found %v", gw6, te.gw6)
  523. }
  524. }