handle_test.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. package netlink
  2. import (
  3. "crypto/rand"
  4. "encoding/hex"
  5. "fmt"
  6. "io"
  7. "net"
  8. "sync"
  9. "sync/atomic"
  10. "testing"
  11. "github.com/vishvananda/netlink/nl"
  12. "github.com/vishvananda/netns"
  13. )
  14. func TestHandleCreateDelete(t *testing.T) {
  15. h, err := NewHandle()
  16. if err != nil {
  17. t.Fatal(err)
  18. }
  19. for _, f := range nl.SupportedNlFamilies {
  20. sh, ok := h.sockets[f]
  21. if !ok {
  22. t.Fatalf("Handle socket(s) for family %d was not created", f)
  23. }
  24. if sh.Socket == nil {
  25. t.Fatalf("Socket for family %d was not created", f)
  26. }
  27. }
  28. h.Delete()
  29. if h.sockets != nil {
  30. t.Fatalf("Handle socket(s) were not destroyed")
  31. }
  32. }
  33. func TestHandleCreateNetns(t *testing.T) {
  34. id := make([]byte, 4)
  35. if _, err := io.ReadFull(rand.Reader, id); err != nil {
  36. t.Fatal(err)
  37. }
  38. ifName := "dummy-" + hex.EncodeToString(id)
  39. // Create an handle on the current netns
  40. curNs, err := netns.Get()
  41. if err != nil {
  42. t.Fatal(err)
  43. }
  44. defer curNs.Close()
  45. ch, err := NewHandleAt(curNs)
  46. if err != nil {
  47. t.Fatal(err)
  48. }
  49. defer ch.Delete()
  50. // Create an handle on a custom netns
  51. newNs, err := netns.New()
  52. if err != nil {
  53. t.Fatal(err)
  54. }
  55. defer newNs.Close()
  56. nh, err := NewHandleAt(newNs)
  57. if err != nil {
  58. t.Fatal(err)
  59. }
  60. defer nh.Delete()
  61. // Create an interface using the current handle
  62. err = ch.LinkAdd(&Dummy{LinkAttrs{Name: ifName}})
  63. if err != nil {
  64. t.Fatal(err)
  65. }
  66. l, err := ch.LinkByName(ifName)
  67. if err != nil {
  68. t.Fatal(err)
  69. }
  70. if l.Type() != "dummy" {
  71. t.Fatalf("Unexpected link type: %s", l.Type())
  72. }
  73. // Verify the new handle cannot find the interface
  74. ll, err := nh.LinkByName(ifName)
  75. if err == nil {
  76. t.Fatalf("Unexpected link found on netns %s: %v", newNs, ll)
  77. }
  78. // Move the interface to the new netns
  79. err = ch.LinkSetNsFd(l, int(newNs))
  80. if err != nil {
  81. t.Fatal(err)
  82. }
  83. // Verify new netns handle can find the interface while current cannot
  84. ll, err = nh.LinkByName(ifName)
  85. if err != nil {
  86. t.Fatal(err)
  87. }
  88. if ll.Type() != "dummy" {
  89. t.Fatalf("Unexpected link type: %s", ll.Type())
  90. }
  91. ll, err = ch.LinkByName(ifName)
  92. if err == nil {
  93. t.Fatalf("Unexpected link found on netns %s: %v", curNs, ll)
  94. }
  95. }
  96. var (
  97. iter = 10
  98. numThread = uint32(4)
  99. prefix = "iface"
  100. handle1 *Handle
  101. handle2 *Handle
  102. ns1 netns.NsHandle
  103. ns2 netns.NsHandle
  104. done uint32
  105. initError error
  106. once sync.Once
  107. )
  108. func getXfrmState(thread int) *XfrmState {
  109. return &XfrmState{
  110. Src: net.IPv4(byte(192), byte(168), 1, byte(1+thread)),
  111. Dst: net.IPv4(byte(192), byte(168), 2, byte(1+thread)),
  112. Proto: XFRM_PROTO_AH,
  113. Mode: XFRM_MODE_TUNNEL,
  114. Spi: thread,
  115. Auth: &XfrmStateAlgo{
  116. Name: "hmac(sha256)",
  117. Key: []byte("abcdefghijklmnopqrstuvwzyzABCDEF"),
  118. },
  119. }
  120. }
  121. func getXfrmPolicy(thread int) *XfrmPolicy {
  122. return &XfrmPolicy{
  123. Src: &net.IPNet{IP: net.IPv4(byte(10), byte(10), byte(thread), 0), Mask: []byte{255, 255, 255, 0}},
  124. Dst: &net.IPNet{IP: net.IPv4(byte(10), byte(10), byte(thread), 0), Mask: []byte{255, 255, 255, 0}},
  125. Proto: 17,
  126. DstPort: 1234,
  127. SrcPort: 5678,
  128. Dir: XFRM_DIR_OUT,
  129. Tmpls: []XfrmPolicyTmpl{
  130. {
  131. Src: net.IPv4(byte(192), byte(168), 1, byte(thread)),
  132. Dst: net.IPv4(byte(192), byte(168), 2, byte(thread)),
  133. Proto: XFRM_PROTO_ESP,
  134. Mode: XFRM_MODE_TUNNEL,
  135. },
  136. },
  137. }
  138. }
  139. func initParallel() {
  140. ns1, initError = netns.New()
  141. if initError != nil {
  142. return
  143. }
  144. handle1, initError = NewHandleAt(ns1)
  145. if initError != nil {
  146. return
  147. }
  148. ns2, initError = netns.New()
  149. if initError != nil {
  150. return
  151. }
  152. handle2, initError = NewHandleAt(ns2)
  153. if initError != nil {
  154. return
  155. }
  156. }
  157. func parallelDone() {
  158. atomic.AddUint32(&done, 1)
  159. if done == numThread {
  160. if ns1.IsOpen() {
  161. ns1.Close()
  162. }
  163. if ns2.IsOpen() {
  164. ns2.Close()
  165. }
  166. if handle1 != nil {
  167. handle1.Delete()
  168. }
  169. if handle2 != nil {
  170. handle2.Delete()
  171. }
  172. }
  173. }
  174. // Do few route and xfrm operation on the two handles in parallel
  175. func runParallelTests(t *testing.T, thread int) {
  176. defer parallelDone()
  177. t.Parallel()
  178. once.Do(initParallel)
  179. if initError != nil {
  180. t.Fatal(initError)
  181. }
  182. state := getXfrmState(thread)
  183. policy := getXfrmPolicy(thread)
  184. for i := 0; i < iter; i++ {
  185. ifName := fmt.Sprintf("%s_%d_%d", prefix, thread, i)
  186. link := &Dummy{LinkAttrs{Name: ifName}}
  187. err := handle1.LinkAdd(link)
  188. if err != nil {
  189. t.Fatal(err)
  190. }
  191. l, err := handle1.LinkByName(ifName)
  192. if err != nil {
  193. t.Fatal(err)
  194. }
  195. err = handle1.LinkSetUp(l)
  196. if err != nil {
  197. t.Fatal(err)
  198. }
  199. handle1.LinkSetNsFd(l, int(ns2))
  200. if err != nil {
  201. t.Fatal(err)
  202. }
  203. err = handle1.XfrmStateAdd(state)
  204. if err != nil {
  205. t.Fatal(err)
  206. }
  207. err = handle1.XfrmPolicyAdd(policy)
  208. if err != nil {
  209. t.Fatal(err)
  210. }
  211. err = handle2.LinkSetDown(l)
  212. if err != nil {
  213. t.Fatal(err)
  214. }
  215. err = handle2.XfrmStateAdd(state)
  216. if err != nil {
  217. t.Fatal(err)
  218. }
  219. err = handle2.XfrmPolicyAdd(policy)
  220. if err != nil {
  221. t.Fatal(err)
  222. }
  223. _, err = handle2.LinkByName(ifName)
  224. if err != nil {
  225. t.Fatal(err)
  226. }
  227. handle2.LinkSetNsFd(l, int(ns1))
  228. if err != nil {
  229. t.Fatal(err)
  230. }
  231. err = handle1.LinkSetUp(l)
  232. if err != nil {
  233. t.Fatal(err)
  234. }
  235. l, err = handle1.LinkByName(ifName)
  236. if err != nil {
  237. t.Fatal(err)
  238. }
  239. err = handle1.XfrmPolicyDel(policy)
  240. if err != nil {
  241. t.Fatal(err)
  242. }
  243. err = handle2.XfrmPolicyDel(policy)
  244. if err != nil {
  245. t.Fatal(err)
  246. }
  247. err = handle1.XfrmStateDel(state)
  248. if err != nil {
  249. t.Fatal(err)
  250. }
  251. err = handle2.XfrmStateDel(state)
  252. if err != nil {
  253. t.Fatal(err)
  254. }
  255. }
  256. }
  257. func TestHandleParallel1(t *testing.T) {
  258. runParallelTests(t, 1)
  259. }
  260. func TestHandleParallel2(t *testing.T) {
  261. runParallelTests(t, 2)
  262. }
  263. func TestHandleParallel3(t *testing.T) {
  264. runParallelTests(t, 3)
  265. }
  266. func TestHandleParallel4(t *testing.T) {
  267. runParallelTests(t, 4)
  268. }