Commit 12f36e9b authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso
Browse files

netfilter: nft_fib_ipv6: skip ipv6 packets from any to link-local

The ip6tables rpfilter match has an extra check to skip packets with
"::" source address.

Extend this to ipv6 fib expression.  Else ipv6 duplicate address detection
packets will fail rpf route check -- lookup returns -ENETUNREACH.

While at it, extend the prerouting check to also cover the ingress hook.

Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1543


Fixes: f6d0cbcf ("netfilter: nf_tables: add fib expression")
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 82944421
Loading
Loading
Loading
Loading
+18 −4
Original line number Diff line number Diff line
@@ -135,6 +135,17 @@ void nft_fib6_eval_type(const struct nft_expr *expr, struct nft_regs *regs,
}
EXPORT_SYMBOL_GPL(nft_fib6_eval_type);

static bool nft_fib_v6_skip_icmpv6(const struct sk_buff *skb, u8 next, const struct ipv6hdr *iph)
{
	if (likely(next != IPPROTO_ICMPV6))
		return false;

	if (ipv6_addr_type(&iph->saddr) != IPV6_ADDR_ANY)
		return false;

	return ipv6_addr_type(&iph->daddr) & IPV6_ADDR_LINKLOCAL;
}

void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
		   const struct nft_pktinfo *pkt)
{
@@ -163,11 +174,14 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,

	lookup_flags = nft_fib6_flowi_init(&fl6, priv, pkt, oif, iph);

	if (nft_hook(pkt) == NF_INET_PRE_ROUTING &&
	    nft_fib_is_loopback(pkt->skb, nft_in(pkt))) {
	if (nft_hook(pkt) == NF_INET_PRE_ROUTING ||
	    nft_hook(pkt) == NF_INET_INGRESS) {
		if (nft_fib_is_loopback(pkt->skb, nft_in(pkt)) ||
		    nft_fib_v6_skip_icmpv6(pkt->skb, pkt->tprot, iph)) {
			nft_fib_store_result(dest, priv, nft_in(pkt));
			return;
		}
	}

	*dest = 0;
	rt = (void *)ip6_route_lookup(nft_net(pkt), &fl6, pkt->skb,