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

     1  //go:build linux
     2  // +build linux
     3  
     4  package netlink
     5  
     6  import (
     7  	"testing"
     8  )
     9  
    10  func TestTbfAddDel(t *testing.T) {
    11  	tearDown := setUpNetlinkTest(t)
    12  	defer tearDown()
    13  	if err := LinkAdd(&Ifb{LinkAttrs{Name: "foo"}}); err != nil {
    14  		t.Fatal(err)
    15  	}
    16  	link, err := LinkByName("foo")
    17  	if err != nil {
    18  		t.Fatal(err)
    19  	}
    20  	if err := LinkSetUp(link); err != nil {
    21  		t.Fatal(err)
    22  	}
    23  	qdisc := &Tbf{
    24  		QdiscAttrs: QdiscAttrs{
    25  			LinkIndex: link.Attrs().Index,
    26  			Handle:    MakeHandle(1, 0),
    27  			Parent:    HANDLE_ROOT,
    28  		},
    29  		Rate:   131072,
    30  		Limit:  1220703,
    31  		Buffer: 16793,
    32  	}
    33  	if err := QdiscAdd(qdisc); err != nil {
    34  		t.Fatal(err)
    35  	}
    36  	qdiscs, err := SafeQdiscList(link)
    37  	if err != nil {
    38  		t.Fatal(err)
    39  	}
    40  	if len(qdiscs) != 1 {
    41  		t.Fatal("Failed to add qdisc")
    42  	}
    43  	tbf, ok := qdiscs[0].(*Tbf)
    44  	if !ok {
    45  		t.Fatal("Qdisc is the wrong type")
    46  	}
    47  	if tbf.Rate != qdisc.Rate {
    48  		t.Fatal("Rate doesn't match")
    49  	}
    50  	if tbf.Limit != qdisc.Limit {
    51  		t.Fatal("Limit doesn't match")
    52  	}
    53  	if tbf.Buffer != qdisc.Buffer {
    54  		t.Fatal("Buffer doesn't match")
    55  	}
    56  	if err := QdiscDel(qdisc); err != nil {
    57  		t.Fatal(err)
    58  	}
    59  	qdiscs, err = SafeQdiscList(link)
    60  	if err != nil {
    61  		t.Fatal(err)
    62  	}
    63  	if len(qdiscs) != 0 {
    64  		t.Fatal("Failed to remove qdisc")
    65  	}
    66  }
    67  
    68  func TestHtbAddDel(t *testing.T) {
    69  	tearDown := setUpNetlinkTest(t)
    70  	defer tearDown()
    71  	if err := LinkAdd(&Ifb{LinkAttrs{Name: "foo"}}); err != nil {
    72  		t.Fatal(err)
    73  	}
    74  	link, err := LinkByName("foo")
    75  	if err != nil {
    76  		t.Fatal(err)
    77  	}
    78  	if err := LinkSetUp(link); err != nil {
    79  		t.Fatal(err)
    80  	}
    81  
    82  	attrs := QdiscAttrs{
    83  		LinkIndex: link.Attrs().Index,
    84  		Handle:    MakeHandle(1, 0),
    85  		Parent:    HANDLE_ROOT,
    86  	}
    87  
    88  	qdisc := NewHtb(attrs)
    89  	qdisc.Rate2Quantum = 5
    90  	if err := QdiscAdd(qdisc); err != nil {
    91  		t.Fatal(err)
    92  	}
    93  
    94  	qdiscs, err := SafeQdiscList(link)
    95  	if err != nil {
    96  		t.Fatal(err)
    97  	}
    98  	if len(qdiscs) != 1 {
    99  		t.Fatal("Failed to add qdisc")
   100  	}
   101  	htb, ok := qdiscs[0].(*Htb)
   102  	if !ok {
   103  		t.Fatal("Qdisc is the wrong type")
   104  	}
   105  	if htb.Defcls != qdisc.Defcls {
   106  		t.Fatal("Defcls doesn't match")
   107  	}
   108  	if htb.Rate2Quantum != qdisc.Rate2Quantum {
   109  		t.Fatal("Rate2Quantum doesn't match")
   110  	}
   111  	if htb.Debug != qdisc.Debug {
   112  		t.Fatal("Debug doesn't match")
   113  	}
   114  	if err := QdiscDel(qdisc); err != nil {
   115  		t.Fatal(err)
   116  	}
   117  	qdiscs, err = SafeQdiscList(link)
   118  	if err != nil {
   119  		t.Fatal(err)
   120  	}
   121  	if len(qdiscs) != 0 {
   122  		t.Fatal("Failed to remove qdisc")
   123  	}
   124  }
   125  
   126  func TestSfqAddDel(t *testing.T) {
   127  	tearDown := setUpNetlinkTestWithKModule(t, "sch_sfq")
   128  	defer tearDown()
   129  	if err := LinkAdd(&Ifb{LinkAttrs{Name: "foo"}}); err != nil {
   130  		t.Fatal(err)
   131  	}
   132  	link, err := LinkByName("foo")
   133  	if err != nil {
   134  		t.Fatal(err)
   135  	}
   136  	if err := LinkSetUp(link); err != nil {
   137  		t.Fatal(err)
   138  	}
   139  
   140  	attrs := QdiscAttrs{
   141  		LinkIndex: link.Attrs().Index,
   142  		Handle:    MakeHandle(1, 0),
   143  		Parent:    HANDLE_ROOT,
   144  	}
   145  
   146  	qdisc := Sfq{
   147  		QdiscAttrs: attrs,
   148  		Quantum:    2,
   149  		Perturb:    11,
   150  		Limit:      123,
   151  		Divisor:    4,
   152  	}
   153  	if err := QdiscAdd(&qdisc); err != nil {
   154  		t.Fatal(err)
   155  	}
   156  
   157  	qdiscs, err := SafeQdiscList(link)
   158  	if err != nil {
   159  		t.Fatal(err)
   160  	}
   161  	if len(qdiscs) != 1 {
   162  		t.Fatal("Failed to add qdisc")
   163  	}
   164  	sfq, ok := qdiscs[0].(*Sfq)
   165  	if !ok {
   166  		t.Fatal("Qdisc is the wrong type")
   167  	}
   168  	if sfq.Quantum != qdisc.Quantum {
   169  		t.Fatal("Quantum doesn't match")
   170  	}
   171  	if sfq.Perturb != qdisc.Perturb {
   172  		t.Fatal("Perturb doesn't match")
   173  	}
   174  	if sfq.Limit != qdisc.Limit {
   175  		t.Fatal("Limit doesn't match")
   176  	}
   177  	if sfq.Divisor != qdisc.Divisor {
   178  		t.Fatal("Divisor doesn't match")
   179  	}
   180  	if err := QdiscDel(&qdisc); err != nil {
   181  		t.Fatal(err)
   182  	}
   183  	qdiscs, err = SafeQdiscList(link)
   184  	if err != nil {
   185  		t.Fatal(err)
   186  	}
   187  	if len(qdiscs) != 0 {
   188  		t.Fatal("Failed to remove qdisc")
   189  	}
   190  }
   191  
   192  func TestPrioAddDel(t *testing.T) {
   193  	tearDown := setUpNetlinkTest(t)
   194  	defer tearDown()
   195  	if err := LinkAdd(&Ifb{LinkAttrs{Name: "foo"}}); err != nil {
   196  		t.Fatal(err)
   197  	}
   198  	link, err := LinkByName("foo")
   199  	if err != nil {
   200  		t.Fatal(err)
   201  	}
   202  	if err := LinkSetUp(link); err != nil {
   203  		t.Fatal(err)
   204  	}
   205  	qdisc := NewPrio(QdiscAttrs{
   206  		LinkIndex: link.Attrs().Index,
   207  		Handle:    MakeHandle(1, 0),
   208  		Parent:    HANDLE_ROOT,
   209  	})
   210  	if err := QdiscAdd(qdisc); err != nil {
   211  		t.Fatal(err)
   212  	}
   213  	qdiscs, err := SafeQdiscList(link)
   214  	if err != nil {
   215  		t.Fatal(err)
   216  	}
   217  	if len(qdiscs) != 1 {
   218  		t.Fatal("Failed to add qdisc")
   219  	}
   220  	_, ok := qdiscs[0].(*Prio)
   221  	if !ok {
   222  		t.Fatal("Qdisc is the wrong type")
   223  	}
   224  	if err := QdiscDel(qdisc); err != nil {
   225  		t.Fatal(err)
   226  	}
   227  	qdiscs, err = SafeQdiscList(link)
   228  	if err != nil {
   229  		t.Fatal(err)
   230  	}
   231  	if len(qdiscs) != 0 {
   232  		t.Fatal("Failed to remove qdisc")
   233  	}
   234  }
   235  
   236  func TestTbfAddHtbReplaceDel(t *testing.T) {
   237  	tearDown := setUpNetlinkTest(t)
   238  	defer tearDown()
   239  	if err := LinkAdd(&Ifb{LinkAttrs{Name: "foo"}}); err != nil {
   240  		t.Fatal(err)
   241  	}
   242  	link, err := LinkByName("foo")
   243  	if err != nil {
   244  		t.Fatal(err)
   245  	}
   246  	if err := LinkSetUp(link); err != nil {
   247  		t.Fatal(err)
   248  	}
   249  
   250  	// Add
   251  	attrs := QdiscAttrs{
   252  		LinkIndex: link.Attrs().Index,
   253  		Handle:    MakeHandle(1, 0),
   254  		Parent:    HANDLE_ROOT,
   255  	}
   256  	qdisc := &Tbf{
   257  		QdiscAttrs: attrs,
   258  		Rate:       131072,
   259  		Limit:      1220703,
   260  		Buffer:     16793,
   261  	}
   262  	if err := QdiscAdd(qdisc); err != nil {
   263  		t.Fatal(err)
   264  	}
   265  	qdiscs, err := SafeQdiscList(link)
   266  	if err != nil {
   267  		t.Fatal(err)
   268  	}
   269  	if len(qdiscs) != 1 {
   270  		t.Fatal("Failed to add qdisc")
   271  	}
   272  	tbf, ok := qdiscs[0].(*Tbf)
   273  	if !ok {
   274  		t.Fatal("Qdisc is the wrong type")
   275  	}
   276  	if tbf.Rate != qdisc.Rate {
   277  		t.Fatal("Rate doesn't match")
   278  	}
   279  	if tbf.Limit != qdisc.Limit {
   280  		t.Fatal("Limit doesn't match")
   281  	}
   282  	if tbf.Buffer != qdisc.Buffer {
   283  		t.Fatal("Buffer doesn't match")
   284  	}
   285  	// Replace
   286  	// For replace to work, the handle MUST be different that the running one
   287  	attrs.Handle = MakeHandle(2, 0)
   288  	qdisc2 := NewHtb(attrs)
   289  	qdisc2.Rate2Quantum = 5
   290  	if err := QdiscReplace(qdisc2); err != nil {
   291  		t.Fatal(err)
   292  	}
   293  
   294  	qdiscs, err = SafeQdiscList(link)
   295  	if err != nil {
   296  		t.Fatal(err)
   297  	}
   298  	if len(qdiscs) != 1 {
   299  		t.Fatal("Failed to add qdisc")
   300  	}
   301  	htb, ok := qdiscs[0].(*Htb)
   302  	if !ok {
   303  		t.Fatal("Qdisc is the wrong type")
   304  	}
   305  	if htb.Defcls != qdisc2.Defcls {
   306  		t.Fatal("Defcls doesn't match")
   307  	}
   308  	if htb.Rate2Quantum != qdisc2.Rate2Quantum {
   309  		t.Fatal("Rate2Quantum doesn't match")
   310  	}
   311  	if htb.Debug != qdisc2.Debug {
   312  		t.Fatal("Debug doesn't match")
   313  	}
   314  
   315  	if err := QdiscDel(qdisc2); err != nil {
   316  		t.Fatal(err)
   317  	}
   318  	qdiscs, err = SafeQdiscList(link)
   319  	if err != nil {
   320  		t.Fatal(err)
   321  	}
   322  	if len(qdiscs) != 0 {
   323  		t.Fatal("Failed to remove qdisc")
   324  	}
   325  }
   326  
   327  func TestTbfAddTbfChangeDel(t *testing.T) {
   328  	tearDown := setUpNetlinkTest(t)
   329  	defer tearDown()
   330  	if err := LinkAdd(&Ifb{LinkAttrs{Name: "foo"}}); err != nil {
   331  		t.Fatal(err)
   332  	}
   333  	link, err := LinkByName("foo")
   334  	if err != nil {
   335  		t.Fatal(err)
   336  	}
   337  	if err := LinkSetUp(link); err != nil {
   338  		t.Fatal(err)
   339  	}
   340  
   341  	// Add
   342  	attrs := QdiscAttrs{
   343  		LinkIndex: link.Attrs().Index,
   344  		Handle:    MakeHandle(1, 0),
   345  		Parent:    HANDLE_ROOT,
   346  	}
   347  	qdisc := &Tbf{
   348  		QdiscAttrs: attrs,
   349  		Rate:       131072,
   350  		Limit:      1220703,
   351  		Buffer:     16793,
   352  	}
   353  	if err := QdiscAdd(qdisc); err != nil {
   354  		t.Fatal(err)
   355  	}
   356  	qdiscs, err := SafeQdiscList(link)
   357  	if err != nil {
   358  		t.Fatal(err)
   359  	}
   360  	if len(qdiscs) != 1 {
   361  		t.Fatal("Failed to add qdisc")
   362  	}
   363  	tbf, ok := qdiscs[0].(*Tbf)
   364  	if !ok {
   365  		t.Fatal("Qdisc is the wrong type")
   366  	}
   367  	if tbf.Rate != qdisc.Rate {
   368  		t.Fatal("Rate doesn't match")
   369  	}
   370  	if tbf.Limit != qdisc.Limit {
   371  		t.Fatal("Limit doesn't match")
   372  	}
   373  	if tbf.Buffer != qdisc.Buffer {
   374  		t.Fatal("Buffer doesn't match")
   375  	}
   376  	// Change
   377  	// For change to work, the handle MUST not change
   378  	qdisc.Rate = 23456
   379  	if err := QdiscChange(qdisc); err != nil {
   380  		t.Fatal(err)
   381  	}
   382  
   383  	qdiscs, err = SafeQdiscList(link)
   384  	if err != nil {
   385  		t.Fatal(err)
   386  	}
   387  	if len(qdiscs) != 1 {
   388  		t.Fatal("Failed to add qdisc")
   389  	}
   390  	tbf, ok = qdiscs[0].(*Tbf)
   391  	if !ok {
   392  		t.Fatal("Qdisc is the wrong type")
   393  	}
   394  	if tbf.Rate != qdisc.Rate {
   395  		t.Fatal("Rate doesn't match")
   396  	}
   397  	if tbf.Limit != qdisc.Limit {
   398  		t.Fatal("Limit doesn't match")
   399  	}
   400  	if tbf.Buffer != qdisc.Buffer {
   401  		t.Fatal("Buffer doesn't match")
   402  	}
   403  
   404  	if err := QdiscDel(qdisc); err != nil {
   405  		t.Fatal(err)
   406  	}
   407  	qdiscs, err = SafeQdiscList(link)
   408  	if err != nil {
   409  		t.Fatal(err)
   410  	}
   411  	if len(qdiscs) != 0 {
   412  		t.Fatal("Failed to remove qdisc")
   413  	}
   414  }
   415  
   416  func TestFqAddChangeDel(t *testing.T) {
   417  	minKernelRequired(t, 3, 11)
   418  
   419  	tearDown := setUpNetlinkTest(t)
   420  	defer tearDown()
   421  	if err := LinkAdd(&Ifb{LinkAttrs{Name: "foo"}}); err != nil {
   422  		t.Fatal(err)
   423  	}
   424  	link, err := LinkByName("foo")
   425  	if err != nil {
   426  		t.Fatal(err)
   427  	}
   428  	if err := LinkSetUp(link); err != nil {
   429  		t.Fatal(err)
   430  	}
   431  	qdisc := &Fq{
   432  		QdiscAttrs: QdiscAttrs{
   433  			LinkIndex: link.Attrs().Index,
   434  			Handle:    MakeHandle(1, 0),
   435  			Parent:    HANDLE_ROOT,
   436  		},
   437  		FlowPacketLimit: 123,
   438  		Pacing:          0,
   439  	}
   440  	if err := QdiscAdd(qdisc); err != nil {
   441  		t.Fatal(err)
   442  	}
   443  	qdiscs, err := SafeQdiscList(link)
   444  	if err != nil {
   445  		t.Fatal(err)
   446  	}
   447  	if len(qdiscs) != 1 {
   448  		t.Fatal("Failed to add qdisc")
   449  	}
   450  	fq, ok := qdiscs[0].(*Fq)
   451  	if !ok {
   452  		t.Fatal("Qdisc is the wrong type")
   453  	}
   454  	if fq.FlowPacketLimit != qdisc.FlowPacketLimit {
   455  		t.Fatal("Flow Packet Limit does not match")
   456  	}
   457  	if fq.Pacing != qdisc.Pacing {
   458  		t.Fatal("Pacing does not match")
   459  	}
   460  
   461  	if err := QdiscDel(qdisc); err != nil {
   462  		t.Fatal(err)
   463  	}
   464  	qdiscs, err = SafeQdiscList(link)
   465  	if err != nil {
   466  		t.Fatal(err)
   467  	}
   468  	if len(qdiscs) != 0 {
   469  		t.Fatal("Failed to remove qdisc")
   470  	}
   471  }
   472  
   473  func TestFqHorizon(t *testing.T) {
   474  	minKernelRequired(t, 5, 7)
   475  
   476  	tearDown := setUpNetlinkTest(t)
   477  	defer tearDown()
   478  	if err := LinkAdd(&Ifb{LinkAttrs{Name: "foo"}}); err != nil {
   479  		t.Fatal(err)
   480  	}
   481  	link, err := LinkByName("foo")
   482  	if err != nil {
   483  		t.Fatal(err)
   484  	}
   485  	if err := LinkSetUp(link); err != nil {
   486  		t.Fatal(err)
   487  	}
   488  	qdisc := &Fq{
   489  		QdiscAttrs: QdiscAttrs{
   490  			LinkIndex: link.Attrs().Index,
   491  			Handle:    MakeHandle(1, 0),
   492  			Parent:    HANDLE_ROOT,
   493  		},
   494  		Horizon:           1000,
   495  		HorizonDropPolicy: HORIZON_DROP_POLICY_CAP,
   496  	}
   497  	if err := QdiscAdd(qdisc); err != nil {
   498  		t.Fatal(err)
   499  	}
   500  	qdiscs, err := SafeQdiscList(link)
   501  	if err != nil {
   502  		t.Fatal(err)
   503  	}
   504  	if len(qdiscs) != 1 {
   505  		t.Fatal("Failed to add qdisc")
   506  	}
   507  	fq, ok := qdiscs[0].(*Fq)
   508  	if !ok {
   509  		t.Fatal("Qdisc is the wrong type")
   510  	}
   511  	if fq.Horizon != qdisc.Horizon {
   512  		t.Fatal("Horizon does not match")
   513  	}
   514  	if fq.HorizonDropPolicy != qdisc.HorizonDropPolicy {
   515  		t.Fatal("HorizonDropPolicy does not match")
   516  	}
   517  
   518  	if err := QdiscDel(qdisc); err != nil {
   519  		t.Fatal(err)
   520  	}
   521  	qdiscs, err = SafeQdiscList(link)
   522  	if err != nil {
   523  		t.Fatal(err)
   524  	}
   525  	if len(qdiscs) != 0 {
   526  		t.Fatal("Failed to remove qdisc")
   527  	}
   528  }
   529  
   530  func TestFqCodelAddChangeDel(t *testing.T) {
   531  	minKernelRequired(t, 3, 4)
   532  
   533  	tearDown := setUpNetlinkTest(t)
   534  	defer tearDown()
   535  	if err := LinkAdd(&Ifb{LinkAttrs{Name: "foo"}}); err != nil {
   536  		t.Fatal(err)
   537  	}
   538  	link, err := LinkByName("foo")
   539  	if err != nil {
   540  		t.Fatal(err)
   541  	}
   542  	if err := LinkSetUp(link); err != nil {
   543  		t.Fatal(err)
   544  	}
   545  	qdisc := &FqCodel{
   546  		QdiscAttrs: QdiscAttrs{
   547  			LinkIndex: link.Attrs().Index,
   548  			Handle:    MakeHandle(1, 0),
   549  			Parent:    HANDLE_ROOT,
   550  		},
   551  		ECN:     1,
   552  		Quantum: 9000,
   553  	}
   554  	if err := QdiscAdd(qdisc); err != nil {
   555  		t.Fatal(err)
   556  	}
   557  	qdiscs, err := SafeQdiscList(link)
   558  	if err != nil {
   559  		t.Fatal(err)
   560  	}
   561  	if len(qdiscs) != 1 {
   562  		t.Fatal("Failed to add qdisc")
   563  	}
   564  	fqcodel, ok := qdiscs[0].(*FqCodel)
   565  	if !ok {
   566  		t.Fatal("Qdisc is the wrong type")
   567  	}
   568  	if fqcodel.Quantum != qdisc.Quantum {
   569  		t.Fatal("Quantum does not match")
   570  	}
   571  
   572  	if err := QdiscDel(qdisc); err != nil {
   573  		t.Fatal(err)
   574  	}
   575  	qdiscs, err = SafeQdiscList(link)
   576  	if err != nil {
   577  		t.Fatal(err)
   578  	}
   579  	if len(qdiscs) != 0 {
   580  		t.Fatal("Failed to remove qdisc")
   581  	}
   582  }
   583  
   584  func TestIngressAddDel(t *testing.T) {
   585  	tearDown := setUpNetlinkTest(t)
   586  	defer tearDown()
   587  	if err := LinkAdd(&Ifb{LinkAttrs{Name: "foo"}}); err != nil {
   588  		t.Fatal(err)
   589  	}
   590  	link, err := LinkByName("foo")
   591  	if err != nil {
   592  		t.Fatal(err)
   593  	}
   594  	qdisc := &Ingress{
   595  		QdiscAttrs: QdiscAttrs{
   596  			LinkIndex: link.Attrs().Index,
   597  			Parent:    HANDLE_INGRESS,
   598  		},
   599  	}
   600  	err = QdiscAdd(qdisc)
   601  	if err != nil {
   602  		t.Fatal("Failed to add qdisc")
   603  	}
   604  	qdiscs, err := SafeQdiscList(link)
   605  	if err != nil {
   606  		t.Fatal("Failed to list qdisc")
   607  	}
   608  	if len(qdiscs) != 1 {
   609  		t.Fatal("Failed to add qdisc")
   610  	}
   611  	if err = QdiscDel(qdisc); err != nil {
   612  		t.Fatal(err)
   613  	}
   614  	qdiscs, err = SafeQdiscList(link)
   615  	if err != nil {
   616  		t.Fatal(err)
   617  	}
   618  	if len(qdiscs) != 0 {
   619  		t.Fatal("Failed to remove qdisc")
   620  	}
   621  }