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 &GTP{
  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  }