[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20201124002345.GA42222@ubuntu>
Date: Mon, 23 Nov 2020 19:23:45 -0500
From: Stephen Suryaputra <ssuryaextr@...il.com>
To: netdev@...r.kernel.org
Subject: VRF NS for lladdr sent on the wrong interface
Hi,
I'm running into a problem with lladdr pinging all-host mcast all nodes
addr. The ping intially works but after cycling the interface that
receives the ping, the echo request packet causes a neigh solicitation
being sent on a different interface.
To repro, I included the attached namespace scripts. This is the
topology and an output of my test.
# +-------+ +----------+ +-------+
# | h0 | | r0 | | h1 |
# | v00+-----+v00 v01+---+v10 |
# | | | | | |
# +-------+ +----------+ +-------+
Setup and list of addresses:
$ sudo sh ./setup.sh
$ sudo ip netns exec h0 ip addr show
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
28: h0_v00@...7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether b2:72:0a:25:7d:0f brd ff:ff:ff:ff:ff:ff link-netns r0
inet6 fe80::b072:aff:fe25:7d0f/64 scope link
valid_lft forever preferred_lft forever
$ sudo ip netns exec r0 ip addr show
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: vrf_r0: <NOARP,MASTER,UP,LOWER_UP> mtu 65536 qdisc noqueue state UP group default qlen 1000
link/ether 5a:48:08:1e:e6:38 brd ff:ff:ff:ff:ff:ff
inet 127.0.0.1/8 scope host vrf_r0
valid_lft forever preferred_lft forever
27: r0_v00@...8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master vrf_r0 state UP group default qlen 1000
link/ether aa:9d:a5:cf:ab:75 brd ff:ff:ff:ff:ff:ff link-netns h0
inet6 fe80::a89d:a5ff:fecf:ab75/64 scope link
valid_lft forever preferred_lft forever
30: r0_v01@...9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master vrf_r0 state UP group default qlen 1000
link/ether 52:0f:70:b5:a8:6a brd ff:ff:ff:ff:ff:ff link-netns h1
inet6 fe80::500f:70ff:feb5:a86a/64 scope link
valid_lft forever preferred_lft forever
$ sudo ip netns exec h1 ip addr show
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
29: h1_v10@...0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether aa:3c:c1:a0:07:7c brd ff:ff:ff:ff:ff:ff link-netns r0
inet6 fe80::a83c:c1ff:fea0:77c/64 scope link
valid_lft forever preferred_lft forever
Initially ping is replied by r0_v00:
$ sudo ip netns exec h0 ping -c 1 ff02::1%h0_v00
PING ff02::1%h0_v00(ff02::1%h0_v00) 56 data bytes
64 bytes from fe80::a89d:a5ff:fecf:ab75%h0_v00: icmp_seq=1 ttl=64 time=4.44 ms
--- ff02::1%h0_v00 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 4.443/4.443/4.443/0.000 ms
Cycle r0_v00. Ping isn't replied and the tcpdump shows that the NS for h0_v00 lladdr
is sent over r0_v01:
$ sudo ip netns exec r0 ip link set r0_v00 down
$ sudo ip netns exec r0 ip link set r0_v00 up
$ sudo ip netns exec r0 ip addr show dev r0_v00
27: r0_v00@...8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master vrf_r0 state UP group default qlen 1000
link/ether aa:9d:a5:cf:ab:75 brd ff:ff:ff:ff:ff:ff link-netns h0
inet6 fe80::a89d:a5ff:fecf:ab75/64 scope link
valid_lft forever preferred_lft forever
$ sudo ip netns exec h0 ping -c 1 ff02::1%h0_v00
PING ff02::1%h0_v00(ff02::1%h0_v00) 56 data bytes
--- ff02::1%h0_v00 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
$ sudo ip netns exec h1 tcpdump -i h1_v10
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on h1_v10, link-type EN10MB (Ethernet), capture size 262144 bytes
^C12:36:12.210524 IP6 fe80::a83c:c1ff:fea0:77c > ip6-allrouters: ICMP6, router solicitation, length 16
12:36:34.456650 IP6 fe80::500f:70ff:feb5:a86a > ff02::1:ff25:7d0f: ICMP6, neighbor solicitation, who has fe80::b072:aff:fe25:7d0f, length 32
12:36:35.474519 IP6 fe80::500f:70ff:feb5:a86a > ff02::1:ff25:7d0f: ICMP6, neighbor solicitation, who has fe80::b072:aff:fe25:7d0f, length 32
12:36:36.498455 IP6 fe80::500f:70ff:feb5:a86a > ff02::1:ff25:7d0f: ICMP6, neighbor solicitation, who has fe80::b072:aff:fe25:7d0f, length 32
4 packets captured
4 packets received by filter
0 packets dropped by kernel
I'm thinking that the following patch is needed:
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index f2793ffde191..30f4e867fe5b 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -1315,11 +1315,14 @@ static struct sk_buff *vrf_ip6_rcv(struct net_device *vrf_dev,
int orig_iif = skb->skb_iif;
bool need_strict = rt6_need_strict(&ipv6_hdr(skb)->daddr);
bool is_ndisc = ipv6_ndisc_frame(skb);
+ bool is_ll_src;
/* loopback, multicast & non-ND link-local traffic; do not push through
* packet taps again. Reset pkt_type for upper layers to process skb
*/
- if (skb->pkt_type == PACKET_LOOPBACK || (need_strict && !is_ndisc)) {
+ is_ll_src = ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL;
+ if (skb->pkt_type == PACKET_LOOPBACK ||
+ (need_strict && !is_ndisc && !is_ll_src)) {
skb->dev = vrf_dev;
skb->skb_iif = vrf_dev->ifindex;
IP6CB(skb)->flags |= IP6SKB_L3SLAVE;
But wanting to probe first to see if I could have missed something. Or
is there a better patch. I would be happy to follow up with a formal patch.
Thank you,
Stephen.
Download attachment "setup.sh" of type "application/x-sh" (887 bytes)
Download attachment "teardown.sh" of type "application/x-sh" (177 bytes)
Powered by blists - more mailing lists