vcl: add api to retrieve num bytes for tx
[vpp.git] / src / vnet / srmpls / sr_mpls_policy.c
old mode 100755 (executable)
new mode 100644 (file)
index 5bb7fb2..41cb716
@@ -61,9 +61,10 @@ create_sl (mpls_sr_policy_t * sr_policy, mpls_label_t * sl, u32 weight)
 {
   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));
+  clib_memset (segment_list, 0, sizeof (*segment_list));
 
   vec_add1 (sr_policy->segments_lists, segment_list - sm->sid_lists);
 
@@ -85,13 +86,28 @@ create_sl (mpls_sr_policy_t * sr_policy, mpls_label_t * sl, u32 weight)
       .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);
 
-    /* *INDENT-OFF* */
     fib_prefix_t pfx = {
         .fp_len = 21,
         .fp_proto = FIB_PROTOCOL_MPLS,
@@ -99,7 +115,6 @@ create_sl (mpls_sr_policy_t * sr_policy, mpls_label_t * sl, u32 weight)
         .fp_eos = eos,
         .fp_payload_proto = DPO_PROTO_MPLS,
     };
-    /* *INDENT-ON* */
 
     fib_table_entry_path_add2 (0,
                               &pfx,
@@ -142,6 +157,10 @@ sr_mpls_policy_add (mpls_label_t bsid, mpls_label_t * segments,
   if (!sm->sr_policies_index_hash)
     sm->sr_policies_index_hash = hash_create (0, sizeof (mpls_label_t));
 
+  /* MPLS SR policies cannot be created unless the MPLS table is present */
+  if (~0 == fib_table_find (FIB_PROTOCOL_MPLS, MPLS_FIB_DEFAULT_TABLE_ID))
+    return (VNET_API_ERROR_NO_SUCH_TABLE);
+
   /* Search for existing keys (BSID) */
   p = hash_get (sm->sr_policies_index_hash, bsid);
   if (p)
@@ -151,7 +170,14 @@ sr_mpls_policy_add (mpls_label_t bsid, mpls_label_t * segments,
     }
   /* Add an SR policy object */
   pool_get (sm->sr_policies, sr_policy);
-  memset (sr_policy, 0, sizeof (*sr_policy));
+  clib_memset (sr_policy, 0, sizeof (*sr_policy));
+
+  /* the first policy needs to lock the MPLS table so it doesn't
+   * disappear with policies in it */
+  if (1 == pool_elts (sm->sr_policies))
+    fib_table_find_or_create_and_lock (FIB_PROTOCOL_MPLS,
+                                      MPLS_FIB_DEFAULT_TABLE_ID,
+                                      FIB_SOURCE_SR);
   sr_policy->bsid = bsid;
   sr_policy->type = behavior;
   sr_policy->endpoint_type = 0;
@@ -217,7 +243,6 @@ sr_mpls_policy_del (mpls_label_t bsid)
     /* remove each of the MPLS routes */
     FOR_EACH_MPLS_EOS_BIT (eos)
     {
-                       /* *INDENT-OFF* */
                        fib_prefix_t    pfx = {
                                .fp_len = 21,
                                .fp_proto = FIB_PROTOCOL_MPLS,
@@ -225,7 +250,6 @@ sr_mpls_policy_del (mpls_label_t bsid)
                                .fp_eos = eos,
                                .fp_payload_proto = DPO_PROTO_MPLS,
                        };
-                       /* *INDENT-ON* */
 
       fib_table_entry_path_remove2 (0, &pfx, FIB_SOURCE_SR, paths);
     }
@@ -244,6 +268,10 @@ sr_mpls_policy_del (mpls_label_t bsid)
   hash_unset (sm->sr_policies_index_hash, sr_policy->bsid);
   pool_put (sm->sr_policies, sr_policy);
 
+  if (0 == pool_elts (sm->sr_policies))
+    fib_table_unlock (MPLS_FIB_DEFAULT_TABLE_ID,
+                     FIB_PROTOCOL_MPLS, FIB_SOURCE_SR);
+
   return 0;
 }
 
@@ -327,7 +355,6 @@ sr_mpls_policy_mod (mpls_label_t bsid, u8 operation,
 
       FOR_EACH_MPLS_EOS_BIT (eos)
       {
-                       /* *INDENT-OFF* */
                        fib_prefix_t    pfx = {
                                .fp_len = 21,
                                .fp_proto = FIB_PROTOCOL_MPLS,
@@ -335,7 +362,6 @@ sr_mpls_policy_mod (mpls_label_t bsid, u8 operation,
                                .fp_eos = eos,
                                .fp_payload_proto = DPO_PROTO_MPLS,
                        };
-                       /* *INDENT-ON* */
 
        fib_table_entry_path_remove2 (0, &pfx, FIB_SOURCE_SR, paths);
       }
@@ -379,7 +405,6 @@ sr_mpls_policy_mod (mpls_label_t bsid, u8 operation,
 
       FOR_EACH_MPLS_EOS_BIT (eos)
       {
-                       /* *INDENT-OFF* */
                        fib_prefix_t    pfx = {
                                .fp_len = 21,
                                .fp_proto = FIB_PROTOCOL_MPLS,
@@ -387,7 +412,6 @@ sr_mpls_policy_mod (mpls_label_t bsid, u8 operation,
                                .fp_eos = eos,
                                .fp_payload_proto = DPO_PROTO_MPLS,
                        };
-                       /* *INDENT-ON* */
 
        fib_table_entry_path_remove2 (0, &pfx, FIB_SOURCE_SR, paths);
       }
@@ -402,7 +426,6 @@ sr_mpls_policy_mod (mpls_label_t bsid, u8 operation,
 
       FOR_EACH_MPLS_EOS_BIT (eos)
       {
-                       /* *INDENT-OFF* */
                        fib_prefix_t    pfx = {
                                .fp_len = 21,
                                .fp_proto = FIB_PROTOCOL_MPLS,
@@ -410,7 +433,6 @@ sr_mpls_policy_mod (mpls_label_t bsid, u8 operation,
                                .fp_eos = eos,
                                .fp_payload_proto = DPO_PROTO_MPLS,
                        };
-                       /* *INDENT-ON* */
 
        fib_table_entry_path_add2 (0,
                                   &pfx,
@@ -485,6 +507,7 @@ sr_mpls_policy_command_fn (vlib_main_t * vm, unformat_input_t * input,
       rv = sr_mpls_policy_add (bsid, segments,
                               (is_spray ? SR_POLICY_TYPE_SPRAY :
                                SR_POLICY_TYPE_DEFAULT), weight);
+      vec_free (segments);
     }
   else if (is_del)
     rv = sr_mpls_policy_del (bsid);
@@ -499,6 +522,7 @@ sr_mpls_policy_command_fn (vlib_main_t * vm, unformat_input_t * input,
       if (operation == 3 && weight == (u32) ~ 0)
        return clib_error_return (0, "No new weight for the SL specified");
       rv = sr_mpls_policy_mod (bsid, operation, segments, sl_index, weight);
+      vec_free (segments);
     }
   switch (rv)
     {
@@ -526,13 +550,14 @@ sr_mpls_policy_command_fn (vlib_main_t * vm, unformat_input_t * input,
       return clib_error_return (0,
                                "Could not modify the segment list. "
                                "The given SL is not associated with such SR policy.");
+    case VNET_API_ERROR_NO_SUCH_TABLE:
+      return clib_error_return (0, "the Default MPLS table is not present");
     default:
       return clib_error_return (0, "BUG: sr policy returns %d", rv);
     }
   return 0;
 }
 
-/* *INDENT-OFF* */
 VLIB_CLI_COMMAND(sr_mpls_policy_command, static)=
 {
        .path = "sr mpls policy",
@@ -541,7 +566,6 @@ VLIB_CLI_COMMAND(sr_mpls_policy_command, static)=
                .long_help = "TBD.\n",
                .function = sr_mpls_policy_command_fn,
 };
-/* *INDENT-ON* */
 
 /**
  * @brief CLI to display onscreen all the SR MPLS policies
@@ -561,11 +585,9 @@ show_sr_mpls_policies_command_fn (vlib_main_t * vm, unformat_input_t * input,
 
   vlib_cli_output (vm, "SR MPLS policies:");
 
-       /* *INDENT-OFF* */
-       pool_foreach(sr_policy, sm->sr_policies, {
+       pool_foreach (sr_policy, sm->sr_policies) {
                vec_add1(vec_policies, sr_policy);
-       });
-       /* *INDENT-ON* */
+       }
 
   vec_foreach_index (i, vec_policies)
   {
@@ -611,14 +633,12 @@ show_sr_mpls_policies_command_fn (vlib_main_t * vm, unformat_input_t * input,
   return 0;
 }
 
-/* *INDENT-OFF* */
 VLIB_CLI_COMMAND(show_sr_mpls_policies_command, static)=
 {
        .path = "show sr mpls policies",
                .short_help = "show sr mpls policies",
                .function = show_sr_mpls_policies_command_fn,
 };
-/* *INDENT-ON* */
 
 /**
  * @brief Update the Endpoint,Color tuple of an SR policy
@@ -664,7 +684,7 @@ sr_mpls_policy_assign_endpoint_color (mpls_label_t bsid,
 
       /* CID 180995 This should never be NULL unless the two hash tables
        * get out of sync */
-      ASSERT (old_value != NULL);
+      ALWAYS_ASSERT (old_value != NULL);
 
       fib_prefix_t pfx = { 0 };
       pfx.fp_proto = FIB_PROTOCOL_MPLS;
@@ -804,7 +824,7 @@ cli_sr_mpls_policy_ec_command_fn (vlib_main_t * vm, unformat_input_t * input,
   u8 endpoint_type = 0;
   char clear = 0, color_set = 0, bsid_set = 0;
 
-  memset (&endpoint, 0, sizeof (ip46_address_t));
+  clib_memset (&endpoint, 0, sizeof (ip46_address_t));
 
   int rv;
   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
@@ -852,14 +872,12 @@ cli_sr_mpls_policy_ec_command_fn (vlib_main_t * vm, unformat_input_t * input,
   return 0;
 }
 
-/* *INDENT-OFF* */
 VLIB_CLI_COMMAND(cli_sr_mpls_policy_ec_command, static)=
 {
        .path = "sr mpls policy te",
                .short_help = "sr mpls policy te bsid xxxxx endpoint x.x.x.x color 12341234",
                .function = cli_sr_mpls_policy_ec_command_fn,
 };
-/* *INDENT-ON* */
 
 /********************* SR MPLS Policy initialization ***********************/
 /**