github.com/vishvananda/netlink@v1.3.0/link_test.go (about)

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