diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index e83dbc6de8..33999fd0f4 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 nil, err + } + // Set the local bit + buf[0] |= 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,31 @@ func vfIsReady(pciAddr string) (netlink.Link, error) { return vfLink, nil } +func isValidAddress(address [6]byte) bool { + switch address { + case + [6]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + [6]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}: + return false + } + return true +} + +func getEffectiveMacAddress(hwAddr HardwareAddr) (HardwareAddr, error) { + newAddr = [6]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + zeroAddr := net.HardwareAddr(newAddr[:]) + if hwAddr == zeroAddr { + for isValidAddress(newAddr) == false { + newAddr, err := generateRandomMacAddressVfs() + 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 +645,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 }