Problem
portmap (and ipmasq) fail to select the nftables backend even on systems where iptables is not installed and nftables is the only available firewall subsystem.
Root cause
Backend auto-detection uses a single-tier check:
if !utils.SupportsIPTables() && utils.SupportsNFTables() {
use nftables
} else {
use iptables // ← always taken when both return false
}
SupportsNFTables() calls knftables.New(), which runs nft --check via exec. That subprocess requires CAP_NET_ADMIN to connect to the kernel nftables subsystem via netlink — even for a dry run. If the process doesn't hold that capability at detection time (test environments, containers, or any context where privileges are acquired later), SupportsNFTables() returns false.
Result: when iptables is absent, SupportsIPTables() correctly returns false, but SupportsNFTables() also returns false due to the cap check failing. The && condition is never satisfied, so the plugin unconditionally falls back to iptables — which then also fails.
Affected code
- plugins/meta/portmap/main.go — ensureBackend()
- pkg/ip/ipmasq_linux.go — SetupIPMasqForNetworks()
- pkg/utils/netfilter.go — SupportsNFTables()
Reproduction
On a system with nft installed but no iptables binary, invoke portmap as a CNI plugin. Detection picks iptables regardless, and port forwarding rules are never installed.
The same failure can be reproduced without removing iptables by running SupportsNFTables() in a context without CAP_NET_ADMIN: both functions return false simultaneously and the default wins.
Expected behavior
When iptables binary is absent and nft binary is present, portmap should select the nftables backend even if the full kernel-access check cannot be completed at detection time.
Problem
portmap (and ipmasq) fail to select the nftables backend even on systems where iptables is not installed and nftables is the only available firewall subsystem.
Root cause
Backend auto-detection uses a single-tier check:
SupportsNFTables() calls knftables.New(), which runs nft --check via exec. That subprocess requires CAP_NET_ADMIN to connect to the kernel nftables subsystem via netlink — even for a dry run. If the process doesn't hold that capability at detection time (test environments, containers, or any context where privileges are acquired later), SupportsNFTables() returns false.
Result: when iptables is absent, SupportsIPTables() correctly returns false, but SupportsNFTables() also returns false due to the cap check failing. The && condition is never satisfied, so the plugin unconditionally falls back to iptables — which then also fails.
Affected code
Reproduction
On a system with nft installed but no iptables binary, invoke portmap as a CNI plugin. Detection picks iptables regardless, and port forwarding rules are never installed.
The same failure can be reproduced without removing iptables by running SupportsNFTables() in a context without CAP_NET_ADMIN: both functions return false simultaneously and the default wins.
Expected behavior
When iptables binary is absent and nft binary is present, portmap should select the nftables backend even if the full kernel-access check cannot be completed at detection time.