Le lundi 21 mars 2011 Ã 23:25 +0100, Florian Westphal a Ãcrit : > ipv6 fib lookup can set RT6_LOOKUP_F_IFACE flag to restrict search > to an interface, but this flag cannot be set via struct flowi. > > Also, it cannot be set via ip6_route_output: this function uses the > passed sock struct to determine if this flag is required > (by testing for nonzero sk_bound_dev_if). > > Work around this by passing in an artificial struct sk in case > 'strict' argument is true. > > This is required to replace the rt6_lookup call in xt_addrtype.c with > nf_afinfo->route(). > > Signed-off-by: Florian Westphal <fw@xxxxxxxxx> > --- > Patrick, > > the change in nf_ip6_route() is very ugly, but I found no > other way to set RT6_LOOKUP_F_IFACE. > > rt6_lookup() can't be used instead of ip6_route_output > since it does not take a flowi argument... > > include/linux/netfilter.h | 2 +- > net/ipv4/netfilter.c | 2 +- > net/ipv6/netfilter.c | 14 ++++++++++++-- > net/netfilter/nf_conntrack_h323_main.c | 8 ++++---- > net/netfilter/xt_TCPMSS.c | 2 +- > 5 files changed, 19 insertions(+), 9 deletions(-) > > diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h > index 20ed452..7fa95df 100644 > --- a/include/linux/netfilter.h > +++ b/include/linux/netfilter.h > @@ -271,7 +271,7 @@ struct nf_afinfo { > unsigned int len, > u_int8_t protocol); > int (*route)(struct net *net, struct dst_entry **dst, > - struct flowi *fl); > + struct flowi *fl, bool strict); > void (*saveroute)(const struct sk_buff *skb, > struct nf_queue_entry *entry); > int (*reroute)(struct sk_buff *skb, > diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c > index 138e106..87f20e8 100644 > --- a/net/ipv4/netfilter.c > +++ b/net/ipv4/netfilter.c > @@ -218,7 +218,7 @@ static __sum16 nf_ip_checksum_partial(struct sk_buff *skb, unsigned int hook, > } > > static int nf_ip_route(struct net *net, struct dst_entry **dst, > - struct flowi *fl) > + struct flowi *fl, bool strict __always_unused) > { > return ip_route_output_key(net, (struct rtable **)dst, fl); > } > diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c > index 9e1b3e4..f237d58 100644 > --- a/net/ipv6/netfilter.c > +++ b/net/ipv6/netfilter.c > @@ -90,9 +90,19 @@ static int nf_ip6_reroute(struct sk_buff *skb, > } > > static int nf_ip6_route(struct net *net, struct dst_entry **dst, > - struct flowi *fl) > + struct flowi *fl, bool strict) > { > - *dst = ip6_route_output(net, NULL, fl); > + static const struct ipv6_pinfo fake_pinfo; > + static const struct inet_sock fake_sk = { > + /* makes ip6_route_output set RT6_LOOKUP_F_IFACE: */ > + .sk.sk_bound_dev_if = 1, > + .pinet6 = (struct ipv6_pinfo *) &fake_pinfo, > + }; > + struct sock *sk = NULL; > + > + if (strict) > + sk = (struct sock *) &fake_sk; > + *dst = ip6_route_output(net, sk, fl); > return (*dst)->error; > } > Wow... I can tell you David will not accept this... This is about 800 bytes on stack, initted, so quite a huge cost for this function. -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html