#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>
}
-void
+int
abf_policy_update (u32 policy_id,
u32 acl_index, const fib_route_path_t * rpaths)
{
{
/*
* 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)
{
fib_walk_sync (abf_policy_fib_node_type, api, &ctx);
}
+ return (0);
}
static void
/*
* 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);
}
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;
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)
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.
*/
.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)
{
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 *
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
{
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)
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
*