From d125594e9145dc6d4fb7d6fded57111cb218ad5e Mon Sep 17 00:00:00 2001 From: Alexander Maslennikov Date: Wed, 3 Nov 2021 17:26:11 +0300 Subject: [PATCH] Use sriovnet provider to get PF name if PF is in switchdev mode Signed-off-by: Alexander Maslennikov --- pkg/utils/utils.go | 33 ++++++++++++++++++++-- pkg/utils/utils_test.go | 61 +++++++++++++++++++++++++++++++++++------ 2 files changed, 84 insertions(+), 10 deletions(-) diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 34f9c4139..798daa994 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -31,8 +31,9 @@ var ( ) const ( - totalVfFile = "sriov_totalvfs" - configuredVfFile = "sriov_numvfs" + totalVfFile = "sriov_totalvfs" + configuredVfFile = "sriov_numvfs" + eswitchModeSwitchdev = "switchdev" ) // DetectPluginWatchMode returns true if plugins registry directory exist @@ -60,6 +61,20 @@ func GetPfAddr(pciAddr string) (string, error) { // GetPfName returns SRIOV PF name for the given VF // If device is not VF then it will return its own ifname if exist else empty string func GetPfName(pciAddr string) (string, error) { + pfEswitchMode, err := GetPfEswitchMode(pciAddr) + if err != nil { + return "", err + } + if pfEswitchMode == eswitchModeSwitchdev { + name, err := GetSriovnetProvider().GetUplinkRepresentor(pciAddr) + + if err != nil { + return "", err + } + + return name, nil + } + path := filepath.Join(sysBusPci, pciAddr, "physfn", "net") files, err := ioutil.ReadDir(path) if err != nil { @@ -393,3 +408,17 @@ func GetVFID(pciAddr string) (vfID int, err error) { vfID = -1 return vfID, nil } + +// GetPfEswitchMode returns PF's eswitch mode for the given VF +// If device is not VF then it will return its own eswitch mode +func GetPfEswitchMode(pciAddr string) (string, error) { + pfAddr, err := GetPfAddr(pciAddr) + if err != nil { + return "", fmt.Errorf("error getting PF eswitch mode for PCI device %s %v", pciAddr, err) + } + devLinkDeviceAttrs, err := GetNetlinkProvider().GetDevLinkDeviceEswitchAttrs(pfAddr) + if err != nil { + return "", err + } + return devLinkDeviceAttrs.Mode, nil +} diff --git a/pkg/utils/utils_test.go b/pkg/utils/utils_test.go index 45dfca867..d2b48444f 100644 --- a/pkg/utils/utils_test.go +++ b/pkg/utils/utils_test.go @@ -4,6 +4,10 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/extensions/table" . "github.com/onsi/gomega" + "github.com/stretchr/testify/mock" + nl "github.com/vishvananda/netlink" + + mocks "github.com/k8snetworkplumbingwg/sriov-network-device-plugin/pkg/utils/mocks" ) func assertShouldFail(err error, shouldFail bool) { @@ -396,35 +400,76 @@ var _ = Describe("In the utils package", func() { ) DescribeTable("getting PF names", - func(fs *FakeFilesystem, device string, expected string, shouldFail bool) { + func(fs *FakeFilesystem, eswitchMode string, device string, expected string, shouldFail bool) { + fakeNetlinkProvider := mocks.NetlinkProvider{} + fakeNetlinkProvider. + On("GetDevLinkDeviceEswitchAttrs", mock.AnythingOfType("string")). + Return(&nl.DevlinkDevEswitchAttr{Mode: eswitchMode}, nil) + SetNetlinkProviderInst(&fakeNetlinkProvider) + + fakeSriovnetProvider := mocks.SriovnetProvider{} + fakeSriovnetProvider. + On("GetUplinkRepresentor", mock.AnythingOfType("string")). + Return("fakeSwitchdevPF", nil) + SetSriovnetProviderInst(&fakeSriovnetProvider) + defer fs.Use()() actual, err := GetPfName(device) Expect(actual).To(Equal(expected)) assertShouldFail(err, shouldFail) }, - Entry("device doesn't exist", &FakeFilesystem{}, "0000:01:10.0", nil, true), + Entry("device doesn't exist", &FakeFilesystem{}, "fake", "0000:01:10.0", nil, true), Entry("device is a VF and interface name exists", - &FakeFilesystem{Dirs: []string{"sys/bus/pci/devices/0000:01:10.0/physfn/net/fakePF"}}, - "0000:01:10.0", "fakePF", false, + &FakeFilesystem{ + Dirs: []string{ + "sys/bus/pci/devices/0000:01:10.0", + "sys/bus/pci/devices/0000:01:00.0/net/fakePF", + }, + Symlinks: map[string]string{ + "sys/bus/pci/devices/0000:01:10.0/physfn/": "../0000:01:00.0", + }, + }, + "fake", "0000:01:10.0", "fakePF", false, ), Entry("device is a VF and interface name does not exist", &FakeFilesystem{Dirs: []string{"sys/bus/pci/devices/0000:01:10.0/physfn/net/"}}, - "0000:01:10.0", "", true, + "fake", "0000:01:10.0", "", true, ), Entry("device is a PF and interface name exists", &FakeFilesystem{Dirs: []string{"sys/bus/pci/devices/0000:01:10.0/net/fakeIF"}}, - "0000:01:10.0", "fakeIF", false, + "fake", "0000:01:10.0", "fakeIF", false, ), Entry("device is a PF interface name does not exist", &FakeFilesystem{Dirs: []string{"sys/bus/pci/devices/0000:01:10.0/net/fakeIF"}}, - "0000:01:10.0", "fakeIF", false, + "fake", "0000:01:10.0", "fakeIF", false, ), Entry("net is not a directory at all", &FakeFilesystem{ Dirs: []string{"sys/bus/pci/devices/0000:01:10.0"}, Files: map[string][]byte{"sys/bus/pci/devices/0000:01:10.0/net": []byte("junk")}, }, - "0000:01:10.0", "", true, + "fake", "0000:01:10.0", "", true, + ), + Entry("device is a VF and PF is in switchdev mode", + &FakeFilesystem{ + Dirs: []string{ + "sys/bus/pci/devices/0000:01:10.0", + "sys/bus/pci/devices/0000:01:00.0/net/fakePF", + "sys/bus/pci/devices/0000:01:00.0/net/fakeVF", + }, + Symlinks: map[string]string{ + "sys/bus/pci/devices/0000:01:10.0/physfn/": "../0000:01:00.0", + }, + }, + "switchdev", "0000:01:10.0", "fakeSwitchdevPF", false, + ), + Entry("device is a PF in switchdev mode", + &FakeFilesystem{ + Dirs: []string{ + "sys/bus/pci/devices/0000:01:00.0/net/fakePF", + }, + }, + "switchdev", "0000:01:00.0", "fakeSwitchdevPF", false, ), )