Skip to content

[Bug]: kernel configs build an nft-only kernel on linux-6.18.5 (NETFILTER_XTABLES_LEGACY unset), legacy iptables tables disappear #913

Description

@saiyam1814

I have done the following

  • I have searched the existing issues
  • 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:
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

  • I agree to follow this project's Code of Conduct

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions