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

Fix a race condition in getting the trunk name via its mac #15

Merged
merged 1 commit into from
May 29, 2019

Conversation

fenxiong
Copy link
Contributor

@fenxiong fenxiong commented May 29, 2019

During setting up a branch interface, the branch can have the same mac address as the trunk for a short period of time, and we may end up picking the branch's name when trying to get the trunk name by mac. Fixing it by picking the shortest name available since branch name is strictly longer than trunk.

Unit test added and passed. The e2e tests via vpc-branch-eni-e2e-tests target passed. Manually reproduced the race with unfixed version and verified that it's fixed with this pr.

Issue #, if available:

Description of changes:

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

// getInterfaceByMac gets the interface with specified mac address, and picks the one with shortest name
// if there are multiple matches, which can happen temporarily when setting up a branch ENI, in which it
// can have the same mac address as the trunk during branch.AttachToLink.
func getInterfaceByMac(macAddress net.HardwareAddr, interfaces []net.Interface) *net.Interface {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you please call this getInterfaceByMACAddress, to comply with the Go naming conventions? Also please move to the end of the file to keep the ENI class methods together.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated

@@ -102,6 +97,27 @@ func (eni *ENI) AttachToLink() error {
return nil
}

// getInterfaceByMac gets the interface with specified mac address, and picks the one with shortest name
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's not discuss the trunk vs. branch MAC address here. The ENI class doesn't know about trunks etc.
// getInterfaceByMACAddress returns the interface with the specified MAC address.

Move the rest of your comment block to just before the for loop (line 106):
// If there are multiple matches, pick the one with the shortest name.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated

// if there are multiple matches, which can happen temporarily when setting up a branch ENI, in which it
// can have the same mac address as the trunk during branch.AttachToLink.
func getInterfaceByMac(macAddress net.HardwareAddr, interfaces []net.Interface) *net.Interface {
var chosenInterface net.Interface
Copy link
Contributor

Choose a reason for hiding this comment

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

If you define this as a pointer (var chosen *net.Interface), then

the if check at line 108 can become simply
if chosen == nil || len(chosen.Name) > len(i.Name)

line 109 becomes a pointer copy instead of a struct copy

you can remove the if block lines 114-116.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i originally did that. then i found the variable "i" in the for loop shares the same address, so i can't just save the address.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

discussed offline. fixed.

break
}
}
iface = getInterfaceByMac(eni.macAddress, interfaces)
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we move the net.Interfaces() call to the new getInterfaceByMACAddress function? That way we wouldn't have to pass it as an argument.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

that makes it hard to add unit test i think..

Index: 3,
Name: "eth1.1.1",
HardwareAddr: mac,
},
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for adding tests. For testing an interesting corner case, you can add one more interface here with a three letter name but a different MAC address. To make sure MAC address match is prioritized.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated the test

@@ -0,0 +1,33 @@
package eni
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we add the copyright header to the top of the file?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good catch, added

@fenxiong fenxiong force-pushed the fix-name branch 2 times, most recently from c83e765 to fda2912 Compare May 29, 2019 21:44
During setting up a branch interface, it can have the same mac address as the trunk for a short period of time, and we may end up picking the branch's name when trying to get the trunk name by mac. Fixing it by picking the shortest name available since branch name is strictly longer than trunk.
@ofiliz ofiliz merged commit d90eebe into aws:master May 29, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants