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 missing iptables after a HostEndpoint-protected interface is deleted and re-added #1883
Merged
Conversation
This file contains 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
A customer reported a calico/node having got into a state where expected iptables programming for a HostEndpoint was missing. They created a bridge device, and a HostEndpoint to protect that, and initially the expected iptables programming was present. However, after some period of churn, which we believe included - deleting and re-adding the bridge device - setting the state of the bridge device down and later up again - creating and deleting many real or simulated pods/containers on that node, it was observed that the HostEndpoint iptables were missing, and that setting the bridge device down and up made no difference to this. The missing iptables could only be recreated by restarting the calico/node. We identified a bug that would account for this if all of the following points are also true: 1. One time when the bridge device is deleted, the Netlink event for that is lost (or delayed for a long time), and the removal of the device is then detected by a period resync that the Felix code does. The bug is that the exact handling here is different than when processing an individual Netlink event. 2. When the bridge device is added again, it has the same addresses and interface index as before it was deleted, and either there is no Netlink event reporting the addresses, or Felix sees that event before it sees the event about the device reappearing. 3. Later, when the bridge device is set down and up again, either there are no address changes that ensue from that (which is unusual, because Linux devices normally do IPv6 autoconfiguration, which means that an IPv6 address is added when the device goes up, and taken away when the device goes down), or there is some other reason why Netlink address events are not generated, or don't reach Felix. This change adds a UT case to repro that scenario, and demonstrates the result that we are missing a non-nil address callback when the bridge device is added again. In Felix as a whole, the absence of that callback means that HostEndpoint iptables are not reprogrammed.
fasaxc
approved these changes
Aug 23, 2018
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just one small comment. Otherwise LGTM.
ifacemonitor/iface_monitor.go
Outdated
@@ -52,7 +52,7 @@ type InterfaceMonitor struct { | |||
|
|||
netlinkStub netlinkStub | |||
resyncC <-chan time.Time | |||
upIfaces set.Set | |||
upIfaces map[string]int |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Worth commenting what the int is that you're storing.
The test code's intention is to test when a deleted link is detected in a resync. However there was a race, and the following was also possible: 1. Kick off a resync. 2. Kick off link deletion. 3. Resync queries links and finds that the link is question is still present. 4. Link deletion now proceeds, and state for that link deleted. 5. Resync queries addresses for that link and finds that there aren't any. resulting in an addr callback with set.New(), instead of an addr callback with nil. We can now use delLinkNoSignal to ensure that the original intended scenario reliably happens, so that's what this change does.
fasaxc
approved these changes
Aug 23, 2018
This was referenced Aug 23, 2018
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.
Description
A customer reported a calico/node having got into a state where expected
iptables programming for a HostEndpoint was missing. They created a
bridge device, and a HostEndpoint to protect that, and initially the
expected iptables programming was present. However, after some period
of churn, which we believe included
node,
it was observed that the HostEndpoint iptables were missing, and that
setting the bridge device down and up made no difference to this. The
missing iptables could only be recreated by restarting the calico/node.
We identified a bug that would account for this if all of the following
points are also true:
One time when the bridge device is deleted, the Netlink event for
that is lost (or delayed for a long time), and the removal of the device
is then detected by a period resync that the Felix code does. The bug
is that the exact handling here is different than when processing an
individual Netlink event.
When the bridge device is added again, it has the same addresses and
interface index as before it was deleted, and either there is no Netlink
event reporting the addresses, or Felix sees that event before it sees
the event about the device reappearing.
Later, when the bridge device is set down and up again, either there
are no address changes that ensue from that (which is unusual, because
Linux devices normally do IPv6 autoconfiguration, which means that an
IPv6 address is added when the device goes up, and taken away when the
device goes down), or there is some other reason why Netlink address
events are not generated, or don't reach Felix.
This change adds a UT case to repro that scenario, and demonstrates the
result that we are missing a non-nil address callback when the bridge
device is added again. In Felix as a whole, the absence of that
callback means that HostEndpoint iptables are not reprogrammed.
The fix - also in this PR - is to clear ifacemonitor's caches at the point in
that scenario when resync spots that an interface has disappeared.
Todos
Release Note