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

     1  //go:build linux
     2  // +build linux
     3  
     4  package netlink
     5  
     6  import (
     7  	"io/ioutil"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/vishvananda/netns"
    12  )
    13  
    14  func setupRdmaKModule(t *testing.T, name string) {
    15  	skipUnlessRoot(t)
    16  	file, err := ioutil.ReadFile("/proc/modules")
    17  	if err != nil {
    18  		t.Fatal("Failed to open /proc/modules", err)
    19  	}
    20  	for _, line := range strings.Split(string(file), "\n") {
    21  		n := strings.Split(line, " ")[0]
    22  		if n == name {
    23  			return
    24  		}
    25  
    26  	}
    27  	t.Skipf("Test requires kmodule %q.", name)
    28  }
    29  
    30  func TestRdmaGetRdmaLink(t *testing.T) {
    31  	minKernelRequired(t, 4, 16)
    32  	setupRdmaKModule(t, "ib_core")
    33  	_, err := RdmaLinkByName("foo")
    34  	if err != nil {
    35  		t.Fatal(err)
    36  	}
    37  }
    38  
    39  func TestRdmaSetRdmaLinkName(t *testing.T) {
    40  	minKernelRequired(t, 4, 19)
    41  	setupRdmaKModule(t, "ib_core")
    42  	link, err := RdmaLinkByName("foo")
    43  	if err != nil {
    44  		t.Fatal(err)
    45  	}
    46  	// Set new name
    47  	err = RdmaLinkSetName(link, "bar")
    48  	if err != nil {
    49  		t.Fatal(err)
    50  	}
    51  	// Revert back to old name
    52  	err = RdmaLinkSetName(link, "foo")
    53  	if err != nil {
    54  		t.Fatal(err)
    55  	}
    56  }
    57  
    58  func TestRdmaSystemGetNetnsMode(t *testing.T) {
    59  	minKernelRequired(t, 5, 2)
    60  	setupRdmaKModule(t, "ib_core")
    61  
    62  	mode, err := RdmaSystemGetNetnsMode()
    63  	if err != nil {
    64  		t.Fatal(err)
    65  	}
    66  	t.Log("rdma system netns mode =", mode)
    67  }
    68  
    69  func TestRdmaSystemSetNetnsMode(t *testing.T) {
    70  	var newMode string
    71  	var mode string
    72  	var err error
    73  
    74  	minKernelRequired(t, 5, 2)
    75  	setupRdmaKModule(t, "ib_core")
    76  
    77  	mode, err = RdmaSystemGetNetnsMode()
    78  	if err != nil {
    79  		t.Fatal(err)
    80  	}
    81  	t.Log("current rdma system mode =", mode)
    82  
    83  	err = RdmaSystemSetNetnsMode(mode)
    84  	if err != nil {
    85  		t.Fatal(err)
    86  	}
    87  	// Flip the mode from current mode
    88  	if mode == "exclusive" {
    89  		RdmaSystemSetNetnsMode("shared")
    90  	} else {
    91  		RdmaSystemSetNetnsMode("exclusive")
    92  	}
    93  	newMode, err = RdmaSystemGetNetnsMode()
    94  	if err != nil {
    95  		t.Fatal(err)
    96  	}
    97  	t.Log("new rdma system mode =", newMode)
    98  
    99  	// Change back to original mode
   100  	err = RdmaSystemSetNetnsMode(mode)
   101  	if err != nil {
   102  		t.Fatal(err)
   103  	}
   104  }
   105  
   106  func TestRdmaLinkSetNsFd(t *testing.T) {
   107  	minKernelRequired(t, 5, 2)
   108  	setupRdmaKModule(t, "ib_core")
   109  
   110  	mode, err := RdmaSystemGetNetnsMode()
   111  	if err != nil {
   112  		t.Fatal(err)
   113  	}
   114  	t.Log("current rdma netns mode", mode)
   115  	err = RdmaSystemSetNetnsMode("exclusive")
   116  	if err != nil {
   117  		t.Fatal(err)
   118  	}
   119  	basens, err := netns.Get()
   120  	if err != nil {
   121  		RdmaSystemSetNetnsMode(mode)
   122  		t.Fatal("Failed to get basens")
   123  	}
   124  	defer basens.Close()
   125  
   126  	newns, err := netns.New()
   127  	if err != nil {
   128  		RdmaSystemSetNetnsMode(mode)
   129  		t.Fatal("Failed to create newns")
   130  	}
   131  
   132  	netns.Set(basens)
   133  	link, err := RdmaLinkByName("foo")
   134  	if err != nil {
   135  		// Remove the namespace as RDMA subsystem requires
   136  		// no namespace to exist when changing net namespace mode
   137  		newns.Close()
   138  		RdmaSystemSetNetnsMode(mode)
   139  		t.Fatal(err)
   140  	}
   141  	t.Log("rdma link: ", link)
   142  
   143  	err = RdmaLinkSetNsFd(link, uint32(newns))
   144  	if err != nil {
   145  		newns.Close()
   146  		RdmaSystemSetNetnsMode(mode)
   147  		t.Fatal(err)
   148  	}
   149  
   150  	newns.Close()
   151  	//Set the old mode back at start of the test
   152  	err = RdmaSystemSetNetnsMode(mode)
   153  	if err != nil {
   154  		t.Fatal(err)
   155  	}
   156  }
   157  
   158  func TestRdmaLinkList(t *testing.T) {
   159  	minKernelRequired(t, 4, 16)
   160  	setupRdmaKModule(t, "ib_core")
   161  	links, err := RdmaLinkList()
   162  	if err != nil {
   163  		t.Fatal(err)
   164  	}
   165  	t.Log("RDMA devices:")
   166  	for _, link := range links {
   167  		t.Logf("%d: %s", link.Attrs.Index, link.Attrs.Name)
   168  	}
   169  }
   170  
   171  func TestRdmaLinkAddAndDel(t *testing.T) {
   172  	// related commit is https://github.com/torvalds/linux/commit/3856ec4b93c9463d36ee39098dde1fbbd29ec6dd.
   173  	minKernelRequired(t, 5, 1)
   174  	setupRdmaKModule(t, "rdma_rxe")
   175  
   176  	checkPresence := func(name string, exist bool) {
   177  		links, err := RdmaLinkList()
   178  		if err != nil {
   179  			t.Fatal(err)
   180  		}
   181  
   182  		found := false
   183  		for _, link := range links {
   184  			if link.Attrs.Name == name {
   185  				found = true
   186  				break
   187  			}
   188  		}
   189  
   190  		if found != exist {
   191  			t.Fatalf("expected rdma link %s presence=%v, but got presence=%v", name, exist, found)
   192  		}
   193  	}
   194  
   195  	linkName := t.Name()
   196  
   197  	if err := RdmaLinkAdd(linkName, "rxe", "lo"); err != nil {
   198  		t.Fatal(err)
   199  	}
   200  
   201  	checkPresence(linkName, true)
   202  
   203  	if err := RdmaLinkDel(linkName); err != nil {
   204  		t.Fatal(err)
   205  	}
   206  
   207  	checkPresence(linkName, false)
   208  }