From 24a50ba5e1a21bd758826d852ad7a88e2db3193f Mon Sep 17 00:00:00 2001 From: Vrindle Date: Thu, 16 Jun 2022 17:58:57 -0400 Subject: [PATCH] Generates random MAC address when effective virtual function MAC address is zero. This is to set VF effective MAC addresses when the VF effective MAC address is all zero for some vendor NICs. --- pkg/utils/utils.go | 47 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index e83dbc6de..a523ca953 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -330,6 +330,7 @@ func configSriovDevice(iface *sriovnetworkv1.Interface, ifaceStatus *sriovnetwor return err } } + if err = setVfAdminMac(addr, pfLink, vfLink); err != nil { glog.Errorf("configSriovDevice(): fail to configure VF admin mac address for device %s %q", addr, err) return err @@ -375,6 +376,17 @@ func configSriovDevice(iface *sriovnetworkv1.Interface, ifaceStatus *sriovnetwor return nil } +func generateRandomMacAddressVfs() ([]byte, error) { + buf := make([]byte, 6) + _, err := rand.Read(buf) + if err != nil { + return buf, err + } + // Set the local bit + buf[0] = (buf[0] & 0xfe) | 2 + return buf, nil +} + func setSriovNumVfs(pciAddr string, numVfs int) error { glog.V(2).Infof("setSriovNumVfs(): set NumVfs for device %s", pciAddr) numVfsFilePath := filepath.Join(sysBusPciDevices, pciAddr, numVfsFile) @@ -600,6 +612,35 @@ func vfIsReady(pciAddr string) (netlink.Link, error) { return vfLink, nil } +func isValidAddress(address []byte) bool { + invalidAddresses := [][]byte{ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + } + for _, invalidAddress := range invalidAddresses { + if bytes.Equal(address, invalidAddress) { + return false + } + } + return true +} + +func getEffectiveMacAddress(hwAddr net.HardwareAddr) (net.HardwareAddr, error) { + newAddr := []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + zeroAddr := net.HardwareAddr(newAddr[:]) + if bytes.Equal(hwAddr, zeroAddr) { + for !isValidAddress(newAddr) { + newAddr2, err := generateRandomMacAddressVfs() + newAddr = newAddr2 + if err != nil { + return nil, err + } + } + return net.HardwareAddr(newAddr[:]), nil + } + return hwAddr, nil +} + func setVfAdminMac(vfAddr string, pfLink, vfLink netlink.Link) error { glog.Infof("setVfAdminMac(): VF %s", vfAddr) @@ -608,8 +649,12 @@ func setVfAdminMac(vfAddr string, pfLink, vfLink netlink.Link) error { glog.Errorf("setVfAdminMac(): unable to get VF id %+v %q", vfAddr, err) return err } + hwAddr, err := getEffectiveMacAddress(vfLink.Attrs().HardwareAddr) + if err != nil { + return err + } - if err := netlink.LinkSetVfHardwareAddr(pfLink, vfID, vfLink.Attrs().HardwareAddr); err != nil { + if err := netlink.LinkSetVfHardwareAddr(pfLink, vfID, hwAddr); err != nil { return err }