Skip to content

[v3.31] Fix rendering of NatPortRange in nftables mode#11741

Merged
nelljerram merged 3 commits into
projectcalico:release-v3.31from
nelljerram:auto-pick-of-#11736-origin-release-v3.31
Feb 2, 2026
Merged

[v3.31] Fix rendering of NatPortRange in nftables mode#11741
nelljerram merged 3 commits into
projectcalico:release-v3.31from
nelljerram:auto-pick-of-#11736-origin-release-v3.31

Conversation

@nelljerram
Copy link
Copy Markdown
Member

Cherry-pick history

Release Note

Bugfix: fix rendering of NatPortRange option when using nftables.

…ort-range

Fix rendering of NatPortRange in nftables mode

(cherry picked from commit 3856883)
Copilot AI review requested due to automatic review settings January 29, 2026 11:38
@nelljerram nelljerram requested a review from a team as a code owner January 29, 2026 11:38
@nelljerram nelljerram added release-note-required Change has user-facing impact (no matter how small) docs-not-required Docs not required for this change merge-when-ready delete-branch labels Jan 29, 2026
@marvin-tigera marvin-tigera added this to the Calico v3.31.4 milestone Jan 29, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes nftables NAT port-range rendering for MASQUERADE/SNAT so Felix can successfully program nft rules when natPortRange is set.

Changes:

  • Update nftables MasqAction rendering to emit masquerade to :<min>-<max> (leading : required by nft syntax).
  • Extend iptables/nftables unit tests to cover MasqAction with ToPorts.
  • Add an FV test intended to validate NAT port-range rendering.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
felix/nftables/actions.go Fix nftables masquerade syntax when a port range is configured.
felix/nftables/actions_test.go Add unit coverage for nftables MasqAction port-range rendering.
felix/iptables/actions_test.go Add unit coverage for iptables MasqAction port-range rendering.
felix/fv/nat_outgoing_test.go Add FV test for NAT port-range rendering across iptables/nft modes.

Comment on lines +40 to +42
Entry("MasqAction", environment.Features{}, MasqAction{ToPorts: "32768-65535"}, "masquerade to :32768-65535"),
Entry("MasqAction", environment.Features{MASQFullyRandom: true}, MasqAction{}, "masquerade fully-random"),
Entry("MasqAction", environment.Features{MASQFullyRandom: true}, MasqAction{ToPorts: "32768-65535"}, "masquerade to :32768-65535 fully-random"),
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

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

These new table entries reuse the same description string ("MasqAction") as existing entries. In Ginkgo Table output, that makes failures hard to attribute to a specific case; please give the new entries distinct names (e.g. indicate "with ports" and/or "fully random").

Suggested change
Entry("MasqAction", environment.Features{}, MasqAction{ToPorts: "32768-65535"}, "masquerade to :32768-65535"),
Entry("MasqAction", environment.Features{MASQFullyRandom: true}, MasqAction{}, "masquerade fully-random"),
Entry("MasqAction", environment.Features{MASQFullyRandom: true}, MasqAction{ToPorts: "32768-65535"}, "masquerade to :32768-65535 fully-random"),
Entry("MasqAction with ports", environment.Features{}, MasqAction{ToPorts: "32768-65535"}, "masquerade to :32768-65535"),
Entry("MasqAction fully random", environment.Features{MASQFullyRandom: true}, MasqAction{}, "masquerade fully-random"),
Entry("MasqAction fully random with ports", environment.Features{MASQFullyRandom: true}, MasqAction{ToPorts: "32768-65535"}, "masquerade to :32768-65535 fully-random"),

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Correct but it seems conventional in this file.

Comment on lines 39 to +42
Entry("MasqAction", environment.Features{}, MasqAction{}, "--jump MASQUERADE"),
Entry("MasqAction", environment.Features{}, MasqAction{ToPorts: "32768-65535"}, "--jump MASQUERADE --to-ports 32768-65535"),
Entry("MasqAction", environment.Features{MASQFullyRandom: true}, MasqAction{}, "--jump MASQUERADE --random-fully"),
Entry("MasqAction", environment.Features{MASQFullyRandom: true}, MasqAction{ToPorts: "32768-65535"}, "--jump MASQUERADE --to-ports 32768-65535 --random-fully"),
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

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

These new table entries reuse the same description string ("MasqAction") as existing entries. In Ginkgo Table output, that makes failures hard to attribute to a specific case; please give the new entries distinct names (e.g. indicate "with ports" and/or "fully random").

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Ditto

Comment on lines +128 to +132
opts.ExtraEnvVars = map[string]string{
"FELIX_NATPortRange": "32768:65535",
}
tc, client = infrastructure.StartSingleNodeTopology(opts, infra)

Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

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

This new FV test starts topology containers (StartSingleNodeTopology) and a datastore infra but never stops them. Please add an AfterEach (like the earlier NATOutgoing test in this file) to call tc.Stop() and infra.Stop() so the test suite doesn't leak containers/resources and become flaky.

Copilot uses AI. Check for mistakes.
Comment on lines +143 to +147
if NFTMode() {
Eventually(func() string {
output, _ := tc.Felixes[0].ExecOutput("nft", "list", "chain", "ip", "calico", "nat-cali-nat-outgoing")
return output
}, 5*time.Second, 100*time.Millisecond).Should(ContainSubstring("32768-65535"))
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

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

The NFT-mode assertion only checks for the port range substring ("32768-65535"). That would still pass even if the rendered rule is missing the required leading colon (the bug this PR is fixing). Please assert on the full expected fragment for nftables (e.g. include "to :32768-65535" / ":32768-65535").

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes I could have included the colon in the test. However it's wrong to say that the test would pass before the bug fix: in fact what happened is that nft execution failed with an error, because of the missing colon, and hence those rules did not get programmed at all, so the test still failed even without the colon.

@marvin-tigera
Copy link
Copy Markdown
Contributor

Removing "merge-when-ready" label due to new commits

@nelljerram nelljerram merged commit dfc3c61 into projectcalico:release-v3.31 Feb 2, 2026
3 checks passed
@nelljerram nelljerram deleted the auto-pick-of-#11736-origin-release-v3.31 branch February 2, 2026 08:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs-not-required Docs not required for this change release-note-required Change has user-facing impact (no matter how small)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants