Network Firewall and Netfilter
A firewall is not a subsystem a packet enters — it is one entry in an array. nf_hook_slow() walks the hook functions registered at a hook in priority order and knows nothing about rules, tables or chains, and ipt_do_table() and nft_do_chain() are two peer entries in that array: iptables and nftables register into the same place rather than one replacing the other. That settles the sentence everyone repeats. nftables does not make the chain walk sublinear, because nft_do_chain() walks its rule list linearly with `for (; !rule->is_last ; rule = nft_rule_next(rule))`, exactly as ipt_do_table() walks its entry list; what it adds is a pluggable lookup INSIDE a rule, resolved through set->ops->lookup() across a bitmap, a hash, pipapo and an rbtree. So ten thousand addresses become one rule holding one set lookup, and the walk gets shorter because there is less to walk rather than because walking got cheaper — and the identical restructuring is available to iptables through ipset, which makes the fix for a long chain a set in either representation. Which chain a packet reaches is not your decision: the routing lookup has already installed a dst whose input function is either ip_local_deliver() or ip_forward(), one NF_HOOK call site each and mutually exclusive, so a rule in the wrong chain is unreachable rather than weak. And only three of the five hooks are ones the iptables filter TABLE may be registered at, which makes a DROP at PREROUTING a category error there rather than a tuning choice — while an nftables base chain carries its own hook and priority and the kernel accepts all five, so that restriction belongs to the table rather than to netfilter. A table is a priority number on a compile-time enum, so ordering is arithmetic: conntrack's lookup at -200, DNAT at -100, your rules at 0, SNAT at +100, conntrack's confirmation at INT_MAX — from which two routinely-reversed consequences follow, that a FORWARD rule matches the post-DNAT destination and never sees the post-SNAT source. The policy is a rule you cannot see: a built-in entry's verdict in iptables, reached by running off the end of the list, and a struct field in nftables, read only after the walk falls through. A stock kernel's FORWARD policy is ACCEPT, set by a module parameter whose comment explains itself as a maintainer's inbox. INVALID is not a connection state at all — no IP_CT_INVALID exists anywhere, and the match synthesises bit 0 precisely because a real state can never occupy it — so with conntrack unloaded no rule can match ESTABLISHED at any policy, and a stateless ruleset gets a vocabulary in which INVALID is the only state word that still matches anything. Rate limiting adds a second hash table with its own entry ceiling, and at saturation it drops rather than stopping limiting, overriding both your rule's target and the chain policy. Change the rule count, the representation, the hook, the policy, conntrack and the hashlimit rate, and watch the server-computed cascade across all five sections. Validated against Linux 6.12.93 source.
- All current + future modules
- Full kata library
- Progress dashboard + weak area analysis
Cancel anytime. Billed annually.