Message ID | 1366274725-16286-1-git-send-email-fw@strlen.de |
---|---|
State | Accepted |
Headers | show |
Hi Florian, On Thu, Apr 18, 2013 at 10:45:24AM +0200, Florian Westphal wrote: > Alex Efros reported rpfilter module doesn't match following packets: > IN=br.qemu SRC=192.168.2.1 DST=192.168.2.255 [ .. ] > (netfilter bugzilla #814). > > Problem is that network stack arranges for the locally generated broadcasts > to appear on the interface they were sent out, so the IFF_LOOPBACK check > doesn't trigger. > > As -m rpfilter is restricted to PREROUTING, we can check for existing > rtable instead, it catches locally-generated broad/multicast case, too. > > Signed-off-by: Florian Westphal <fw@strlen.de> > --- > Pablo, > > I did have a look at nf_conntrack_broadcast, but > 1. I cannot check skb->sk (TPROXY can set that for incoming packets) > 2. I don't want to test conntrack info to avoid dependency on conntrack > > So, this is pretty much the very same patch as V1, except that this > also checks for _LOCAL flag instead of just checking for presence of > skb_dst(). > > Is this ok, or did you have something else in mind? That's fine. I just wanted a bit further validation to avoid an easy breakage in case this assumption is not fulfilled anymore. I have made a comestic change: renamed is_local to rpfilter_is_local just to stick to the corresponding function namespace. Applied, thanks. -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/net/ipv4/netfilter/ipt_rpfilter.c b/net/ipv4/netfilter/ipt_rpfilter.c index c301300..faa35b7 100644 --- a/net/ipv4/netfilter/ipt_rpfilter.c +++ b/net/ipv4/netfilter/ipt_rpfilter.c @@ -66,6 +66,12 @@ static bool rpfilter_lookup_reverse(struct flowi4 *fl4, return dev_match; } +static bool is_local(const struct sk_buff *skb) +{ + const struct rtable *rt = skb_rtable(skb); + return rt && (rt->rt_flags & RTCF_LOCAL); +} + static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) { const struct xt_rpfilter_info *info; @@ -76,7 +82,7 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) info = par->matchinfo; invert = info->flags & XT_RPFILTER_INVERT; - if (par->in->flags & IFF_LOOPBACK) + if (is_local(skb)) return true ^ invert; iph = ip_hdr(skb); diff --git a/net/ipv6/netfilter/ip6t_rpfilter.c b/net/ipv6/netfilter/ip6t_rpfilter.c index 5060d54..43114010 100644 --- a/net/ipv6/netfilter/ip6t_rpfilter.c +++ b/net/ipv6/netfilter/ip6t_rpfilter.c @@ -71,6 +71,12 @@ static bool rpfilter_lookup_reverse6(const struct sk_buff *skb, return ret; } +static bool is_local(const struct sk_buff *skb) +{ + const struct rt6_info *rt = (const void *) skb_dst(skb); + return rt && (rt->rt6i_flags & RTF_LOCAL); +} + static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) { const struct xt_rpfilter_info *info = par->matchinfo; @@ -78,7 +84,7 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) struct ipv6hdr *iph; bool invert = info->flags & XT_RPFILTER_INVERT; - if (par->in->flags & IFF_LOOPBACK) + if (is_local(skb)) return true ^ invert; iph = ipv6_hdr(skb);
Alex Efros reported rpfilter module doesn't match following packets: IN=br.qemu SRC=192.168.2.1 DST=192.168.2.255 [ .. ] (netfilter bugzilla #814). Problem is that network stack arranges for the locally generated broadcasts to appear on the interface they were sent out, so the IFF_LOOPBACK check doesn't trigger. As -m rpfilter is restricted to PREROUTING, we can check for existing rtable instead, it catches locally-generated broad/multicast case, too. Signed-off-by: Florian Westphal <fw@strlen.de> --- Pablo, I did have a look at nf_conntrack_broadcast, but 1. I cannot check skb->sk (TPROXY can set that for incoming packets) 2. I don't want to test conntrack info to avoid dependency on conntrack So, this is pretty much the very same patch as V1, except that this also checks for _LOCAL flag instead of just checking for presence of skb_dst(). Is this ok, or did you have something else in mind? net/ipv4/netfilter/ipt_rpfilter.c | 8 +++++++- net/ipv6/netfilter/ip6t_rpfilter.c | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-)