abf: add API parameter n_paths range checks
Also check for non-zero rpath length in CLI cmd.
While there, no need to use "else" after a return.
Also while there, notice and fix numerous input_line
buffer leaks and fix them.
Type: fix
Fixes: 669d07dc01
Signed-off-by: Jon Loeliger <jdl@netgate.com>
Change-Id: I18ea44b7b82e8938c3e793e7c2a04dfe157076d8
This commit is contained in:

committed by
Neale Ranns

parent
6e3b3b7672
commit
755b529c11
@ -51,7 +51,7 @@ define abf_plugin_get_version_reply
|
||||
/** \brief A description of an ABF policy
|
||||
@param policy_id User chosen Identifier for the policy
|
||||
@param acl_index The ACL that the policy will match against
|
||||
@param n_paths Number of paths
|
||||
@param n_paths Number of paths, 1..255
|
||||
@param paths The set of forwarding paths that are being added or removed.
|
||||
*/
|
||||
typedef abf_policy
|
||||
|
@ -69,6 +69,12 @@ vl_api_abf_policy_add_del_t_handler (vl_api_abf_policy_add_del_t * mp)
|
||||
int rv = 0;
|
||||
u8 pi;
|
||||
|
||||
if (mp->policy.n_paths == 0)
|
||||
{
|
||||
rv = VNET_API_ERROR_INVALID_VALUE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
vec_validate (paths, mp->policy.n_paths - 1);
|
||||
|
||||
for (pi = 0; pi < mp->policy.n_paths; pi++)
|
||||
|
@ -192,50 +192,45 @@ abf_policy_delete (u32 policy_id, const fib_route_path_t * rpaths)
|
||||
*/
|
||||
return (VNET_API_ERROR_INVALID_VALUE);
|
||||
}
|
||||
else
|
||||
|
||||
/*
|
||||
* 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 = abf_policy_get (api);
|
||||
old_pl = ap->ap_pl;
|
||||
|
||||
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);
|
||||
|
||||
fib_path_list_child_remove (old_pl, ap->ap_sibling);
|
||||
ap->ap_sibling = ~0;
|
||||
|
||||
if (FIB_NODE_INDEX_INVALID == 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
|
||||
* no more paths on this policy. It's toast
|
||||
* remove the CLI/API's lock
|
||||
*/
|
||||
fib_node_index_t old_pl;
|
||||
|
||||
ap = abf_policy_get (api);
|
||||
old_pl = ap->ap_pl;
|
||||
|
||||
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);
|
||||
|
||||
fib_path_list_child_remove (old_pl, ap->ap_sibling);
|
||||
ap->ap_sibling = ~0;
|
||||
|
||||
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_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);
|
||||
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_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);
|
||||
}
|
||||
@ -272,14 +267,25 @@ abf_policy_cmd (vlib_main_t * vm,
|
||||
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)
|
||||
@ -287,7 +293,7 @@ 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;
|
||||
}
|
||||
|
||||
rv = abf_policy_update (policy_id, acl_index, rpaths);
|
||||
@ -296,7 +302,7 @@ abf_policy_cmd (vlib_main_t * vm,
|
||||
{
|
||||
vlib_cli_output (vm,
|
||||
"ACL index must match existing ACL index in policy");
|
||||
return 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -304,6 +310,7 @@ abf_policy_cmd (vlib_main_t * vm,
|
||||
abf_policy_delete (policy_id, rpaths);
|
||||
}
|
||||
|
||||
out:
|
||||
unformat_free (line_input);
|
||||
return (NULL);
|
||||
}
|
||||
|
Reference in New Issue
Block a user