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

libnetwork: Remove iptables nat rule when hairpin is disabled #44803

Merged
merged 1 commit into from Jan 12, 2023

Conversation

akerouanton
Copy link
Member

When userland-proxy is turned off and on again, the iptables nat rule
doing hairpinning isn't properly removed. This fix makes sure this nat
rule is removed whenever the bridge is torn down or hairpinning is
disabled (through setting userland-proxy to true).

Unlike for ip masquerading and ICC, the programChainRule() call
setting up the "MASQ LOCAL HOST" rule has to be called unconditionally
because the hairpin parameter isn't restored from the driver store, but
always comes from the driver config.

For the "SKIP DNAT" rule, things are a bit different: this rule is
always deleted by removeIPChains() when the bridge driver is
initialized.

Fixes #44721.

Side note: I'm not super happy with this fix. It does its job but there're now 3 ways iptables rules created by setupIPTablesInternal are torn down. There might be a better way to do that, but this probably won't be possible until libnetwork got cleaned up and iptables rules are managed in a better way.

- How to verify it

Turning userland-proxy off and on again, and then running iptables -t nat -nvL. There should be no rule looking like -A POSTROUTING -o docker0 -m addrtype --src-type LOCAL -j MASQUERADE.

When userland-proxy is turned off and on again, the iptables nat rule
doing hairpinning isn't properly removed. This fix makes sure this nat
rule is removed whenever the bridge is torn down or hairpinning is
disabled (through setting userland-proxy to true).

Unlike for ip masquerading and ICC, the `programChainRule()` call
setting up the "MASQ LOCAL HOST" rule has to be called unconditionally
because the hairpin parameter isn't restored from the driver store, but
always comes from the driver config.

For the "SKIP DNAT" rule, things are a bit different: this rule is
always deleted by `removeIPChains()` when the bridge driver is
initialized.

Fixes moby#44721.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
Copy link
Member

@neersighted neersighted left a comment

Choose a reason for hiding this comment

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

Overall LGTM. This is definitely messy, but not as bad as I feared in #44721 (comment), and the one-line change makes it a lot more palatable.

Overall I think this is the lesser evil until the rules logic gets cleaned up in its entirety.

docs/contributing/debug.md Outdated Show resolved Hide resolved
@neersighted
Copy link
Member

Eyeing this for 23.0.y; I think it's fine to omit from 20.10.

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

whoops, I kicked CI earlier, thought I LGTM'd

backporting sounds okay to me

@neersighted
Copy link
Member

Test failure is known flake/unrelated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

userland-proxy: false does not clean-up NAT rule when switching to userland-proxy: true
4 participants