Commit b575b24b authored by Miaohe Lin's avatar Miaohe Lin Committed by Pablo Neira Ayuso
Browse files

netfilter: Fix rpfilter dropping vrf packets by mistake



When firewalld is enabled with ipv4/ipv6 rpfilter, vrf
ipv4/ipv6 packets will be dropped. Vrf device will pass
through netfilter hook twice. One with enslaved device
and another one with l3 master device. So in device may
dismatch witch out device because out device is always
enslaved device.So failed with the check of the rpfilter
and drop the packets by mistake.

Signed-off-by: default avatarMiaohe Lin <linmiaohe@huawei.com>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 1b0890cd
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par)
	flow.flowi4_mark = info->flags & XT_RPFILTER_VALID_MARK ? skb->mark : 0;
	flow.flowi4_tos = RT_TOS(iph->tos);
	flow.flowi4_scope = RT_SCOPE_UNIVERSE;
	flow.flowi4_oif = l3mdev_master_ifindex_rcu(xt_in(par));

	return rpfilter_lookup_reverse(xt_net(par), &flow, xt_in(par), info->flags) ^ invert;
}
+6 −2
Original line number Diff line number Diff line
@@ -55,7 +55,9 @@ static bool rpfilter_lookup_reverse6(struct net *net, const struct sk_buff *skb,
	if (rpfilter_addr_linklocal(&iph->saddr)) {
		lookup_flags |= RT6_LOOKUP_F_IFACE;
		fl6.flowi6_oif = dev->ifindex;
	} else if ((flags & XT_RPFILTER_LOOSE) == 0)
	/* Set flowi6_oif for vrf devices to lookup route in l3mdev domain. */
	} else if (netif_is_l3_master(dev) || netif_is_l3_slave(dev) ||
		  (flags & XT_RPFILTER_LOOSE) == 0)
		fl6.flowi6_oif = dev->ifindex;

	rt = (void *)ip6_route_lookup(net, &fl6, skb, lookup_flags);
@@ -70,7 +72,9 @@ static bool rpfilter_lookup_reverse6(struct net *net, const struct sk_buff *skb,
		goto out;
	}

	if (rt->rt6i_idev->dev == dev || (flags & XT_RPFILTER_LOOSE))
	if (rt->rt6i_idev->dev == dev ||
	    l3mdev_master_ifindex_rcu(rt->rt6i_idev->dev) == dev->ifindex ||
	    (flags & XT_RPFILTER_LOOSE))
		ret = true;
 out:
	ip6_rt_put(rt);