VRF: ICMPV6 Echo Reply failed to egress if ingress pkt Src is IPV6 Global and Dest is IPV6 Link Local.
KERNEL VERSION: ================ 4.14.28 BUG REPORT: ============ https://bugzilla.kernel.org/show_bug.cgi?id=199573 CONFIGURATION AND PACKET FLOW: ============================== 1) Created VRF device(Vrf_258) and enslaved network device(v1_F4246) to this VRF. Assigned Global address 2001::1 and fe80::1 to VLAN device. /exos/bin # ifconfig -a v1_F4246 v1_F4246 Link encap:Ethernet HWaddr 00:04:96:98:C9:18 inet6 addr: 2001::1/64 Scope:Global inet6 addr: fe80::1/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:52 errors:0 dropped:0 overruns:0 frame:0 TX packets:98 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:3024 (2.9 KiB) TX bytes:8116 (7.9 KiB) /exos/bin # ifconfig -a vrf_258 vrf_258 Link encap:Ethernet HWaddr 00:04:96:98:C9:18 inet addr:127.0.0.1 Mask:255.0.0.0 UP RUNNING NOARP MASTER MTU:65536 Metric:1 RX packets:27 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:1512 (1.4 KiB) TX bytes:0 (0.0 B) /exos/bin # ip link show vrf_258 14: vrf_258: <NOARP,MASTER,UP,LOWER_UP> mtu 65536 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 00:04:96:98:c9:18 brd ff:ff:ff:ff:ff:ff /exos/bin # ip link show v1_F4246 54: v1_F4246: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master vrf_258 state UNKNOWN mode DEFAULT group default qlen 1000 link/ether 00:04:96:98:c9:18 brd ff:ff:ff:ff:ff:ff 2) Received Ping request to local intf IP 2001::1 from neigbour DUT with following SRC/Dest. Rx ICMPV6 Echo Req Pkt's SRC IP = fe800000:0:0:2, DEST IP = 20010000:0:0:1 3) Incoming packet SRC is IPv6 Global address so skb->dev changed to vrf_258 by ip receive function. 4) Since it is local delivered packet icmpv6_echo_reply() is invoked. This function tries to send reply with SRC IP = 20010000:0:0:1 DEST IP = fe800000:0:0:2 flowi6_oif = vrf_dev258 5) ip6_dst_lookup() is failed for this packet and got dropped. fl6.flowi6_oif = icmp6_iif(skb); flowi6_oif is having vrf device index when ip6_dst_lookup() is invoked. Pkt flows to ip6_dst_lookup() -> ip6_dst_lookup_tail()->ip6_route_output_flags()->l3mdev_link_scope_lookup()->vrf_link_scope_lookup() There is a check in vrf_link_scope_lookup() which is dropping the reply packet. In this case flowi6_oif and dev->ifindex are same. .. if (fl6->flowi6_oif == dev->ifindex) { dst = &net->ipv6.ip6_null_entry->dst; dst_hold(dst); return dst; } .. TEMP FIX: ========= Return Ingress vlan device's ifIndex instead of skb->dev's. static int icmp6_iif(const struct sk_buff *skb) { int iif = IP6CB(skb)->iif; // skb->dev->ifindex; .. .. }