nf_hook_egress(9)
π nf_hook_egress π
okay bestie, welcome to nf_hook_egress(9) from the Kernel API Manual β yes it's a real manual page, yes it's kind of iconic, and yes we're gonna get through it together π«Ά
β¨ NAME β¨
nf_hook_egress β classify packets before transmission π (that's it, that's the whole vibe: sort your packets before they leave the house)
πΈ SYNOPSIS πΈ
struct sk_buff * nf_hook_egress (struct sk_buff *skb , int *rc , struct
net_device *dev );
three args, one return, no cap β¨
π ARGUMENTS π
skbβ the packet to be classified, literally the main character of this whole function πrcβ a result code pointer; this is the code that shall be returned by__dev_queue_xmiton failure, so it's the "if this goes wrong, here's what we say" slot π«Άdevβ the netdev whose egress hooks shall be applied toskb; like, which interface's hooks are we running here π
π¦ DESCRIPTION π¦
First thing first, bestie: the caller must hold rcu_read_lock. Not optional. Not a suggestion. Hold it. π
okay so here's the lore. On ingress, packets are classified first by tc, then by netfilter. On egress, the order is reversed β for symmetry π (the kernel is very into symmetry, we love a consistent queen).
Conceptually, tc and netfilter can be thought of as layers, with netfilter layered above tc: when tc redirects a packet to another interface, netfilter is not applied, because the packet is on the tc layer. so close to netfilter yet so far π
The nf_skip_egress flag controls whether netfilter is applied on egress. It is updated by __netif_receive_skb_core and __dev_queue_xmit when the packet passes through tc and netfilter. Because __dev_queue_xmit may be called recursively by tunnel drivers such as vxlan, the flag is reverted to false after sch_handle_egress. This ensures that netfilter is applied both on the overlay and the underlying network πβ¨ (double the network, double the netfilter, we ate)
lowkey the flag reset is the whole plot twist β no flag reset, no overlay + underlay coverage. respect the flag π«‘
π RETURN π
skbon success πNULLif the packet was consumed or filtered π (it's gone, it's not coming back, we don't talk about it)
π SEE ALSO π
Kernel file ./include/linux/netfilter_netdev.h β go read it, it's giving source of truth πβ¨
okay that's the page!! sourced straight from ./include/linux, dated October 2026, and yeah she's still filed under nf_hook_egress(9) because some things never change π§π mwah, go classify some packets π
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms