ip tests: Fixes and UT for MPLS 6PE 47/21047/4
authorNeale Ranns <nranns@cisco.com>
Sun, 4 Aug 2019 10:30:56 +0000 (03:30 -0700)
committerOle Trøan <otroan@employees.org>
Tue, 6 Aug 2019 08:56:30 +0000 (08:56 +0000)
Type: fix

Change-Id: I48650473591aa181167cf3a86ed2f5da58a81072
Signed-off-by: Neale Ranns <nranns@cisco.com>
src/vnet/ip/ip.api
src/vnet/ip/ip_api.c
test/test_mpls.py
test/vpp_ip_route.py

index 39d394f..c4ef626 100644 (file)
@@ -384,6 +384,8 @@ autoreply define sw_interface_ip6_enable_disable
                                  are used for forwarding. lower value is better.
     @param next_hop_id - Used when the path resolves via an object that has a unique
                          identifier.
+    @param next_hop_proto - The protocol of the next-hop (address)
+                            0=use same AF as the route, 1=IPv4, 2=IPv6
     @param dst_address_length - 
     @param dst_address[16] - 
     @param next_hop_address[16] - 
index ce3456d..7a6e6fe 100644 (file)
@@ -1025,7 +1025,8 @@ ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp,
 {
   u32 fib_index, next_hop_fib_index;
   fib_mpls_label_t *label_stack = NULL;
-  int rv, ii, n_labels;;
+  dpo_proto_t nh_proto;
+  int rv, ii, n_labels;
 
   rv = add_del_route_check (FIB_PROTOCOL_IP4,
                            mp->table_id,
@@ -1044,8 +1045,18 @@ ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp,
   clib_memcpy (&pfx.fp_addr.ip4, mp->dst_address, sizeof (pfx.fp_addr.ip4));
 
   ip46_address_t nh;
-  clib_memset (&nh, 0, sizeof (nh));
-  memcpy (&nh.ip4, mp->next_hop_address, sizeof (nh.ip4));
+
+  if (0 == mp->next_hop_proto || 1 == mp->next_hop_proto)
+    {
+      clib_memset (&nh, 0, sizeof (nh));
+      memcpy (&nh.ip4, mp->next_hop_address, sizeof (nh.ip4));
+      nh_proto = DPO_PROTO_IP4;
+    }
+  else
+    {
+      memcpy (&nh.ip6, mp->next_hop_address, sizeof (nh.ip6));
+      nh_proto = DPO_PROTO_IP6;
+    }
 
   n_labels = mp->next_hop_n_out_labels;
   if (n_labels == 0)
@@ -1078,7 +1089,7 @@ ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp,
                                mp->is_dvr,
                                mp->is_source_lookup,
                                mp->is_udp_encap,
-                               fib_index, &pfx, DPO_PROTO_IP4,
+                               fib_index, &pfx, nh_proto,
                                &nh,
                                ntohl (mp->next_hop_id),
                                ntohl (mp->next_hop_sw_if_index),
@@ -1099,7 +1110,8 @@ ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp,
 {
   fib_mpls_label_t *label_stack = NULL;
   u32 fib_index, next_hop_fib_index;
-  int rv, ii, n_labels;;
+  dpo_proto_t nh_proto;
+  int rv, ii, n_labels;
 
   rv = add_del_route_check (FIB_PROTOCOL_IP6,
                            mp->table_id,
@@ -1118,8 +1130,18 @@ ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp,
   clib_memcpy (&pfx.fp_addr.ip6, mp->dst_address, sizeof (pfx.fp_addr.ip6));
 
   ip46_address_t nh;
-  clib_memset (&nh, 0, sizeof (nh));
-  memcpy (&nh.ip6, mp->next_hop_address, sizeof (nh.ip6));
+
+  if (1 == mp->next_hop_proto)
+    {
+      clib_memset (&nh, 0, sizeof (nh));
+      memcpy (&nh.ip4, mp->next_hop_address, sizeof (nh.ip4));
+      nh_proto = DPO_PROTO_IP4;
+    }
+  else
+    {
+      memcpy (&nh.ip6, mp->next_hop_address, sizeof (nh.ip6));
+      nh_proto = DPO_PROTO_IP6;
+    }
 
   n_labels = mp->next_hop_n_out_labels;
   if (n_labels == 0)
@@ -1152,7 +1174,7 @@ ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp,
                                mp->is_dvr,
                                mp->is_source_lookup,
                                mp->is_udp_encap,
-                               fib_index, &pfx, DPO_PROTO_IP6,
+                               fib_index, &pfx, nh_proto,
                                &nh, ntohl (mp->next_hop_id),
                                ntohl (mp->next_hop_sw_if_index),
                                next_hop_fib_index,
index 4a1c663..0b88839 100644 (file)
@@ -4,7 +4,7 @@ import unittest
 import socket
 
 from framework import VppTestCase, VppTestRunner
-from vpp_ip import DpoProto
+from vpp_ip import DpoProto, INVALID_INDEX
 from vpp_ip_route import VppIpRoute, VppRoutePath, VppMplsRoute, \
     VppMplsIpBind, VppIpMRoute, VppMRoutePath, \
     MRouteItfFlags, MRouteEntryFlags, VppIpTable, VppMplsTable, \
@@ -1387,6 +1387,60 @@ class TestMPLS(VppTestCase):
                                              dst_ip="ff01::1")
         self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
 
+    def test_6pe(self):
+        """ MPLS 6PE """
+
+        #
+        # Add a non-recursive route with a single out label
+        #
+        route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
+                                    [VppRoutePath(self.pg0.remote_ip4,
+                                                  self.pg0.sw_if_index,
+                                                  labels=[VppMplsLabel(45)])])
+        route_10_0_0_1.add_vpp_config()
+
+        # bind a local label to the route
+        binding = VppMplsIpBind(self, 44, "10.0.0.1", 32)
+        binding.add_vpp_config()
+
+        #
+        # a labelled v6 route that resolves through the v4
+        #
+        route_2001_3 = VppIpRoute(
+            self, "2001::3", 128,
+            [VppRoutePath("10.0.0.1",
+                          INVALID_INDEX,
+                          labels=[VppMplsLabel(32)])],
+            is_ip6=1)
+
+        route_2001_3.add_vpp_config()
+
+        tx = self.create_stream_ip6(self.pg0, "2001::3")
+        rx = self.send_and_expect(self.pg0, tx, self.pg0)
+
+        self.verify_capture_labelled_ip6(self.pg0, rx, tx,
+                                         [VppMplsLabel(45),
+                                          VppMplsLabel(32)])
+
+        #
+        # and a v4 recursive via the v6
+        #
+        route_20_3 = VppIpRoute(
+            self, "20.0.0.3", 32,
+            [VppRoutePath("2001::3",
+                          INVALID_INDEX,
+                          proto=DpoProto.DPO_PROTO_IP6,
+                          labels=[VppMplsLabel(99)])])
+        route_20_3.add_vpp_config()
+
+        tx = self.create_stream_ip4(self.pg0, "20.0.0.3")
+        rx = self.send_and_expect(self.pg0, tx, self.pg0)
+
+        self.verify_capture_labelled_ip4(self.pg0, rx, tx,
+                                         [VppMplsLabel(45),
+                                          VppMplsLabel(32),
+                                          VppMplsLabel(99)])
+
 
 class TestMPLSDisabled(VppTestCase):
     """ MPLS disabled """
index 0bd6dd3..516fcb8 100644 (file)
@@ -389,6 +389,13 @@ class VppIpRoute(VppObject):
         else:
             for path in self.paths:
                 lstack = path.encode_labels()
+                nh_proto = 0
+
+                # cross AF next-hop
+                if self.is_ip6 and path.proto == DpoProto.DPO_PROTO_IP4:
+                    nh_proto = 1
+                elif not self.is_ip6 and path.proto == DpoProto.DPO_PROTO_IP6:
+                    nh_proto = 2
 
                 r = self._test.vapi.ip_add_del_route(
                     dst_address=self.dest_addr,
@@ -400,6 +407,7 @@ class VppIpRoute(VppObject):
                     next_hop_out_label_stack=lstack,
                     next_hop_via_label=path.nh_via_label,
                     next_hop_id=path.next_hop_id,
+                    next_hop_proto=nh_proto,
                     is_resolve_host=path.is_resolve_host,
                     is_resolve_attached=path.is_resolve_attached,
                     is_ipv6=self.is_ip6, is_local=self.is_local,