* [PATCH net 0/2] ipv6: fix sticky pktinfo behaviour @ 2016-01-27 13:45 Paolo Abeni 2016-01-27 13:45 ` [PATCH net 1/2] ipv6: enforce flowi6_oif usage in ip6_dst_lookup_tail() Paolo Abeni 2016-01-27 13:45 ` [PATCH net 2/2] ipv6/udp: use sticky pktinfo egress ifindex on connect() Paolo Abeni 0 siblings, 2 replies; 8+ messages in thread From: Paolo Abeni @ 2016-01-27 13:45 UTC (permalink / raw) To: netdev Cc: David S. Miller, David Ahern, Hajime Tazaki, lucien.xin, Marcelo Ricardo Leitner Currently: ip addr add dev eth0 2001:0010::1/64 ip addr add dev eth1 2001:0020::1/64 ping6 -I eth0 2001:0020::2 do not leads to the expected results, i.e. eth1 is used as the egress interface. This is due to two related issues in handling sticky pktinfo, used by ping6 to enforce the device binding: - ip6_dst_lookup_flow()/ip6_dst_lookup_tail() do not really enforce flowi6_oif match - ipv6 udp connect() just ignore flowi6_oif These patches address each issue individually. Paolo Abeni (2): ipv6: enforce flowi6_oif usage in ip6_dst_lookup_tail() ipv6/udp: use sticky pktinfo egress ifindex on connect() include/net/ip6_route.h | 2 ++ net/ipv6/datagram.c | 3 +++ net/ipv6/ip6_output.c | 6 +++++- net/ipv6/route.c | 12 +++++++++--- 4 files changed, 19 insertions(+), 4 deletions(-) -- 1.8.3.1 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH net 1/2] ipv6: enforce flowi6_oif usage in ip6_dst_lookup_tail() 2016-01-27 13:45 [PATCH net 0/2] ipv6: fix sticky pktinfo behaviour Paolo Abeni @ 2016-01-27 13:45 ` Paolo Abeni 2016-01-27 18:38 ` Hannes Frederic Sowa 2016-01-28 14:59 ` David Ahern 2016-01-27 13:45 ` [PATCH net 2/2] ipv6/udp: use sticky pktinfo egress ifindex on connect() Paolo Abeni 1 sibling, 2 replies; 8+ messages in thread From: Paolo Abeni @ 2016-01-27 13:45 UTC (permalink / raw) To: netdev Cc: David S. Miller, David Ahern, Hajime Tazaki, lucien.xin, Marcelo Ricardo Leitner The current implementation of ip6_dst_lookup_tail() basically ignore the egress ifindex match: if the saddr is set, ip6_route_output() purposefully ignores flowi6_oif, due to the commit d46a9d678e4c ("net: ipv6: Dont add RT6_LOOKUP_F_IFACE flag if saddr set"), if the saddr is 'any' the first route lookup in ip6_dst_lookup_tail fails, but upon failure a second lookup will be performed with saddr set, thus ignoring the ifindex constraint. This commit adds an output route lookup function variant, which allows the caller to specify additional lookup flags, and modify ip6_dst_lookup_tail() to enforce the ifindex match on the second lookup via said helper. Fixes: d46a9d678e4c ("net: ipv6: Dont add RT6_LOOKUP_F_IFACE flag if saddr set") Signed-off-by: Paolo Abeni <pabeni@redhat.com> --- include/net/ip6_route.h | 2 ++ net/ipv6/ip6_output.c | 6 +++++- net/ipv6/route.c | 12 +++++++++--- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 877f682..c221e36 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -66,6 +66,8 @@ void ip6_route_input(struct sk_buff *skb); struct dst_entry *ip6_route_output(struct net *net, const struct sock *sk, struct flowi6 *fl6); +struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk, + struct flowi6 *fl6, int flags); struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6, int flags); diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 23de98f..a163102 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -909,6 +909,7 @@ static int ip6_dst_lookup_tail(struct net *net, const struct sock *sk, struct rt6_info *rt; #endif int err; + int flags = 0; /* The correct way to handle this would be to do * ip6_route_get_saddr, and then ip6_route_output; however, @@ -940,10 +941,13 @@ static int ip6_dst_lookup_tail(struct net *net, const struct sock *sk, dst_release(*dst); *dst = NULL; } + + if (fl6->flowi6_oif) + flags |= RT6_LOOKUP_F_IFACE; } if (!*dst) - *dst = ip6_route_output(net, sk, fl6); + *dst = ip6_route_output_flags(net, sk, fl6, flags); err = (*dst)->error; if (err) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 3c8834b..973cb73 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1183,11 +1183,10 @@ static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags); } -struct dst_entry *ip6_route_output(struct net *net, const struct sock *sk, - struct flowi6 *fl6) +struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk, + struct flowi6 *fl6, int flags) { struct dst_entry *dst; - int flags = 0; bool any_src; dst = l3mdev_rt6_dst_by_oif(net, fl6); @@ -1208,6 +1207,13 @@ struct dst_entry *ip6_route_output(struct net *net, const struct sock *sk, return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_output); } +EXPORT_SYMBOL_GPL(ip6_route_output_flags); + +struct dst_entry *ip6_route_output(struct net *net, const struct sock *sk, + struct flowi6 *fl6) +{ + return ip6_route_output_flags(net, sk, fl6, 0); +} EXPORT_SYMBOL(ip6_route_output); struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_orig) -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH net 1/2] ipv6: enforce flowi6_oif usage in ip6_dst_lookup_tail() 2016-01-27 13:45 ` [PATCH net 1/2] ipv6: enforce flowi6_oif usage in ip6_dst_lookup_tail() Paolo Abeni @ 2016-01-27 18:38 ` Hannes Frederic Sowa 2016-01-28 12:27 ` Paolo Abeni 2016-01-28 14:59 ` David Ahern 1 sibling, 1 reply; 8+ messages in thread From: Hannes Frederic Sowa @ 2016-01-27 18:38 UTC (permalink / raw) To: Paolo Abeni, netdev Cc: David S. Miller, David Ahern, Hajime Tazaki, lucien.xin, Marcelo Ricardo Leitner On 27.01.2016 14:45, Paolo Abeni wrote: > diff --git a/net/ipv6/route.c b/net/ipv6/route.c > index 3c8834b..973cb73 100644 > --- a/net/ipv6/route.c > +++ b/net/ipv6/route.c > @@ -1183,11 +1183,10 @@ static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table > return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags); > } > > -struct dst_entry *ip6_route_output(struct net *net, const struct sock *sk, > - struct flowi6 *fl6) > +struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk, > + struct flowi6 *fl6, int flags) > { > struct dst_entry *dst; > - int flags = 0; > bool any_src; > > dst = l3mdev_rt6_dst_by_oif(net, fl6); > @@ -1208,6 +1207,13 @@ struct dst_entry *ip6_route_output(struct net *net, const struct sock *sk, > > return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_output); > } > +EXPORT_SYMBOL_GPL(ip6_route_output_flags); > + > +struct dst_entry *ip6_route_output(struct net *net, const struct sock *sk, > + struct flowi6 *fl6) > +{ > + return ip6_route_output_flags(net, sk, fl6, 0); > +} > EXPORT_SYMBOL(ip6_route_output); I think this can just be a static inline function. Is it a lot of work to introduce the flags argument globally? Most other functions already have a flags parameter, maybe instead of just adding another wrapper just bite the bullet and add it everywhere? Thanks, Hannes ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net 1/2] ipv6: enforce flowi6_oif usage in ip6_dst_lookup_tail() 2016-01-27 18:38 ` Hannes Frederic Sowa @ 2016-01-28 12:27 ` Paolo Abeni 2016-01-28 13:02 ` Hannes Frederic Sowa 0 siblings, 1 reply; 8+ messages in thread From: Paolo Abeni @ 2016-01-28 12:27 UTC (permalink / raw) To: Hannes Frederic Sowa Cc: netdev, David S. Miller, David Ahern, Hajime Tazaki, lucien.xin, Marcelo Ricardo Leitner On Wed, 2016-01-27 at 19:38 +0100, Hannes Frederic Sowa wrote: > On 27.01.2016 14:45, Paolo Abeni wrote: > > diff --git a/net/ipv6/route.c b/net/ipv6/route.c > > index 3c8834b..973cb73 100644 > > --- a/net/ipv6/route.c > > +++ b/net/ipv6/route.c > > @@ -1183,11 +1183,10 @@ static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table > > return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags); > > } > > > > -struct dst_entry *ip6_route_output(struct net *net, const struct sock *sk, > > - struct flowi6 *fl6) > > +struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk, > > + struct flowi6 *fl6, int flags) > > { > > struct dst_entry *dst; > > - int flags = 0; > > bool any_src; > > > > dst = l3mdev_rt6_dst_by_oif(net, fl6); > > @@ -1208,6 +1207,13 @@ struct dst_entry *ip6_route_output(struct net *net, const struct sock *sk, > > > > return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_output); > > } > > +EXPORT_SYMBOL_GPL(ip6_route_output_flags); > > + > > +struct dst_entry *ip6_route_output(struct net *net, const struct sock *sk, > > + struct flowi6 *fl6) > > +{ > > + return ip6_route_output_flags(net, sk, fl6, 0); > > +} > > EXPORT_SYMBOL(ip6_route_output); > > I think this can just be a static inline function. > > Is it a lot of work to introduce the flags argument globally? Most other > functions already have a flags parameter, maybe instead of just adding > another wrapper just bite the bullet and add it everywhere? There are ~20 call sites for ip6_route_output(). Replacing them with ip6_route_output_flags() should be trivial, but it sounds quite invasive. Moving the new ip6_route_output() definition into the header file as static inline function should be pretty much equivalent, may I go with the latter option ? Cheers, Paolo ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net 1/2] ipv6: enforce flowi6_oif usage in ip6_dst_lookup_tail() 2016-01-28 12:27 ` Paolo Abeni @ 2016-01-28 13:02 ` Hannes Frederic Sowa 0 siblings, 0 replies; 8+ messages in thread From: Hannes Frederic Sowa @ 2016-01-28 13:02 UTC (permalink / raw) To: Paolo Abeni Cc: netdev, David S. Miller, David Ahern, Hajime Tazaki, lucien.xin, Marcelo Ricardo Leitner On 28.01.2016 13:27, Paolo Abeni wrote: > On Wed, 2016-01-27 at 19:38 +0100, Hannes Frederic Sowa wrote: >> On 27.01.2016 14:45, Paolo Abeni wrote: >>> diff --git a/net/ipv6/route.c b/net/ipv6/route.c >>> index 3c8834b..973cb73 100644 >>> --- a/net/ipv6/route.c >>> +++ b/net/ipv6/route.c >>> @@ -1183,11 +1183,10 @@ static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table >>> return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags); >>> } >>> >>> -struct dst_entry *ip6_route_output(struct net *net, const struct sock *sk, >>> - struct flowi6 *fl6) >>> +struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk, >>> + struct flowi6 *fl6, int flags) >>> { >>> struct dst_entry *dst; >>> - int flags = 0; >>> bool any_src; >>> >>> dst = l3mdev_rt6_dst_by_oif(net, fl6); >>> @@ -1208,6 +1207,13 @@ struct dst_entry *ip6_route_output(struct net *net, const struct sock *sk, >>> >>> return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_output); >>> } >>> +EXPORT_SYMBOL_GPL(ip6_route_output_flags); >>> + >>> +struct dst_entry *ip6_route_output(struct net *net, const struct sock *sk, >>> + struct flowi6 *fl6) >>> +{ >>> + return ip6_route_output_flags(net, sk, fl6, 0); >>> +} >>> EXPORT_SYMBOL(ip6_route_output); >> >> I think this can just be a static inline function. >> >> Is it a lot of work to introduce the flags argument globally? Most other >> functions already have a flags parameter, maybe instead of just adding >> another wrapper just bite the bullet and add it everywhere? > > There are ~20 call sites for ip6_route_output(). Replacing them with > ip6_route_output_flags() should be trivial, but it sounds quite > invasive. Moving the new ip6_route_output() definition into the header > file as static inline function should be pretty much equivalent, may I > go with the latter option ? I am not really a fan of such static inline wrappers all over the place, it doesnt't really help to evolve the code base. But as a net/stable fix, go with the static inline first, IMHO. Thanks, Hannes ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net 1/2] ipv6: enforce flowi6_oif usage in ip6_dst_lookup_tail() 2016-01-27 13:45 ` [PATCH net 1/2] ipv6: enforce flowi6_oif usage in ip6_dst_lookup_tail() Paolo Abeni 2016-01-27 18:38 ` Hannes Frederic Sowa @ 2016-01-28 14:59 ` David Ahern 2016-01-28 17:04 ` Paolo Abeni 1 sibling, 1 reply; 8+ messages in thread From: David Ahern @ 2016-01-28 14:59 UTC (permalink / raw) To: Paolo Abeni, netdev Cc: David S. Miller, Hajime Tazaki, lucien.xin, Marcelo Ricardo Leitner On 1/27/16 6:45 AM, Paolo Abeni wrote: > The current implementation of ip6_dst_lookup_tail() basically > ignore the egress ifindex match: if the saddr is set, > ip6_route_output() purposefully ignores flowi6_oif, due > to the commit d46a9d678e4c ("net: ipv6: Dont add RT6_LOOKUP_F_IFACE > flag if saddr set"), if the saddr is 'any' the first route lookup > in ip6_dst_lookup_tail fails, but upon failure a second lookup will > be performed with saddr set, thus ignoring the ifindex constraint. > > This commit adds an output route lookup function variant, which > allows the caller to specify additional lookup flags, and modify > ip6_dst_lookup_tail() to enforce the ifindex match on the second > lookup via said helper. > > Fixes: d46a9d678e4c ("net: ipv6: Dont add RT6_LOOKUP_F_IFACE flag if saddr set") > Signed-off-by: Paolo Abeni <pabeni@redhat.com> I don't agree with that 'Fixes:' tag. ip6_route_output did not add the RT6_LOOKUP_F_IFACE flag until 741a11d9e410; d46a9d678e4c is a follow on to limit adding the flag only if no source address is given. Since ip6_dst_lookup_tail never considered the flowi6_oif this is a general bug fix rather than a fix of d46a9d678e4c. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net 1/2] ipv6: enforce flowi6_oif usage in ip6_dst_lookup_tail() 2016-01-28 14:59 ` David Ahern @ 2016-01-28 17:04 ` Paolo Abeni 0 siblings, 0 replies; 8+ messages in thread From: Paolo Abeni @ 2016-01-28 17:04 UTC (permalink / raw) To: David Ahern Cc: netdev, David S. Miller, Hajime Tazaki, lucien.xin, Marcelo Ricardo Leitner On Thu, 2016-01-28 at 07:59 -0700, David Ahern wrote: > On 1/27/16 6:45 AM, Paolo Abeni wrote: > > The current implementation of ip6_dst_lookup_tail() basically > > ignore the egress ifindex match: if the saddr is set, > > ip6_route_output() purposefully ignores flowi6_oif, due > > to the commit d46a9d678e4c ("net: ipv6: Dont add RT6_LOOKUP_F_IFACE > > flag if saddr set"), if the saddr is 'any' the first route lookup > > in ip6_dst_lookup_tail fails, but upon failure a second lookup will > > be performed with saddr set, thus ignoring the ifindex constraint. > > > > This commit adds an output route lookup function variant, which > > allows the caller to specify additional lookup flags, and modify > > ip6_dst_lookup_tail() to enforce the ifindex match on the second > > lookup via said helper. > > > > Fixes: d46a9d678e4c ("net: ipv6: Dont add RT6_LOOKUP_F_IFACE flag if saddr set") > > Signed-off-by: Paolo Abeni <pabeni@redhat.com> > > I don't agree with that 'Fixes:' tag. > > ip6_route_output did not add the RT6_LOOKUP_F_IFACE flag until > 741a11d9e410; d46a9d678e4c is a follow on to limit adding the flag only > if no source address is given. > > Since ip6_dst_lookup_tail never considered the flowi6_oif this is a > general bug fix rather than a fix of d46a9d678e4c. Ok, I'll remove it in the v2, which will include Hannes feedback, too. Regards, Paolo ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH net 2/2] ipv6/udp: use sticky pktinfo egress ifindex on connect() 2016-01-27 13:45 [PATCH net 0/2] ipv6: fix sticky pktinfo behaviour Paolo Abeni 2016-01-27 13:45 ` [PATCH net 1/2] ipv6: enforce flowi6_oif usage in ip6_dst_lookup_tail() Paolo Abeni @ 2016-01-27 13:45 ` Paolo Abeni 1 sibling, 0 replies; 8+ messages in thread From: Paolo Abeni @ 2016-01-27 13:45 UTC (permalink / raw) To: netdev Cc: David S. Miller, David Ahern, Hajime Tazaki, lucien.xin, Marcelo Ricardo Leitner Currently, the egress interface index specified via IPV6_PKTINFO is ignored by __ip6_datagram_connect(), so that RFC 3542 section 6.7 can be subverted when the user space application calls connect() before sendmsg(). Fix it by initializing properly flowi6_oif in connect() before performing the route lookup. Signed-off-by: Paolo Abeni <pabeni@redhat.com> --- net/ipv6/datagram.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 517c55b..4281621 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -162,6 +162,9 @@ ipv4_connected: fl6.fl6_dport = inet->inet_dport; fl6.fl6_sport = inet->inet_sport; + if (!fl6.flowi6_oif) + fl6.flowi6_oif = np->sticky_pktinfo.ipi6_ifindex; + if (!fl6.flowi6_oif && (addr_type&IPV6_ADDR_MULTICAST)) fl6.flowi6_oif = np->mcast_oif; -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2016-01-28 17:04 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-01-27 13:45 [PATCH net 0/2] ipv6: fix sticky pktinfo behaviour Paolo Abeni 2016-01-27 13:45 ` [PATCH net 1/2] ipv6: enforce flowi6_oif usage in ip6_dst_lookup_tail() Paolo Abeni 2016-01-27 18:38 ` Hannes Frederic Sowa 2016-01-28 12:27 ` Paolo Abeni 2016-01-28 13:02 ` Hannes Frederic Sowa 2016-01-28 14:59 ` David Ahern 2016-01-28 17:04 ` Paolo Abeni 2016-01-27 13:45 ` [PATCH net 2/2] ipv6/udp: use sticky pktinfo egress ifindex on connect() Paolo Abeni
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).