SR-MPLS: fixes and tests

- the FIB path takes a vector of type fib_mpls_label_t not u32 so the untype safe vec_add did not work
- write som eSR-MPLS tests
- allow an MPLS tunnel to resolve through a SR BSID

Change-Id: I2a18b9a9bf43584100ac269c4ebc286c9e3b3ea5
Signed-off-by: Neale Ranns <nranns@cisco.com>
diff --git a/src/vnet/dpo/mpls_label_dpo.c b/src/vnet/dpo/mpls_label_dpo.c
index 0a7063c..bee155b 100644
--- a/src/vnet/dpo/mpls_label_dpo.c
+++ b/src/vnet/dpo/mpls_label_dpo.c
@@ -205,7 +205,7 @@
     }
 
     mld = mpls_label_dpo_get(index);
-    s = format(s, "mpls-label[%U%d]:",
+    s = format(s, "mpls-label[%U@%d]:",
                format_mpls_label_dpo_flags,
                (int) mld->mld_flags, index);
 
diff --git a/src/vnet/mpls/mpls.api b/src/vnet/mpls/mpls.api
index 6047d25..7ab0f37 100644
--- a/src/vnet/mpls/mpls.api
+++ b/src/vnet/mpls/mpls.api
@@ -54,6 +54,7 @@
   u8 mt_next_hop_preference;
   u8 mt_next_hop[16];
   u8 mt_next_hop_n_out_labels;
+  u32 mt_next_hop_via_label;
   u32 mt_next_hop_sw_if_index;
   u32 mt_next_hop_table_id;
   vl_api_fib_mpls_label_t mt_next_hop_out_label_stack[mt_next_hop_n_out_labels];
diff --git a/src/vnet/mpls/mpls_api.c b/src/vnet/mpls/mpls_api.c
index a35e94d..8fec8e8 100644
--- a/src/vnet/mpls/mpls_api.c
+++ b/src/vnet/mpls/mpls_api.c
@@ -306,6 +306,7 @@
   u32 tunnel_sw_if_index;
   int ii;
   fib_route_path_t rpath, *rpaths = NULL;
+  u32 next_hop_via_label;
 
   memset (&rpath, 0, sizeof (rpath));
 
@@ -326,6 +327,14 @@
   rpath.frp_sw_if_index = ntohl (mp->mt_next_hop_sw_if_index);
   rpath.frp_weight = 1;
 
+  next_hop_via_label = ntohl (mp->mt_next_hop_via_label);
+  if ((MPLS_LABEL_INVALID != next_hop_via_label) && (0 != next_hop_via_label))
+    {
+      rpath.frp_proto = DPO_PROTO_MPLS;
+      rpath.frp_local_label = next_hop_via_label;
+      rpath.frp_eos = MPLS_NON_EOS;
+    }
+
   if (mp->mt_is_add)
     {
       for (ii = 0; ii < mp->mt_next_hop_n_out_labels; ii++)
diff --git a/src/vnet/srmpls/sr_mpls_policy.c b/src/vnet/srmpls/sr_mpls_policy.c
index 5bb7fb2..86cd169 100755
--- a/src/vnet/srmpls/sr_mpls_policy.c
+++ b/src/vnet/srmpls/sr_mpls_policy.c
@@ -61,6 +61,7 @@
 {
   mpls_sr_main_t *sm = &sr_mpls_main;
   mpls_sr_sl_t *segment_list;
+  u32 ii;
 
   pool_get (sm->sid_lists, segment_list);
   memset (segment_list, 0, sizeof (*segment_list));
@@ -85,8 +86,24 @@
       .frp_local_label = sl[0],
     };
 
-    if (vec_len (sl) - 1)
-      vec_add (path.frp_label_stack, sl + 1, vec_len (sl) - 1);
+    if (vec_len (sl) > 1)
+      {
+	vec_validate (path.frp_label_stack, vec_len (sl) - 2);
+	for (ii = 1; ii < vec_len (sl); ii++)
+	  {
+	    path.frp_label_stack[ii - 1].fml_value = sl[ii];
+	  }
+      }
+    else
+      {
+	/*
+	 * add an impliciet NULL label to allow non-eos recursion
+	 */
+	fib_mpls_label_t lbl = {
+	  .fml_value = MPLS_IETF_IMPLICIT_NULL_LABEL,
+	};
+	vec_add1 (path.frp_label_stack, lbl);
+      }
 
     fib_route_path_t *paths = NULL;
     vec_add1 (paths, path);