We can often find the default netfilter packet flow from the following figure (although it's a little bit out dated ...):
You may wish to change the position of these blocks (hooks). It is not really complex to do that. As we can find the priority of these hooks in (kernel-source)/include/linux/netfilter_ipv4.h (if you'd like to modify other address families, just find the corresponding header files). Simply add new priorities into the enumeration of nf_ip_hook_priorities and then modify the table registration data structure, e.g., the mangle table registration is done in (kernel-source)/net/ipv4/netfilter/iptable_mangle.c.
Suppose we are going to move the "mangle" table before "nat" table in the POSTROUTING chain. The steps are:
- Add a new priority, say NF_IP_PRI_POST_MANGLE = 150 into the nf_ip_hook_priorities enumeration.
- Modify the ipt_ops data structure in iptable_mangle.c so that the priority of that hook in POSTROUTING chain is set to the newly added NF_IP_PRO_POST_MANGLE.
Recompile your kernel and everything is done! Just remember that a hook with a lower priority number will be placed earlier in the chain.