mpls: Fix 6PE forwarding
authorVinay K Nallamothu <nvinay@juniper.net>
Tue, 19 Mar 2019 22:41:18 +0000 (22:41 +0000)
committerDavid S. Miller <davem@davemloft.net>
Tue, 19 Mar 2019 23:00:22 +0000 (16:00 -0700)
This patch adds support for 6PE (RFC 4798) which uses IPv4-mapped IPv6
nexthop to connect IPv6 islands over IPv4 only MPLS network core.

Prior to this fix, to find the link-layer destination mac address, 6PE
enabled host/router was sending IPv6 ND requests for IPv4-mapped IPv6
nexthop address over the interface facing the IPv4 only core which
wouldn't success as the core is IPv6 free.

This fix changes that behavior on 6PE host to treat the nexthop as IPv4
address and send ARP requests whenever the next-hop address is an
IPv4-mapped IPv6 address.

Below topology illustrates the issue and how the patch addresses it.

abcd::1.1.1.1 (lo)                                              abcd::2.2.2.2 (lo)
R0 (PE/host)------------------------R1--------------------------------R2 (PE/host)
            <--- IPv4 MPLS core --->   <------ IPv4 MPLS core -------->
           eth1               eth2       eth3                       eth4
          172.18.0.10     172.18.0.11   172.19.0.11              172.19.0.12
    ffff::172.18.0.10                                      ffff::172.19.0.12
            <------------------IPv6 MPLS tunnel ---------------------->

R0 and R2 act as 6PE routers of IPv6 islands. R1 is IPv4 only with MPLS tunnels
between R0,R1 and R1,R2.

 docker exec r0 ip -f inet6 route add abcd::2.2.2.2/128 nexthop encap mpls 100 via ::ffff:172.18.0.11 dev eth1
 docker exec r2 ip -f inet6 route add abcd::1.1.1.1/128 nexthop encap mpls 200 via ::ffff:172.19.0.11 dev eth4

 docker exec r1 ip -f mpls route add 100 via inet 172.19.0.12 dev eth3
 docker exec r1 ip -f mpls route add 200 via inet 172.18.0.10 dev eth2

With the change, when R0 sends an IPv6 packet over MPLS tunnel to abcd::2.2.2.2,
using ::ffff:172.18.0.11 as the nexthop, it does neighbor discovery for
172.18.18.0.11.

Signed-off-by: Vinay K Nallamothu <nvinay@juniper.net>
Tested-by: Avinash Lingala <ar977m@att.com>
Tested-by: Aravind Srinivas Srinivasa Prabhakar <aprabh@juniper.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/mpls/mpls_iptunnel.c

index dda8930..f3a8557 100644 (file)
@@ -140,9 +140,15 @@ static int mpls_xmit(struct sk_buff *skb)
        if (rt)
                err = neigh_xmit(NEIGH_ARP_TABLE, out_dev, &rt->rt_gateway,
                                 skb);
-       else if (rt6)
-               err = neigh_xmit(NEIGH_ND_TABLE, out_dev, &rt6->rt6i_gateway,
-                                skb);
+       else if (rt6) {
+               if (ipv6_addr_v4mapped(&rt6->rt6i_gateway)) {
+                       /* 6PE (RFC 4798) */
+                       err = neigh_xmit(NEIGH_ARP_TABLE, out_dev, &rt6->rt6i_gateway.s6_addr32[3],
+                                        skb);
+               } else
+                       err = neigh_xmit(NEIGH_ND_TABLE, out_dev, &rt6->rt6i_gateway,
+                                        skb);
+       }
        if (err)
                net_dbg_ratelimited("%s: packet transmission failed: %d\n",
                                    __func__, err);