tun_test.go 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. package nebula
  2. import (
  3. "fmt"
  4. "net"
  5. "testing"
  6. "github.com/slackhq/nebula/config"
  7. "github.com/slackhq/nebula/util"
  8. "github.com/stretchr/testify/assert"
  9. )
  10. func Test_parseRoutes(t *testing.T) {
  11. l := util.NewTestLogger()
  12. c := config.NewC(l)
  13. _, n, _ := net.ParseCIDR("10.0.0.0/24")
  14. // test no routes config
  15. routes, err := parseRoutes(c, n)
  16. assert.Nil(t, err)
  17. assert.Len(t, routes, 0)
  18. // not an array
  19. c.Settings["tun"] = map[interface{}]interface{}{"routes": "hi"}
  20. routes, err = parseRoutes(c, n)
  21. assert.Nil(t, routes)
  22. assert.EqualError(t, err, "tun.routes is not an array")
  23. // no routes
  24. c.Settings["tun"] = map[interface{}]interface{}{"routes": []interface{}{}}
  25. routes, err = parseRoutes(c, n)
  26. assert.Nil(t, err)
  27. assert.Len(t, routes, 0)
  28. // weird route
  29. c.Settings["tun"] = map[interface{}]interface{}{"routes": []interface{}{"asdf"}}
  30. routes, err = parseRoutes(c, n)
  31. assert.Nil(t, routes)
  32. assert.EqualError(t, err, "entry 1 in tun.routes is invalid")
  33. // no mtu
  34. c.Settings["tun"] = map[interface{}]interface{}{"routes": []interface{}{map[interface{}]interface{}{}}}
  35. routes, err = parseRoutes(c, n)
  36. assert.Nil(t, routes)
  37. assert.EqualError(t, err, "entry 1.mtu in tun.routes is not present")
  38. // bad mtu
  39. c.Settings["tun"] = map[interface{}]interface{}{"routes": []interface{}{map[interface{}]interface{}{"mtu": "nope"}}}
  40. routes, err = parseRoutes(c, n)
  41. assert.Nil(t, routes)
  42. assert.EqualError(t, err, "entry 1.mtu in tun.routes is not an integer: strconv.Atoi: parsing \"nope\": invalid syntax")
  43. // low mtu
  44. c.Settings["tun"] = map[interface{}]interface{}{"routes": []interface{}{map[interface{}]interface{}{"mtu": "499"}}}
  45. routes, err = parseRoutes(c, n)
  46. assert.Nil(t, routes)
  47. assert.EqualError(t, err, "entry 1.mtu in tun.routes is below 500: 499")
  48. // missing route
  49. c.Settings["tun"] = map[interface{}]interface{}{"routes": []interface{}{map[interface{}]interface{}{"mtu": "500"}}}
  50. routes, err = parseRoutes(c, n)
  51. assert.Nil(t, routes)
  52. assert.EqualError(t, err, "entry 1.route in tun.routes is not present")
  53. // unparsable route
  54. c.Settings["tun"] = map[interface{}]interface{}{"routes": []interface{}{map[interface{}]interface{}{"mtu": "500", "route": "nope"}}}
  55. routes, err = parseRoutes(c, n)
  56. assert.Nil(t, routes)
  57. assert.EqualError(t, err, "entry 1.route in tun.routes failed to parse: invalid CIDR address: nope")
  58. // below network range
  59. c.Settings["tun"] = map[interface{}]interface{}{"routes": []interface{}{map[interface{}]interface{}{"mtu": "500", "route": "1.0.0.0/8"}}}
  60. routes, err = parseRoutes(c, n)
  61. assert.Nil(t, routes)
  62. assert.EqualError(t, err, "entry 1.route in tun.routes is not contained within the network attached to the certificate; route: 1.0.0.0/8, network: 10.0.0.0/24")
  63. // above network range
  64. c.Settings["tun"] = map[interface{}]interface{}{"routes": []interface{}{map[interface{}]interface{}{"mtu": "500", "route": "10.0.1.0/24"}}}
  65. routes, err = parseRoutes(c, n)
  66. assert.Nil(t, routes)
  67. assert.EqualError(t, err, "entry 1.route in tun.routes is not contained within the network attached to the certificate; route: 10.0.1.0/24, network: 10.0.0.0/24")
  68. // happy case
  69. c.Settings["tun"] = map[interface{}]interface{}{"routes": []interface{}{
  70. map[interface{}]interface{}{"mtu": "9000", "route": "10.0.0.0/29"},
  71. map[interface{}]interface{}{"mtu": "8000", "route": "10.0.0.1/32"},
  72. }}
  73. routes, err = parseRoutes(c, n)
  74. assert.Nil(t, err)
  75. assert.Len(t, routes, 2)
  76. tested := 0
  77. for _, r := range routes {
  78. if r.mtu == 8000 {
  79. assert.Equal(t, "10.0.0.1/32", r.route.String())
  80. tested++
  81. } else {
  82. assert.Equal(t, 9000, r.mtu)
  83. assert.Equal(t, "10.0.0.0/29", r.route.String())
  84. tested++
  85. }
  86. }
  87. if tested != 2 {
  88. t.Fatal("Did not see both routes")
  89. }
  90. }
  91. func Test_parseUnsafeRoutes(t *testing.T) {
  92. l := util.NewTestLogger()
  93. c := config.NewC(l)
  94. _, n, _ := net.ParseCIDR("10.0.0.0/24")
  95. // test no routes config
  96. routes, err := parseUnsafeRoutes(c, n)
  97. assert.Nil(t, err)
  98. assert.Len(t, routes, 0)
  99. // not an array
  100. c.Settings["tun"] = map[interface{}]interface{}{"unsafe_routes": "hi"}
  101. routes, err = parseUnsafeRoutes(c, n)
  102. assert.Nil(t, routes)
  103. assert.EqualError(t, err, "tun.unsafe_routes is not an array")
  104. // no routes
  105. c.Settings["tun"] = map[interface{}]interface{}{"unsafe_routes": []interface{}{}}
  106. routes, err = parseUnsafeRoutes(c, n)
  107. assert.Nil(t, err)
  108. assert.Len(t, routes, 0)
  109. // weird route
  110. c.Settings["tun"] = map[interface{}]interface{}{"unsafe_routes": []interface{}{"asdf"}}
  111. routes, err = parseUnsafeRoutes(c, n)
  112. assert.Nil(t, routes)
  113. assert.EqualError(t, err, "entry 1 in tun.unsafe_routes is invalid")
  114. // no via
  115. c.Settings["tun"] = map[interface{}]interface{}{"unsafe_routes": []interface{}{map[interface{}]interface{}{}}}
  116. routes, err = parseUnsafeRoutes(c, n)
  117. assert.Nil(t, routes)
  118. assert.EqualError(t, err, "entry 1.via in tun.unsafe_routes is not present")
  119. // invalid via
  120. for _, invalidValue := range []interface{}{
  121. 127, false, nil, 1.0, []string{"1", "2"},
  122. } {
  123. c.Settings["tun"] = map[interface{}]interface{}{"unsafe_routes": []interface{}{map[interface{}]interface{}{"via": invalidValue}}}
  124. routes, err = parseUnsafeRoutes(c, n)
  125. assert.Nil(t, routes)
  126. assert.EqualError(t, err, fmt.Sprintf("entry 1.via in tun.unsafe_routes is not a string: found %T", invalidValue))
  127. }
  128. // unparsable via
  129. c.Settings["tun"] = map[interface{}]interface{}{"unsafe_routes": []interface{}{map[interface{}]interface{}{"mtu": "500", "via": "nope"}}}
  130. routes, err = parseUnsafeRoutes(c, n)
  131. assert.Nil(t, routes)
  132. assert.EqualError(t, err, "entry 1.via in tun.unsafe_routes failed to parse address: nope")
  133. // missing route
  134. c.Settings["tun"] = map[interface{}]interface{}{"unsafe_routes": []interface{}{map[interface{}]interface{}{"via": "127.0.0.1", "mtu": "500"}}}
  135. routes, err = parseUnsafeRoutes(c, n)
  136. assert.Nil(t, routes)
  137. assert.EqualError(t, err, "entry 1.route in tun.unsafe_routes is not present")
  138. // unparsable route
  139. c.Settings["tun"] = map[interface{}]interface{}{"unsafe_routes": []interface{}{map[interface{}]interface{}{"via": "127.0.0.1", "mtu": "500", "route": "nope"}}}
  140. routes, err = parseUnsafeRoutes(c, n)
  141. assert.Nil(t, routes)
  142. assert.EqualError(t, err, "entry 1.route in tun.unsafe_routes failed to parse: invalid CIDR address: nope")
  143. // within network range
  144. c.Settings["tun"] = map[interface{}]interface{}{"unsafe_routes": []interface{}{map[interface{}]interface{}{"via": "127.0.0.1", "route": "10.0.0.0/24"}}}
  145. routes, err = parseUnsafeRoutes(c, n)
  146. assert.Nil(t, routes)
  147. assert.EqualError(t, err, "entry 1.route in tun.unsafe_routes is contained within the network attached to the certificate; route: 10.0.0.0/24, network: 10.0.0.0/24")
  148. // below network range
  149. c.Settings["tun"] = map[interface{}]interface{}{"unsafe_routes": []interface{}{map[interface{}]interface{}{"via": "127.0.0.1", "route": "1.0.0.0/8"}}}
  150. routes, err = parseUnsafeRoutes(c, n)
  151. assert.Len(t, routes, 1)
  152. assert.Nil(t, err)
  153. // above network range
  154. c.Settings["tun"] = map[interface{}]interface{}{"unsafe_routes": []interface{}{map[interface{}]interface{}{"via": "127.0.0.1", "route": "10.0.1.0/24"}}}
  155. routes, err = parseUnsafeRoutes(c, n)
  156. assert.Len(t, routes, 1)
  157. assert.Nil(t, err)
  158. // no mtu
  159. c.Settings["tun"] = map[interface{}]interface{}{"unsafe_routes": []interface{}{map[interface{}]interface{}{"via": "127.0.0.1", "route": "1.0.0.0/8"}}}
  160. routes, err = parseUnsafeRoutes(c, n)
  161. assert.Len(t, routes, 1)
  162. assert.Equal(t, DEFAULT_MTU, routes[0].mtu)
  163. // bad mtu
  164. c.Settings["tun"] = map[interface{}]interface{}{"unsafe_routes": []interface{}{map[interface{}]interface{}{"via": "127.0.0.1", "mtu": "nope"}}}
  165. routes, err = parseUnsafeRoutes(c, n)
  166. assert.Nil(t, routes)
  167. assert.EqualError(t, err, "entry 1.mtu in tun.unsafe_routes is not an integer: strconv.Atoi: parsing \"nope\": invalid syntax")
  168. // low mtu
  169. c.Settings["tun"] = map[interface{}]interface{}{"unsafe_routes": []interface{}{map[interface{}]interface{}{"via": "127.0.0.1", "mtu": "499"}}}
  170. routes, err = parseUnsafeRoutes(c, n)
  171. assert.Nil(t, routes)
  172. assert.EqualError(t, err, "entry 1.mtu in tun.unsafe_routes is below 500: 499")
  173. // happy case
  174. c.Settings["tun"] = map[interface{}]interface{}{"unsafe_routes": []interface{}{
  175. map[interface{}]interface{}{"via": "127.0.0.1", "mtu": "9000", "route": "1.0.0.0/29"},
  176. map[interface{}]interface{}{"via": "127.0.0.1", "mtu": "8000", "route": "1.0.0.1/32"},
  177. map[interface{}]interface{}{"via": "127.0.0.1", "mtu": "1500", "metric": 1234, "route": "1.0.0.2/32"},
  178. }}
  179. routes, err = parseUnsafeRoutes(c, n)
  180. assert.Nil(t, err)
  181. assert.Len(t, routes, 3)
  182. tested := 0
  183. for _, r := range routes {
  184. if r.mtu == 8000 {
  185. assert.Equal(t, "1.0.0.1/32", r.route.String())
  186. tested++
  187. } else if r.mtu == 9000 {
  188. assert.Equal(t, 9000, r.mtu)
  189. assert.Equal(t, "1.0.0.0/29", r.route.String())
  190. tested++
  191. } else {
  192. assert.Equal(t, 1500, r.mtu)
  193. assert.Equal(t, 1234, r.metric)
  194. assert.Equal(t, "1.0.0.2/32", r.route.String())
  195. tested++
  196. }
  197. }
  198. if tested != 3 {
  199. t.Fatal("Did not see both unsafe_routes")
  200. }
  201. }