vppinfra: Improve code portability
[vpp.git] / src / plugins / abf / abf_policy.c
index a0c4ac8..e6dfe4f 100644 (file)
@@ -17,7 +17,6 @@
 
 #include <vlib/vlib.h>
 #include <vnet/plugin/plugin.h>
-#include <vpp/app/version.h>
 #include <vnet/fib/fib_path_list.h>
 #include <vnet/fib/fib_walk.h>
 
@@ -77,7 +76,7 @@ abf_policy_find (u32 policy_id)
 }
 
 
-void
+int
 abf_policy_update (u32 policy_id,
                   u32 acl_index, const fib_route_path_t * rpaths)
 {
@@ -122,13 +121,18 @@ abf_policy_update (u32 policy_id,
     {
       /*
        * update an existing policy.
-       * - add the path to the path-list and swap our ancestory
+       * - add the path to the path-list and swap our ancestry
        * - backwalk to poke all attachments to update
        */
       fib_node_index_t old_pl;
 
       ap = abf_policy_get (api);
       old_pl = ap->ap_pl;
+      if (ap->ap_acl != acl_index)
+       {
+         /* Should change this error code to something more descriptive */
+         return (VNET_API_ERROR_INVALID_VALUE);
+       }
 
       if (FIB_NODE_INDEX_INVALID != old_pl)
        {
@@ -156,6 +160,7 @@ abf_policy_update (u32 policy_id,
 
       fib_walk_sync (abf_policy_fib_node_type, api, &ctx);
     }
+  return (0);
 }
 
 static void
@@ -185,50 +190,47 @@ abf_policy_delete (u32 policy_id, const fib_route_path_t * rpaths)
       /*
        * no such policy
        */
-      return (-1);
+      return (VNET_API_ERROR_INVALID_VALUE);
     }
-  else
-    {
-      /*
-       * update an existing policy.
-       * - add the path to the path-list and swap our ancestory
-       * - backwalk to poke all attachments to update
-       */
-      fib_node_index_t old_pl;
 
-      ap = abf_policy_get (api);
-      old_pl = ap->ap_pl;
+  /*
+   * update an existing policy.
+   * - add the path to the path-list and swap our ancestry
+   * - backwalk to poke all attachments to update
+   */
+  fib_node_index_t old_pl;
 
-      ap->ap_pl =
-       fib_path_list_copy_and_path_remove (ap->ap_pl,
-                                           (FIB_PATH_LIST_FLAG_SHARED |
-                                            FIB_PATH_LIST_FLAG_NO_URPF),
-                                           rpaths);
+  ap = abf_policy_get (api);
+  old_pl = ap->ap_pl;
 
-      fib_path_list_child_remove (old_pl, ap->ap_sibling);
-      ap->ap_sibling = ~0;
+  fib_path_list_lock (old_pl);
+  ap->ap_pl = fib_path_list_copy_and_path_remove (
+    ap->ap_pl, (FIB_PATH_LIST_FLAG_SHARED | FIB_PATH_LIST_FLAG_NO_URPF),
+    rpaths);
 
-      if (FIB_NODE_INDEX_INVALID == ap->ap_pl)
-       {
-         /*
-          * no more paths on this policy. It's toast
-          * remove the CLI/API's lock
-          */
-         fib_node_unlock (&ap->ap_node);
-       }
-      else
-       {
-         ap->ap_sibling = fib_path_list_child_add (ap->ap_pl,
-                                                   abf_policy_fib_node_type,
-                                                   api);
+  fib_path_list_child_remove (old_pl, ap->ap_sibling);
+  ap->ap_sibling = ~0;
 
-         fib_node_back_walk_ctx_t ctx = {
-           .fnbw_reason = FIB_NODE_BW_REASON_FLAG_EVALUATE,
-         };
+  if (FIB_NODE_INDEX_INVALID == ap->ap_pl)
+    {
+      /*
+       * no more paths on this policy. It's toast
+       * remove the CLI/API's lock
+       */
+      fib_node_unlock (&ap->ap_node);
+    }
+  else
+    {
+      ap->ap_sibling =
+       fib_path_list_child_add (ap->ap_pl, abf_policy_fib_node_type, api);
 
-         fib_walk_sync (abf_policy_fib_node_type, api, &ctx);
-       }
+      fib_node_back_walk_ctx_t ctx = {
+       .fnbw_reason = FIB_NODE_BW_REASON_FLAG_EVALUATE,
+      };
+
+      fib_walk_sync (abf_policy_fib_node_type, api, &ctx);
     }
+  fib_path_list_unlock (old_pl);
 
   return (0);
 }
@@ -238,9 +240,10 @@ abf_policy_cmd (vlib_main_t * vm,
                unformat_input_t * main_input, vlib_cli_command_t * cmd)
 {
   unformat_input_t _line_input, *line_input = &_line_input;
-  u32 acl_index, policy_id;
   fib_route_path_t *rpaths = NULL, rpath;
-  u32 is_del;
+  u32 acl_index, policy_id, is_del;
+  dpo_proto_t payload_proto;
+  int rv = 0;
 
   is_del = 0;
   acl_index = INDEX_INVALID;
@@ -261,17 +264,28 @@ abf_policy_cmd (vlib_main_t * vm,
       else if (unformat (line_input, "add"))
        is_del = 0;
       else if (unformat (line_input, "via %U",
-                        unformat_fib_route_path, &rpath))
+                        unformat_fib_route_path, &rpath, &payload_proto))
        vec_add1 (rpaths, rpath);
       else
-       return (clib_error_return (0, "unknown input '%U'",
-                                  format_unformat_error, line_input));
+       {
+         clib_error_t *err;
+         err = clib_error_return (0, "unknown input '%U'",
+                                  format_unformat_error, line_input);
+         unformat_free (line_input);
+         return err;
+       }
     }
 
   if (INDEX_INVALID == policy_id)
     {
       vlib_cli_output (vm, "Specify a Policy ID");
-      return 0;
+      goto out;
+    }
+
+  if (vec_len (rpaths) == 0)
+    {
+      vlib_cli_output (vm, "Hop path must not be empty");
+      goto out;
     }
 
   if (!is_del)
@@ -279,21 +293,28 @@ abf_policy_cmd (vlib_main_t * vm,
       if (INDEX_INVALID == acl_index)
        {
          vlib_cli_output (vm, "ACL index must be set");
-         return 0;
+         goto out;
        }
 
-      abf_policy_update (policy_id, acl_index, rpaths);
+      rv = abf_policy_update (policy_id, acl_index, rpaths);
+      /* Should change this error code to something more descriptive */
+      if (rv == VNET_API_ERROR_INVALID_VALUE)
+       {
+         vlib_cli_output (vm,
+                          "ACL index must match existing ACL index in policy");
+         goto out;
+       }
     }
   else
     {
       abf_policy_delete (policy_id, rpaths);
     }
 
+out:
   unformat_free (line_input);
   return (NULL);
 }
 
-/* *INDENT-OFF* */
 /**
  * Create an ABF policy.
  */
@@ -303,7 +324,6 @@ VLIB_CLI_COMMAND (abf_policy_cmd_node, static) = {
   .short_help = "abf policy [add|del] id <index> acl <index> via ...",
   .is_mp_safe = 1,
 };
-/* *INDENT-ON* */
 
 static u8 *
 format_abf (u8 * s, va_list * args)
@@ -330,13 +350,11 @@ abf_policy_walk (abf_policy_walk_cb_t cb, void *ctx)
 {
   u32 api;
 
-  /* *INDENT-OFF* */
-  pool_foreach_index(api, abf_policy_pool,
-  ({
+  pool_foreach_index (api, abf_policy_pool)
+   {
     if (!cb(api, ctx))
       break;
-  }));
-  /* *INDENT-ON* */
+  }
 }
 
 static clib_error_t *
@@ -359,12 +377,10 @@ abf_show_policy_cmd (vlib_main_t * vm,
 
   if (INDEX_INVALID == policy_id)
     {
-      /* *INDENT-OFF* */
-      pool_foreach(ap, abf_policy_pool,
-      ({
+      pool_foreach (ap, abf_policy_pool)
+       {
         vlib_cli_output(vm, "%U", format_abf, ap);
-      }));
-      /* *INDENT-ON* */
+      }
     }
   else
     {
@@ -379,14 +395,12 @@ abf_show_policy_cmd (vlib_main_t * vm,
   return (NULL);
 }
 
-/* *INDENT-OFF* */
 VLIB_CLI_COMMAND (abf_policy_show_policy_cmd_node, static) = {
   .path = "show abf policy",
   .function = abf_show_policy_cmd,
   .short_help = "show abf policy <value>",
   .is_mp_safe = 1,
 };
-/* *INDENT-ON* */
 
 static fib_node_t *
 abf_policy_get_node (fib_node_index_t index)
@@ -441,20 +455,14 @@ static const fib_node_vft_t abf_policy_vft = {
 static clib_error_t *
 abf_policy_init (vlib_main_t * vm)
 {
-  abf_policy_fib_node_type = fib_node_register_new_type (&abf_policy_vft);
+  abf_policy_fib_node_type =
+    fib_node_register_new_type ("abf-policy", &abf_policy_vft);
 
   return (NULL);
 }
 
 VLIB_INIT_FUNCTION (abf_policy_init);
 
-/* *INDENT-OFF* */
-VLIB_PLUGIN_REGISTER () = {
-    .version = VPP_BUILD_VER,
-    .description = "ACL based Forwarding",
-};
-/* *INDENT-ON* */
-
 /*
  * fd.io coding-style-patch-verification: ON
  *