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