bridge_test.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. package bridge
  2. import (
  3. "bytes"
  4. "fmt"
  5. "net"
  6. "regexp"
  7. "testing"
  8. "github.com/docker/docker/pkg/iptables"
  9. "github.com/docker/libnetwork/netutils"
  10. "github.com/docker/libnetwork/pkg/options"
  11. "github.com/vishvananda/netlink"
  12. )
  13. func TestCreateFullOptions(t *testing.T) {
  14. defer netutils.SetupTestNetNS(t)()
  15. _, d := New()
  16. config := &Configuration{
  17. BridgeName: DefaultBridgeName,
  18. EnableIPv6: true,
  19. FixedCIDR: bridgeNetworks[0],
  20. EnableIPTables: true,
  21. EnableIPForwarding: true,
  22. }
  23. _, config.FixedCIDRv6, _ = net.ParseCIDR("2001:db8::/48")
  24. genericOption := make(map[string]interface{})
  25. genericOption[options.GenericData] = config
  26. if err := d.Config(genericOption); err != nil {
  27. t.Fatalf("Failed to setup driver config: %v", err)
  28. }
  29. err := d.CreateNetwork("dummy", nil)
  30. if err != nil {
  31. t.Fatalf("Failed to create bridge: %v", err)
  32. }
  33. }
  34. func TestCreate(t *testing.T) {
  35. defer netutils.SetupTestNetNS(t)()
  36. _, d := New()
  37. config := &Configuration{BridgeName: DefaultBridgeName}
  38. genericOption := make(map[string]interface{})
  39. genericOption[options.GenericData] = config
  40. if err := d.Config(genericOption); err != nil {
  41. t.Fatalf("Failed to setup driver config: %v", err)
  42. }
  43. if err := d.CreateNetwork("dummy", nil); err != nil {
  44. t.Fatalf("Failed to create bridge: %v", err)
  45. }
  46. }
  47. func TestCreateFail(t *testing.T) {
  48. defer netutils.SetupTestNetNS(t)()
  49. _, d := New()
  50. config := &Configuration{BridgeName: "dummy0"}
  51. genericOption := make(map[string]interface{})
  52. genericOption[options.GenericData] = config
  53. if err := d.Config(genericOption); err != nil {
  54. t.Fatalf("Failed to setup driver config: %v", err)
  55. }
  56. if err := d.CreateNetwork("dummy", nil); err == nil {
  57. t.Fatal("Bridge creation was expected to fail")
  58. }
  59. }
  60. func TestQueryEndpointInfo(t *testing.T) {
  61. defer netutils.SetupTestNetNS(t)()
  62. _, d := New()
  63. config := &Configuration{
  64. BridgeName: DefaultBridgeName,
  65. EnableIPTables: true,
  66. EnableICC: false,
  67. }
  68. genericOption := make(map[string]interface{})
  69. genericOption[options.GenericData] = config
  70. if err := d.Config(genericOption); err != nil {
  71. t.Fatalf("Failed to setup driver config: %v", err)
  72. }
  73. err := d.CreateNetwork("net1", nil)
  74. if err != nil {
  75. t.Fatalf("Failed to create bridge: %v", err)
  76. }
  77. portMappings := getPortMapping()
  78. epOptions := make(map[string]interface{})
  79. epOptions[options.PortMap] = portMappings
  80. _, err = d.CreateEndpoint("net1", "ep1", epOptions)
  81. if err != nil {
  82. t.Fatalf("Failed to create an endpoint : %s", err.Error())
  83. }
  84. dd := d.(*driver)
  85. ep, _ := dd.network.endpoints["ep1"]
  86. data, err := d.EndpointInfo(dd.network.id, ep.id)
  87. if err != nil {
  88. t.Fatalf("Failed to ask for endpoint operational data: %v", err)
  89. }
  90. pmd, ok := data[options.PortMap]
  91. if !ok {
  92. t.Fatalf("Endpoint operational data does not contain port mapping data")
  93. }
  94. pm, ok := pmd.([]netutils.PortBinding)
  95. if !ok {
  96. t.Fatalf("Unexpected format for port mapping in endpoint operational data")
  97. }
  98. if len(ep.portMapping) != len(pm) {
  99. t.Fatalf("Incomplete data for port mapping in endpoint operational data")
  100. }
  101. for i, pb := range ep.portMapping {
  102. if !pb.Equal(&pm[i]) {
  103. t.Fatalf("Unexpected data for port mapping in endpoint operational data")
  104. }
  105. }
  106. // Cleanup as host ports are there
  107. err = releasePorts(ep)
  108. if err != nil {
  109. t.Fatalf("Failed to release mapped ports: %v", err)
  110. }
  111. }
  112. func TestCreateLinkWithOptions(t *testing.T) {
  113. defer netutils.SetupTestNetNS(t)()
  114. _, d := New()
  115. config := &Configuration{BridgeName: DefaultBridgeName}
  116. driverOptions := make(map[string]interface{})
  117. driverOptions[options.GenericData] = config
  118. if err := d.Config(driverOptions); err != nil {
  119. t.Fatalf("Failed to setup driver config: %v", err)
  120. }
  121. err := d.CreateNetwork("net1", nil)
  122. if err != nil {
  123. t.Fatalf("Failed to create bridge: %v", err)
  124. }
  125. mac := net.HardwareAddr([]byte{0x1e, 0x67, 0x66, 0x44, 0x55, 0x66})
  126. epOptions := make(map[string]interface{})
  127. epOptions[options.MacAddress] = mac
  128. sinfo, err := d.CreateEndpoint("net1", "ep", epOptions)
  129. if err != nil {
  130. t.Fatalf("Failed to create a link: %s", err.Error())
  131. }
  132. ifaceName := sinfo.Interfaces[0].SrcName
  133. veth, err := netlink.LinkByName(ifaceName)
  134. if err != nil {
  135. t.Fatal(err)
  136. }
  137. if !bytes.Equal(mac, veth.Attrs().HardwareAddr) {
  138. t.Fatalf("Failed to parse and program endpoint configuration")
  139. }
  140. }
  141. func getExposedPorts() []netutils.TransportPort {
  142. return []netutils.TransportPort{
  143. netutils.TransportPort{Proto: netutils.TCP, Port: uint16(5000)},
  144. netutils.TransportPort{Proto: netutils.UDP, Port: uint16(400)},
  145. netutils.TransportPort{Proto: netutils.TCP, Port: uint16(600)},
  146. }
  147. }
  148. func getPortMapping() []netutils.PortBinding {
  149. return []netutils.PortBinding{
  150. netutils.PortBinding{Proto: netutils.TCP, Port: uint16(230), HostPort: uint16(23000)},
  151. netutils.PortBinding{Proto: netutils.UDP, Port: uint16(200), HostPort: uint16(22000)},
  152. netutils.PortBinding{Proto: netutils.TCP, Port: uint16(120), HostPort: uint16(12000)},
  153. }
  154. }
  155. func TestLinkContainers(t *testing.T) {
  156. defer netutils.SetupTestNetNS(t)()
  157. _, d := New()
  158. config := &Configuration{
  159. BridgeName: DefaultBridgeName,
  160. EnableIPTables: true,
  161. EnableICC: false,
  162. }
  163. genericOption := make(map[string]interface{})
  164. genericOption[options.GenericData] = config
  165. if err := d.Config(genericOption); err != nil {
  166. t.Fatalf("Failed to setup driver config: %v", err)
  167. }
  168. err := d.CreateNetwork("net1", nil)
  169. if err != nil {
  170. t.Fatalf("Failed to create bridge: %v", err)
  171. }
  172. exposedPorts := getExposedPorts()
  173. epOptions := make(map[string]interface{})
  174. epOptions[options.ExposedPorts] = exposedPorts
  175. sinfo, err := d.CreateEndpoint("net1", "ep1", epOptions)
  176. if err != nil {
  177. t.Fatalf("Failed to create an endpoint : %s", err.Error())
  178. }
  179. addr1 := sinfo.Interfaces[0].Address
  180. if addr1 == nil {
  181. t.Fatalf("No Ipv4 address assigned to the endpoint: ep1")
  182. }
  183. sinfo, err = d.CreateEndpoint("net1", "ep2", nil)
  184. if err != nil {
  185. t.Fatalf("Failed to create an endpoint : %s", err.Error())
  186. }
  187. addr2 := sinfo.Interfaces[0].Address
  188. if addr2 == nil {
  189. t.Fatalf("No Ipv4 address assigned to the endpoint: ep2")
  190. }
  191. ce := []string{"ep1"}
  192. cConfig := &ContainerConfiguration{ChildEndpoints: ce}
  193. genericOption = make(map[string]interface{})
  194. genericOption[options.GenericData] = cConfig
  195. _, err = d.Join("net1", "ep2", "", genericOption)
  196. if err != nil {
  197. t.Fatalf("Failed to link ep1 and ep2")
  198. }
  199. out, err := iptables.Raw("-L", DockerChain)
  200. for _, pm := range exposedPorts {
  201. regex := fmt.Sprintf("%s dpt:%d", pm.Proto.String(), pm.Port)
  202. re := regexp.MustCompile(regex)
  203. matches := re.FindAllString(string(out[:]), -1)
  204. if len(matches) != 1 {
  205. t.Fatalf("IP Tables programming failed %s", string(out[:]))
  206. }
  207. regex = fmt.Sprintf("%s spt:%d", pm.Proto.String(), pm.Port)
  208. matched, _ := regexp.MatchString(regex, string(out[:]))
  209. if !matched {
  210. t.Fatalf("IP Tables programming failed %s", string(out[:]))
  211. }
  212. }
  213. err = d.Leave("net1", "ep2", genericOption)
  214. if err != nil {
  215. t.Fatalf("Failed to unlink ep1 and ep2")
  216. }
  217. out, err = iptables.Raw("-L", DockerChain)
  218. for _, pm := range exposedPorts {
  219. regex := fmt.Sprintf("%s dpt:%d", pm.Proto.String(), pm.Port)
  220. re := regexp.MustCompile(regex)
  221. matches := re.FindAllString(string(out[:]), -1)
  222. if len(matches) != 0 {
  223. t.Fatalf("Leave should have deleted relevant IPTables rules %s", string(out[:]))
  224. }
  225. regex = fmt.Sprintf("%s spt:%d", pm.Proto.String(), pm.Port)
  226. matched, _ := regexp.MatchString(regex, string(out[:]))
  227. if matched {
  228. t.Fatalf("Leave should have deleted relevant IPTables rules %s", string(out[:]))
  229. }
  230. }
  231. // Error condition test with an invalid endpoint-id "ep4"
  232. ce = []string{"ep1", "ep4"}
  233. cConfig = &ContainerConfiguration{ChildEndpoints: ce}
  234. genericOption = make(map[string]interface{})
  235. genericOption[options.GenericData] = cConfig
  236. _, err = d.Join("net1", "ep2", "", genericOption)
  237. if err != nil {
  238. out, err = iptables.Raw("-L", DockerChain)
  239. for _, pm := range exposedPorts {
  240. regex := fmt.Sprintf("%s dpt:%d", pm.Proto.String(), pm.Port)
  241. re := regexp.MustCompile(regex)
  242. matches := re.FindAllString(string(out[:]), -1)
  243. if len(matches) != 0 {
  244. t.Fatalf("Error handling should rollback relevant IPTables rules %s", string(out[:]))
  245. }
  246. regex = fmt.Sprintf("%s spt:%d", pm.Proto.String(), pm.Port)
  247. matched, _ := regexp.MatchString(regex, string(out[:]))
  248. if matched {
  249. t.Fatalf("Error handling should rollback relevant IPTables rules %s", string(out[:]))
  250. }
  251. }
  252. } else {
  253. t.Fatalf("Expected Join to fail given link conditions are not satisfied")
  254. }
  255. }
  256. func TestValidateConfig(t *testing.T) {
  257. // Test mtu
  258. c := Configuration{Mtu: -2}
  259. err := c.Validate()
  260. if err == nil {
  261. t.Fatalf("Failed to detect invalid MTU number")
  262. }
  263. c.Mtu = 9000
  264. err = c.Validate()
  265. if err != nil {
  266. t.Fatalf("unexpected validation error on MTU number")
  267. }
  268. // Bridge network
  269. _, network, _ := net.ParseCIDR("172.28.0.0/16")
  270. // Test FixedCIDR
  271. _, containerSubnet, _ := net.ParseCIDR("172.27.0.0/16")
  272. c = Configuration{
  273. AddressIPv4: network,
  274. FixedCIDR: containerSubnet,
  275. }
  276. err = c.Validate()
  277. if err == nil {
  278. t.Fatalf("Failed to detect invalid FixedCIDR network")
  279. }
  280. _, containerSubnet, _ = net.ParseCIDR("172.28.0.0/16")
  281. c.FixedCIDR = containerSubnet
  282. err = c.Validate()
  283. if err != nil {
  284. t.Fatalf("Unexpected validation error on FixedCIDR network")
  285. }
  286. _, containerSubnet, _ = net.ParseCIDR("172.28.0.0/15")
  287. c.FixedCIDR = containerSubnet
  288. err = c.Validate()
  289. if err == nil {
  290. t.Fatalf("Failed to detect invalid FixedCIDR network")
  291. }
  292. _, containerSubnet, _ = net.ParseCIDR("172.28.0.0/17")
  293. c.FixedCIDR = containerSubnet
  294. err = c.Validate()
  295. if err != nil {
  296. t.Fatalf("Unexpected validation error on FixedCIDR network")
  297. }
  298. // Test v4 gw
  299. c.DefaultGatewayIPv4 = net.ParseIP("172.27.30.234")
  300. err = c.Validate()
  301. if err == nil {
  302. t.Fatalf("Failed to detect invalid default gateway")
  303. }
  304. c.DefaultGatewayIPv4 = net.ParseIP("172.28.30.234")
  305. err = c.Validate()
  306. if err != nil {
  307. t.Fatalf("Unexpected validation error on default gateway")
  308. }
  309. // Test v6 gw
  310. _, containerSubnet, _ = net.ParseCIDR("2001:1234:ae:b004::/64")
  311. c = Configuration{
  312. EnableIPv6: true,
  313. FixedCIDRv6: containerSubnet,
  314. DefaultGatewayIPv6: net.ParseIP("2001:1234:ac:b004::bad:a55"),
  315. }
  316. err = c.Validate()
  317. if err == nil {
  318. t.Fatalf("Failed to detect invalid v6 default gateway")
  319. }
  320. c.DefaultGatewayIPv6 = net.ParseIP("2001:1234:ae:b004::bad:a55")
  321. err = c.Validate()
  322. if err != nil {
  323. t.Fatalf("Unexpected validation error on v6 default gateway")
  324. }
  325. c.FixedCIDRv6 = nil
  326. err = c.Validate()
  327. if err == nil {
  328. t.Fatalf("Failed to detect invalid v6 default gateway")
  329. }
  330. }
  331. func TestSetDefaultGw(t *testing.T) {
  332. defer netutils.SetupTestNetNS(t)()
  333. _, d := New()
  334. _, subnetv6, _ := net.ParseCIDR("2001:db8:ea9:9abc:b0c4::/80")
  335. gw4 := bridgeNetworks[0].IP.To4()
  336. gw4[3] = 254
  337. gw6 := net.ParseIP("2001:db8:ea9:9abc:b0c4::254")
  338. config := &Configuration{
  339. BridgeName: DefaultBridgeName,
  340. EnableIPv6: true,
  341. FixedCIDRv6: subnetv6,
  342. DefaultGatewayIPv4: gw4,
  343. DefaultGatewayIPv6: gw6,
  344. }
  345. genericOption := make(map[string]interface{})
  346. genericOption[options.GenericData] = config
  347. if err := d.Config(genericOption); err != nil {
  348. t.Fatalf("Failed to setup driver config: %v", err)
  349. }
  350. err := d.CreateNetwork("dummy", nil)
  351. if err != nil {
  352. t.Fatalf("Failed to create bridge: %v", err)
  353. }
  354. sinfo, err := d.CreateEndpoint("dummy", "ep", nil)
  355. if err != nil {
  356. t.Fatalf("Failed to create endpoint: %v", err)
  357. }
  358. if !gw4.Equal(sinfo.Gateway) {
  359. t.Fatalf("Failed to configure default gateway. Expected %v. Found %v", gw4, sinfo.Gateway)
  360. }
  361. if !gw6.Equal(sinfo.GatewayIPv6) {
  362. t.Fatalf("Failed to configure default gateway. Expected %v. Found %v", gw6, sinfo.GatewayIPv6)
  363. }
  364. }