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

net: vrf: Drop conntrack data after pass through VRF device on Tx

Locally originated traffic in a VRF fails in the presence of a POSTROUTING
rule. For example,

$ iptables -t nat -A POSTROUTING -s 11.1.1.0/24 -j MASQUERADE
$ ping -I red -c1 11.1.1.3
ping: Warning: source address might be selected on device other than red.
PING 11.1.1.3 (11.1.1.3) from 11.1.1.2 red: 56(84) bytes of data.
ping: sendmsg: Operation not permitted

Worse, the above causes random corruption resulting in a panic in random
places (I have not seen a consistent backtrace).

Call nf_reset to drop the conntrack info following the pass through the
VRF device. The nf_reset is needed on Tx but not Rx because of the order
in which NF_HOOK's are hit: on Rx the VRF device is after the real ingress
device and on Tx it is is before the real egress device. Connection
tracking should be tied to the real egress device and not the VRF device.

Fixes: 8f58336d3f78a ("net: Add ethernet header for pass through VRF device")
Fixes: 35402e3136634 ("net: Add IPv6 support to VRF device")
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

David Ahern and committed by
David S. Miller
eb63ecc1 a0f37efa

+4
+4
drivers/net/vrf.c
··· 366 366 struct in6_addr *nexthop; 367 367 int ret; 368 368 369 + nf_reset(skb); 370 + 369 371 skb->protocol = htons(ETH_P_IPV6); 370 372 skb->dev = dev; 371 373 ··· 548 546 struct neighbour *neigh; 549 547 u32 nexthop; 550 548 int ret = -EINVAL; 549 + 550 + nf_reset(skb); 551 551 552 552 /* Be paranoid, rather than too clever. */ 553 553 if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops)) {