Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OCPBUGS-21831: [release-4.14] Set MAC address after renaming the interface #92

Merged
merged 1 commit into from
Oct 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 15 additions & 13 deletions pkg/sriov/sriov.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package sriov

import (
"fmt"

"github.com/containernetworking/plugins/pkg/ns"

sriovtypes "github.com/k8snetworkplumbingwg/sriov-cni/pkg/types"
Expand Down Expand Up @@ -65,6 +66,9 @@ func (s *sriovManager) SetupVF(conf *sriovtypes.NetConf, podifName string, netns
return fmt.Errorf("error getting VF netdevice with name %s", linkName)
}

// Save the original effective MAC address before overriding it
conf.OrigVfState.EffectiveMAC = linkObj.Attrs().HardwareAddr.String()

// tempName used as intermediary name to avoid name conflicts
tempName := fmt.Sprintf("%s%d", "temp_", linkObj.Attrs().Index)

Expand All @@ -78,31 +82,29 @@ func (s *sriovManager) SetupVF(conf *sriovtypes.NetConf, podifName string, netns
return fmt.Errorf("error setting temp IF name %s for %s", tempName, linkName)
}

// Save the original effective MAC address before overriding it
conf.OrigVfState.EffectiveMAC = linkObj.Attrs().HardwareAddr.String()
// 3. Set MAC address
if conf.MAC != "" {
err = utils.SetVFEffectiveMAC(s.nLink, tempName, conf.MAC)
if err != nil {
return fmt.Errorf("failed to set netlink MAC address to %s: %v", conf.MAC, err)
}
}

// 4. Change netns
// 3. Change netns
if err := s.nLink.LinkSetNsFd(linkObj, int(netns.Fd())); err != nil {
return fmt.Errorf("failed to move IF %s to netns: %q", tempName, err)
}

if err := netns.Do(func(_ ns.NetNS) error {
// 5. Set Pod IF name
// 4. Set Pod IF name
if err := s.nLink.LinkSetName(linkObj, podifName); err != nil {
return fmt.Errorf("error setting container interface name %s for %s", linkName, tempName)
}

// 6. Enable IPv4 ARP notify and IPv6 Network Discovery notify
// 5. Enable IPv4 ARP notify and IPv6 Network Discovery notify
// Error is ignored here because enabling this feature is only a performance enhancement.
_ = s.utils.EnableArpAndNdiscNotify(podifName)

// 6. Set MAC address
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I did not catch this in U/S sriov-cni. But setting the MAC address after we send out GARPs may be an issue. Since ARPs require that the MAC address is setup properly.

You are moving SetVFEffectiveMAC down to solve a race condition, is that correct? So moving it before EnableArpAndNdiscNotify shouldn't be any different (although solving race conditions this way really is a toss of the coin).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I did not catch this in U/S sriov-cni. But setting the MAC address after we send out GARPs may be an issue. Since ARPs require that the MAC address is setup properly.

Does the GARP go out before setting up the interface? That happens on step 7

You are moving SetVFEffectiveMAC down to solve a race condition, is that correct? So moving it before EnableArpAndNdiscNotify shouldn't be any different (although solving race conditions this way really is a toss of the coin).

I agree, that's the best we could do from the CNI side while the investigation on the kernel side is still ongoing.
As the root cause is not yet clear, moving that statement can make a difference. At least, we should run an extensive test suite as we did with these changes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I forgot that it is also done after IPAM. Then this is lgtm.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It actually doesn't happen at step 7 but after IPAM is setup.

if conf.MAC != "" {
err = utils.SetVFEffectiveMAC(s.nLink, podifName, conf.MAC)
if err != nil {
return fmt.Errorf("failed to set netlink MAC address to %s: %v", conf.MAC, err)
}
}

// 7. Bring IF up in Pod netns
if err := s.nLink.LinkSetUp(linkObj); err != nil {
return fmt.Errorf("error bringing interface up in container ns: %q", err)
Expand Down
11 changes: 6 additions & 5 deletions pkg/sriov/sriov_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package sriov

import (
"github.com/k8snetworkplumbingwg/sriov-cni/pkg/utils"
"net"

"github.com/k8snetworkplumbingwg/sriov-cni/pkg/utils"

"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils"
"github.com/k8snetworkplumbingwg/sriov-cni/pkg/sriov/mocks"
Expand Down Expand Up @@ -100,17 +101,17 @@ var _ = Describe("Sriov", func() {
HardwareAddr: fakeMac,
}}

tempLink := &utils.FakeLink{LinkAttrs: netlink.LinkAttrs{
net1Link := &utils.FakeLink{LinkAttrs: netlink.LinkAttrs{
Index: 1000,
Name: "temp_1000",
Name: "net1",
HardwareAddr: expMac,
}}

mocked.On("LinkByName", "enp175s6").Return(fakeLink, nil)
mocked.On("LinkByName", "temp_1000").Return(tempLink, nil)
mocked.On("LinkByName", "net1").Return(net1Link, nil)
mocked.On("LinkSetDown", fakeLink).Return(nil)
mocked.On("LinkSetName", fakeLink, mock.Anything).Return(nil)
mocked.On("LinkSetHardwareAddr", tempLink, expMac).Return(nil)
mocked.On("LinkSetHardwareAddr", net1Link, expMac).Return(nil)
mocked.On("LinkSetNsFd", fakeLink, mock.AnythingOfType("int")).Return(nil)
mocked.On("LinkSetUp", fakeLink).Return(nil)
mockedPciUtils.On("EnableArpAndNdiscNotify", mock.AnythingOfType("string")).Return(nil)
Expand Down