Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: nft_fib: reverse path filter for policy-based routing on iif

If policy-based routing using the iif selector is used, then the fib
expression fails to look up for the reverse path from the prerouting
hook because the input interface cannot be inferred. In order to support
this scenario, extend the fib expression to allow to use after the route
lookup, from the forward hook.

This patch also adds support for the input hook for usability reasons.
Since the prerouting hook cannot be used for the scenario described
above, users need two rules: one for the forward chain and another rule
for the input chain to check for the reverse path check for locally
targeted traffic.

Acked-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

+12
+4
net/ipv4/netfilter/nft_fib_ipv4.c
··· 112 112 fl4.daddr = iph->daddr; 113 113 fl4.saddr = get_saddr(iph->saddr); 114 114 } else { 115 + if (nft_hook(pkt) == NF_INET_FORWARD && 116 + priv->flags & NFTA_FIB_F_IIF) 117 + fl4.flowi4_iif = nft_out(pkt)->ifindex; 118 + 115 119 fl4.daddr = iph->saddr; 116 120 fl4.saddr = get_saddr(iph->daddr); 117 121 }
+4
net/ipv6/netfilter/nft_fib_ipv6.c
··· 30 30 fl6->daddr = iph->daddr; 31 31 fl6->saddr = iph->saddr; 32 32 } else { 33 + if (nft_hook(pkt) == NF_INET_FORWARD && 34 + priv->flags & NFTA_FIB_F_IIF) 35 + fl6->flowi6_iif = nft_out(pkt)->ifindex; 36 + 33 37 fl6->daddr = iph->saddr; 34 38 fl6->saddr = iph->daddr; 35 39 }
+4
net/netfilter/nft_fib.c
··· 35 35 case NFT_FIB_RESULT_OIF: 36 36 case NFT_FIB_RESULT_OIFNAME: 37 37 hooks = (1 << NF_INET_PRE_ROUTING); 38 + if (priv->flags & NFTA_FIB_F_IIF) { 39 + hooks |= (1 << NF_INET_LOCAL_IN) | 40 + (1 << NF_INET_FORWARD); 41 + } 38 42 break; 39 43 case NFT_FIB_RESULT_ADDRTYPE: 40 44 if (priv->flags & NFTA_FIB_F_IIF)