bridge: reliably pin the MAC on a bridge that lost its ports#1265
Open
twz123 wants to merge 2 commits into
Open
bridge: reliably pin the MAC on a bridge that lost its ports#1265twz123 wants to merge 2 commits into
twz123 wants to merge 2 commits into
Conversation
4d7a078 to
8be5425
Compare
The ensureAddr function pins the bridge's MAC address so it doesn't change as ports come and go. The pinning happens after the gateway address is set, so if a run set the address but then failed before pinning, subsequent runs never reattempted to pin the MAC, leaving behind a bridge with a floating MAC. Always pin the MAC, even if the gateway address is already present, regardless of the outcomes of previous attempts. Signed-off-by: Tom Wieczorek <twieczorek@mirantis.com>
The kernel zeroes a bridge's MAC address when its last port is removed. The ensureAddr function pins the bridge's MAC address using the address read when the bridge was looked up, which is before the veth is attached. So for an existing bridge that had previously lost all its ports, the address it tried to pin is all zeros, and pinning an all-zero address fails with EINVAL. In fact, this can happen in practice: an ADD that fails has its veth cleaned up, which, if it was the first ADD, leaves the bridge portless and hence its MAC zeroed, so the next ADD fails to pin it. Detect that case and regenerate a random MAC address the same way the kernel does. This is fine as it only happens if the bridge has no ports, so no peer can hold stale state about the old address. Signed-off-by: Tom Wieczorek <twieczorek@mirantis.com>
8be5425 to
d06315e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The
ensureAddrfunction pins the bridge's MAC address so it doesn't change as ports come and go. The pinning happens after the gateway address is set, so if a run set the address but then failed before pinning, subsequent runs never reattempted to pin the MAC, leaving behind a bridge with a floating MAC. The kernel zeroes a bridge's MAC address when its last port is removed, andensureAddrpins the MAC using the address read when the bridge was looked up, which is before the veth is attached. So for an existing bridge that had previously lost all its ports, the address it tried to pin is all zeros, and pinning an all-zero address fails withEINVAL.In fact, this can happen in practice: an ADD that fails has its veth cleaned up, which, if it was the first ADD, leaves the bridge portless and hence its MAC zeroed, so the next ADD fails to pin it.
Always pin the MAC, even if the gateway address is already present, regardless of the outcomes of previous attempts. Detect zero MACs and regenerate a random MAC address the same way the kernel does. This is fine as it only happens if the bridge has no ports, so no peer can hold stale state about the old address.