github.com/sagernet/netlink@v0.0.0-20240612041022-b9a21c07ac6a/link_test.go (about)

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