* [PATCH net] net/ipv6: Reinstate ping/traceroute use with source address in VRF
@ 2019-05-20 8:40 Mike Manning
2019-05-20 16:58 ` David Ahern
0 siblings, 1 reply; 3+ messages in thread
From: Mike Manning @ 2019-05-20 8:40 UTC (permalink / raw)
To: netdev, dsahern
Since the commit 1893ff20275b ("net/ipv6: Add l3mdev check to
ipv6_chk_addr_and_flags"), traceroute using TCP SYN or ICMP ECHO option
and ping fail when specifying a source address typically on a loopback
/dummy interface in the same VRF, e.g.:
# ip vrf exec vrfgreen ping 3000::1 -I 2222::2
ping: bind icmp socket: Cannot assign requested address
# ip vrf exec vrfgreen traceroute 3000::1 -s 2222::2 -T
bind: Cannot assign requested address
IPv6 traceroute using default UDP and IPv4 ping & traceroute continue
to work inside a VRF using a source address.
The reason is that the source address is provided via bind without a
device given by these applications in this case. The call to
ipv6_check_addr() in rawv6_bind() returns false as the default VRF is
assumed if no dev was given, but the src addr is in a non-default VRF.
The solution is to check that the address exists in the L3 domain that
the dev is part of only if the dev has been specified.
Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
---
net/ipv6/addrconf.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index f96d1de79509..3963306ec27f 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1908,6 +1908,7 @@ int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
int strict, u32 banned_flags)
{
unsigned int hash = inet6_addr_hash(net, addr);
+ const struct net_device *orig_dev = dev;
const struct net_device *l3mdev;
struct inet6_ifaddr *ifp;
u32 ifp_flags;
@@ -1922,7 +1923,7 @@ int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
if (!net_eq(dev_net(ifp->idev->dev), net))
continue;
- if (l3mdev_master_dev_rcu(ifp->idev->dev) != l3mdev)
+ if (orig_dev && l3mdev_master_dev_rcu(ifp->idev->dev) != l3mdev)
continue;
/* Decouple optimistic from tentative for evaluation here.
--
2.11.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH net] net/ipv6: Reinstate ping/traceroute use with source address in VRF
2019-05-20 8:40 [PATCH net] net/ipv6: Reinstate ping/traceroute use with source address in VRF Mike Manning
@ 2019-05-20 16:58 ` David Ahern
2019-05-20 18:59 ` Mike Manning
0 siblings, 1 reply; 3+ messages in thread
From: David Ahern @ 2019-05-20 16:58 UTC (permalink / raw)
To: Mike Manning, netdev
On 5/20/19 2:40 AM, Mike Manning wrote:
> Since the commit 1893ff20275b ("net/ipv6: Add l3mdev check to
> ipv6_chk_addr_and_flags"), traceroute using TCP SYN or ICMP ECHO option
> and ping fail when specifying a source address typically on a loopback
> /dummy interface in the same VRF, e.g.:
>
> # ip vrf exec vrfgreen ping 3000::1 -I 2222::2
> ping: bind icmp socket: Cannot assign requested address
> # ip vrf exec vrfgreen traceroute 3000::1 -s 2222::2 -T
> bind: Cannot assign requested address
>
> IPv6 traceroute using default UDP and IPv4 ping & traceroute continue
> to work inside a VRF using a source address.
>
> The reason is that the source address is provided via bind without a
> device given by these applications in this case. The call to
> ipv6_check_addr() in rawv6_bind() returns false as the default VRF is
> assumed if no dev was given, but the src addr is in a non-default VRF.
>
> The solution is to check that the address exists in the L3 domain that
> the dev is part of only if the dev has been specified.
>
> Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
> ---
> net/ipv6/addrconf.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> index f96d1de79509..3963306ec27f 100644
> --- a/net/ipv6/addrconf.c
> +++ b/net/ipv6/addrconf.c
> @@ -1908,6 +1908,7 @@ int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
> int strict, u32 banned_flags)
> {
> unsigned int hash = inet6_addr_hash(net, addr);
> + const struct net_device *orig_dev = dev;
> const struct net_device *l3mdev;
> struct inet6_ifaddr *ifp;
> u32 ifp_flags;
> @@ -1922,7 +1923,7 @@ int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
> if (!net_eq(dev_net(ifp->idev->dev), net))
> continue;
>
> - if (l3mdev_master_dev_rcu(ifp->idev->dev) != l3mdev)
> + if (orig_dev && l3mdev_master_dev_rcu(ifp->idev->dev) != l3mdev)
> continue;
>
> /* Decouple optimistic from tentative for evaluation here.
>
Wrong fix. When looking up the address you have to give the L3 domain of
interest.
This change:
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 84dbe21b71e5..96a3559f2a09 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -287,7 +287,9 @@ static int rawv6_bind(struct sock *sk, struct
sockaddr *uaddr, int addr_len)
/* Binding to link-local address requires an
interface */
if (!sk->sk_bound_dev_if)
goto out_unlock;
+ }
+ if (sk->sk_bound_dev_if) {
err = -ENODEV;
dev = dev_get_by_index_rcu(sock_net(sk),
sk->sk_bound_dev_if);
make raw binds similar to tcp. See:
c5ee066333ebc ("ipv6: Consider sk_bound_dev_if when binding a socket to
an address")
ec90ad334986f ("ipv6: Consider sk_bound_dev_if when binding a socket to
a v4 mapped address")
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH net] net/ipv6: Reinstate ping/traceroute use with source address in VRF
2019-05-20 16:58 ` David Ahern
@ 2019-05-20 18:59 ` Mike Manning
0 siblings, 0 replies; 3+ messages in thread
From: Mike Manning @ 2019-05-20 18:59 UTC (permalink / raw)
To: David Ahern, netdev
On 20/05/2019 17:58, David Ahern wrote:
> On 5/20/19 2:40 AM, Mike Manning wrote:
>> Since the commit 1893ff20275b ("net/ipv6: Add l3mdev check to
>> ipv6_chk_addr_and_flags"), traceroute using TCP SYN or ICMP ECHO option
>> and ping fail when specifying a source address typically on a loopback
>> /dummy interface in the same VRF, e.g.:
>>
>> # ip vrf exec vrfgreen ping 3000::1 -I 2222::2
>> ping: bind icmp socket: Cannot assign requested address
>> # ip vrf exec vrfgreen traceroute 3000::1 -s 2222::2 -T
>> bind: Cannot assign requested address
>>
>> IPv6 traceroute using default UDP and IPv4 ping & traceroute continue
>> to work inside a VRF using a source address.
>>
>> The reason is that the source address is provided via bind without a
>> device given by these applications in this case. The call to
>> ipv6_check_addr() in rawv6_bind() returns false as the default VRF is
>> assumed if no dev was given, but the src addr is in a non-default VRF.
>>
>> The solution is to check that the address exists in the L3 domain that
>> the dev is part of only if the dev has been specified.
>>
>> Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
>> ---
>> net/ipv6/addrconf.c | 3 ++-
>> 1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
>> index f96d1de79509..3963306ec27f 100644
>> --- a/net/ipv6/addrconf.c
>> +++ b/net/ipv6/addrconf.c
>> @@ -1908,6 +1908,7 @@ int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
>> int strict, u32 banned_flags)
>> {
>> unsigned int hash = inet6_addr_hash(net, addr);
>> + const struct net_device *orig_dev = dev;
>> const struct net_device *l3mdev;
>> struct inet6_ifaddr *ifp;
>> u32 ifp_flags;
>> @@ -1922,7 +1923,7 @@ int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
>> if (!net_eq(dev_net(ifp->idev->dev), net))
>> continue;
>>
>> - if (l3mdev_master_dev_rcu(ifp->idev->dev) != l3mdev)
>> + if (orig_dev && l3mdev_master_dev_rcu(ifp->idev->dev) != l3mdev)
>> continue;
>>
>> /* Decouple optimistic from tentative for evaluation here.
>>
> Wrong fix. When looking up the address you have to give the L3 domain of
> interest.
>
> This change:
>
> diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
> index 84dbe21b71e5..96a3559f2a09 100644
> --- a/net/ipv6/raw.c
> +++ b/net/ipv6/raw.c
> @@ -287,7 +287,9 @@ static int rawv6_bind(struct sock *sk, struct
> sockaddr *uaddr, int addr_len)
> /* Binding to link-local address requires an
> interface */
> if (!sk->sk_bound_dev_if)
> goto out_unlock;
> + }
>
> + if (sk->sk_bound_dev_if) {
> err = -ENODEV;
> dev = dev_get_by_index_rcu(sock_net(sk),
> sk->sk_bound_dev_if);
>
> make raw binds similar to tcp. See:
>
> c5ee066333ebc ("ipv6: Consider sk_bound_dev_if when binding a socket to
> an address")
> ec90ad334986f ("ipv6: Consider sk_bound_dev_if when binding a socket to
> a v4 mapped address")
Thanks, I withdraw this submission and have submitted a new one as you
recommend.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2019-05-20 19:00 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-20 8:40 [PATCH net] net/ipv6: Reinstate ping/traceroute use with source address in VRF Mike Manning
2019-05-20 16:58 ` David Ahern
2019-05-20 18:59 ` Mike Manning
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.