route_test.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. package netlink
  2. import (
  3. "net"
  4. "syscall"
  5. "testing"
  6. "time"
  7. "github.com/vishvananda/netns"
  8. )
  9. func TestRouteAddDel(t *testing.T) {
  10. tearDown := setUpNetlinkTest(t)
  11. defer tearDown()
  12. // get loopback interface
  13. link, err := LinkByName("lo")
  14. if err != nil {
  15. t.Fatal(err)
  16. }
  17. // bring the interface up
  18. if err := LinkSetUp(link); err != nil {
  19. t.Fatal(err)
  20. }
  21. // add a gateway route
  22. dst := &net.IPNet{
  23. IP: net.IPv4(192, 168, 0, 0),
  24. Mask: net.CIDRMask(24, 32),
  25. }
  26. ip := net.IPv4(127, 1, 1, 1)
  27. route := Route{LinkIndex: link.Attrs().Index, Dst: dst, Src: ip}
  28. if err := RouteAdd(&route); err != nil {
  29. t.Fatal(err)
  30. }
  31. routes, err := RouteList(link, FAMILY_V4)
  32. if err != nil {
  33. t.Fatal(err)
  34. }
  35. if len(routes) != 1 {
  36. t.Fatal("Route not added properly")
  37. }
  38. dstIP := net.IPv4(192, 168, 0, 42)
  39. routeToDstIP, err := RouteGet(dstIP)
  40. if err != nil {
  41. t.Fatal(err)
  42. }
  43. if len(routeToDstIP) == 0 {
  44. t.Fatal("Default route not present")
  45. }
  46. if err := RouteDel(&route); err != nil {
  47. t.Fatal(err)
  48. }
  49. routes, err = RouteList(link, FAMILY_V4)
  50. if err != nil {
  51. t.Fatal(err)
  52. }
  53. if len(routes) != 0 {
  54. t.Fatal("Route not removed properly")
  55. }
  56. }
  57. func TestRouteAddIncomplete(t *testing.T) {
  58. tearDown := setUpNetlinkTest(t)
  59. defer tearDown()
  60. // get loopback interface
  61. link, err := LinkByName("lo")
  62. if err != nil {
  63. t.Fatal(err)
  64. }
  65. // bring the interface up
  66. if err = LinkSetUp(link); err != nil {
  67. t.Fatal(err)
  68. }
  69. route := Route{LinkIndex: link.Attrs().Index}
  70. if err := RouteAdd(&route); err == nil {
  71. t.Fatal("Adding incomplete route should fail")
  72. }
  73. }
  74. func expectRouteUpdate(ch <-chan RouteUpdate, t uint16, dst net.IP) bool {
  75. for {
  76. timeout := time.After(time.Minute)
  77. select {
  78. case update := <-ch:
  79. if update.Type == t && update.Route.Dst.IP.Equal(dst) {
  80. return true
  81. }
  82. case <-timeout:
  83. return false
  84. }
  85. }
  86. }
  87. func TestRouteSubscribe(t *testing.T) {
  88. tearDown := setUpNetlinkTest(t)
  89. defer tearDown()
  90. ch := make(chan RouteUpdate)
  91. done := make(chan struct{})
  92. defer close(done)
  93. if err := RouteSubscribe(ch, done); err != nil {
  94. t.Fatal(err)
  95. }
  96. // get loopback interface
  97. link, err := LinkByName("lo")
  98. if err != nil {
  99. t.Fatal(err)
  100. }
  101. // bring the interface up
  102. if err = LinkSetUp(link); err != nil {
  103. t.Fatal(err)
  104. }
  105. // add a gateway route
  106. dst := &net.IPNet{
  107. IP: net.IPv4(192, 168, 0, 0),
  108. Mask: net.CIDRMask(24, 32),
  109. }
  110. ip := net.IPv4(127, 1, 1, 1)
  111. route := Route{LinkIndex: link.Attrs().Index, Dst: dst, Src: ip}
  112. if err := RouteAdd(&route); err != nil {
  113. t.Fatal(err)
  114. }
  115. if !expectRouteUpdate(ch, syscall.RTM_NEWROUTE, dst.IP) {
  116. t.Fatal("Add update not received as expected")
  117. }
  118. if err := RouteDel(&route); err != nil {
  119. t.Fatal(err)
  120. }
  121. if !expectRouteUpdate(ch, syscall.RTM_DELROUTE, dst.IP) {
  122. t.Fatal("Del update not received as expected")
  123. }
  124. }
  125. func TestRouteSubscribeAt(t *testing.T) {
  126. // Create an handle on a custom netns
  127. newNs, err := netns.New()
  128. if err != nil {
  129. t.Fatal(err)
  130. }
  131. defer newNs.Close()
  132. nh, err := NewHandleAt(newNs)
  133. if err != nil {
  134. t.Fatal(err)
  135. }
  136. defer nh.Delete()
  137. // Subscribe for Route events on the custom netns
  138. ch := make(chan RouteUpdate)
  139. done := make(chan struct{})
  140. defer close(done)
  141. if err := RouteSubscribeAt(newNs, ch, done); err != nil {
  142. t.Fatal(err)
  143. }
  144. // get loopback interface
  145. link, err := nh.LinkByName("lo")
  146. if err != nil {
  147. t.Fatal(err)
  148. }
  149. // bring the interface up
  150. if err = nh.LinkSetUp(link); err != nil {
  151. t.Fatal(err)
  152. }
  153. // add a gateway route
  154. dst := &net.IPNet{
  155. IP: net.IPv4(192, 169, 0, 0),
  156. Mask: net.CIDRMask(24, 32),
  157. }
  158. ip := net.IPv4(127, 100, 1, 1)
  159. route := Route{LinkIndex: link.Attrs().Index, Dst: dst, Src: ip}
  160. if err := nh.RouteAdd(&route); err != nil {
  161. t.Fatal(err)
  162. }
  163. if !expectRouteUpdate(ch, syscall.RTM_NEWROUTE, dst.IP) {
  164. t.Fatal("Add update not received as expected")
  165. }
  166. if err := nh.RouteDel(&route); err != nil {
  167. t.Fatal(err)
  168. }
  169. if !expectRouteUpdate(ch, syscall.RTM_DELROUTE, dst.IP) {
  170. t.Fatal("Del update not received as expected")
  171. }
  172. }
  173. func TestRouteExtraFields(t *testing.T) {
  174. tearDown := setUpNetlinkTest(t)
  175. defer tearDown()
  176. // get loopback interface
  177. link, err := LinkByName("lo")
  178. if err != nil {
  179. t.Fatal(err)
  180. }
  181. // bring the interface up
  182. if err = LinkSetUp(link); err != nil {
  183. t.Fatal(err)
  184. }
  185. // add a gateway route
  186. dst := &net.IPNet{
  187. IP: net.IPv4(1, 1, 1, 1),
  188. Mask: net.CIDRMask(32, 32),
  189. }
  190. src := net.IPv4(127, 3, 3, 3)
  191. route := Route{
  192. LinkIndex: link.Attrs().Index,
  193. Dst: dst,
  194. Src: src,
  195. Scope: syscall.RT_SCOPE_LINK,
  196. Priority: 13,
  197. Table: syscall.RT_TABLE_MAIN,
  198. Type: syscall.RTN_UNICAST,
  199. Tos: 14,
  200. }
  201. if err := RouteAdd(&route); err != nil {
  202. t.Fatal(err)
  203. }
  204. routes, err := RouteListFiltered(FAMILY_V4, &Route{
  205. Dst: dst,
  206. Src: src,
  207. Scope: syscall.RT_SCOPE_LINK,
  208. Table: syscall.RT_TABLE_MAIN,
  209. Type: syscall.RTN_UNICAST,
  210. Tos: 14,
  211. }, RT_FILTER_DST|RT_FILTER_SRC|RT_FILTER_SCOPE|RT_FILTER_TABLE|RT_FILTER_TYPE|RT_FILTER_TOS)
  212. if err != nil {
  213. t.Fatal(err)
  214. }
  215. if len(routes) != 1 {
  216. t.Fatal("Route not added properly")
  217. }
  218. if routes[0].Scope != syscall.RT_SCOPE_LINK {
  219. t.Fatal("Invalid Scope. Route not added properly")
  220. }
  221. if routes[0].Priority != 13 {
  222. t.Fatal("Invalid Priority. Route not added properly")
  223. }
  224. if routes[0].Table != syscall.RT_TABLE_MAIN {
  225. t.Fatal("Invalid Scope. Route not added properly")
  226. }
  227. if routes[0].Type != syscall.RTN_UNICAST {
  228. t.Fatal("Invalid Type. Route not added properly")
  229. }
  230. if routes[0].Tos != 14 {
  231. t.Fatal("Invalid Tos. Route not added properly")
  232. }
  233. }
  234. func TestRouteMultiPath(t *testing.T) {
  235. tearDown := setUpNetlinkTest(t)
  236. defer tearDown()
  237. // get loopback interface
  238. link, err := LinkByName("lo")
  239. if err != nil {
  240. t.Fatal(err)
  241. }
  242. // bring the interface up
  243. if err = LinkSetUp(link); err != nil {
  244. t.Fatal(err)
  245. }
  246. // add a gateway route
  247. dst := &net.IPNet{
  248. IP: net.IPv4(192, 168, 0, 0),
  249. Mask: net.CIDRMask(24, 32),
  250. }
  251. idx := link.Attrs().Index
  252. route := Route{Dst: dst, MultiPath: []*NexthopInfo{&NexthopInfo{LinkIndex: idx}, &NexthopInfo{LinkIndex: idx}}}
  253. if err := RouteAdd(&route); err != nil {
  254. t.Fatal(err)
  255. }
  256. routes, err := RouteList(nil, FAMILY_V4)
  257. if err != nil {
  258. t.Fatal(err)
  259. }
  260. if len(routes) != 1 {
  261. t.Fatal("MultiPath Route not added properly")
  262. }
  263. if len(routes[0].MultiPath) != 2 {
  264. t.Fatal("MultiPath Route not added properly")
  265. }
  266. }