link_test.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944
  1. package netlink
  2. import (
  3. "bytes"
  4. "net"
  5. "os"
  6. "syscall"
  7. "testing"
  8. "time"
  9. "github.com/vishvananda/netns"
  10. )
  11. const (
  12. testTxQLen int = 100
  13. defaultTxQLen int = 1000
  14. )
  15. func testLinkAddDel(t *testing.T, link Link) {
  16. links, err := LinkList()
  17. if err != nil {
  18. t.Fatal(err)
  19. }
  20. num := len(links)
  21. if err := LinkAdd(link); err != nil {
  22. t.Fatal(err)
  23. }
  24. base := link.Attrs()
  25. result, err := LinkByName(base.Name)
  26. if err != nil {
  27. t.Fatal(err)
  28. }
  29. rBase := result.Attrs()
  30. if vlan, ok := link.(*Vlan); ok {
  31. other, ok := result.(*Vlan)
  32. if !ok {
  33. t.Fatal("Result of create is not a vlan")
  34. }
  35. if vlan.VlanId != other.VlanId {
  36. t.Fatal("Link.VlanId id doesn't match")
  37. }
  38. }
  39. if veth, ok := result.(*Veth); ok {
  40. if rBase.TxQLen != base.TxQLen {
  41. t.Fatalf("qlen is %d, should be %d", rBase.TxQLen, base.TxQLen)
  42. }
  43. if rBase.MTU != base.MTU {
  44. t.Fatalf("MTU is %d, should be %d", rBase.MTU, base.MTU)
  45. }
  46. if original, ok := link.(*Veth); ok {
  47. if original.PeerName != "" {
  48. var peer *Veth
  49. other, err := LinkByName(original.PeerName)
  50. if err != nil {
  51. t.Fatalf("Peer %s not created", veth.PeerName)
  52. }
  53. if peer, ok = other.(*Veth); !ok {
  54. t.Fatalf("Peer %s is incorrect type", veth.PeerName)
  55. }
  56. if peer.TxQLen != testTxQLen {
  57. t.Fatalf("TxQLen of peer is %d, should be %d", peer.TxQLen, testTxQLen)
  58. }
  59. }
  60. }
  61. } else {
  62. // recent kernels set the parent index for veths in the response
  63. if rBase.ParentIndex == 0 && base.ParentIndex != 0 {
  64. t.Fatalf("Created link doesn't have parent %d but it should", base.ParentIndex)
  65. } else if rBase.ParentIndex != 0 && base.ParentIndex == 0 {
  66. t.Fatalf("Created link has parent %d but it shouldn't", rBase.ParentIndex)
  67. } else if rBase.ParentIndex != 0 && base.ParentIndex != 0 {
  68. if rBase.ParentIndex != base.ParentIndex {
  69. t.Fatalf("Link.ParentIndex doesn't match %d != %d", rBase.ParentIndex, base.ParentIndex)
  70. }
  71. }
  72. }
  73. if vxlan, ok := link.(*Vxlan); ok {
  74. other, ok := result.(*Vxlan)
  75. if !ok {
  76. t.Fatal("Result of create is not a vxlan")
  77. }
  78. compareVxlan(t, vxlan, other)
  79. }
  80. if ipv, ok := link.(*IPVlan); ok {
  81. other, ok := result.(*IPVlan)
  82. if !ok {
  83. t.Fatal("Result of create is not a ipvlan")
  84. }
  85. if ipv.Mode != other.Mode {
  86. t.Fatalf("Got unexpected mode: %d, expected: %d", other.Mode, ipv.Mode)
  87. }
  88. }
  89. if macv, ok := link.(*Macvlan); ok {
  90. other, ok := result.(*Macvlan)
  91. if !ok {
  92. t.Fatal("Result of create is not a macvlan")
  93. }
  94. if macv.Mode != other.Mode {
  95. t.Fatalf("Got unexpected mode: %d, expected: %d", other.Mode, macv.Mode)
  96. }
  97. }
  98. if macv, ok := link.(*Macvtap); ok {
  99. other, ok := result.(*Macvtap)
  100. if !ok {
  101. t.Fatal("Result of create is not a macvtap")
  102. }
  103. if macv.Mode != other.Mode {
  104. t.Fatalf("Got unexpected mode: %d, expected: %d", other.Mode, macv.Mode)
  105. }
  106. }
  107. if err = LinkDel(link); err != nil {
  108. t.Fatal(err)
  109. }
  110. links, err = LinkList()
  111. if err != nil {
  112. t.Fatal(err)
  113. }
  114. if len(links) != num {
  115. t.Fatal("Link not removed properly")
  116. return
  117. }
  118. }
  119. func compareVxlan(t *testing.T, expected, actual *Vxlan) {
  120. if actual.VxlanId != expected.VxlanId {
  121. t.Fatal("Vxlan.VxlanId doesn't match")
  122. }
  123. if expected.SrcAddr != nil && !actual.SrcAddr.Equal(expected.SrcAddr) {
  124. t.Fatal("Vxlan.SrcAddr doesn't match")
  125. }
  126. if expected.Group != nil && !actual.Group.Equal(expected.Group) {
  127. t.Fatal("Vxlan.Group doesn't match")
  128. }
  129. if expected.TTL != -1 && actual.TTL != expected.TTL {
  130. t.Fatal("Vxlan.TTL doesn't match")
  131. }
  132. if expected.TOS != -1 && actual.TOS != expected.TOS {
  133. t.Fatal("Vxlan.TOS doesn't match")
  134. }
  135. if actual.Learning != expected.Learning {
  136. t.Fatal("Vxlan.Learning doesn't match")
  137. }
  138. if actual.Proxy != expected.Proxy {
  139. t.Fatal("Vxlan.Proxy doesn't match")
  140. }
  141. if actual.RSC != expected.RSC {
  142. t.Fatal("Vxlan.RSC doesn't match")
  143. }
  144. if actual.L2miss != expected.L2miss {
  145. t.Fatal("Vxlan.L2miss doesn't match")
  146. }
  147. if actual.L3miss != expected.L3miss {
  148. t.Fatal("Vxlan.L3miss doesn't match")
  149. }
  150. if actual.GBP != expected.GBP {
  151. t.Fatal("Vxlan.GBP doesn't match")
  152. }
  153. if expected.NoAge {
  154. if !actual.NoAge {
  155. t.Fatal("Vxlan.NoAge doesn't match")
  156. }
  157. } else if expected.Age > 0 && actual.Age != expected.Age {
  158. t.Fatal("Vxlan.Age doesn't match")
  159. }
  160. if expected.Limit > 0 && actual.Limit != expected.Limit {
  161. t.Fatal("Vxlan.Limit doesn't match")
  162. }
  163. if expected.Port > 0 && actual.Port != expected.Port {
  164. t.Fatal("Vxlan.Port doesn't match")
  165. }
  166. if expected.PortLow > 0 || expected.PortHigh > 0 {
  167. if actual.PortLow != expected.PortLow {
  168. t.Fatal("Vxlan.PortLow doesn't match")
  169. }
  170. if actual.PortHigh != expected.PortHigh {
  171. t.Fatal("Vxlan.PortHigh doesn't match")
  172. }
  173. }
  174. }
  175. func TestLinkAddDelDummy(t *testing.T) {
  176. tearDown := setUpNetlinkTest(t)
  177. defer tearDown()
  178. testLinkAddDel(t, &Dummy{LinkAttrs{Name: "foo"}})
  179. }
  180. func TestLinkAddDelIfb(t *testing.T) {
  181. tearDown := setUpNetlinkTest(t)
  182. defer tearDown()
  183. testLinkAddDel(t, &Ifb{LinkAttrs{Name: "foo"}})
  184. }
  185. func TestLinkAddDelBridge(t *testing.T) {
  186. tearDown := setUpNetlinkTest(t)
  187. defer tearDown()
  188. testLinkAddDel(t, &Bridge{LinkAttrs{Name: "foo", MTU: 1400}})
  189. }
  190. func TestLinkAddDelGretap(t *testing.T) {
  191. tearDown := setUpNetlinkTest(t)
  192. defer tearDown()
  193. testLinkAddDel(t, &Gretap{
  194. LinkAttrs: LinkAttrs{Name: "foo"},
  195. IKey: 0x101,
  196. OKey: 0x101,
  197. PMtuDisc: 1,
  198. Local: net.IPv4(127, 0, 0, 1),
  199. Remote: net.IPv4(127, 0, 0, 1)})
  200. }
  201. func TestLinkAddDelVlan(t *testing.T) {
  202. tearDown := setUpNetlinkTest(t)
  203. defer tearDown()
  204. parent := &Dummy{LinkAttrs{Name: "foo"}}
  205. if err := LinkAdd(parent); err != nil {
  206. t.Fatal(err)
  207. }
  208. testLinkAddDel(t, &Vlan{LinkAttrs{Name: "bar", ParentIndex: parent.Attrs().Index}, 900})
  209. if err := LinkDel(parent); err != nil {
  210. t.Fatal(err)
  211. }
  212. }
  213. func TestLinkAddDelMacvlan(t *testing.T) {
  214. tearDown := setUpNetlinkTest(t)
  215. defer tearDown()
  216. parent := &Dummy{LinkAttrs{Name: "foo"}}
  217. if err := LinkAdd(parent); err != nil {
  218. t.Fatal(err)
  219. }
  220. testLinkAddDel(t, &Macvlan{
  221. LinkAttrs: LinkAttrs{Name: "bar", ParentIndex: parent.Attrs().Index},
  222. Mode: MACVLAN_MODE_PRIVATE,
  223. })
  224. testLinkAddDel(t, &Macvlan{
  225. LinkAttrs: LinkAttrs{Name: "bar", ParentIndex: parent.Attrs().Index},
  226. Mode: MACVLAN_MODE_BRIDGE,
  227. })
  228. testLinkAddDel(t, &Macvlan{
  229. LinkAttrs: LinkAttrs{Name: "bar", ParentIndex: parent.Attrs().Index},
  230. Mode: MACVLAN_MODE_VEPA,
  231. })
  232. if err := LinkDel(parent); err != nil {
  233. t.Fatal(err)
  234. }
  235. }
  236. func TestLinkAddDelMacvtap(t *testing.T) {
  237. tearDown := setUpNetlinkTest(t)
  238. defer tearDown()
  239. parent := &Dummy{LinkAttrs{Name: "foo"}}
  240. if err := LinkAdd(parent); err != nil {
  241. t.Fatal(err)
  242. }
  243. testLinkAddDel(t, &Macvtap{
  244. Macvlan: Macvlan{
  245. LinkAttrs: LinkAttrs{Name: "bar", ParentIndex: parent.Attrs().Index},
  246. Mode: MACVLAN_MODE_PRIVATE,
  247. },
  248. })
  249. testLinkAddDel(t, &Macvtap{
  250. Macvlan: Macvlan{
  251. LinkAttrs: LinkAttrs{Name: "bar", ParentIndex: parent.Attrs().Index},
  252. Mode: MACVLAN_MODE_BRIDGE,
  253. },
  254. })
  255. testLinkAddDel(t, &Macvtap{
  256. Macvlan: Macvlan{
  257. LinkAttrs: LinkAttrs{Name: "bar", ParentIndex: parent.Attrs().Index},
  258. Mode: MACVLAN_MODE_VEPA,
  259. },
  260. })
  261. if err := LinkDel(parent); err != nil {
  262. t.Fatal(err)
  263. }
  264. }
  265. func TestLinkAddDelVeth(t *testing.T) {
  266. tearDown := setUpNetlinkTest(t)
  267. defer tearDown()
  268. veth := &Veth{LinkAttrs: LinkAttrs{Name: "foo", TxQLen: testTxQLen, MTU: 1400}, PeerName: "bar"}
  269. testLinkAddDel(t, veth)
  270. }
  271. func TestLinkAddDelBond(t *testing.T) {
  272. tearDown := setUpNetlinkTest(t)
  273. defer tearDown()
  274. testLinkAddDel(t, NewLinkBond(LinkAttrs{Name: "foo"}))
  275. }
  276. func TestLinkAddVethWithDefaultTxQLen(t *testing.T) {
  277. tearDown := setUpNetlinkTest(t)
  278. defer tearDown()
  279. la := NewLinkAttrs()
  280. la.Name = "foo"
  281. veth := &Veth{LinkAttrs: la, PeerName: "bar"}
  282. if err := LinkAdd(veth); err != nil {
  283. t.Fatal(err)
  284. }
  285. link, err := LinkByName("foo")
  286. if err != nil {
  287. t.Fatal(err)
  288. }
  289. if veth, ok := link.(*Veth); !ok {
  290. t.Fatalf("unexpected link type: %T", link)
  291. } else {
  292. if veth.TxQLen != defaultTxQLen {
  293. t.Fatalf("TxQLen is %d, should be %d", veth.TxQLen, defaultTxQLen)
  294. }
  295. }
  296. peer, err := LinkByName("bar")
  297. if err != nil {
  298. t.Fatal(err)
  299. }
  300. if veth, ok := peer.(*Veth); !ok {
  301. t.Fatalf("unexpected link type: %T", link)
  302. } else {
  303. if veth.TxQLen != defaultTxQLen {
  304. t.Fatalf("TxQLen is %d, should be %d", veth.TxQLen, defaultTxQLen)
  305. }
  306. }
  307. }
  308. func TestLinkAddVethWithZeroTxQLen(t *testing.T) {
  309. tearDown := setUpNetlinkTest(t)
  310. defer tearDown()
  311. la := NewLinkAttrs()
  312. la.Name = "foo"
  313. la.TxQLen = 0
  314. veth := &Veth{LinkAttrs: la, PeerName: "bar"}
  315. if err := LinkAdd(veth); err != nil {
  316. t.Fatal(err)
  317. }
  318. link, err := LinkByName("foo")
  319. if err != nil {
  320. t.Fatal(err)
  321. }
  322. if veth, ok := link.(*Veth); !ok {
  323. t.Fatalf("unexpected link type: %T", link)
  324. } else {
  325. if veth.TxQLen != 0 {
  326. t.Fatalf("TxQLen is %d, should be %d", veth.TxQLen, 0)
  327. }
  328. }
  329. peer, err := LinkByName("bar")
  330. if err != nil {
  331. t.Fatal(err)
  332. }
  333. if veth, ok := peer.(*Veth); !ok {
  334. t.Fatalf("unexpected link type: %T", link)
  335. } else {
  336. if veth.TxQLen != 0 {
  337. t.Fatalf("TxQLen is %d, should be %d", veth.TxQLen, 0)
  338. }
  339. }
  340. }
  341. func TestLinkAddDummyWithTxQLen(t *testing.T) {
  342. tearDown := setUpNetlinkTest(t)
  343. defer tearDown()
  344. la := NewLinkAttrs()
  345. la.Name = "foo"
  346. la.TxQLen = 1500
  347. dummy := &Dummy{LinkAttrs: la}
  348. if err := LinkAdd(dummy); err != nil {
  349. t.Fatal(err)
  350. }
  351. link, err := LinkByName("foo")
  352. if err != nil {
  353. t.Fatal(err)
  354. }
  355. if dummy, ok := link.(*Dummy); !ok {
  356. t.Fatalf("unexpected link type: %T", link)
  357. } else {
  358. if dummy.TxQLen != 1500 {
  359. t.Fatalf("TxQLen is %d, should be %d", dummy.TxQLen, 1500)
  360. }
  361. }
  362. }
  363. func TestLinkAddDelBridgeMaster(t *testing.T) {
  364. tearDown := setUpNetlinkTest(t)
  365. defer tearDown()
  366. master := &Bridge{LinkAttrs{Name: "foo"}}
  367. if err := LinkAdd(master); err != nil {
  368. t.Fatal(err)
  369. }
  370. testLinkAddDel(t, &Dummy{LinkAttrs{Name: "bar", MasterIndex: master.Attrs().Index}})
  371. if err := LinkDel(master); err != nil {
  372. t.Fatal(err)
  373. }
  374. }
  375. func TestLinkSetUnsetResetMaster(t *testing.T) {
  376. tearDown := setUpNetlinkTest(t)
  377. defer tearDown()
  378. master := &Bridge{LinkAttrs{Name: "foo"}}
  379. if err := LinkAdd(master); err != nil {
  380. t.Fatal(err)
  381. }
  382. newmaster := &Bridge{LinkAttrs{Name: "bar"}}
  383. if err := LinkAdd(newmaster); err != nil {
  384. t.Fatal(err)
  385. }
  386. slave := &Dummy{LinkAttrs{Name: "baz"}}
  387. if err := LinkAdd(slave); err != nil {
  388. t.Fatal(err)
  389. }
  390. nonexistsmaster := &Bridge{LinkAttrs{Name: "foobar"}}
  391. if err := LinkSetMaster(slave, nonexistsmaster); err == nil {
  392. t.Fatal("error expected")
  393. }
  394. if err := LinkSetMaster(slave, master); err != nil {
  395. t.Fatal(err)
  396. }
  397. link, err := LinkByName("baz")
  398. if err != nil {
  399. t.Fatal(err)
  400. }
  401. if link.Attrs().MasterIndex != master.Attrs().Index {
  402. t.Fatal("Master not set properly")
  403. }
  404. if err := LinkSetMaster(slave, newmaster); err != nil {
  405. t.Fatal(err)
  406. }
  407. link, err = LinkByName("baz")
  408. if err != nil {
  409. t.Fatal(err)
  410. }
  411. if link.Attrs().MasterIndex != newmaster.Attrs().Index {
  412. t.Fatal("Master not reset properly")
  413. }
  414. if err := LinkSetNoMaster(slave); err != nil {
  415. t.Fatal(err)
  416. }
  417. link, err = LinkByName("baz")
  418. if err != nil {
  419. t.Fatal(err)
  420. }
  421. if link.Attrs().MasterIndex != 0 {
  422. t.Fatal("Master not unset properly")
  423. }
  424. if err := LinkDel(slave); err != nil {
  425. t.Fatal(err)
  426. }
  427. if err := LinkDel(newmaster); err != nil {
  428. t.Fatal(err)
  429. }
  430. if err := LinkDel(master); err != nil {
  431. t.Fatal(err)
  432. }
  433. }
  434. func TestLinkSetNs(t *testing.T) {
  435. tearDown := setUpNetlinkTest(t)
  436. defer tearDown()
  437. basens, err := netns.Get()
  438. if err != nil {
  439. t.Fatal("Failed to get basens")
  440. }
  441. defer basens.Close()
  442. newns, err := netns.New()
  443. if err != nil {
  444. t.Fatal("Failed to create newns")
  445. }
  446. defer newns.Close()
  447. link := &Veth{LinkAttrs{Name: "foo"}, "bar"}
  448. if err := LinkAdd(link); err != nil {
  449. t.Fatal(err)
  450. }
  451. peer, err := LinkByName("bar")
  452. if err != nil {
  453. t.Fatal(err)
  454. }
  455. LinkSetNsFd(peer, int(basens))
  456. if err != nil {
  457. t.Fatal("Failed to set newns for link")
  458. }
  459. _, err = LinkByName("bar")
  460. if err == nil {
  461. t.Fatal("Link bar is still in newns")
  462. }
  463. err = netns.Set(basens)
  464. if err != nil {
  465. t.Fatal("Failed to set basens")
  466. }
  467. peer, err = LinkByName("bar")
  468. if err != nil {
  469. t.Fatal("Link is not in basens")
  470. }
  471. if err := LinkDel(peer); err != nil {
  472. t.Fatal(err)
  473. }
  474. err = netns.Set(newns)
  475. if err != nil {
  476. t.Fatal("Failed to set newns")
  477. }
  478. _, err = LinkByName("foo")
  479. if err == nil {
  480. t.Fatal("Other half of veth pair not deleted")
  481. }
  482. }
  483. func TestLinkAddDelVxlan(t *testing.T) {
  484. tearDown := setUpNetlinkTest(t)
  485. defer tearDown()
  486. parent := &Dummy{
  487. LinkAttrs{Name: "foo"},
  488. }
  489. if err := LinkAdd(parent); err != nil {
  490. t.Fatal(err)
  491. }
  492. vxlan := Vxlan{
  493. LinkAttrs: LinkAttrs{
  494. Name: "bar",
  495. },
  496. VxlanId: 10,
  497. VtepDevIndex: parent.Index,
  498. Learning: true,
  499. L2miss: true,
  500. L3miss: true,
  501. }
  502. testLinkAddDel(t, &vxlan)
  503. if err := LinkDel(parent); err != nil {
  504. t.Fatal(err)
  505. }
  506. }
  507. func TestLinkAddDelVxlanGbp(t *testing.T) {
  508. if os.Getenv("TRAVIS_BUILD_DIR") != "" {
  509. t.Skipf("Kernel in travis is too old for this test")
  510. }
  511. tearDown := setUpNetlinkTest(t)
  512. defer tearDown()
  513. parent := &Dummy{
  514. LinkAttrs{Name: "foo"},
  515. }
  516. if err := LinkAdd(parent); err != nil {
  517. t.Fatal(err)
  518. }
  519. vxlan := Vxlan{
  520. LinkAttrs: LinkAttrs{
  521. Name: "bar",
  522. },
  523. VxlanId: 10,
  524. VtepDevIndex: parent.Index,
  525. Learning: true,
  526. L2miss: true,
  527. L3miss: true,
  528. GBP: true,
  529. }
  530. testLinkAddDel(t, &vxlan)
  531. if err := LinkDel(parent); err != nil {
  532. t.Fatal(err)
  533. }
  534. }
  535. func TestLinkAddDelIPVlanL2(t *testing.T) {
  536. if os.Getenv("TRAVIS_BUILD_DIR") != "" {
  537. t.Skipf("Kernel in travis is too old for this test")
  538. }
  539. tearDown := setUpNetlinkTest(t)
  540. defer tearDown()
  541. parent := &Dummy{LinkAttrs{Name: "foo"}}
  542. if err := LinkAdd(parent); err != nil {
  543. t.Fatal(err)
  544. }
  545. ipv := IPVlan{
  546. LinkAttrs: LinkAttrs{
  547. Name: "bar",
  548. ParentIndex: parent.Index,
  549. },
  550. Mode: IPVLAN_MODE_L2,
  551. }
  552. testLinkAddDel(t, &ipv)
  553. }
  554. func TestLinkAddDelIPVlanL3(t *testing.T) {
  555. if os.Getenv("TRAVIS_BUILD_DIR") != "" {
  556. t.Skipf("Kernel in travis is too old for this test")
  557. }
  558. tearDown := setUpNetlinkTest(t)
  559. defer tearDown()
  560. parent := &Dummy{LinkAttrs{Name: "foo"}}
  561. if err := LinkAdd(parent); err != nil {
  562. t.Fatal(err)
  563. }
  564. ipv := IPVlan{
  565. LinkAttrs: LinkAttrs{
  566. Name: "bar",
  567. ParentIndex: parent.Index,
  568. },
  569. Mode: IPVLAN_MODE_L3,
  570. }
  571. testLinkAddDel(t, &ipv)
  572. }
  573. func TestLinkAddDelIPVlanNoParent(t *testing.T) {
  574. tearDown := setUpNetlinkTest(t)
  575. defer tearDown()
  576. ipv := IPVlan{
  577. LinkAttrs: LinkAttrs{
  578. Name: "bar",
  579. },
  580. Mode: IPVLAN_MODE_L3,
  581. }
  582. err := LinkAdd(&ipv)
  583. if err == nil {
  584. t.Fatal("Add should fail if ipvlan creating without ParentIndex")
  585. }
  586. if err.Error() != "Can't create ipvlan link without ParentIndex" {
  587. t.Fatalf("Error should be about missing ParentIndex, got %q", err)
  588. }
  589. }
  590. func TestLinkByIndex(t *testing.T) {
  591. tearDown := setUpNetlinkTest(t)
  592. defer tearDown()
  593. dummy := &Dummy{LinkAttrs{Name: "dummy"}}
  594. if err := LinkAdd(dummy); err != nil {
  595. t.Fatal(err)
  596. }
  597. found, err := LinkByIndex(dummy.Index)
  598. if err != nil {
  599. t.Fatal(err)
  600. }
  601. if found.Attrs().Index != dummy.Attrs().Index {
  602. t.Fatalf("Indices don't match: %v != %v", found.Attrs().Index, dummy.Attrs().Index)
  603. }
  604. LinkDel(dummy)
  605. // test not found
  606. _, err = LinkByIndex(dummy.Attrs().Index)
  607. if err == nil {
  608. t.Fatalf("LinkByIndex(%v) found deleted link", err)
  609. }
  610. }
  611. func TestLinkSet(t *testing.T) {
  612. tearDown := setUpNetlinkTest(t)
  613. defer tearDown()
  614. iface := &Dummy{LinkAttrs{Name: "foo"}}
  615. if err := LinkAdd(iface); err != nil {
  616. t.Fatal(err)
  617. }
  618. link, err := LinkByName("foo")
  619. if err != nil {
  620. t.Fatal(err)
  621. }
  622. err = LinkSetName(link, "bar")
  623. if err != nil {
  624. t.Fatalf("Could not change interface name: %v", err)
  625. }
  626. link, err = LinkByName("bar")
  627. if err != nil {
  628. t.Fatalf("Interface name not changed: %v", err)
  629. }
  630. err = LinkSetMTU(link, 1400)
  631. if err != nil {
  632. t.Fatalf("Could not set MTU: %v", err)
  633. }
  634. link, err = LinkByName("bar")
  635. if err != nil {
  636. t.Fatal(err)
  637. }
  638. if link.Attrs().MTU != 1400 {
  639. t.Fatal("MTU not changed!")
  640. }
  641. addr, err := net.ParseMAC("00:12:34:56:78:AB")
  642. if err != nil {
  643. t.Fatal(err)
  644. }
  645. err = LinkSetHardwareAddr(link, addr)
  646. if err != nil {
  647. t.Fatal(err)
  648. }
  649. link, err = LinkByName("bar")
  650. if err != nil {
  651. t.Fatal(err)
  652. }
  653. if !bytes.Equal(link.Attrs().HardwareAddr, addr) {
  654. t.Fatalf("hardware address not changed!")
  655. }
  656. err = LinkSetAlias(link, "barAlias")
  657. if err != nil {
  658. t.Fatalf("Could not set alias: %v", err)
  659. }
  660. link, err = LinkByName("bar")
  661. if err != nil {
  662. t.Fatal(err)
  663. }
  664. if link.Attrs().Alias != "barAlias" {
  665. t.Fatalf("alias not changed!")
  666. }
  667. link, err = LinkByAlias("barAlias")
  668. if err != nil {
  669. t.Fatal(err)
  670. }
  671. }
  672. func expectLinkUpdate(ch <-chan LinkUpdate, ifaceName string, up bool) bool {
  673. for {
  674. timeout := time.After(time.Minute)
  675. select {
  676. case update := <-ch:
  677. if ifaceName == update.Link.Attrs().Name && (update.IfInfomsg.Flags&syscall.IFF_UP != 0) == up {
  678. return true
  679. }
  680. case <-timeout:
  681. return false
  682. }
  683. }
  684. }
  685. func TestLinkSubscribe(t *testing.T) {
  686. tearDown := setUpNetlinkTest(t)
  687. defer tearDown()
  688. ch := make(chan LinkUpdate)
  689. done := make(chan struct{})
  690. defer close(done)
  691. if err := LinkSubscribe(ch, done); err != nil {
  692. t.Fatal(err)
  693. }
  694. link := &Veth{LinkAttrs{Name: "foo", TxQLen: testTxQLen, MTU: 1400}, "bar"}
  695. if err := LinkAdd(link); err != nil {
  696. t.Fatal(err)
  697. }
  698. if !expectLinkUpdate(ch, "foo", false) {
  699. t.Fatal("Add update not received as expected")
  700. }
  701. if err := LinkSetUp(link); err != nil {
  702. t.Fatal(err)
  703. }
  704. if !expectLinkUpdate(ch, "foo", true) {
  705. t.Fatal("Link Up update not received as expected")
  706. }
  707. if err := LinkDel(link); err != nil {
  708. t.Fatal(err)
  709. }
  710. if !expectLinkUpdate(ch, "foo", false) {
  711. t.Fatal("Del update not received as expected")
  712. }
  713. }
  714. func TestLinkSubscribeAt(t *testing.T) {
  715. // Create an handle on a custom netns
  716. newNs, err := netns.New()
  717. if err != nil {
  718. t.Fatal(err)
  719. }
  720. defer newNs.Close()
  721. nh, err := NewHandleAt(newNs)
  722. if err != nil {
  723. t.Fatal(err)
  724. }
  725. defer nh.Delete()
  726. // Subscribe for Link events on the custom netns
  727. ch := make(chan LinkUpdate)
  728. done := make(chan struct{})
  729. defer close(done)
  730. if err := LinkSubscribeAt(newNs, ch, done); err != nil {
  731. t.Fatal(err)
  732. }
  733. link := &Veth{LinkAttrs{Name: "test", TxQLen: testTxQLen, MTU: 1400}, "bar"}
  734. if err := nh.LinkAdd(link); err != nil {
  735. t.Fatal(err)
  736. }
  737. if !expectLinkUpdate(ch, "test", false) {
  738. t.Fatal("Add update not received as expected")
  739. }
  740. if err := nh.LinkSetUp(link); err != nil {
  741. t.Fatal(err)
  742. }
  743. if !expectLinkUpdate(ch, "test", true) {
  744. t.Fatal("Link Up update not received as expected")
  745. }
  746. if err := nh.LinkDel(link); err != nil {
  747. t.Fatal(err)
  748. }
  749. if !expectLinkUpdate(ch, "test", false) {
  750. t.Fatal("Del update not received as expected")
  751. }
  752. }
  753. func TestLinkStats(t *testing.T) {
  754. defer setUpNetlinkTest(t)()
  755. // Create a veth pair and verify the cross-stats once both
  756. // ends are brought up and some ICMPv6 packets are exchanged
  757. v0 := "v0"
  758. v1 := "v1"
  759. vethLink := &Veth{LinkAttrs: LinkAttrs{Name: v0}, PeerName: v1}
  760. if err := LinkAdd(vethLink); err != nil {
  761. t.Fatal(err)
  762. }
  763. veth0, err := LinkByName(v0)
  764. if err != nil {
  765. t.Fatal(err)
  766. }
  767. if err := LinkSetUp(veth0); err != nil {
  768. t.Fatal(err)
  769. }
  770. veth1, err := LinkByName(v1)
  771. if err != nil {
  772. t.Fatal(err)
  773. }
  774. if err := LinkSetUp(veth1); err != nil {
  775. t.Fatal(err)
  776. }
  777. time.Sleep(2 * time.Second)
  778. // verify statistics
  779. veth0, err = LinkByName(v0)
  780. if err != nil {
  781. t.Fatal(err)
  782. }
  783. veth1, err = LinkByName(v1)
  784. if err != nil {
  785. t.Fatal(err)
  786. }
  787. v0Stats := veth0.Attrs().Statistics
  788. v1Stats := veth1.Attrs().Statistics
  789. if v0Stats.RxPackets != v1Stats.TxPackets || v0Stats.TxPackets != v1Stats.RxPackets ||
  790. v0Stats.RxBytes != v1Stats.TxBytes || v0Stats.TxBytes != v1Stats.RxBytes {
  791. t.Fatalf("veth ends counters differ:\n%v\n%v", v0Stats, v1Stats)
  792. }
  793. }