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