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: Miaohe Lin <[email protected]>
---
net/ipv4/netfilter/ipt_rpfilter.c | 1 +
net/ipv6/netfilter/ip6t_rpfilter.c | 8 +++++++-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/netfilter/ipt_rpfilter.c b/net/ipv4/netfilter/ipt_rpfilter.c
index 59031670b16a..cc23f1ce239c 100644
--- a/net/ipv4/netfilter/ipt_rpfilter.c
+++ b/net/ipv4/netfilter/ipt_rpfilter.c
@@ -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;
}
diff --git a/net/ipv6/netfilter/ip6t_rpfilter.c b/net/ipv6/netfilter/ip6t_rpfilter.c
index 6bcaf7357183..3c4a1772c15f 100644
--- a/net/ipv6/netfilter/ip6t_rpfilter.c
+++ b/net/ipv6/netfilter/ip6t_rpfilter.c
@@ -55,6 +55,10 @@ 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;
+ /* Set flowi6_oif for vrf devices to lookup route in l3mdev domain. */
+ } else if (netif_is_l3_master(dev) || netif_is_l3_slave(dev)) {
+ lookup_flags |= FLOWI_FLAG_SKIP_NH_OIF;
+ fl6.flowi6_oif = dev->ifindex;
} else if ((flags & XT_RPFILTER_LOOSE) == 0)
fl6.flowi6_oif = dev->ifindex;
@@ -70,7 +74,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);
--
2.21.GIT
On 6/28/19 3:06 AM, Miaohe Lin wrote:
> diff --git a/net/ipv6/netfilter/ip6t_rpfilter.c b/net/ipv6/netfilter/ip6t_rpfilter.c
> index 6bcaf7357183..3c4a1772c15f 100644
> --- a/net/ipv6/netfilter/ip6t_rpfilter.c
> +++ b/net/ipv6/netfilter/ip6t_rpfilter.c
> @@ -55,6 +55,10 @@ 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;
> + /* Set flowi6_oif for vrf devices to lookup route in l3mdev domain. */
> + } else if (netif_is_l3_master(dev) || netif_is_l3_slave(dev)) {
> + lookup_flags |= FLOWI_FLAG_SKIP_NH_OIF;
you don't need to set that flag here. It is done by the fib_rules code
as needed.
On 6/29/19 1:05 AM, David Ahern wrote:
> On 6/28/19 3:06 AM, Miaohe Lin wrote:
> > diff --git a/net/ipv6/netfilter/ip6t_rpfilter.c
> > b/net/ipv6/netfilter/ip6t_rpfilter.c
> > index 6bcaf7357183..3c4a1772c15f 100644
> > --- a/net/ipv6/netfilter/ip6t_rpfilter.c
> > +++ b/net/ipv6/netfilter/ip6t_rpfilter.c
> > @@ -55,6 +55,10 @@ 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;
> > + /* Set flowi6_oif for vrf devices to lookup route in l3mdev domain. */
> > + } else if (netif_is_l3_master(dev) || netif_is_l3_slave(dev)) {
> > + lookup_flags |= FLOWI_FLAG_SKIP_NH_OIF;
>
> you don't need to set that flag here. It is done by the fib_rules code as needed.
>
You're right. Fib rules code would set FLOWI_FLAG_SKIP_NH_OIF flag. But I set
it here for distinguish with the flags & XT_RPFILTER_LOOSE branch. Without
this, they do the same work and maybe should be combined. I don't want to
do that as that makes code confusing.
Is this code snipet below ok ? If so, I would delete this flag setting.
} else if (netif_is_l3_master(dev) || netif_is_l3_slave(dev)) {
fl6.flowi6_oif = dev->ifindex;
} else if ((flags & XT_RPFILTER_LOOSE) == 0)
fl6.flowi6_oif = dev->ifindex;
On 6/28/19 8:13 PM, linmiaohe wrote:
> You're right. Fib rules code would set FLOWI_FLAG_SKIP_NH_OIF flag. But I set
> it here for distinguish with the flags & XT_RPFILTER_LOOSE branch. Without
> this, they do the same work and maybe should be combined. I don't want to
> do that as that makes code confusing.
> Is this code snipet below ok ? If so, I would delete this flag setting.
>
> } else if (netif_is_l3_master(dev) || netif_is_l3_slave(dev)) {
> fl6.flowi6_oif = dev->ifindex;
> } else if ((flags & XT_RPFILTER_LOOSE) == 0)
> fl6.flowi6_oif = dev->ifindex;
that looks fine to me, but it is up to Pablo.
On 6/29/19 20:20 PM, David Ahern wrote:
> On 6/28/19 8:13 PM, linmiaohe wrote:
> > You're right. Fib rules code would set FLOWI_FLAG_SKIP_NH_OIF flag.
> > But I set it here for distinguish with the flags & XT_RPFILTER_LOOSE
> > branch. Without this, they do the same work and maybe should be
> > combined. I don't want to do that as that makes code confusing.
> > Is this code snipet below ok ? If so, I would delete this flag setting.
> >
> > } else if (netif_is_l3_master(dev) || netif_is_l3_slave(dev)) {
> > fl6.flowi6_oif = dev->ifindex;
> > } else if ((flags & XT_RPFILTER_LOOSE) == 0)
> > fl6.flowi6_oif = dev->ifindex;
> that looks fine to me, but it is up to Pablo.
@David Ahern Many thanks for your valuable advice.
@ Pablo Hi, could you please tell me if this code snipet is ok?
If not, which code would you prefer? It's very nice of you to
figure it out for me. Thanks a lot.
Have a nice day.
Best wishes.
On Sat, Jun 29, 2019 at 02:13:59PM +0000, linmiaohe wrote:
> On 6/29/19 20:20 PM, David Ahern wrote:
> > On 6/28/19 8:13 PM, linmiaohe wrote:
> > > You're right. Fib rules code would set FLOWI_FLAG_SKIP_NH_OIF flag.
> > > But I set it here for distinguish with the flags & XT_RPFILTER_LOOSE
> > > branch. Without this, they do the same work and maybe should be
> > > combined. I don't want to do that as that makes code confusing.
> > > Is this code snipet below ok ? If so, I would delete this flag setting.
> > >
> > > } else if (netif_is_l3_master(dev) || netif_is_l3_slave(dev)) {
> > > fl6.flowi6_oif = dev->ifindex;
> > > } else if ((flags & XT_RPFILTER_LOOSE) == 0)
> > > fl6.flowi6_oif = dev->ifindex;
>
> > that looks fine to me, but it is up to Pablo.
>
> @David Ahern Many thanks for your valuable advice.
>
> @ Pablo Hi, could you please tell me if this code snipet is ok?
> If not, which code would you prefer? It's very nice of you to
> figure it out for me. Thanks a lot.
Probably this?
} else if (netif_is_l3_master(dev) || netif_is_l3_slave(dev) ||
(flags & XT_RPFILTER_LOOSE) == 0) {
fl6.flowi6_oif = dev->ifindex;
}
Thanks.
On Sat, July 2, 2019 at 02:02:59AM, Pablo wrote:
>
> Probably this?
>
> } else if (netif_is_l3_master(dev) || netif_is_l3_slave(dev) ||
> (flags & XT_RPFILTER_LOOSE) == 0) {
> fl6.flowi6_oif = dev->ifindex;
> }
>
> Thanks.
I would send patch v5 according to this. Many Thanks.
Have a nice day.
Best wishes.