apple / apple/containerization
[Bug]: kernel configs build an nft-only kernel on linux-6.18.5 (NETFILTER_XTABLES_LEGACY unset), legacy iptables tables disappear
- Dominant language
- Swift
- Stars
- 8.9k
- Forks
- 359
- Avg merge
- 2d 20h
- Merged PRs (30d)
- 13
Description
### I have done the following
- [x] I have searched the existing issues
- [x] If possible, I've reproduced the issue using the 'main' branch of this project
### Steps to reproduce
1. Build the kernel from `main` as `kernel/Makefile` does (`KSOURCE` is linux-6.18.5): `cp kernel/config-arm64 .config && make ARCH=arm64 olddefconfig && make ARCH=arm64 Image`.
2. Boot it and try the legacy tables:
```sh
container run --rm --kernel ./Image --cap-add NET_ADMIN alpine:3.20 sh -c \
'apk add -q iptables iptables-legacy; iptables-legacy -t nat -L -n; iptables-legacy -t mangle -L -n'
```
### Current behavior
```
iptables v1.8.10 (legacy): can't initialize iptables table `nat': Table does not exist (do you need to insmod?)
iptables v1.8.10 (legacy): can't initialize iptables table `mangle': Table does not exist (do you need to insmod?)
```
`iptables-nft` works on the same kernel, and both work on the default 6.12.28 kernel.
Cause: the file was generated on 6.1.68 and still carries `CONFIG_IP_NF_IPTABLES=y`, `CONFIG_IP_NF_NAT=y`, `CONFIG_IP_NF_MANGLE=y`, `CONFIG_IP_NF_FILTER=y`. Newer kernels gate the legacy tables behind `CONFIG_NETFILTER_XTABLES_LEGACY` (net/netfilter/Kconfig, a bare bool that defaults off); `CONFIG_IP_NF_IPTABLES_LEGACY` and `CONFIG_IP6_NF_IPTABLES_LEGACY` depend on it, and `IP_NF_NAT`, `IP_NF_MANGLE` and `IP_NF_FILTER` depend on `IP_NF_IPTABLES_LEGACY`. The file predates those symbols, so on 6.18.5 `olddefconfig` leaves them unset and the legacy filter, nat and mangle tables silently drop out while the `=y` lines stay in the file:
```
$ make ARCH=arm64 olddefconfig; grep -E "XTABLES_LEGACY|IP_NF_IPTABLES" .config
CONFIG_IP_NF_IPTABLES=y
CONFIG_IP6_NF_IPTABLES=y
# CONFIG_NETFILTER_XTABLES_LEGACY is not set
```
Effect on Kubernetes node images: apple/container#2120 already shows the two iptables backends are not interchangeable in kindest/node (there node prep calls `iptables-nft` and fails because the default kernel has no nf_tables). An nft-only kernel inverts it: kind's entrypoint selects the node's backend by counting existing rules and sends a 0-0 tie to legacy, so `/usr/sbin/iptables` inside the node answers "Table does not exist" and the `container k8s` node-prep rules cannot apply. kube-proxy itself keeps working because its image carries its own wrapper and picks nft (checked on a Cilium cluster on this kernel: ClusterIP and DNS answer); node-level tools that shell out to `iptables-legacy` are what break.
### Expected behavior
Either the legacy tables the file still lists come back (`CONFIG_NETFILTER_XTABLES_LEGACY=y`, `CONFIG_IP_NF_IPTABLES_LEGACY=y`, `CONFIG_IP6_NF_IPTABLES_LEGACY=y`, which makes the existing `IP_NF_*` lines take effect again), or the kernel is documented as nft-only and the stale `IP_NF_NAT`/`IP_NF_MANGLE`/`IP_NF_FILTER` lines are removed so the file matches what it builds. Happy to send the PR for whichever you prefer.
### Environment
- OS: macOS 26.2 (25C56), Apple silicon
- Xcode / Swift: not involved (kernel build in an ubuntu:24.04 container with gcc 13.3; the Kconfig defaults are toolchain-independent, but I have not run the in-tree `kernel/image` path)
- Container: container CLI version 1.0.0 (build: release, commit: ee848e3)
- containerization: `kernel/config-arm64` at `main` (sha256 dedb03de...), linux-6.18.5
### Relevant log output
Found while measuring the config change proposed in #912.
### Code of Conduct
- [x] I agree to follow this project's Code of Conduct
Contributor guide
Research direction
Start with kernel/config-arm64 and kernel/Makefile, then compare the generated configuration against the linux-6.18.5 Netfilter Kconfig symbols. Run the reported arm64 olddefconfig command and inspect the legacy and nftables settings with grep. Done means the selected backend is reflected consistently in the config and the reported legacy-table reproduction no longer contradicts that choice.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- linux
- Domain
- build-system, operating-systems
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100