github.com/sagernet/netlink@v0.0.0-20240612041022-b9a21c07ac6a/link_test.go (about) 1 //go:build linux 2 // +build linux 3 4 package netlink 5 6 import ( 7 "bytes" 8 "errors" 9 "fmt" 10 "net" 11 "os" 12 "os/exec" 13 "syscall" 14 "testing" 15 "time" 16 17 "github.com/sagernet/netlink/nl" 18 "github.com/vishvananda/netns" 19 "golang.org/x/sys/unix" 20 ) 21 22 const ( 23 testTxQLen int = 100 24 defaultTxQLen int = 1000 25 testTxQueues int = 4 26 testRxQueues int = 8 27 ) 28 29 func testLinkAddDel(t *testing.T, link Link) { 30 _, err := LinkList() 31 if err != nil { 32 t.Fatal(err) 33 } 34 35 if err := LinkAdd(link); err != nil { 36 t.Fatal(err) 37 } 38 39 base := link.Attrs() 40 41 result, err := LinkByName(base.Name) 42 if err != nil { 43 t.Fatal(err) 44 } 45 46 rBase := result.Attrs() 47 48 if base.Index != 0 { 49 if base.Index != rBase.Index { 50 t.Fatalf("index is %d, should be %d", rBase.Index, base.Index) 51 } 52 } 53 54 if base.Group > 0 { 55 if base.Group != rBase.Group { 56 t.Fatalf("group is %d, should be %d", rBase.Group, base.Group) 57 } 58 } 59 60 if vlan, ok := link.(*Vlan); ok { 61 other, ok := result.(*Vlan) 62 if !ok { 63 t.Fatal("Result of create is not a vlan") 64 } 65 if vlan.VlanId != other.VlanId { 66 t.Fatal("Link.VlanId id doesn't match") 67 } 68 } 69 70 if veth, ok := result.(*Veth); ok { 71 if rBase.TxQLen != base.TxQLen { 72 t.Fatalf("qlen is %d, should be %d", rBase.TxQLen, base.TxQLen) 73 } 74 75 if rBase.NumTxQueues != base.NumTxQueues { 76 t.Fatalf("txQueues is %d, should be %d", rBase.NumTxQueues, base.NumTxQueues) 77 } 78 79 if rBase.NumRxQueues != base.NumRxQueues { 80 t.Fatalf("rxQueues is %d, should be %d", rBase.NumRxQueues, base.NumRxQueues) 81 } 82 83 if rBase.MTU != base.MTU { 84 t.Fatalf("MTU is %d, should be %d", rBase.MTU, base.MTU) 85 } 86 87 if original, ok := link.(*Veth); ok { 88 if original.PeerName != "" { 89 var peer *Veth 90 other, err := LinkByName(original.PeerName) 91 if err != nil { 92 t.Fatalf("Peer %s not created", veth.PeerName) 93 } 94 if peer, ok = other.(*Veth); !ok { 95 t.Fatalf("Peer %s is incorrect type", veth.PeerName) 96 } 97 if peer.TxQLen != testTxQLen { 98 t.Fatalf("TxQLen of peer is %d, should be %d", peer.TxQLen, testTxQLen) 99 } 100 if peer.NumTxQueues != testTxQueues { 101 t.Fatalf("NumTxQueues of peer is %d, should be %d", peer.NumTxQueues, testTxQueues) 102 } 103 if peer.NumRxQueues != testRxQueues { 104 t.Fatalf("NumRxQueues of peer is %d, should be %d", peer.NumRxQueues, testRxQueues) 105 } 106 if !bytes.Equal(peer.Attrs().HardwareAddr, original.PeerHardwareAddr) { 107 t.Fatalf("Peer MAC addr is %s, should be %s", peer.Attrs().HardwareAddr, original.PeerHardwareAddr) 108 } 109 } 110 } 111 } else { 112 // recent kernels set the parent index for veths in the response 113 if rBase.ParentIndex == 0 && base.ParentIndex != 0 { 114 t.Fatalf("Created link doesn't have parent %d but it should", base.ParentIndex) 115 } else if rBase.ParentIndex != 0 && base.ParentIndex == 0 { 116 t.Fatalf("Created link has parent %d but it shouldn't", rBase.ParentIndex) 117 } else if rBase.ParentIndex != 0 && base.ParentIndex != 0 { 118 if rBase.ParentIndex != base.ParentIndex { 119 t.Fatalf("Link.ParentIndex doesn't match %d != %d", rBase.ParentIndex, base.ParentIndex) 120 } 121 } 122 } 123 124 if _, ok := link.(*Wireguard); ok { 125 _, ok := result.(*Wireguard) 126 if !ok { 127 t.Fatal("Result of create is not a wireguard") 128 } 129 } 130 131 if vxlan, ok := link.(*Vxlan); ok { 132 other, ok := result.(*Vxlan) 133 if !ok { 134 t.Fatal("Result of create is not a vxlan") 135 } 136 compareVxlan(t, vxlan, other) 137 } 138 139 if ipv, ok := link.(*IPVlan); ok { 140 other, ok := result.(*IPVlan) 141 if !ok { 142 t.Fatal("Result of create is not a ipvlan") 143 } 144 if ipv.Mode != other.Mode { 145 t.Fatalf("Got unexpected mode: %d, expected: %d", other.Mode, ipv.Mode) 146 } 147 if ipv.Flag != other.Flag { 148 t.Fatalf("Got unexpected flag: %d, expected: %d", other.Flag, ipv.Flag) 149 } 150 } 151 152 if macv, ok := link.(*Macvlan); ok { 153 other, ok := result.(*Macvlan) 154 if !ok { 155 t.Fatal("Result of create is not a macvlan") 156 } 157 if macv.Mode != other.Mode { 158 t.Fatalf("Got unexpected mode: %d, expected: %d", other.Mode, macv.Mode) 159 } 160 } 161 162 if macv, ok := link.(*Macvtap); ok { 163 other, ok := result.(*Macvtap) 164 if !ok { 165 t.Fatal("Result of create is not a macvtap") 166 } 167 if macv.Mode != other.Mode { 168 t.Fatalf("Got unexpected mode: %d, expected: %d", other.Mode, macv.Mode) 169 } 170 } 171 172 if _, ok := link.(*Vti); ok { 173 _, ok := result.(*Vti) 174 if !ok { 175 t.Fatal("Result of create is not a vti") 176 } 177 } 178 179 if bond, ok := link.(*Bond); ok { 180 other, ok := result.(*Bond) 181 if !ok { 182 t.Fatal("Result of create is not a bond") 183 } 184 if bond.Mode != other.Mode { 185 t.Fatalf("Got unexpected mode: %d, expected: %d", other.Mode, bond.Mode) 186 } 187 if bond.ArpIpTargets != nil { 188 if other.ArpIpTargets == nil { 189 t.Fatalf("Got unexpected ArpIpTargets: nil") 190 } 191 192 if len(bond.ArpIpTargets) != len(other.ArpIpTargets) { 193 t.Fatalf("Got unexpected ArpIpTargets len: %d, expected: %d", 194 len(other.ArpIpTargets), len(bond.ArpIpTargets)) 195 } 196 197 for i := range bond.ArpIpTargets { 198 if !bond.ArpIpTargets[i].Equal(other.ArpIpTargets[i]) { 199 t.Fatalf("Got unexpected ArpIpTargets: %s, expected: %s", 200 other.ArpIpTargets[i], bond.ArpIpTargets[i]) 201 } 202 } 203 } 204 205 switch mode := bondModeToString[bond.Mode]; mode { 206 case "802.3ad": 207 if bond.AdSelect != other.AdSelect { 208 t.Fatalf("Got unexpected AdSelect: %d, expected: %d", other.AdSelect, bond.AdSelect) 209 } 210 if bond.AdActorSysPrio != other.AdActorSysPrio { 211 t.Fatalf("Got unexpected AdActorSysPrio: %d, expected: %d", other.AdActorSysPrio, bond.AdActorSysPrio) 212 } 213 if bond.AdUserPortKey != other.AdUserPortKey { 214 t.Fatalf("Got unexpected AdUserPortKey: %d, expected: %d", other.AdUserPortKey, bond.AdUserPortKey) 215 } 216 if !bytes.Equal(bond.AdActorSystem, other.AdActorSystem) { 217 t.Fatalf("Got unexpected AdActorSystem: %d, expected: %d", other.AdActorSystem, bond.AdActorSystem) 218 } 219 case "balance-tlb": 220 if bond.TlbDynamicLb != other.TlbDynamicLb { 221 t.Fatalf("Got unexpected TlbDynamicLb: %d, expected: %d", other.TlbDynamicLb, bond.TlbDynamicLb) 222 } 223 } 224 } 225 226 if _, ok := link.(*Iptun); ok { 227 _, ok := result.(*Iptun) 228 if !ok { 229 t.Fatal("Result of create is not a iptun") 230 } 231 } 232 233 if _, ok := link.(*Ip6tnl); ok { 234 _, ok := result.(*Ip6tnl) 235 if !ok { 236 t.Fatal("Result of create is not a ip6tnl") 237 } 238 } 239 240 if _, ok := link.(*Sittun); ok { 241 _, ok := result.(*Sittun) 242 if !ok { 243 t.Fatal("Result of create is not a sittun") 244 } 245 } 246 247 if geneve, ok := link.(*Geneve); ok { 248 other, ok := result.(*Geneve) 249 if !ok { 250 t.Fatal("Result of create is not a Geneve") 251 } 252 compareGeneve(t, geneve, other) 253 } 254 255 if gretap, ok := link.(*Gretap); ok { 256 other, ok := result.(*Gretap) 257 if !ok { 258 t.Fatal("Result of create is not a Gretap") 259 } 260 compareGretap(t, gretap, other) 261 } 262 263 if gretun, ok := link.(*Gretun); ok { 264 other, ok := result.(*Gretun) 265 if !ok { 266 t.Fatal("Result of create is not a Gretun") 267 } 268 compareGretun(t, gretun, other) 269 } 270 271 if xfrmi, ok := link.(*Xfrmi); ok { 272 other, ok := result.(*Xfrmi) 273 if !ok { 274 t.Fatal("Result of create is not a xfrmi") 275 } 276 compareXfrmi(t, xfrmi, other) 277 } 278 279 if tuntap, ok := link.(*Tuntap); ok { 280 other, ok := result.(*Tuntap) 281 if !ok { 282 t.Fatal("Result of create is not a tuntap") 283 } 284 compareTuntap(t, tuntap, other) 285 } 286 287 if bareudp, ok := link.(*BareUDP); ok { 288 other, ok := result.(*BareUDP) 289 if !ok { 290 t.Fatal("Result of create is not a BareUDP") 291 } 292 compareBareUDP(t, bareudp, other) 293 } 294 295 if err = LinkDel(link); err != nil { 296 t.Fatal(err) 297 } 298 299 links, err := LinkList() 300 if err != nil { 301 t.Fatal(err) 302 } 303 304 for _, l := range links { 305 if l.Attrs().Name == link.Attrs().Name { 306 t.Fatal("Link not removed properly") 307 } 308 } 309 } 310 311 func compareGeneve(t *testing.T, expected, actual *Geneve) { 312 if actual.ID != expected.ID { 313 t.Fatalf("Geneve.ID doesn't match: %d %d", actual.ID, expected.ID) 314 } 315 316 // set the Dport to 6081 (the linux default) if it wasn't specified at creation 317 if expected.Dport == 0 { 318 expected.Dport = 6081 319 } 320 321 if actual.Dport != expected.Dport { 322 t.Fatal("Geneve.Dport doesn't match") 323 } 324 325 if actual.Ttl != expected.Ttl { 326 t.Fatal("Geneve.Ttl doesn't match") 327 } 328 329 if actual.Tos != expected.Tos { 330 t.Fatal("Geneve.Tos doesn't match") 331 } 332 333 if !actual.Remote.Equal(expected.Remote) { 334 t.Fatalf("Geneve.Remote is not equal: %s!=%s", actual.Remote, expected.Remote) 335 } 336 337 // TODO: we should implement the rest of the geneve methods 338 } 339 340 func compareGretap(t *testing.T, expected, actual *Gretap) { 341 if actual.IKey != expected.IKey { 342 t.Fatal("Gretap.IKey doesn't match") 343 } 344 345 if actual.OKey != expected.OKey { 346 t.Fatal("Gretap.OKey doesn't match") 347 } 348 349 if actual.EncapSport != expected.EncapSport { 350 t.Fatal("Gretap.EncapSport doesn't match") 351 } 352 353 if actual.EncapDport != expected.EncapDport { 354 t.Fatal("Gretap.EncapDport doesn't match") 355 } 356 357 if expected.Local != nil && !actual.Local.Equal(expected.Local) { 358 t.Fatal("Gretap.Local doesn't match") 359 } 360 361 if expected.Remote != nil && !actual.Remote.Equal(expected.Remote) { 362 t.Fatal("Gretap.Remote doesn't match") 363 } 364 365 if actual.IFlags != expected.IFlags { 366 t.Fatal("Gretap.IFlags doesn't match") 367 } 368 369 if actual.OFlags != expected.OFlags { 370 t.Fatal("Gretap.OFlags doesn't match") 371 } 372 373 if actual.PMtuDisc != expected.PMtuDisc { 374 t.Fatal("Gretap.PMtuDisc doesn't match") 375 } 376 377 if actual.Ttl != expected.Ttl { 378 t.Fatal("Gretap.Ttl doesn't match") 379 } 380 381 if actual.Tos != expected.Tos { 382 t.Fatal("Gretap.Tos doesn't match") 383 } 384 385 if actual.EncapType != expected.EncapType { 386 t.Fatal("Gretap.EncapType doesn't match") 387 } 388 389 if actual.EncapFlags != expected.EncapFlags { 390 t.Fatal("Gretap.EncapFlags doesn't match") 391 } 392 393 if actual.Link != expected.Link { 394 t.Fatal("Gretap.Link doesn't match") 395 } 396 397 if actual.FlowBased != expected.FlowBased { 398 t.Fatal("Gretap.FlowBased doesn't match") 399 } 400 } 401 402 func compareGretun(t *testing.T, expected, actual *Gretun) { 403 if actual.Link != expected.Link { 404 t.Fatal("Gretun.Link doesn't match") 405 } 406 407 if actual.IFlags != expected.IFlags { 408 t.Fatal("Gretun.IFlags doesn't match") 409 } 410 411 if actual.OFlags != expected.OFlags { 412 t.Fatal("Gretun.OFlags doesn't match") 413 } 414 415 if actual.IKey != expected.IKey { 416 t.Fatal("Gretun.IKey doesn't match") 417 } 418 419 if actual.OKey != expected.OKey { 420 t.Fatal("Gretun.OKey doesn't match") 421 } 422 423 if expected.Local != nil && !actual.Local.Equal(expected.Local) { 424 t.Fatal("Gretun.Local doesn't match") 425 } 426 427 if expected.Remote != nil && !actual.Remote.Equal(expected.Remote) { 428 t.Fatal("Gretun.Remote doesn't match") 429 } 430 431 if actual.Ttl != expected.Ttl { 432 t.Fatal("Gretun.Ttl doesn't match") 433 } 434 435 if actual.Tos != expected.Tos { 436 t.Fatal("Gretun.Tos doesn't match") 437 } 438 439 if actual.PMtuDisc != expected.PMtuDisc { 440 t.Fatal("Gretun.PMtuDisc doesn't match") 441 } 442 443 if actual.EncapType != expected.EncapType { 444 t.Fatal("Gretun.EncapType doesn't match") 445 } 446 447 if actual.EncapFlags != expected.EncapFlags { 448 t.Fatal("Gretun.EncapFlags doesn't match") 449 } 450 451 if actual.EncapSport != expected.EncapSport { 452 t.Fatal("Gretun.EncapSport doesn't match") 453 } 454 455 if actual.EncapDport != expected.EncapDport { 456 t.Fatal("Gretun.EncapDport doesn't match") 457 } 458 if actual.FlowBased != expected.FlowBased { 459 t.Fatal("Gretun.FlowBased doesn't match") 460 } 461 } 462 463 func compareVxlan(t *testing.T, expected, actual *Vxlan) { 464 465 if actual.VxlanId != expected.VxlanId { 466 t.Fatal("Vxlan.VxlanId doesn't match") 467 } 468 if expected.SrcAddr != nil && !actual.SrcAddr.Equal(expected.SrcAddr) { 469 t.Fatal("Vxlan.SrcAddr doesn't match") 470 } 471 if expected.Group != nil && !actual.Group.Equal(expected.Group) { 472 t.Fatal("Vxlan.Group doesn't match") 473 } 474 if expected.TTL != -1 && actual.TTL != expected.TTL { 475 t.Fatal("Vxlan.TTL doesn't match") 476 } 477 if expected.TOS != -1 && actual.TOS != expected.TOS { 478 t.Fatal("Vxlan.TOS doesn't match") 479 } 480 if actual.Learning != expected.Learning { 481 t.Fatal("Vxlan.Learning doesn't match") 482 } 483 if actual.Proxy != expected.Proxy { 484 t.Fatal("Vxlan.Proxy doesn't match") 485 } 486 if actual.RSC != expected.RSC { 487 t.Fatal("Vxlan.RSC doesn't match") 488 } 489 if actual.L2miss != expected.L2miss { 490 t.Fatal("Vxlan.L2miss doesn't match") 491 } 492 if actual.L3miss != expected.L3miss { 493 t.Fatal("Vxlan.L3miss doesn't match") 494 } 495 if actual.GBP != expected.GBP { 496 t.Fatal("Vxlan.GBP doesn't match") 497 } 498 if actual.FlowBased != expected.FlowBased { 499 t.Fatal("Vxlan.FlowBased doesn't match") 500 } 501 if actual.UDP6ZeroCSumTx != expected.UDP6ZeroCSumTx { 502 t.Fatal("Vxlan.UDP6ZeroCSumTx doesn't match") 503 } 504 if actual.UDP6ZeroCSumRx != expected.UDP6ZeroCSumRx { 505 t.Fatal("Vxlan.UDP6ZeroCSumRx doesn't match") 506 } 507 if expected.NoAge { 508 if !actual.NoAge { 509 t.Fatal("Vxlan.NoAge doesn't match") 510 } 511 } else if expected.Age > 0 && actual.Age != expected.Age { 512 t.Fatal("Vxlan.Age doesn't match") 513 } 514 if expected.Limit > 0 && actual.Limit != expected.Limit { 515 t.Fatal("Vxlan.Limit doesn't match") 516 } 517 if expected.Port > 0 && actual.Port != expected.Port { 518 t.Fatal("Vxlan.Port doesn't match") 519 } 520 if expected.PortLow > 0 || expected.PortHigh > 0 { 521 if actual.PortLow != expected.PortLow { 522 t.Fatal("Vxlan.PortLow doesn't match") 523 } 524 if actual.PortHigh != expected.PortHigh { 525 t.Fatal("Vxlan.PortHigh doesn't match") 526 } 527 } 528 } 529 530 func compareXfrmi(t *testing.T, expected, actual *Xfrmi) { 531 if expected.Ifid != actual.Ifid { 532 t.Fatal("Xfrmi.Ifid doesn't match") 533 } 534 } 535 536 func compareTuntap(t *testing.T, expected, actual *Tuntap) { 537 if expected.Mode != actual.Mode { 538 t.Fatalf("Tuntap.Mode doesn't match: expected : %+v, got %+v", expected.Mode, actual.Mode) 539 } 540 541 if expected.Owner != actual.Owner { 542 t.Fatal("Tuntap.Owner doesn't match") 543 } 544 545 if expected.Group != actual.Group { 546 t.Fatal("Tuntap.Group doesn't match") 547 } 548 549 if expected.NonPersist != actual.NonPersist { 550 t.Fatal("Tuntap.Group doesn't match") 551 } 552 } 553 554 func compareBareUDP(t *testing.T, expected, actual *BareUDP) { 555 // set the Port to 6635 (the linux default) if it wasn't specified at creation 556 if expected.Port == 0 { 557 expected.Port = 6635 558 } 559 if actual.Port != expected.Port { 560 t.Fatalf("BareUDP.Port doesn't match: %d %d", actual.Port, expected.Port) 561 } 562 563 if actual.EtherType != expected.EtherType { 564 t.Fatalf("BareUDP.EtherType doesn't match: %x %x", actual.EtherType, expected.EtherType) 565 } 566 567 if actual.SrcPortMin != expected.SrcPortMin { 568 t.Fatalf("BareUDP.SrcPortMin doesn't match: %d %d", actual.SrcPortMin, expected.SrcPortMin) 569 } 570 571 if actual.MultiProto != expected.MultiProto { 572 t.Fatal("BareUDP.MultiProto doesn't match") 573 } 574 } 575 576 func TestLinkAddDelWithIndex(t *testing.T) { 577 tearDown := setUpNetlinkTest(t) 578 defer tearDown() 579 580 testLinkAddDel(t, &Dummy{LinkAttrs{Index: 1000, Name: "foo"}}) 581 } 582 583 func TestLinkAddDelDummy(t *testing.T) { 584 tearDown := setUpNetlinkTest(t) 585 defer tearDown() 586 587 testLinkAddDel(t, &Dummy{LinkAttrs{Name: "foo"}}) 588 } 589 590 func TestLinkAddDelDummyWithGroup(t *testing.T) { 591 tearDown := setUpNetlinkTest(t) 592 defer tearDown() 593 594 testLinkAddDel(t, &Dummy{LinkAttrs{Name: "foo", Group: 42}}) 595 } 596 597 func TestLinkModify(t *testing.T) { 598 tearDown := setUpNetlinkTest(t) 599 defer tearDown() 600 601 linkName := "foo" 602 originalMTU := 1500 603 updatedMTU := 1442 604 605 link := &Dummy{LinkAttrs{Name: linkName, MTU: originalMTU}} 606 base := link.Attrs() 607 608 if err := LinkAdd(link); err != nil { 609 t.Fatal(err) 610 } 611 612 link.MTU = updatedMTU 613 if err := LinkModify(link); err != nil { 614 t.Fatal(err) 615 } 616 617 result, err := LinkByName(linkName) 618 if err != nil { 619 t.Fatal(err) 620 } 621 622 rBase := result.Attrs() 623 if rBase.MTU != updatedMTU { 624 t.Fatalf("MTU is %d, should be %d", rBase.MTU, base.MTU) 625 } 626 } 627 628 func TestLinkAddDelIfb(t *testing.T) { 629 tearDown := setUpNetlinkTest(t) 630 defer tearDown() 631 632 testLinkAddDel(t, &Ifb{LinkAttrs{Name: "foo"}}) 633 } 634 635 func TestLinkAddDelBridge(t *testing.T) { 636 tearDown := setUpNetlinkTest(t) 637 defer tearDown() 638 639 testLinkAddDel(t, &Bridge{LinkAttrs: LinkAttrs{Name: "foo", MTU: 1400}}) 640 } 641 642 func TestLinkAddDelGeneve(t *testing.T) { 643 tearDown := setUpNetlinkTest(t) 644 defer tearDown() 645 646 testLinkAddDel(t, &Geneve{ 647 LinkAttrs: LinkAttrs{Name: "foo4", EncapType: "geneve"}, 648 ID: 0x1000, 649 Remote: net.IPv4(127, 0, 0, 1)}) 650 651 testLinkAddDel(t, &Geneve{ 652 LinkAttrs: LinkAttrs{Name: "foo6", EncapType: "geneve"}, 653 ID: 0x1000, 654 Remote: net.ParseIP("2001:db8:ef33::2")}) 655 } 656 657 func TestGeneveCompareToIP(t *testing.T) { 658 ns, tearDown := setUpNamedNetlinkTest(t) 659 defer tearDown() 660 661 expected := &Geneve{ 662 ID: 0x764332, // 23 bits 663 Remote: net.ParseIP("1.2.3.4"), 664 Dport: 6081, 665 } 666 667 // Create interface 668 cmd := exec.Command("ip", "netns", "exec", ns, 669 "ip", "link", "add", "gen0", 670 "type", "geneve", 671 "vni", fmt.Sprint(expected.ID), 672 "remote", expected.Remote.String(), 673 // TODO: unit tests are currently done on ubuntu 16, and the version of iproute2 there doesn't support dstport 674 // We can still do most of the testing by verifying that we do read the default port 675 // "dstport", fmt.Sprint(expected.Dport), 676 ) 677 out := &bytes.Buffer{} 678 cmd.Stdout = out 679 cmd.Stderr = out 680 681 if rc := cmd.Run(); rc != nil { 682 t.Fatal("failed creating link:", rc, out.String()) 683 } 684 685 link, err := LinkByName("gen0") 686 if err != nil { 687 t.Fatal("Failed getting link: ", err) 688 } 689 actual, ok := link.(*Geneve) 690 if !ok { 691 t.Fatalf("resulted interface is not geneve: %T", link) 692 } 693 compareGeneve(t, expected, actual) 694 } 695 696 func TestLinkAddDelGretap(t *testing.T) { 697 tearDown := setUpNetlinkTest(t) 698 defer tearDown() 699 700 testLinkAddDel(t, &Gretap{ 701 LinkAttrs: LinkAttrs{Name: "foo4"}, 702 IKey: 0x101, 703 OKey: 0x101, 704 PMtuDisc: 1, 705 Local: net.IPv4(127, 0, 0, 1), 706 Remote: net.IPv4(127, 0, 0, 1)}) 707 708 testLinkAddDel(t, &Gretap{ 709 LinkAttrs: LinkAttrs{Name: "foo6"}, 710 IKey: 0x101, 711 OKey: 0x101, 712 Local: net.ParseIP("2001:db8:abcd::1"), 713 Remote: net.ParseIP("2001:db8:ef33::2")}) 714 } 715 716 func TestLinkAddDelGretun(t *testing.T) { 717 tearDown := setUpNetlinkTest(t) 718 defer tearDown() 719 720 testLinkAddDel(t, &Gretun{ 721 LinkAttrs: LinkAttrs{Name: "foo4"}, 722 Local: net.IPv4(127, 0, 0, 1), 723 Remote: net.IPv4(127, 0, 0, 1)}) 724 725 testLinkAddDel(t, &Gretun{ 726 LinkAttrs: LinkAttrs{Name: "foo6"}, 727 Local: net.ParseIP("2001:db8:abcd::1"), 728 Remote: net.ParseIP("2001:db8:ef33::2")}) 729 } 730 731 func TestLinkAddDelGretunPointToMultiPoint(t *testing.T) { 732 tearDown := setUpNetlinkTest(t) 733 defer tearDown() 734 735 testLinkAddDel(t, &Gretun{ 736 LinkAttrs: LinkAttrs{Name: "foo"}, 737 Local: net.IPv4(127, 0, 0, 1), 738 IKey: 1234, 739 OKey: 1234}) 740 741 testLinkAddDel(t, &Gretun{ 742 LinkAttrs: LinkAttrs{Name: "foo6"}, 743 Local: net.ParseIP("2001:db8:1234::4"), 744 IKey: 5678, 745 OKey: 7890}) 746 } 747 748 func TestLinkAddDelGretunFlowBased(t *testing.T) { 749 minKernelRequired(t, 4, 3) 750 751 tearDown := setUpNetlinkTest(t) 752 defer tearDown() 753 754 testLinkAddDel(t, &Gretun{ 755 LinkAttrs: LinkAttrs{Name: "foo"}, 756 FlowBased: true}) 757 } 758 759 func TestLinkAddDelGretapFlowBased(t *testing.T) { 760 minKernelRequired(t, 4, 3) 761 762 tearDown := setUpNetlinkTest(t) 763 defer tearDown() 764 765 testLinkAddDel(t, &Gretap{ 766 LinkAttrs: LinkAttrs{Name: "foo"}, 767 FlowBased: true}) 768 } 769 770 func TestLinkAddDelVlan(t *testing.T) { 771 tearDown := setUpNetlinkTest(t) 772 defer tearDown() 773 774 parent := &Dummy{LinkAttrs{Name: "foo"}} 775 if err := LinkAdd(parent); err != nil { 776 t.Fatal(err) 777 } 778 779 testLinkAddDel(t, &Vlan{LinkAttrs{Name: "bar", ParentIndex: parent.Attrs().Index}, 900, VLAN_PROTOCOL_8021Q}) 780 781 if err := LinkDel(parent); err != nil { 782 t.Fatal(err) 783 } 784 } 785 786 func TestLinkAddDelMacvlan(t *testing.T) { 787 tearDown := setUpNetlinkTest(t) 788 defer tearDown() 789 790 parent := &Dummy{LinkAttrs{Name: "foo"}} 791 if err := LinkAdd(parent); err != nil { 792 t.Fatal(err) 793 } 794 795 testLinkAddDel(t, &Macvlan{ 796 LinkAttrs: LinkAttrs{Name: "bar", ParentIndex: parent.Attrs().Index}, 797 Mode: MACVLAN_MODE_PRIVATE, 798 }) 799 800 testLinkAddDel(t, &Macvlan{ 801 LinkAttrs: LinkAttrs{Name: "bar", ParentIndex: parent.Attrs().Index}, 802 Mode: MACVLAN_MODE_BRIDGE, 803 }) 804 805 testLinkAddDel(t, &Macvlan{ 806 LinkAttrs: LinkAttrs{Name: "bar", ParentIndex: parent.Attrs().Index}, 807 Mode: MACVLAN_MODE_VEPA, 808 }) 809 810 if err := LinkDel(parent); err != nil { 811 t.Fatal(err) 812 } 813 } 814 815 func TestLinkAddDelMacvtap(t *testing.T) { 816 tearDown := setUpNetlinkTest(t) 817 defer tearDown() 818 819 parent := &Dummy{LinkAttrs{Name: "foo"}} 820 if err := LinkAdd(parent); err != nil { 821 t.Fatal(err) 822 } 823 824 testLinkAddDel(t, &Macvtap{ 825 Macvlan: Macvlan{ 826 LinkAttrs: LinkAttrs{Name: "bar", ParentIndex: parent.Attrs().Index}, 827 Mode: MACVLAN_MODE_PRIVATE, 828 }, 829 }) 830 831 testLinkAddDel(t, &Macvtap{ 832 Macvlan: Macvlan{ 833 LinkAttrs: LinkAttrs{Name: "bar", ParentIndex: parent.Attrs().Index}, 834 Mode: MACVLAN_MODE_BRIDGE, 835 }, 836 }) 837 838 testLinkAddDel(t, &Macvtap{ 839 Macvlan: Macvlan{ 840 LinkAttrs: LinkAttrs{Name: "bar", ParentIndex: parent.Attrs().Index}, 841 Mode: MACVLAN_MODE_VEPA, 842 }, 843 }) 844 845 if err := LinkDel(parent); err != nil { 846 t.Fatal(err) 847 } 848 } 849 850 func TestLinkAddDelVeth(t *testing.T) { 851 tearDown := setUpNetlinkTest(t) 852 defer tearDown() 853 854 peerMAC, _ := net.ParseMAC("00:12:34:56:78:02") 855 856 veth := &Veth{ 857 LinkAttrs: LinkAttrs{ 858 Name: "foo", 859 TxQLen: testTxQLen, 860 MTU: 1400, 861 NumTxQueues: testTxQueues, 862 NumRxQueues: testRxQueues, 863 }, 864 PeerName: "bar", 865 PeerHardwareAddr: peerMAC, 866 } 867 testLinkAddDel(t, veth) 868 } 869 870 func TestLinkAddDelBond(t *testing.T) { 871 minKernelRequired(t, 3, 13) 872 873 tearDown := setUpNetlinkTest(t) 874 defer tearDown() 875 876 modes := []string{"802.3ad", "balance-tlb"} 877 for _, mode := range modes { 878 bond := NewLinkBond(LinkAttrs{Name: "foo"}) 879 bond.Mode = StringToBondModeMap[mode] 880 switch mode { 881 case "802.3ad": 882 bond.AdSelect = BondAdSelect(BOND_AD_SELECT_BANDWIDTH) 883 bond.AdActorSysPrio = 1 884 bond.AdUserPortKey = 1 885 bond.AdActorSystem, _ = net.ParseMAC("06:aa:bb:cc:dd:ee") 886 bond.ArpIpTargets = []net.IP{net.ParseIP("1.1.1.1"), net.ParseIP("1.1.1.2")} 887 case "balance-tlb": 888 bond.TlbDynamicLb = 1 889 bond.ArpIpTargets = []net.IP{net.ParseIP("1.1.1.2"), net.ParseIP("1.1.1.1")} 890 } 891 testLinkAddDel(t, bond) 892 } 893 } 894 895 func TestLinkAddVethWithDefaultTxQLen(t *testing.T) { 896 tearDown := setUpNetlinkTest(t) 897 defer tearDown() 898 la := NewLinkAttrs() 899 la.Name = "foo" 900 901 veth := &Veth{LinkAttrs: la, PeerName: "bar"} 902 if err := LinkAdd(veth); err != nil { 903 t.Fatal(err) 904 } 905 link, err := LinkByName("foo") 906 if err != nil { 907 t.Fatal(err) 908 } 909 if veth, ok := link.(*Veth); !ok { 910 t.Fatalf("unexpected link type: %T", link) 911 } else { 912 if veth.TxQLen != defaultTxQLen { 913 t.Fatalf("TxQLen is %d, should be %d", veth.TxQLen, defaultTxQLen) 914 } 915 } 916 peer, err := LinkByName("bar") 917 if err != nil { 918 t.Fatal(err) 919 } 920 if veth, ok := peer.(*Veth); !ok { 921 t.Fatalf("unexpected link type: %T", link) 922 } else { 923 if veth.TxQLen != defaultTxQLen { 924 t.Fatalf("TxQLen is %d, should be %d", veth.TxQLen, defaultTxQLen) 925 } 926 } 927 } 928 929 func TestLinkAddVethWithZeroTxQLen(t *testing.T) { 930 tearDown := setUpNetlinkTest(t) 931 defer tearDown() 932 la := NewLinkAttrs() 933 la.Name = "foo" 934 la.TxQLen = 0 935 936 veth := &Veth{LinkAttrs: la, PeerName: "bar"} 937 if err := LinkAdd(veth); err != nil { 938 t.Fatal(err) 939 } 940 link, err := LinkByName("foo") 941 if err != nil { 942 t.Fatal(err) 943 } 944 if veth, ok := link.(*Veth); !ok { 945 t.Fatalf("unexpected link type: %T", link) 946 } else { 947 if veth.TxQLen != 0 { 948 t.Fatalf("TxQLen is %d, should be %d", veth.TxQLen, 0) 949 } 950 } 951 peer, err := LinkByName("bar") 952 if err != nil { 953 t.Fatal(err) 954 } 955 if veth, ok := peer.(*Veth); !ok { 956 t.Fatalf("unexpected link type: %T", link) 957 } else { 958 if veth.TxQLen != 0 { 959 t.Fatalf("TxQLen is %d, should be %d", veth.TxQLen, 0) 960 } 961 } 962 } 963 964 func TestLinkAddDelDummyWithGSO(t *testing.T) { 965 const ( 966 gsoMaxSegs = 16 967 gsoMaxSize = 1 << 14 968 ) 969 minKernelRequired(t, 4, 16) 970 tearDown := setUpNetlinkTest(t) 971 defer tearDown() 972 973 dummy := &Dummy{LinkAttrs: LinkAttrs{Name: "foo", GSOMaxSize: gsoMaxSize, GSOMaxSegs: gsoMaxSegs}} 974 if err := LinkAdd(dummy); err != nil { 975 t.Fatal(err) 976 } 977 link, err := LinkByName("foo") 978 if err != nil { 979 t.Fatal(err) 980 } 981 dummy, ok := link.(*Dummy) 982 if !ok { 983 t.Fatalf("unexpected link type: %T", link) 984 } 985 986 if dummy.GSOMaxSize != gsoMaxSize { 987 t.Fatalf("GSOMaxSize is %d, should be %d", dummy.GSOMaxSize, gsoMaxSize) 988 } 989 if dummy.GSOMaxSegs != gsoMaxSegs { 990 t.Fatalf("GSOMaxSeg is %d, should be %d", dummy.GSOMaxSegs, gsoMaxSegs) 991 } 992 } 993 994 func TestLinkAddDelDummyWithGRO(t *testing.T) { 995 const ( 996 groMaxSize = 1 << 14 997 ) 998 minKernelRequired(t, 5, 19) 999 tearDown := setUpNetlinkTest(t) 1000 defer tearDown() 1001 1002 dummy := &Dummy{LinkAttrs: LinkAttrs{Name: "foo", GROMaxSize: groMaxSize}} 1003 if err := LinkAdd(dummy); err != nil { 1004 t.Fatal(err) 1005 } 1006 link, err := LinkByName("foo") 1007 if err != nil { 1008 t.Fatal(err) 1009 } 1010 dummy, ok := link.(*Dummy) 1011 if !ok { 1012 t.Fatalf("unexpected link type: %T", link) 1013 } 1014 1015 if dummy.GROMaxSize != groMaxSize { 1016 t.Fatalf("GROMaxSize is %d, should be %d", dummy.GROMaxSize, groMaxSize) 1017 } 1018 } 1019 1020 func TestLinkAddDummyWithTxQLen(t *testing.T) { 1021 tearDown := setUpNetlinkTest(t) 1022 defer tearDown() 1023 la := NewLinkAttrs() 1024 la.Name = "foo" 1025 la.TxQLen = 1500 1026 1027 dummy := &Dummy{LinkAttrs: la} 1028 if err := LinkAdd(dummy); err != nil { 1029 t.Fatal(err) 1030 } 1031 link, err := LinkByName("foo") 1032 if err != nil { 1033 t.Fatal(err) 1034 } 1035 if dummy, ok := link.(*Dummy); !ok { 1036 t.Fatalf("unexpected link type: %T", link) 1037 } else { 1038 if dummy.TxQLen != 1500 { 1039 t.Fatalf("TxQLen is %d, should be %d", dummy.TxQLen, 1500) 1040 } 1041 } 1042 } 1043 1044 func TestLinkAddDelBridgeMaster(t *testing.T) { 1045 tearDown := setUpNetlinkTest(t) 1046 defer tearDown() 1047 1048 master := &Bridge{LinkAttrs: LinkAttrs{Name: "foo"}} 1049 if err := LinkAdd(master); err != nil { 1050 t.Fatal(err) 1051 } 1052 testLinkAddDel(t, &Dummy{LinkAttrs{Name: "bar", MasterIndex: master.Attrs().Index}}) 1053 1054 if err := LinkDel(master); err != nil { 1055 t.Fatal(err) 1056 } 1057 } 1058 1059 func testLinkSetUnsetResetMaster(t *testing.T, master, newmaster Link) { 1060 slave := &Dummy{LinkAttrs{Name: "baz"}} 1061 if err := LinkAdd(slave); err != nil { 1062 t.Fatal(err) 1063 } 1064 1065 nonexistsmaster := &Bridge{LinkAttrs: LinkAttrs{Name: "foobar"}} 1066 1067 if err := LinkSetMaster(slave, nonexistsmaster); err == nil { 1068 t.Fatal("error expected") 1069 } 1070 1071 if err := LinkSetMaster(slave, master); err != nil { 1072 t.Fatal(err) 1073 } 1074 1075 link, err := LinkByName("baz") 1076 if err != nil { 1077 t.Fatal(err) 1078 } 1079 1080 if link.Attrs().MasterIndex != master.Attrs().Index { 1081 t.Fatal("Master not set properly") 1082 } 1083 1084 if err := LinkSetMaster(slave, newmaster); err != nil { 1085 t.Fatal(err) 1086 } 1087 1088 link, err = LinkByName("baz") 1089 if err != nil { 1090 t.Fatal(err) 1091 } 1092 1093 if link.Attrs().MasterIndex != newmaster.Attrs().Index { 1094 t.Fatal("Master not reset properly") 1095 } 1096 1097 if err := LinkSetNoMaster(slave); err != nil { 1098 t.Fatal(err) 1099 } 1100 1101 link, err = LinkByName("baz") 1102 if err != nil { 1103 t.Fatal(err) 1104 } 1105 1106 if link.Attrs().MasterIndex != 0 { 1107 t.Fatal("Master not unset properly") 1108 } 1109 if err := LinkDel(slave); err != nil { 1110 t.Fatal(err) 1111 } 1112 } 1113 1114 func TestLinkSetUnsetResetMaster(t *testing.T) { 1115 tearDown := setUpNetlinkTest(t) 1116 defer tearDown() 1117 1118 master := &Bridge{LinkAttrs: LinkAttrs{Name: "foo"}} 1119 if err := LinkAdd(master); err != nil { 1120 t.Fatal(err) 1121 } 1122 1123 newmaster := &Bridge{LinkAttrs: LinkAttrs{Name: "bar"}} 1124 if err := LinkAdd(newmaster); err != nil { 1125 t.Fatal(err) 1126 } 1127 1128 testLinkSetUnsetResetMaster(t, master, newmaster) 1129 1130 if err := LinkDel(newmaster); err != nil { 1131 t.Fatal(err) 1132 } 1133 1134 if err := LinkDel(master); err != nil { 1135 t.Fatal(err) 1136 } 1137 } 1138 1139 func TestLinkSetUnsetResetMasterBond(t *testing.T) { 1140 tearDown := setUpNetlinkTest(t) 1141 defer tearDown() 1142 1143 master := NewLinkBond(LinkAttrs{Name: "foo"}) 1144 master.Mode = BOND_MODE_BALANCE_RR 1145 if err := LinkAdd(master); err != nil { 1146 t.Fatal(err) 1147 } 1148 1149 newmaster := NewLinkBond(LinkAttrs{Name: "bar"}) 1150 newmaster.Mode = BOND_MODE_BALANCE_RR 1151 if err := LinkAdd(newmaster); err != nil { 1152 t.Fatal(err) 1153 } 1154 1155 testLinkSetUnsetResetMaster(t, master, newmaster) 1156 1157 if err := LinkDel(newmaster); err != nil { 1158 t.Fatal(err) 1159 } 1160 1161 if err := LinkDel(master); err != nil { 1162 t.Fatal(err) 1163 } 1164 } 1165 1166 func TestLinkSetNs(t *testing.T) { 1167 tearDown := setUpNetlinkTest(t) 1168 defer tearDown() 1169 1170 basens, err := netns.Get() 1171 if err != nil { 1172 t.Fatal("Failed to get basens") 1173 } 1174 defer basens.Close() 1175 1176 newns, err := netns.New() 1177 if err != nil { 1178 t.Fatal("Failed to create newns") 1179 } 1180 defer newns.Close() 1181 1182 link := &Veth{LinkAttrs{Name: "foo"}, "bar", nil, nil} 1183 if err := LinkAdd(link); err != nil { 1184 t.Fatal(err) 1185 } 1186 1187 peer, err := LinkByName("bar") 1188 if err != nil { 1189 t.Fatal(err) 1190 } 1191 1192 LinkSetNsFd(peer, int(basens)) 1193 if err != nil { 1194 t.Fatal("Failed to set newns for link") 1195 } 1196 1197 _, err = LinkByName("bar") 1198 if err == nil { 1199 t.Fatal("Link bar is still in newns") 1200 } 1201 1202 err = netns.Set(basens) 1203 if err != nil { 1204 t.Fatal("Failed to set basens") 1205 } 1206 1207 peer, err = LinkByName("bar") 1208 if err != nil { 1209 t.Fatal("Link is not in basens") 1210 } 1211 1212 if err := LinkDel(peer); err != nil { 1213 t.Fatal(err) 1214 } 1215 1216 err = netns.Set(newns) 1217 if err != nil { 1218 t.Fatal("Failed to set newns") 1219 } 1220 1221 _, err = LinkByName("foo") 1222 if err == nil { 1223 t.Fatal("Other half of veth pair not deleted") 1224 } 1225 1226 } 1227 1228 func TestLinkAddDelWireguard(t *testing.T) { 1229 minKernelRequired(t, 5, 6) 1230 1231 tearDown := setUpNetlinkTest(t) 1232 defer tearDown() 1233 1234 testLinkAddDel(t, &Wireguard{LinkAttrs: LinkAttrs{Name: "wg0"}}) 1235 } 1236 1237 func TestVethPeerNs(t *testing.T) { 1238 tearDown := setUpNetlinkTest(t) 1239 defer tearDown() 1240 1241 basens, err := netns.Get() 1242 if err != nil { 1243 t.Fatal("Failed to get basens") 1244 } 1245 defer basens.Close() 1246 1247 newns, err := netns.New() 1248 if err != nil { 1249 t.Fatal("Failed to create newns") 1250 } 1251 defer newns.Close() 1252 1253 link := &Veth{LinkAttrs{Name: "foo"}, "bar", nil, NsFd(basens)} 1254 if err := LinkAdd(link); err != nil { 1255 t.Fatal(err) 1256 } 1257 1258 _, err = LinkByName("bar") 1259 if err == nil { 1260 t.Fatal("Link bar is in newns") 1261 } 1262 1263 err = netns.Set(basens) 1264 if err != nil { 1265 t.Fatal("Failed to set basens") 1266 } 1267 1268 _, err = LinkByName("bar") 1269 if err != nil { 1270 t.Fatal("Link bar is not in basens") 1271 } 1272 1273 err = netns.Set(newns) 1274 if err != nil { 1275 t.Fatal("Failed to set newns") 1276 } 1277 1278 _, err = LinkByName("foo") 1279 if err != nil { 1280 t.Fatal("Link foo is not in newns") 1281 } 1282 } 1283 1284 func TestVethPeerNs2(t *testing.T) { 1285 tearDown := setUpNetlinkTest(t) 1286 defer tearDown() 1287 1288 basens, err := netns.Get() 1289 if err != nil { 1290 t.Fatal("Failed to get basens") 1291 } 1292 defer basens.Close() 1293 1294 onens, err := netns.New() 1295 if err != nil { 1296 t.Fatal("Failed to create newns") 1297 } 1298 defer onens.Close() 1299 1300 twons, err := netns.New() 1301 if err != nil { 1302 t.Fatal("Failed to create twons") 1303 } 1304 defer twons.Close() 1305 1306 link := &Veth{LinkAttrs{Name: "foo", Namespace: NsFd(onens)}, "bar", nil, NsFd(basens)} 1307 if err := LinkAdd(link); err != nil { 1308 t.Fatal(err) 1309 } 1310 1311 _, err = LinkByName("foo") 1312 if err == nil { 1313 t.Fatal("Link foo is in twons") 1314 } 1315 1316 _, err = LinkByName("bar") 1317 if err == nil { 1318 t.Fatal("Link bar is in twons") 1319 } 1320 1321 err = netns.Set(basens) 1322 if err != nil { 1323 t.Fatal("Failed to set basens") 1324 } 1325 1326 _, err = LinkByName("bar") 1327 if err != nil { 1328 t.Fatal("Link bar is not in basens") 1329 } 1330 1331 err = netns.Set(onens) 1332 if err != nil { 1333 t.Fatal("Failed to set onens") 1334 } 1335 1336 _, err = LinkByName("foo") 1337 if err != nil { 1338 t.Fatal("Link foo is not in onens") 1339 } 1340 } 1341 1342 func TestLinkAddDelVxlan(t *testing.T) { 1343 tearDown := setUpNetlinkTest(t) 1344 defer tearDown() 1345 1346 parent := &Dummy{ 1347 LinkAttrs{Name: "foo"}, 1348 } 1349 if err := LinkAdd(parent); err != nil { 1350 t.Fatal(err) 1351 } 1352 1353 vxlan := Vxlan{ 1354 LinkAttrs: LinkAttrs{ 1355 Name: "bar", 1356 }, 1357 VxlanId: 10, 1358 VtepDevIndex: parent.Index, 1359 Learning: true, 1360 L2miss: true, 1361 L3miss: true, 1362 } 1363 1364 testLinkAddDel(t, &vxlan) 1365 if err := LinkDel(parent); err != nil { 1366 t.Fatal(err) 1367 } 1368 } 1369 1370 func TestLinkAddDelVxlanUdpCSum6(t *testing.T) { 1371 minKernelRequired(t, 3, 16) 1372 tearDown := setUpNetlinkTest(t) 1373 defer tearDown() 1374 1375 parent := &Dummy{ 1376 LinkAttrs{Name: "foo"}, 1377 } 1378 if err := LinkAdd(parent); err != nil { 1379 t.Fatal(err) 1380 } 1381 1382 vxlan := Vxlan{ 1383 LinkAttrs: LinkAttrs{ 1384 Name: "bar", 1385 }, 1386 VxlanId: 10, 1387 VtepDevIndex: parent.Index, 1388 Learning: true, 1389 L2miss: true, 1390 L3miss: true, 1391 UDP6ZeroCSumTx: true, 1392 UDP6ZeroCSumRx: true, 1393 } 1394 1395 testLinkAddDel(t, &vxlan) 1396 if err := LinkDel(parent); err != nil { 1397 t.Fatal(err) 1398 } 1399 } 1400 1401 func TestLinkAddDelVxlanGbp(t *testing.T) { 1402 minKernelRequired(t, 4, 0) 1403 1404 tearDown := setUpNetlinkTest(t) 1405 defer tearDown() 1406 1407 parent := &Dummy{ 1408 LinkAttrs{Name: "foo"}, 1409 } 1410 if err := LinkAdd(parent); err != nil { 1411 t.Fatal(err) 1412 } 1413 1414 vxlan := Vxlan{ 1415 LinkAttrs: LinkAttrs{ 1416 Name: "bar", 1417 }, 1418 VxlanId: 10, 1419 VtepDevIndex: parent.Index, 1420 Learning: true, 1421 L2miss: true, 1422 L3miss: true, 1423 UDP6ZeroCSumTx: true, 1424 UDP6ZeroCSumRx: true, 1425 GBP: true, 1426 } 1427 1428 testLinkAddDel(t, &vxlan) 1429 if err := LinkDel(parent); err != nil { 1430 t.Fatal(err) 1431 } 1432 } 1433 1434 func TestLinkAddDelVxlanFlowBased(t *testing.T) { 1435 minKernelRequired(t, 4, 3) 1436 1437 tearDown := setUpNetlinkTest(t) 1438 defer tearDown() 1439 1440 vxlan := Vxlan{ 1441 LinkAttrs: LinkAttrs{ 1442 Name: "foo", 1443 }, 1444 Learning: false, 1445 FlowBased: true, 1446 } 1447 1448 testLinkAddDel(t, &vxlan) 1449 } 1450 1451 func TestLinkAddDelBareUDP(t *testing.T) { 1452 if os.Getenv("CI") == "true" { 1453 t.Skipf("Fails in CI due to operation not supported (missing kernel module?)") 1454 } 1455 minKernelRequired(t, 5, 8) 1456 tearDown := setUpNetlinkTest(t) 1457 defer tearDown() 1458 1459 testLinkAddDel(t, &BareUDP{ 1460 LinkAttrs: LinkAttrs{Name: "foo99"}, 1461 Port: 6635, 1462 EtherType: syscall.ETH_P_MPLS_UC, 1463 SrcPortMin: 12345, 1464 MultiProto: true, 1465 }) 1466 1467 testLinkAddDel(t, &BareUDP{ 1468 LinkAttrs: LinkAttrs{Name: "foo100"}, 1469 Port: 6635, 1470 EtherType: syscall.ETH_P_IP, 1471 SrcPortMin: 12345, 1472 MultiProto: true, 1473 }) 1474 } 1475 1476 func TestBareUDPCompareToIP(t *testing.T) { 1477 if os.Getenv("CI") == "true" { 1478 t.Skipf("Fails in CI due to old iproute2") 1479 } 1480 // requires iproute2 >= 5.10 1481 minKernelRequired(t, 5, 9) 1482 ns, tearDown := setUpNamedNetlinkTest(t) 1483 defer tearDown() 1484 1485 expected := &BareUDP{ 1486 Port: uint16(6635), 1487 EtherType: syscall.ETH_P_MPLS_UC, 1488 SrcPortMin: 12345, 1489 MultiProto: true, 1490 } 1491 1492 // Create interface 1493 cmd := exec.Command("ip", "netns", "exec", ns, 1494 "ip", "link", "add", "b0", 1495 "type", "bareudp", 1496 "dstport", fmt.Sprint(expected.Port), 1497 "ethertype", "mpls_uc", 1498 "srcportmin", fmt.Sprint(expected.SrcPortMin), 1499 "multiproto", 1500 ) 1501 out := &bytes.Buffer{} 1502 cmd.Stdout = out 1503 cmd.Stderr = out 1504 1505 if rc := cmd.Run(); rc != nil { 1506 t.Fatal("failed creating link:", rc, out.String()) 1507 } 1508 1509 link, err := LinkByName("b0") 1510 if err != nil { 1511 t.Fatal("Failed getting link: ", err) 1512 } 1513 actual, ok := link.(*BareUDP) 1514 if !ok { 1515 t.Fatalf("resulted interface is not BareUDP: %T", link) 1516 } 1517 compareBareUDP(t, expected, actual) 1518 } 1519 1520 func TestLinkAddDelIPVlanL2(t *testing.T) { 1521 minKernelRequired(t, 4, 2) 1522 tearDown := setUpNetlinkTest(t) 1523 defer tearDown() 1524 parent := &Dummy{LinkAttrs{Name: "foo"}} 1525 if err := LinkAdd(parent); err != nil { 1526 t.Fatal(err) 1527 } 1528 1529 ipv := IPVlan{ 1530 LinkAttrs: LinkAttrs{ 1531 Name: "bar", 1532 ParentIndex: parent.Index, 1533 }, 1534 Mode: IPVLAN_MODE_L2, 1535 } 1536 1537 testLinkAddDel(t, &ipv) 1538 } 1539 1540 func TestLinkAddDelIPVlanL3(t *testing.T) { 1541 minKernelRequired(t, 4, 2) 1542 tearDown := setUpNetlinkTest(t) 1543 defer tearDown() 1544 parent := &Dummy{LinkAttrs{Name: "foo"}} 1545 if err := LinkAdd(parent); err != nil { 1546 t.Fatal(err) 1547 } 1548 1549 ipv := IPVlan{ 1550 LinkAttrs: LinkAttrs{ 1551 Name: "bar", 1552 ParentIndex: parent.Index, 1553 }, 1554 Mode: IPVLAN_MODE_L3, 1555 } 1556 1557 testLinkAddDel(t, &ipv) 1558 } 1559 1560 func TestLinkAddDelIPVlanVepa(t *testing.T) { 1561 minKernelRequired(t, 4, 15) 1562 tearDown := setUpNetlinkTest(t) 1563 defer tearDown() 1564 parent := &Dummy{LinkAttrs{Name: "foo"}} 1565 if err := LinkAdd(parent); err != nil { 1566 t.Fatal(err) 1567 } 1568 1569 ipv := IPVlan{ 1570 LinkAttrs: LinkAttrs{ 1571 Name: "bar", 1572 ParentIndex: parent.Index, 1573 }, 1574 Mode: IPVLAN_MODE_L3, 1575 Flag: IPVLAN_FLAG_VEPA, 1576 } 1577 1578 testLinkAddDel(t, &ipv) 1579 } 1580 1581 func TestLinkAddDelIPVlanNoParent(t *testing.T) { 1582 tearDown := setUpNetlinkTest(t) 1583 defer tearDown() 1584 1585 ipv := IPVlan{ 1586 LinkAttrs: LinkAttrs{ 1587 Name: "bar", 1588 }, 1589 Mode: IPVLAN_MODE_L3, 1590 } 1591 err := LinkAdd(&ipv) 1592 if err == nil { 1593 t.Fatal("Add should fail if ipvlan creating without ParentIndex") 1594 } 1595 if err.Error() != "Can't create ipvlan link without ParentIndex" { 1596 t.Fatalf("Error should be about missing ParentIndex, got %q", err) 1597 } 1598 } 1599 1600 func TestLinkByIndex(t *testing.T) { 1601 tearDown := setUpNetlinkTest(t) 1602 defer tearDown() 1603 1604 dummy := &Dummy{LinkAttrs{Name: "dummy"}} 1605 if err := LinkAdd(dummy); err != nil { 1606 t.Fatal(err) 1607 } 1608 1609 found, err := LinkByIndex(dummy.Index) 1610 if err != nil { 1611 t.Fatal(err) 1612 } 1613 1614 if found.Attrs().Index != dummy.Attrs().Index { 1615 t.Fatalf("Indices don't match: %v != %v", found.Attrs().Index, dummy.Attrs().Index) 1616 } 1617 1618 LinkDel(dummy) 1619 1620 // test not found 1621 _, err = LinkByIndex(dummy.Attrs().Index) 1622 if err == nil { 1623 t.Fatalf("LinkByIndex(%v) found deleted link", err) 1624 } 1625 } 1626 1627 func TestLinkSet(t *testing.T) { 1628 tearDown := setUpNetlinkTest(t) 1629 defer tearDown() 1630 1631 iface := &Dummy{LinkAttrs{Name: "foo"}} 1632 if err := LinkAdd(iface); err != nil { 1633 t.Fatal(err) 1634 } 1635 1636 link, err := LinkByName("foo") 1637 if err != nil { 1638 t.Fatal(err) 1639 } 1640 1641 err = LinkSetName(link, "bar") 1642 if err != nil { 1643 t.Fatalf("Could not change interface name: %v", err) 1644 } 1645 1646 link, err = LinkByName("bar") 1647 if err != nil { 1648 t.Fatalf("Interface name not changed: %v", err) 1649 } 1650 1651 err = LinkSetMTU(link, 1400) 1652 if err != nil { 1653 t.Fatalf("Could not set MTU: %v", err) 1654 } 1655 1656 link, err = LinkByName("bar") 1657 if err != nil { 1658 t.Fatal(err) 1659 } 1660 1661 if link.Attrs().MTU != 1400 { 1662 t.Fatal("MTU not changed") 1663 } 1664 1665 err = LinkSetTxQLen(link, 500) 1666 if err != nil { 1667 t.Fatalf("Could not set txqlen: %v", err) 1668 } 1669 1670 link, err = LinkByName("bar") 1671 if err != nil { 1672 t.Fatal(err) 1673 } 1674 1675 if link.Attrs().TxQLen != 500 { 1676 t.Fatal("txqlen not changed") 1677 } 1678 1679 addr, err := net.ParseMAC("00:12:34:56:78:AB") 1680 if err != nil { 1681 t.Fatal(err) 1682 } 1683 1684 err = LinkSetHardwareAddr(link, addr) 1685 if err != nil { 1686 t.Fatal(err) 1687 } 1688 1689 link, err = LinkByName("bar") 1690 if err != nil { 1691 t.Fatal(err) 1692 } 1693 1694 if !bytes.Equal(link.Attrs().HardwareAddr, addr) { 1695 t.Fatalf("hardware address not changed") 1696 } 1697 1698 err = LinkSetAlias(link, "barAlias") 1699 if err != nil { 1700 t.Fatalf("Could not set alias: %v", err) 1701 } 1702 1703 link, err = LinkByName("bar") 1704 if err != nil { 1705 t.Fatal(err) 1706 } 1707 1708 if link.Attrs().Alias != "barAlias" { 1709 t.Fatalf("alias not changed") 1710 } 1711 1712 link, err = LinkByAlias("barAlias") 1713 if err != nil { 1714 t.Fatal(err) 1715 } 1716 1717 err = LinkSetGroup(link, 42) 1718 if err != nil { 1719 t.Fatalf("Could not set group: %v", err) 1720 } 1721 1722 link, err = LinkByName("bar") 1723 if err != nil { 1724 t.Fatal(err) 1725 } 1726 1727 if link.Attrs().Group != 42 { 1728 t.Fatal("Link group not changed") 1729 } 1730 } 1731 1732 func TestLinkSetARP(t *testing.T) { 1733 tearDown := setUpNetlinkTest(t) 1734 defer tearDown() 1735 1736 iface := &Veth{LinkAttrs: LinkAttrs{Name: "foo", TxQLen: testTxQLen, MTU: 1500}, PeerName: "banana"} 1737 if err := LinkAdd(iface); err != nil { 1738 t.Fatal(err) 1739 } 1740 1741 link, err := LinkByName("foo") 1742 if err != nil { 1743 t.Fatal(err) 1744 } 1745 1746 err = LinkSetARPOff(link) 1747 if err != nil { 1748 t.Fatal(err) 1749 } 1750 1751 link, err = LinkByName("foo") 1752 if err != nil { 1753 t.Fatal(err) 1754 } 1755 1756 if link.Attrs().RawFlags&unix.IFF_NOARP != uint32(unix.IFF_NOARP) { 1757 t.Fatalf("NOARP was not set") 1758 } 1759 1760 err = LinkSetARPOn(link) 1761 if err != nil { 1762 t.Fatal(err) 1763 } 1764 1765 link, err = LinkByName("foo") 1766 if err != nil { 1767 t.Fatal(err) 1768 } 1769 1770 if link.Attrs().RawFlags&unix.IFF_NOARP != 0 { 1771 t.Fatalf("NOARP is still set") 1772 } 1773 } 1774 1775 func expectLinkUpdate(ch <-chan LinkUpdate, ifaceName string, up bool) bool { 1776 for { 1777 timeout := time.After(time.Minute) 1778 select { 1779 case update := <-ch: 1780 if ifaceName == update.Link.Attrs().Name && (update.IfInfomsg.Flags&unix.IFF_UP != 0) == up { 1781 return true 1782 } 1783 case <-timeout: 1784 return false 1785 } 1786 } 1787 } 1788 1789 func TestLinkSubscribe(t *testing.T) { 1790 tearDown := setUpNetlinkTest(t) 1791 defer tearDown() 1792 1793 ch := make(chan LinkUpdate) 1794 done := make(chan struct{}) 1795 defer close(done) 1796 if err := LinkSubscribe(ch, done); err != nil { 1797 t.Fatal(err) 1798 } 1799 1800 link := &Veth{LinkAttrs{Name: "foo", TxQLen: testTxQLen, MTU: 1400}, "bar", nil, nil} 1801 if err := LinkAdd(link); err != nil { 1802 t.Fatal(err) 1803 } 1804 1805 if !expectLinkUpdate(ch, "foo", false) { 1806 t.Fatal("Add update not received as expected") 1807 } 1808 1809 if err := LinkSetUp(link); err != nil { 1810 t.Fatal(err) 1811 } 1812 1813 if !expectLinkUpdate(ch, "foo", true) { 1814 t.Fatal("Link Up update not received as expected") 1815 } 1816 1817 if err := LinkDel(link); err != nil { 1818 t.Fatal(err) 1819 } 1820 1821 if !expectLinkUpdate(ch, "foo", false) { 1822 t.Fatal("Del update not received as expected") 1823 } 1824 } 1825 1826 func TestLinkSubscribeWithOptions(t *testing.T) { 1827 tearDown := setUpNetlinkTest(t) 1828 defer tearDown() 1829 1830 ch := make(chan LinkUpdate) 1831 done := make(chan struct{}) 1832 defer close(done) 1833 var lastError error 1834 defer func() { 1835 if lastError != nil { 1836 t.Fatalf("Fatal error received during subscription: %v", lastError) 1837 } 1838 }() 1839 if err := LinkSubscribeWithOptions(ch, done, LinkSubscribeOptions{ 1840 ErrorCallback: func(err error) { 1841 lastError = err 1842 }, 1843 }); err != nil { 1844 t.Fatal(err) 1845 } 1846 1847 link := &Veth{LinkAttrs{Name: "foo", TxQLen: testTxQLen, MTU: 1400}, "bar", nil, nil} 1848 if err := LinkAdd(link); err != nil { 1849 t.Fatal(err) 1850 } 1851 1852 if !expectLinkUpdate(ch, "foo", false) { 1853 t.Fatal("Add update not received as expected") 1854 } 1855 } 1856 1857 func TestLinkSubscribeAt(t *testing.T) { 1858 skipUnlessRoot(t) 1859 1860 // Create an handle on a custom netns 1861 newNs, err := netns.New() 1862 if err != nil { 1863 t.Fatal(err) 1864 } 1865 defer newNs.Close() 1866 1867 nh, err := NewHandleAt(newNs) 1868 if err != nil { 1869 t.Fatal(err) 1870 } 1871 defer nh.Close() 1872 1873 // Subscribe for Link events on the custom netns 1874 ch := make(chan LinkUpdate) 1875 done := make(chan struct{}) 1876 defer close(done) 1877 if err := LinkSubscribeAt(newNs, ch, done); err != nil { 1878 t.Fatal(err) 1879 } 1880 1881 link := &Veth{LinkAttrs{Name: "test", TxQLen: testTxQLen, MTU: 1400}, "bar", nil, nil} 1882 if err := nh.LinkAdd(link); err != nil { 1883 t.Fatal(err) 1884 } 1885 1886 if !expectLinkUpdate(ch, "test", false) { 1887 t.Fatal("Add update not received as expected") 1888 } 1889 1890 if err := nh.LinkSetUp(link); err != nil { 1891 t.Fatal(err) 1892 } 1893 1894 if !expectLinkUpdate(ch, "test", true) { 1895 t.Fatal("Link Up update not received as expected") 1896 } 1897 1898 if err := nh.LinkDel(link); err != nil { 1899 t.Fatal(err) 1900 } 1901 1902 if !expectLinkUpdate(ch, "test", false) { 1903 t.Fatal("Del update not received as expected") 1904 } 1905 } 1906 1907 func TestLinkSubscribeListExisting(t *testing.T) { 1908 skipUnlessRoot(t) 1909 1910 // Create an handle on a custom netns 1911 newNs, err := netns.New() 1912 if err != nil { 1913 t.Fatal(err) 1914 } 1915 defer newNs.Close() 1916 1917 nh, err := NewHandleAt(newNs) 1918 if err != nil { 1919 t.Fatal(err) 1920 } 1921 defer nh.Close() 1922 1923 link := &Veth{LinkAttrs{Name: "test", TxQLen: testTxQLen, MTU: 1400}, "bar", nil, nil} 1924 if err := nh.LinkAdd(link); err != nil { 1925 t.Fatal(err) 1926 } 1927 1928 // Subscribe for Link events on the custom netns 1929 ch := make(chan LinkUpdate) 1930 done := make(chan struct{}) 1931 defer close(done) 1932 if err := LinkSubscribeWithOptions(ch, done, LinkSubscribeOptions{ 1933 Namespace: &newNs, 1934 ListExisting: true}, 1935 ); err != nil { 1936 t.Fatal(err) 1937 } 1938 1939 if !expectLinkUpdate(ch, "test", false) { 1940 t.Fatal("Add update not received as expected") 1941 } 1942 1943 if err := nh.LinkSetUp(link); err != nil { 1944 t.Fatal(err) 1945 } 1946 1947 if !expectLinkUpdate(ch, "test", true) { 1948 t.Fatal("Link Up update not received as expected") 1949 } 1950 1951 if err := nh.LinkDel(link); err != nil { 1952 t.Fatal(err) 1953 } 1954 1955 if !expectLinkUpdate(ch, "test", false) { 1956 t.Fatal("Del update not received as expected") 1957 } 1958 } 1959 1960 func TestLinkStats(t *testing.T) { 1961 defer setUpNetlinkTest(t)() 1962 1963 // Create a veth pair and verify the cross-stats once both 1964 // ends are brought up and some ICMPv6 packets are exchanged 1965 v0 := "v0" 1966 v1 := "v1" 1967 1968 vethLink := &Veth{LinkAttrs: LinkAttrs{Name: v0}, PeerName: v1} 1969 if err := LinkAdd(vethLink); err != nil { 1970 t.Fatal(err) 1971 } 1972 1973 veth0, err := LinkByName(v0) 1974 if err != nil { 1975 t.Fatal(err) 1976 } 1977 if err := LinkSetUp(veth0); err != nil { 1978 t.Fatal(err) 1979 } 1980 1981 veth1, err := LinkByName(v1) 1982 if err != nil { 1983 t.Fatal(err) 1984 } 1985 if err := LinkSetUp(veth1); err != nil { 1986 t.Fatal(err) 1987 } 1988 1989 time.Sleep(2 * time.Second) 1990 1991 // verify statistics 1992 veth0, err = LinkByName(v0) 1993 if err != nil { 1994 t.Fatal(err) 1995 } 1996 veth1, err = LinkByName(v1) 1997 if err != nil { 1998 t.Fatal(err) 1999 } 2000 v0Stats := veth0.Attrs().Statistics 2001 v1Stats := veth1.Attrs().Statistics 2002 if v0Stats.RxPackets != v1Stats.TxPackets || v0Stats.TxPackets != v1Stats.RxPackets || 2003 v0Stats.RxBytes != v1Stats.TxBytes || v0Stats.TxBytes != v1Stats.RxBytes { 2004 t.Fatalf("veth ends counters differ:\n%v\n%v", v0Stats, v1Stats) 2005 } 2006 } 2007 2008 func TestLinkXdp(t *testing.T) { 2009 links, err := LinkList() 2010 if err != nil { 2011 t.Fatal(err) 2012 } 2013 var testXdpLink Link 2014 for _, link := range links { 2015 if link.Attrs().Xdp != nil && !link.Attrs().Xdp.Attached { 2016 testXdpLink = link 2017 break 2018 } 2019 } 2020 if testXdpLink == nil { 2021 t.Skipf("No link supporting XDP found") 2022 } 2023 fd, err := loadSimpleBpf(BPF_PROG_TYPE_XDP, 2 /*XDP_PASS*/) 2024 if err != nil { 2025 t.Skipf("Loading bpf program failed: %s", err) 2026 } 2027 if err := LinkSetXdpFd(testXdpLink, fd); err != nil { 2028 t.Fatal(err) 2029 } 2030 if err := LinkSetXdpFdWithFlags(testXdpLink, fd, nl.XDP_FLAGS_UPDATE_IF_NOEXIST); err != unix.EBUSY { 2031 t.Fatal(err) 2032 } 2033 if err := LinkSetXdpFd(testXdpLink, -1); err != nil { 2034 t.Fatal(err) 2035 } 2036 } 2037 2038 func TestLinkAddDelIptun(t *testing.T) { 2039 minKernelRequired(t, 4, 9) 2040 tearDown := setUpNetlinkTest(t) 2041 defer tearDown() 2042 2043 testLinkAddDel(t, &Iptun{ 2044 LinkAttrs: LinkAttrs{Name: "iptunfoo"}, 2045 PMtuDisc: 1, 2046 Local: net.IPv4(127, 0, 0, 1), 2047 Remote: net.IPv4(127, 0, 0, 1)}) 2048 } 2049 2050 func TestLinkAddDelIp6tnl(t *testing.T) { 2051 tearDown := setUpNetlinkTest(t) 2052 defer tearDown() 2053 2054 testLinkAddDel(t, &Ip6tnl{ 2055 LinkAttrs: LinkAttrs{Name: "ip6tnltest"}, 2056 Local: net.ParseIP("2001:db8::100"), 2057 Remote: net.ParseIP("2001:db8::200"), 2058 }) 2059 } 2060 2061 func TestLinkAddDelSittun(t *testing.T) { 2062 tearDown := setUpNetlinkTest(t) 2063 defer tearDown() 2064 2065 testLinkAddDel(t, &Sittun{ 2066 LinkAttrs: LinkAttrs{Name: "sittunfoo"}, 2067 PMtuDisc: 1, 2068 Local: net.IPv4(127, 0, 0, 1), 2069 Remote: net.IPv4(127, 0, 0, 1)}) 2070 } 2071 2072 func TestLinkAddDelVti(t *testing.T) { 2073 tearDown := setUpNetlinkTest(t) 2074 defer tearDown() 2075 2076 testLinkAddDel(t, &Vti{ 2077 LinkAttrs: LinkAttrs{Name: "vtifoo"}, 2078 IKey: 0x101, 2079 OKey: 0x101, 2080 Local: net.IPv4(127, 0, 0, 1), 2081 Remote: net.IPv4(127, 0, 0, 1)}) 2082 2083 testLinkAddDel(t, &Vti{ 2084 LinkAttrs: LinkAttrs{Name: "vtibar"}, 2085 IKey: 0x101, 2086 OKey: 0x101, 2087 Local: net.IPv6loopback, 2088 Remote: net.IPv6loopback}) 2089 } 2090 2091 func TestLinkSetGSOMaxSize(t *testing.T) { 2092 minKernelRequired(t, 5, 19) 2093 tearDown := setUpNetlinkTest(t) 2094 defer tearDown() 2095 2096 iface := &Veth{LinkAttrs: LinkAttrs{Name: "foo", TxQLen: testTxQLen, MTU: 1500}, PeerName: "bar"} 2097 if err := LinkAdd(iface); err != nil { 2098 t.Fatal(err) 2099 } 2100 2101 link, err := LinkByName("foo") 2102 if err != nil { 2103 t.Fatal(err) 2104 } 2105 2106 err = LinkSetGSOMaxSize(link, 32768) 2107 if err != nil { 2108 t.Fatal(err) 2109 } 2110 2111 link, err = LinkByName("foo") 2112 if err != nil { 2113 t.Fatal(err) 2114 } 2115 2116 if link.Attrs().GSOMaxSize != 32768 { 2117 t.Fatalf("GSO max size was not modified") 2118 } 2119 } 2120 2121 func TestLinkSetGROMaxSize(t *testing.T) { 2122 minKernelRequired(t, 5, 19) 2123 tearDown := setUpNetlinkTest(t) 2124 defer tearDown() 2125 2126 iface := &Veth{LinkAttrs: LinkAttrs{Name: "foo", TxQLen: testTxQLen, MTU: 1500}, PeerName: "bar"} 2127 if err := LinkAdd(iface); err != nil { 2128 t.Fatal(err) 2129 } 2130 2131 link, err := LinkByName("foo") 2132 if err != nil { 2133 t.Fatal(err) 2134 } 2135 2136 err = LinkSetGROMaxSize(link, 32768) 2137 if err != nil { 2138 t.Fatal(err) 2139 } 2140 2141 link, err = LinkByName("foo") 2142 if err != nil { 2143 t.Fatal(err) 2144 } 2145 2146 if link.Attrs().GROMaxSize != 32768 { 2147 t.Fatalf("GRO max size was not modified") 2148 } 2149 } 2150 2151 func TestBridgeCreationWithMulticastSnooping(t *testing.T) { 2152 minKernelRequired(t, 4, 4) 2153 2154 tearDown := setUpNetlinkTest(t) 2155 defer tearDown() 2156 2157 bridgeWithDefaultMcastSnoopName := "foo" 2158 bridgeWithDefaultMcastSnoop := &Bridge{LinkAttrs: LinkAttrs{Name: bridgeWithDefaultMcastSnoopName}} 2159 if err := LinkAdd(bridgeWithDefaultMcastSnoop); err != nil { 2160 t.Fatal(err) 2161 } 2162 expectMcastSnooping(t, bridgeWithDefaultMcastSnoopName, true) 2163 if err := LinkDel(bridgeWithDefaultMcastSnoop); err != nil { 2164 t.Fatal(err) 2165 } 2166 2167 mcastSnoop := true 2168 bridgeWithMcastSnoopOnName := "bar" 2169 bridgeWithMcastSnoopOn := &Bridge{LinkAttrs: LinkAttrs{Name: bridgeWithMcastSnoopOnName}, MulticastSnooping: &mcastSnoop} 2170 if err := LinkAdd(bridgeWithMcastSnoopOn); err != nil { 2171 t.Fatal(err) 2172 } 2173 expectMcastSnooping(t, bridgeWithMcastSnoopOnName, true) 2174 if err := LinkDel(bridgeWithMcastSnoopOn); err != nil { 2175 t.Fatal(err) 2176 } 2177 2178 mcastSnoop = false 2179 bridgeWithMcastSnoopOffName := "foobar" 2180 bridgeWithMcastSnoopOff := &Bridge{LinkAttrs: LinkAttrs{Name: bridgeWithMcastSnoopOffName}, MulticastSnooping: &mcastSnoop} 2181 if err := LinkAdd(bridgeWithMcastSnoopOff); err != nil { 2182 t.Fatal(err) 2183 } 2184 expectMcastSnooping(t, bridgeWithMcastSnoopOffName, false) 2185 if err := LinkDel(bridgeWithMcastSnoopOff); err != nil { 2186 t.Fatal(err) 2187 } 2188 } 2189 2190 func TestBridgeSetMcastSnoop(t *testing.T) { 2191 minKernelRequired(t, 4, 4) 2192 2193 tearDown := setUpNetlinkTest(t) 2194 defer tearDown() 2195 2196 bridgeName := "foo" 2197 bridge := &Bridge{LinkAttrs: LinkAttrs{Name: bridgeName}} 2198 if err := LinkAdd(bridge); err != nil { 2199 t.Fatal(err) 2200 } 2201 expectMcastSnooping(t, bridgeName, true) 2202 2203 if err := BridgeSetMcastSnoop(bridge, false); err != nil { 2204 t.Fatal(err) 2205 } 2206 expectMcastSnooping(t, bridgeName, false) 2207 2208 if err := BridgeSetMcastSnoop(bridge, true); err != nil { 2209 t.Fatal(err) 2210 } 2211 expectMcastSnooping(t, bridgeName, true) 2212 2213 if err := LinkDel(bridge); err != nil { 2214 t.Fatal(err) 2215 } 2216 } 2217 2218 func expectMcastSnooping(t *testing.T, linkName string, expected bool) { 2219 bridge, err := LinkByName(linkName) 2220 if err != nil { 2221 t.Fatal(err) 2222 } 2223 2224 if actual := *bridge.(*Bridge).MulticastSnooping; actual != expected { 2225 t.Fatalf("expected %t got %t", expected, actual) 2226 } 2227 } 2228 2229 func TestBridgeSetVlanFiltering(t *testing.T) { 2230 minKernelRequired(t, 4, 4) 2231 2232 tearDown := setUpNetlinkTest(t) 2233 defer tearDown() 2234 2235 bridgeName := "foo" 2236 bridge := &Bridge{LinkAttrs: LinkAttrs{Name: bridgeName}} 2237 if err := LinkAdd(bridge); err != nil { 2238 t.Fatal(err) 2239 } 2240 expectVlanFiltering(t, bridgeName, false) 2241 2242 if err := BridgeSetVlanFiltering(bridge, true); err != nil { 2243 t.Fatal(err) 2244 } 2245 expectVlanFiltering(t, bridgeName, true) 2246 2247 if err := BridgeSetVlanFiltering(bridge, false); err != nil { 2248 t.Fatal(err) 2249 } 2250 expectVlanFiltering(t, bridgeName, false) 2251 2252 if err := LinkDel(bridge); err != nil { 2253 t.Fatal(err) 2254 } 2255 } 2256 2257 func expectVlanFiltering(t *testing.T, linkName string, expected bool) { 2258 bridge, err := LinkByName(linkName) 2259 if err != nil { 2260 t.Fatal(err) 2261 } 2262 2263 if actual := *bridge.(*Bridge).VlanFiltering; actual != expected { 2264 t.Fatalf("expected %t got %t", expected, actual) 2265 } 2266 } 2267 2268 func TestBridgeCreationWithAgeingTime(t *testing.T) { 2269 minKernelRequired(t, 3, 18) 2270 2271 tearDown := setUpNetlinkTest(t) 2272 defer tearDown() 2273 2274 bridgeWithSpecifiedAgeingTimeName := "foo" 2275 ageingTime := uint32(20000) 2276 bridgeWithSpecifiedAgeingTime := &Bridge{LinkAttrs: LinkAttrs{Name: bridgeWithSpecifiedAgeingTimeName}, AgeingTime: &ageingTime} 2277 if err := LinkAdd(bridgeWithSpecifiedAgeingTime); err != nil { 2278 t.Fatal(err) 2279 } 2280 2281 retrievedBridge, err := LinkByName(bridgeWithSpecifiedAgeingTimeName) 2282 if err != nil { 2283 t.Fatal(err) 2284 } 2285 2286 actualAgeingTime := *retrievedBridge.(*Bridge).AgeingTime 2287 if actualAgeingTime != ageingTime { 2288 t.Fatalf("expected %d got %d", ageingTime, actualAgeingTime) 2289 } 2290 if err := LinkDel(bridgeWithSpecifiedAgeingTime); err != nil { 2291 t.Fatal(err) 2292 } 2293 2294 bridgeWithDefaultAgeingTimeName := "bar" 2295 bridgeWithDefaultAgeingTime := &Bridge{LinkAttrs: LinkAttrs{Name: bridgeWithDefaultAgeingTimeName}} 2296 if err := LinkAdd(bridgeWithDefaultAgeingTime); err != nil { 2297 t.Fatal(err) 2298 } 2299 2300 retrievedBridge, err = LinkByName(bridgeWithDefaultAgeingTimeName) 2301 if err != nil { 2302 t.Fatal(err) 2303 } 2304 2305 actualAgeingTime = *retrievedBridge.(*Bridge).AgeingTime 2306 if actualAgeingTime != 30000 { 2307 t.Fatalf("expected %d got %d", 30000, actualAgeingTime) 2308 } 2309 if err := LinkDel(bridgeWithDefaultAgeingTime); err != nil { 2310 t.Fatal(err) 2311 } 2312 } 2313 2314 func TestBridgeCreationWithHelloTime(t *testing.T) { 2315 minKernelRequired(t, 3, 18) 2316 2317 tearDown := setUpNetlinkTest(t) 2318 defer tearDown() 2319 2320 bridgeWithSpecifiedHelloTimeName := "foo" 2321 helloTime := uint32(300) 2322 bridgeWithSpecifiedHelloTime := &Bridge{LinkAttrs: LinkAttrs{Name: bridgeWithSpecifiedHelloTimeName}, HelloTime: &helloTime} 2323 if err := LinkAdd(bridgeWithSpecifiedHelloTime); err != nil { 2324 t.Fatal(err) 2325 } 2326 2327 retrievedBridge, err := LinkByName(bridgeWithSpecifiedHelloTimeName) 2328 if err != nil { 2329 t.Fatal(err) 2330 } 2331 2332 actualHelloTime := *retrievedBridge.(*Bridge).HelloTime 2333 if actualHelloTime != helloTime { 2334 t.Fatalf("expected %d got %d", helloTime, actualHelloTime) 2335 } 2336 if err := LinkDel(bridgeWithSpecifiedHelloTime); err != nil { 2337 t.Fatal(err) 2338 } 2339 2340 bridgeWithDefaultHelloTimeName := "bar" 2341 bridgeWithDefaultHelloTime := &Bridge{LinkAttrs: LinkAttrs{Name: bridgeWithDefaultHelloTimeName}} 2342 if err := LinkAdd(bridgeWithDefaultHelloTime); err != nil { 2343 t.Fatal(err) 2344 } 2345 2346 retrievedBridge, err = LinkByName(bridgeWithDefaultHelloTimeName) 2347 if err != nil { 2348 t.Fatal(err) 2349 } 2350 2351 actualHelloTime = *retrievedBridge.(*Bridge).HelloTime 2352 if actualHelloTime != 200 { 2353 t.Fatalf("expected %d got %d", 200, actualHelloTime) 2354 } 2355 if err := LinkDel(bridgeWithDefaultHelloTime); err != nil { 2356 t.Fatal(err) 2357 } 2358 } 2359 2360 func TestBridgeCreationWithVlanFiltering(t *testing.T) { 2361 minKernelRequired(t, 3, 18) 2362 2363 tearDown := setUpNetlinkTest(t) 2364 defer tearDown() 2365 2366 bridgeWithVlanFilteringEnabledName := "foo" 2367 vlanFiltering := true 2368 bridgeWithVlanFilteringEnabled := &Bridge{LinkAttrs: LinkAttrs{Name: bridgeWithVlanFilteringEnabledName}, VlanFiltering: &vlanFiltering} 2369 if err := LinkAdd(bridgeWithVlanFilteringEnabled); err != nil { 2370 t.Fatal(err) 2371 } 2372 2373 retrievedBridge, err := LinkByName(bridgeWithVlanFilteringEnabledName) 2374 if err != nil { 2375 t.Fatal(err) 2376 } 2377 2378 retrievedVlanFilteringState := *retrievedBridge.(*Bridge).VlanFiltering 2379 if retrievedVlanFilteringState != vlanFiltering { 2380 t.Fatalf("expected %t got %t", vlanFiltering, retrievedVlanFilteringState) 2381 } 2382 if err := LinkDel(bridgeWithVlanFilteringEnabled); err != nil { 2383 t.Fatal(err) 2384 } 2385 2386 bridgeWithDefaultVlanFilteringName := "bar" 2387 bridgeWIthDefaultVlanFiltering := &Bridge{LinkAttrs: LinkAttrs{Name: bridgeWithDefaultVlanFilteringName}} 2388 if err := LinkAdd(bridgeWIthDefaultVlanFiltering); err != nil { 2389 t.Fatal(err) 2390 } 2391 2392 retrievedBridge, err = LinkByName(bridgeWithDefaultVlanFilteringName) 2393 if err != nil { 2394 t.Fatal(err) 2395 } 2396 2397 retrievedVlanFilteringState = *retrievedBridge.(*Bridge).VlanFiltering 2398 if retrievedVlanFilteringState != false { 2399 t.Fatalf("expected %t got %t", false, retrievedVlanFilteringState) 2400 } 2401 if err := LinkDel(bridgeWIthDefaultVlanFiltering); err != nil { 2402 t.Fatal(err) 2403 } 2404 } 2405 2406 func TestLinkSubscribeWithProtinfo(t *testing.T) { 2407 tearDown := setUpNetlinkTest(t) 2408 defer tearDown() 2409 2410 master := &Bridge{LinkAttrs: LinkAttrs{Name: "foo"}} 2411 if err := LinkAdd(master); err != nil { 2412 t.Fatal(err) 2413 } 2414 2415 slave := &Veth{ 2416 LinkAttrs: LinkAttrs{ 2417 Name: "bar", 2418 TxQLen: testTxQLen, 2419 MTU: 1400, 2420 MasterIndex: master.Attrs().Index, 2421 }, 2422 PeerName: "bar-peer", 2423 } 2424 if err := LinkAdd(slave); err != nil { 2425 t.Fatal(err) 2426 } 2427 2428 ch := make(chan LinkUpdate) 2429 done := make(chan struct{}) 2430 defer close(done) 2431 if err := LinkSubscribe(ch, done); err != nil { 2432 t.Fatal(err) 2433 } 2434 2435 if err := LinkSetHairpin(slave, true); err != nil { 2436 t.Fatal(err) 2437 } 2438 2439 select { 2440 case update := <-ch: 2441 if !(update.Attrs().Name == "bar" && update.Attrs().Protinfo != nil && 2442 update.Attrs().Protinfo.Hairpin) { 2443 t.Fatal("Hairpin update not received as expected") 2444 } 2445 case <-time.After(time.Minute): 2446 t.Fatal("Hairpin update timed out") 2447 } 2448 2449 if err := LinkDel(slave); err != nil { 2450 t.Fatal(err) 2451 } 2452 2453 if err := LinkDel(master); err != nil { 2454 t.Fatal(err) 2455 } 2456 } 2457 2458 func testGTPLink(t *testing.T) *GTP { 2459 conn1, err := net.ListenUDP("udp", &net.UDPAddr{ 2460 IP: net.ParseIP("0.0.0.0"), 2461 Port: 3386, 2462 }) 2463 if err != nil { 2464 t.Fatal(err) 2465 } 2466 conn2, err := net.ListenUDP("udp", &net.UDPAddr{ 2467 IP: net.ParseIP("0.0.0.0"), 2468 Port: 2152, 2469 }) 2470 if err != nil { 2471 t.Fatal(err) 2472 } 2473 fd1, _ := conn1.File() 2474 fd2, _ := conn2.File() 2475 return >P{ 2476 LinkAttrs: LinkAttrs{ 2477 Name: "gtp0", 2478 }, 2479 FD0: int(fd1.Fd()), 2480 FD1: int(fd2.Fd()), 2481 } 2482 } 2483 2484 func TestLinkAddDelGTP(t *testing.T) { 2485 tearDown := setUpNetlinkTestWithKModule(t, "gtp") 2486 defer tearDown() 2487 gtp := testGTPLink(t) 2488 testLinkAddDel(t, gtp) 2489 } 2490 2491 func TestLinkAddDelXfrmi(t *testing.T) { 2492 minKernelRequired(t, 4, 19) 2493 defer setUpNetlinkTest(t)() 2494 2495 lo, _ := LinkByName("lo") 2496 2497 testLinkAddDel(t, &Xfrmi{ 2498 LinkAttrs: LinkAttrs{Name: "xfrm123", ParentIndex: lo.Attrs().Index}, 2499 Ifid: 123}) 2500 } 2501 2502 func TestLinkAddDelXfrmiNoId(t *testing.T) { 2503 minKernelRequired(t, 4, 19) 2504 defer setUpNetlinkTest(t)() 2505 2506 lo, _ := LinkByName("lo") 2507 2508 err := LinkAdd(&Xfrmi{ 2509 LinkAttrs: LinkAttrs{Name: "xfrm0", ParentIndex: lo.Attrs().Index}}) 2510 if !errors.Is(err, unix.EINVAL) { 2511 t.Errorf("Error returned expected to be EINVAL") 2512 } 2513 2514 } 2515 2516 func TestLinkByNameWhenLinkIsNotFound(t *testing.T) { 2517 _, err := LinkByName("iammissing") 2518 if err == nil { 2519 t.Fatal("Link not expected to found") 2520 } 2521 2522 _, ok := err.(LinkNotFoundError) 2523 if !ok { 2524 t.Errorf("Error returned expected to of LinkNotFoundError type: %v", err) 2525 } 2526 } 2527 2528 func TestLinkByAliasWhenLinkIsNotFound(t *testing.T) { 2529 _, err := LinkByAlias("iammissing") 2530 if err == nil { 2531 t.Fatal("Link not expected to found") 2532 } 2533 2534 _, ok := err.(LinkNotFoundError) 2535 if !ok { 2536 t.Errorf("Error returned expected to of LinkNotFoundError type: %v", err) 2537 } 2538 } 2539 2540 func TestLinkAddDelTuntap(t *testing.T) { 2541 tearDown := setUpNetlinkTest(t) 2542 defer tearDown() 2543 2544 // Mount sysfs so that sysfs gets the namespace tag of the current network namespace 2545 // This is necessary so that /sys shows the network interfaces of the current namespace. 2546 if err := syscall.Mount("sysfs", "/sys", "sysfs", syscall.MS_RDONLY, ""); err != nil { 2547 t.Fatal("Cannot mount sysfs") 2548 } 2549 2550 defer func() { 2551 if err := syscall.Unmount("/sys", 0); err != nil { 2552 t.Fatal("Cannot umount /sys") 2553 } 2554 }() 2555 2556 testLinkAddDel(t, &Tuntap{ 2557 LinkAttrs: LinkAttrs{Name: "foo"}, 2558 Mode: TUNTAP_MODE_TAP}) 2559 } 2560 2561 func TestLinkAddDelTuntapMq(t *testing.T) { 2562 tearDown := setUpNetlinkTest(t) 2563 defer tearDown() 2564 2565 if err := syscall.Mount("sysfs", "/sys", "sysfs", syscall.MS_RDONLY, ""); err != nil { 2566 t.Fatal("Cannot mount sysfs") 2567 } 2568 2569 defer func() { 2570 if err := syscall.Unmount("/sys", 0); err != nil { 2571 t.Fatal("Cannot umount /sys") 2572 } 2573 }() 2574 2575 testLinkAddDel(t, &Tuntap{ 2576 LinkAttrs: LinkAttrs{Name: "foo"}, 2577 Mode: TUNTAP_MODE_TAP, 2578 Queues: 4}) 2579 2580 testLinkAddDel(t, &Tuntap{ 2581 LinkAttrs: LinkAttrs{Name: "foo"}, 2582 Mode: TUNTAP_MODE_TAP, 2583 Queues: 4, 2584 Flags: TUNTAP_MULTI_QUEUE_DEFAULTS | TUNTAP_VNET_HDR}) 2585 } 2586 2587 func TestLinkAddDelTuntapOwnerGroup(t *testing.T) { 2588 tearDown := setUpNetlinkTest(t) 2589 defer tearDown() 2590 2591 if err := syscall.Mount("sysfs", "/sys", "sysfs", syscall.MS_RDONLY, ""); err != nil { 2592 t.Fatal("Cannot mount sysfs") 2593 } 2594 2595 defer func() { 2596 if err := syscall.Unmount("/sys", 0); err != nil { 2597 t.Fatal("Cannot umount /sys") 2598 } 2599 }() 2600 2601 testLinkAddDel(t, &Tuntap{ 2602 LinkAttrs: LinkAttrs{Name: "foo"}, 2603 Mode: TUNTAP_MODE_TAP, 2604 Owner: 0, 2605 Group: 0, 2606 }) 2607 } 2608 2609 func TestVethPeerIndex(t *testing.T) { 2610 tearDown := setUpNetlinkTest(t) 2611 defer tearDown() 2612 2613 const ( 2614 vethPeer1 = "vethOne" 2615 vethPeer2 = "vethTwo" 2616 ) 2617 2618 link := &Veth{ 2619 LinkAttrs: LinkAttrs{ 2620 Name: vethPeer1, 2621 MTU: 1500, 2622 Flags: net.FlagUp, 2623 }, 2624 PeerName: vethPeer2, 2625 } 2626 2627 if err := LinkAdd(link); err != nil { 2628 t.Fatal(err) 2629 } 2630 2631 linkOne, err := LinkByName("vethOne") 2632 if err != nil { 2633 t.Fatal(err) 2634 } 2635 2636 linkTwo, err := LinkByName("vethTwo") 2637 if err != nil { 2638 t.Fatal(err) 2639 } 2640 2641 peerIndexOne, err := VethPeerIndex(&Veth{LinkAttrs: *linkOne.Attrs()}) 2642 if err != nil { 2643 t.Fatal(err) 2644 } 2645 2646 peerIndexTwo, err := VethPeerIndex(&Veth{LinkAttrs: *linkTwo.Attrs()}) 2647 if err != nil { 2648 t.Fatal(err) 2649 } 2650 2651 if peerIndexOne != linkTwo.Attrs().Index { 2652 t.Errorf("VethPeerIndex(%s) mismatch %d != %d", linkOne.Attrs().Name, peerIndexOne, linkTwo.Attrs().Index) 2653 } 2654 2655 if peerIndexTwo != linkOne.Attrs().Index { 2656 t.Errorf("VethPeerIndex(%s) mismatch %d != %d", linkTwo.Attrs().Name, peerIndexTwo, linkOne.Attrs().Index) 2657 } 2658 } 2659 2660 func TestLinkSlaveBond(t *testing.T) { 2661 minKernelRequired(t, 3, 13) 2662 2663 tearDown := setUpNetlinkTest(t) 2664 defer tearDown() 2665 2666 const ( 2667 bondName = "foo" 2668 slaveName = "fooFoo" 2669 ) 2670 2671 bond := NewLinkBond(LinkAttrs{Name: bondName}) 2672 bond.Mode = BOND_MODE_BALANCE_RR 2673 if err := LinkAdd(bond); err != nil { 2674 t.Fatal(err) 2675 } 2676 defer LinkDel(bond) 2677 2678 slaveDummy := &Dummy{LinkAttrs{Name: slaveName}} 2679 if err := LinkAdd(slaveDummy); err != nil { 2680 t.Fatal(err) 2681 } 2682 defer LinkDel(slaveDummy) 2683 2684 if err := LinkSetBondSlave(slaveDummy, bond); err != nil { 2685 t.Fatal(err) 2686 } 2687 2688 slaveLink, err := LinkByName(slaveName) 2689 if err != nil { 2690 t.Fatal(err) 2691 } 2692 2693 slave := slaveLink.Attrs().Slave 2694 if slave == nil { 2695 t.Errorf("for %s expected slave is not nil.", slaveName) 2696 } 2697 2698 if slaveType := slave.SlaveType(); slaveType != "bond" { 2699 t.Errorf("for %s expected slave type is 'bond', but '%s'", slaveName, slaveType) 2700 } 2701 } 2702 2703 func TestLinkSetBondSlaveQueueId(t *testing.T) { 2704 minKernelRequired(t, 3, 13) 2705 2706 tearDown := setUpNetlinkTest(t) 2707 defer tearDown() 2708 2709 const ( 2710 bondName = "foo" 2711 slave1Name = "fooFoo" 2712 ) 2713 2714 bond := NewLinkBond(LinkAttrs{Name: bondName}) 2715 if err := LinkAdd(bond); err != nil { 2716 t.Fatal(err) 2717 } 2718 defer LinkDel(bond) 2719 2720 slave := &Dummy{LinkAttrs{Name: slave1Name}} 2721 if err := LinkAdd(slave); err != nil { 2722 t.Fatal(err) 2723 } 2724 defer LinkDel(slave) 2725 2726 if err := LinkSetBondSlave(slave, bond); err != nil { 2727 t.Fatal(err) 2728 } 2729 2730 if err := pkgHandle.LinkSetBondSlaveQueueId(slave, 1); err != nil { 2731 t.Fatal(err) 2732 } 2733 } 2734 2735 func TestLinkSetBondSlave(t *testing.T) { 2736 minKernelRequired(t, 3, 13) 2737 2738 tearDown := setUpNetlinkTest(t) 2739 defer tearDown() 2740 2741 const ( 2742 bondName = "foo" 2743 slaveOneName = "fooFoo" 2744 slaveTwoName = "fooBar" 2745 ) 2746 2747 bond := NewLinkBond(LinkAttrs{Name: bondName}) 2748 bond.Mode = StringToBondModeMap["802.3ad"] 2749 bond.AdSelect = BondAdSelect(BOND_AD_SELECT_BANDWIDTH) 2750 bond.AdActorSysPrio = 1 2751 bond.AdUserPortKey = 1 2752 bond.AdActorSystem, _ = net.ParseMAC("06:aa:bb:cc:dd:ee") 2753 2754 if err := LinkAdd(bond); err != nil { 2755 t.Fatal(err) 2756 } 2757 2758 bondLink, err := LinkByName(bondName) 2759 if err != nil { 2760 t.Fatal(err) 2761 } 2762 defer LinkDel(bondLink) 2763 2764 if err := LinkAdd(&Dummy{LinkAttrs{Name: slaveOneName}}); err != nil { 2765 t.Fatal(err) 2766 } 2767 2768 slaveOneLink, err := LinkByName(slaveOneName) 2769 if err != nil { 2770 t.Fatal(err) 2771 } 2772 defer LinkDel(slaveOneLink) 2773 2774 if err := LinkAdd(&Dummy{LinkAttrs{Name: slaveTwoName}}); err != nil { 2775 t.Fatal(err) 2776 } 2777 slaveTwoLink, err := LinkByName(slaveTwoName) 2778 if err != nil { 2779 t.Fatal(err) 2780 } 2781 defer LinkDel(slaveTwoLink) 2782 2783 if err := LinkSetBondSlave(slaveOneLink, &Bond{LinkAttrs: *bondLink.Attrs()}); err != nil { 2784 t.Fatal(err) 2785 } 2786 2787 if err := LinkSetBondSlave(slaveTwoLink, &Bond{LinkAttrs: *bondLink.Attrs()}); err != nil { 2788 t.Fatal(err) 2789 } 2790 2791 // Update info about interfaces 2792 slaveOneLink, err = LinkByName(slaveOneName) 2793 if err != nil { 2794 t.Fatal(err) 2795 } 2796 2797 slaveTwoLink, err = LinkByName(slaveTwoName) 2798 if err != nil { 2799 t.Fatal(err) 2800 } 2801 2802 if slaveOneLink.Attrs().MasterIndex != bondLink.Attrs().Index { 2803 t.Errorf("For %s expected %s to be master", slaveOneLink.Attrs().Name, bondLink.Attrs().Name) 2804 } 2805 2806 if slaveTwoLink.Attrs().MasterIndex != bondLink.Attrs().Index { 2807 t.Errorf("For %s expected %s to be master", slaveTwoLink.Attrs().Name, bondLink.Attrs().Name) 2808 } 2809 } 2810 2811 func TestLinkSetAllmulticast(t *testing.T) { 2812 tearDown := setUpNetlinkTest(t) 2813 defer tearDown() 2814 2815 iface := &Veth{LinkAttrs: LinkAttrs{Name: "foo"}, PeerName: "bar"} 2816 if err := LinkAdd(iface); err != nil { 2817 t.Fatal(err) 2818 } 2819 2820 link, err := LinkByName("foo") 2821 if err != nil { 2822 t.Fatal(err) 2823 } 2824 2825 if err := LinkSetUp(link); err != nil { 2826 t.Fatal(err) 2827 } 2828 2829 link, err = LinkByName("foo") 2830 if err != nil { 2831 t.Fatal(err) 2832 } 2833 2834 if err := LinkSetAllmulticastOn(link); err != nil { 2835 t.Fatal(err) 2836 } 2837 2838 link, err = LinkByName("foo") 2839 if err != nil { 2840 t.Fatal(err) 2841 } 2842 2843 if link.Attrs().Allmulti != 1 { 2844 t.Fatal("IFF_ALLMULTI was not set") 2845 } 2846 2847 if err := LinkSetAllmulticastOff(link); err != nil { 2848 t.Fatal(err) 2849 } 2850 2851 link, err = LinkByName("foo") 2852 if err != nil { 2853 t.Fatal(err) 2854 } 2855 2856 if link.Attrs().Allmulti != 0 { 2857 t.Fatal("IFF_ALLMULTI is still set") 2858 } 2859 } 2860 2861 func TestLinkSetMulticast(t *testing.T) { 2862 tearDown := setUpNetlinkTest(t) 2863 defer tearDown() 2864 2865 iface := &Veth{LinkAttrs: LinkAttrs{Name: "foo"}, PeerName: "bar"} 2866 if err := LinkAdd(iface); err != nil { 2867 t.Fatal(err) 2868 } 2869 2870 link, err := LinkByName("foo") 2871 if err != nil { 2872 t.Fatal(err) 2873 } 2874 2875 if err := LinkSetUp(link); err != nil { 2876 t.Fatal(err) 2877 } 2878 2879 link, err = LinkByName("foo") 2880 if err != nil { 2881 t.Fatal(err) 2882 } 2883 2884 if err := LinkSetMulticastOn(link); err != nil { 2885 t.Fatal(err) 2886 } 2887 2888 link, err = LinkByName("foo") 2889 if err != nil { 2890 t.Fatal(err) 2891 } 2892 2893 if link.Attrs().Multi != 1 { 2894 t.Fatal("IFF_MULTICAST was not set") 2895 } 2896 2897 if err := LinkSetMulticastOff(link); err != nil { 2898 t.Fatal(err) 2899 } 2900 2901 link, err = LinkByName("foo") 2902 if err != nil { 2903 t.Fatal(err) 2904 } 2905 2906 if link.Attrs().Multi != 0 { 2907 t.Fatal("IFF_MULTICAST is still set") 2908 } 2909 } 2910 2911 func TestLinkSetMacvlanMode(t *testing.T) { 2912 tearDown := setUpNetlinkTest(t) 2913 defer tearDown() 2914 2915 const ( 2916 parentName = "foo" 2917 macvlanName = "fooFoo" 2918 macvtapName = "fooBar" 2919 ) 2920 2921 parent := &Dummy{LinkAttrs{Name: parentName}} 2922 if err := LinkAdd(parent); err != nil { 2923 t.Fatal(err) 2924 } 2925 defer LinkDel(parent) 2926 2927 testMacvlanMode := func(link Link, mode MacvlanMode) { 2928 if err := LinkSetMacvlanMode(link, mode); err != nil { 2929 t.Fatal(err) 2930 } 2931 2932 name := link.Attrs().Name 2933 result, err := LinkByName(name) 2934 if err != nil { 2935 t.Fatal(err) 2936 } 2937 2938 var actual MacvlanMode 2939 switch l := result.(type) { 2940 case *Macvlan: 2941 actual = l.Mode 2942 case *Macvtap: 2943 actual = l.Macvlan.Mode 2944 } 2945 2946 if actual != mode { 2947 t.Fatalf("expected %v got %v for %+v", mode, actual, link) 2948 } 2949 } 2950 2951 macvlan := &Macvlan{ 2952 LinkAttrs: LinkAttrs{Name: macvlanName, ParentIndex: parent.Attrs().Index}, 2953 Mode: MACVLAN_MODE_BRIDGE, 2954 } 2955 if err := LinkAdd(macvlan); err != nil { 2956 t.Fatal(err) 2957 } 2958 defer LinkDel(macvlan) 2959 2960 testMacvlanMode(macvlan, MACVLAN_MODE_VEPA) 2961 testMacvlanMode(macvlan, MACVLAN_MODE_PRIVATE) 2962 testMacvlanMode(macvlan, MACVLAN_MODE_SOURCE) 2963 testMacvlanMode(macvlan, MACVLAN_MODE_BRIDGE) 2964 2965 macvtap := &Macvtap{ 2966 Macvlan: Macvlan{ 2967 LinkAttrs: LinkAttrs{Name: macvtapName, ParentIndex: parent.Attrs().Index}, 2968 Mode: MACVLAN_MODE_BRIDGE, 2969 }, 2970 } 2971 if err := LinkAdd(macvtap); err != nil { 2972 t.Fatal(err) 2973 } 2974 defer LinkDel(macvtap) 2975 2976 testMacvlanMode(macvtap, MACVLAN_MODE_VEPA) 2977 testMacvlanMode(macvtap, MACVLAN_MODE_PRIVATE) 2978 testMacvlanMode(macvtap, MACVLAN_MODE_SOURCE) 2979 testMacvlanMode(macvtap, MACVLAN_MODE_BRIDGE) 2980 }