bridge_test.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  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 getPortMapping() []netutils.PortBinding {
  142. return []netutils.PortBinding{
  143. netutils.PortBinding{Proto: netutils.TCP, Port: uint16(230), HostPort: uint16(23000)},
  144. netutils.PortBinding{Proto: netutils.UDP, Port: uint16(200), HostPort: uint16(22000)},
  145. netutils.PortBinding{Proto: netutils.TCP, Port: uint16(120), HostPort: uint16(12000)},
  146. }
  147. }
  148. func TestLinkContainers(t *testing.T) {
  149. defer netutils.SetupTestNetNS(t)()
  150. _, d := New()
  151. config := &Configuration{
  152. BridgeName: DefaultBridgeName,
  153. EnableIPTables: true,
  154. EnableICC: false,
  155. }
  156. genericOption := make(map[string]interface{})
  157. genericOption[options.GenericData] = config
  158. if err := d.Config(genericOption); err != nil {
  159. t.Fatalf("Failed to setup driver config: %v", err)
  160. }
  161. err := d.CreateNetwork("net1", nil)
  162. if err != nil {
  163. t.Fatalf("Failed to create bridge: %v", err)
  164. }
  165. portMappings := getPortMapping()
  166. epOptions := make(map[string]interface{})
  167. epOptions[options.PortMap] = portMappings
  168. sinfo, err := d.CreateEndpoint("net1", "ep1", epOptions)
  169. if err != nil {
  170. t.Fatalf("Failed to create an endpoint : %s", err.Error())
  171. }
  172. addr1 := sinfo.Interfaces[0].Address
  173. if addr1 == nil {
  174. t.Fatalf("No Ipv4 address assigned to the endpoint: ep1")
  175. }
  176. sinfo, err = d.CreateEndpoint("net1", "ep2", nil)
  177. if err != nil {
  178. t.Fatalf("Failed to create an endpoint : %s", err.Error())
  179. }
  180. addr2 := sinfo.Interfaces[0].Address
  181. if addr2 == nil {
  182. t.Fatalf("No Ipv4 address assigned to the endpoint: ep2")
  183. }
  184. ce := []string{"ep1"}
  185. cConfig := &ContainerConfiguration{ChildEndpoints: ce}
  186. genericOption = make(map[string]interface{})
  187. genericOption[options.GenericData] = cConfig
  188. _, err = d.Join("net1", "ep2", "", genericOption)
  189. if err != nil {
  190. t.Fatalf("Failed to link ep1 and ep2")
  191. }
  192. out, err := iptables.Raw("-L", "DOCKER")
  193. for _, pm := range portMappings {
  194. regex := fmt.Sprintf("%s dpt:%d", pm.Proto.String(), pm.Port)
  195. re := regexp.MustCompile(regex)
  196. matches := re.FindAllString(string(out[:]), -1)
  197. // There will be 2 matches : Port-Mapping and Linking table rules
  198. if len(matches) < 2 {
  199. t.Fatalf("IP Tables programming failed %s", string(out[:]))
  200. }
  201. regex = fmt.Sprintf("%s spt:%d", pm.Proto.String(), pm.Port)
  202. matched, _ := regexp.MatchString(regex, string(out[:]))
  203. if !matched {
  204. t.Fatalf("IP Tables programming failed %s", string(out[:]))
  205. }
  206. }
  207. err = d.Leave("net1", "ep2", genericOption)
  208. if err != nil {
  209. t.Fatalf("Failed to unlink ep1 and ep2")
  210. }
  211. out, err = iptables.Raw("-L", "DOCKER")
  212. for _, pm := range portMappings {
  213. regex := fmt.Sprintf("%s dpt:%d", pm.Proto.String(), pm.Port)
  214. re := regexp.MustCompile(regex)
  215. matches := re.FindAllString(string(out[:]), -1)
  216. // There will be 1 match : Port-Mapping
  217. if len(matches) > 1 {
  218. t.Fatalf("Leave should have deleted relevant IPTables rules %s", string(out[:]))
  219. }
  220. regex = fmt.Sprintf("%s spt:%d", pm.Proto.String(), pm.Port)
  221. matched, _ := regexp.MatchString(regex, string(out[:]))
  222. if matched {
  223. t.Fatalf("Leave should have deleted relevant IPTables rules %s", string(out[:]))
  224. }
  225. }
  226. // Error condition test with an invalid endpoint-id "ep4"
  227. ce = []string{"ep1", "ep4"}
  228. cConfig = &ContainerConfiguration{ChildEndpoints: ce}
  229. genericOption = make(map[string]interface{})
  230. genericOption[options.GenericData] = cConfig
  231. _, err = d.Join("net1", "ep2", "", genericOption)
  232. if err != nil {
  233. out, err = iptables.Raw("-L", "DOCKER")
  234. for _, pm := range portMappings {
  235. regex := fmt.Sprintf("%s dpt:%d", pm.Proto.String(), pm.Port)
  236. re := regexp.MustCompile(regex)
  237. matches := re.FindAllString(string(out[:]), -1)
  238. // There must be 1 match : Port-Mapping
  239. if len(matches) > 1 {
  240. t.Fatalf("Error handling should rollback relevant IPTables rules %s", string(out[:]))
  241. }
  242. regex = fmt.Sprintf("%s spt:%d", pm.Proto.String(), pm.Port)
  243. matched, _ := regexp.MatchString(regex, string(out[:]))
  244. if matched {
  245. t.Fatalf("Error handling should rollback relevant IPTables rules %s", string(out[:]))
  246. }
  247. }
  248. }
  249. }
  250. func TestValidateConfig(t *testing.T) {
  251. // Test mtu
  252. c := Configuration{Mtu: -2}
  253. err := c.Validate()
  254. if err == nil {
  255. t.Fatalf("Failed to detect invalid MTU number")
  256. }
  257. c.Mtu = 9000
  258. err = c.Validate()
  259. if err != nil {
  260. t.Fatalf("unexpected validation error on MTU number")
  261. }
  262. // Bridge network
  263. _, network, _ := net.ParseCIDR("172.28.0.0/16")
  264. // Test FixedCIDR
  265. _, containerSubnet, _ := net.ParseCIDR("172.27.0.0/16")
  266. c = Configuration{
  267. AddressIPv4: network,
  268. FixedCIDR: containerSubnet,
  269. }
  270. err = c.Validate()
  271. if err == nil {
  272. t.Fatalf("Failed to detect invalid FixedCIDR network")
  273. }
  274. _, containerSubnet, _ = net.ParseCIDR("172.28.0.0/16")
  275. c.FixedCIDR = containerSubnet
  276. err = c.Validate()
  277. if err != nil {
  278. t.Fatalf("Unexpected validation error on FixedCIDR network")
  279. }
  280. _, containerSubnet, _ = net.ParseCIDR("172.28.0.0/15")
  281. c.FixedCIDR = containerSubnet
  282. err = c.Validate()
  283. if err == nil {
  284. t.Fatalf("Failed to detect invalid FixedCIDR network")
  285. }
  286. _, containerSubnet, _ = net.ParseCIDR("172.28.0.0/17")
  287. c.FixedCIDR = containerSubnet
  288. err = c.Validate()
  289. if err != nil {
  290. t.Fatalf("Unexpected validation error on FixedCIDR network")
  291. }
  292. // Test v4 gw
  293. c.DefaultGatewayIPv4 = net.ParseIP("172.27.30.234")
  294. err = c.Validate()
  295. if err == nil {
  296. t.Fatalf("Failed to detect invalid default gateway")
  297. }
  298. c.DefaultGatewayIPv4 = net.ParseIP("172.28.30.234")
  299. err = c.Validate()
  300. if err != nil {
  301. t.Fatalf("Unexpected validation error on default gateway")
  302. }
  303. // Test v6 gw
  304. _, containerSubnet, _ = net.ParseCIDR("2001:1234:ae:b004::/64")
  305. c = Configuration{
  306. EnableIPv6: true,
  307. FixedCIDRv6: containerSubnet,
  308. DefaultGatewayIPv6: net.ParseIP("2001:1234:ac:b004::bad:a55"),
  309. }
  310. err = c.Validate()
  311. if err == nil {
  312. t.Fatalf("Failed to detect invalid v6 default gateway")
  313. }
  314. c.DefaultGatewayIPv6 = net.ParseIP("2001:1234:ae:b004::bad:a55")
  315. err = c.Validate()
  316. if err != nil {
  317. t.Fatalf("Unexpected validation error on v6 default gateway")
  318. }
  319. c.FixedCIDRv6 = nil
  320. err = c.Validate()
  321. if err == nil {
  322. t.Fatalf("Failed to detect invalid v6 default gateway")
  323. }
  324. }
  325. func TestSetDefaultGw(t *testing.T) {
  326. defer netutils.SetupTestNetNS(t)()
  327. _, d := New()
  328. _, subnetv6, _ := net.ParseCIDR("2001:db8:ea9:9abc:b0c4::/80")
  329. gw4 := bridgeNetworks[0].IP.To4()
  330. gw4[3] = 254
  331. gw6 := net.ParseIP("2001:db8:ea9:9abc:b0c4::254")
  332. config := &Configuration{
  333. BridgeName: DefaultBridgeName,
  334. EnableIPv6: true,
  335. FixedCIDRv6: subnetv6,
  336. DefaultGatewayIPv4: gw4,
  337. DefaultGatewayIPv6: gw6,
  338. }
  339. genericOption := make(map[string]interface{})
  340. genericOption[options.GenericData] = config
  341. if err := d.Config(genericOption); err != nil {
  342. t.Fatalf("Failed to setup driver config: %v", err)
  343. }
  344. err := d.CreateNetwork("dummy", nil)
  345. if err != nil {
  346. t.Fatalf("Failed to create bridge: %v", err)
  347. }
  348. sinfo, err := d.CreateEndpoint("dummy", "ep", nil)
  349. if err != nil {
  350. t.Fatalf("Failed to create endpoint: %v", err)
  351. }
  352. if !gw4.Equal(sinfo.Gateway) {
  353. t.Fatalf("Failed to configure default gateway. Expected %v. Found %v", gw4, sinfo.Gateway)
  354. }
  355. if !gw6.Equal(sinfo.GatewayIPv6) {
  356. t.Fatalf("Failed to configure default gateway. Expected %v. Found %v", gw6, sinfo.GatewayIPv6)
  357. }
  358. }