diff options
| author | Guillaume Nault <gnault@redhat.com> | 2023-06-07 18:05:02 +0200 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2023-06-21 15:59:16 +0200 |
| commit | 688e6db596611e2bbed24169c4af0e1b3c1efcf8 (patch) | |
| tree | ddc812b200d2c19b0153ed022c767066be19324f | |
| parent | 471a4c08e30e33820ad8957abeb82bb2e1bf3d28 (diff) | |
| download | linux-688e6db596611e2bbed24169c4af0e1b3c1efcf8.tar.gz linux-688e6db596611e2bbed24169c4af0e1b3c1efcf8.tar.bz2 linux-688e6db596611e2bbed24169c4af0e1b3c1efcf8.zip | |
ping6: Fix send to link-local addresses with VRF.
[ Upstream commit 91ffd1bae1dafbb9e34b46813f5b058581d9144d ]
Ping sockets can't send packets when they're bound to a VRF master
device and the output interface is set to a slave device.
For example, when net.ipv4.ping_group_range is properly set, so that
ping6 can use ping sockets, the following kind of commands fails:
$ ip vrf exec red ping6 fe80::854:e7ff:fe88:4bf1%eth1
What happens is that sk->sk_bound_dev_if is set to the VRF master
device, but 'oif' is set to the real output device. Since both are set
but different, ping_v6_sendmsg() sees their value as inconsistent and
fails.
Fix this by allowing 'oif' to be a slave device of ->sk_bound_dev_if.
This fixes the following kselftest failure:
$ ./fcnal-test.sh -t ipv6_ping
[...]
TEST: ping out, vrf device+address bind - ns-B IPv6 LLA [FAIL]
Reported-by: Mirsad Todorovac <mirsad.todorovac@alu.unizg.hr>
Closes: https://lore.kernel.org/netdev/b6191f90-ffca-dbca-7d06-88a9788def9c@alu.unizg.hr/
Tested-by: Mirsad Todorovac <mirsad.todorovac@alu.unizg.hr>
Fixes: 5e457896986e ("net: ipv6: Fix ping to link-local addresses.")
Signed-off-by: Guillaume Nault <gnault@redhat.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://lore.kernel.org/r/6c8b53108816a8d0d5705ae37bdc5a8322b5e3d9.1686153846.git.gnault@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
| -rw-r--r-- | net/ipv6/ping.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c index 6ac88fe24a8e..7fab29f3ce6e 100644 --- a/net/ipv6/ping.c +++ b/net/ipv6/ping.c @@ -96,7 +96,8 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) addr_type = ipv6_addr_type(daddr); if ((__ipv6_addr_needs_scope_id(addr_type) && !oif) || (addr_type & IPV6_ADDR_MAPPED) || - (oif && sk->sk_bound_dev_if && oif != sk->sk_bound_dev_if)) + (oif && sk->sk_bound_dev_if && oif != sk->sk_bound_dev_if && + l3mdev_master_ifindex_by_index(sock_net(sk), oif) != sk->sk_bound_dev_if)) return -EINVAL; /* TODO: use ip6_datagram_send_ctl to get options from cmsg */ |
