diff --git a/pkg/sriov/sriov.go b/pkg/sriov/sriov.go index deaad0b98..0386ca6c7 100644 --- a/pkg/sriov/sriov.go +++ b/pkg/sriov/sriov.go @@ -176,7 +176,27 @@ func (s *sriovManager) ReleaseVF(conf *sriovtypes.NetConf, podifName string, cid return fmt.Errorf("failed to parse original effective MAC address %s: %v", conf.OrigVfState.EffectiveMAC, err) } - if err = s.nLink.LinkSetHardwareAddr(linkObj, hwaddr); err != nil { + /* Some NIC drivers (i.e. i40e/iavf) set VF MAC address asynchronously. + This means that we can get an error from the setHardwareAddr, or it may just fail silently + so to cover both cases we will retry the set function + and also check the mac address on the VF after the configuration. + */ + err = utils.Retry(10, 100*time.Millisecond, func() error { + if err := s.nLink.LinkSetHardwareAddr(linkObj, hwaddr); err != nil { + return err + } + + linkObj, err = s.nLink.LinkByName(conf.OrigVfState.HostIFName) + if err != nil { + return fmt.Errorf("failed to get netlink device with name %s: %q", linkObj.Attrs().Name, err) + } + if linkObj.Attrs().HardwareAddr.String() != conf.OrigVfState.EffectiveMAC { + return fmt.Errorf("effective nic mac address is different from original one") + } + + return nil + }) + if err != nil { return fmt.Errorf("failed to restore original effective netlink MAC address %s: %v", hwaddr, err) } } diff --git a/pkg/sriov/sriov_test.go b/pkg/sriov/sriov_test.go index d8c90e24d..1024c1371 100644 --- a/pkg/sriov/sriov_test.go +++ b/pkg/sriov/sriov_test.go @@ -208,9 +208,12 @@ var _ = Describe("Sriov", func() { }() Expect(err).NotTo(HaveOccurred()) mocked := &mocks_utils.NetlinkManager{} - fakeLink := &FakeLink{netlink.LinkAttrs{Index: 1000, Name: "dummylink"}} + macaddr, err := net.ParseMAC("c6:c8:7f:1f:21:90") + Expect(err).NotTo(HaveOccurred()) + fakeLink := &FakeLink{netlink.LinkAttrs{Index: 1000, Name: "dummylink", HardwareAddr: macaddr}} mocked.On("LinkByName", netconf.ContIFNames).Return(fakeLink, nil) + mocked.On("LinkByName", netconf.OrigVfState.HostIFName).Return(fakeLink, nil) mocked.On("LinkSetDown", fakeLink).Return(nil) mocked.On("LinkSetName", fakeLink, netconf.OrigVfState.HostIFName).Return(nil) mocked.On("LinkSetNsFd", fakeLink, mock.AnythingOfType("int")).Return(nil)