diff options
Diffstat (limited to 'src/plugins/acl/acl.c')
-rw-r--r-- | src/plugins/acl/acl.c | 121 |
1 files changed, 79 insertions, 42 deletions
diff --git a/src/plugins/acl/acl.c b/src/plugins/acl/acl.c index 24536eb84b7..e52e82fcf28 100644 --- a/src/plugins/acl/acl.c +++ b/src/plugins/acl/acl.c @@ -36,7 +36,6 @@ #include <acl/acl.api_enum.h> #include <acl/acl.api_types.h> -#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) #include "fa_node.h" #include "public_inlines.h" @@ -53,12 +52,10 @@ acl_main_t acl_main; #include <vppinfra/bihash_template.h> #include <vppinfra/bihash_template.c> -/* *INDENT-OFF* */ VLIB_PLUGIN_REGISTER () = { .version = VPP_BUILD_VER, .description = "Access Control Lists (ACL)", }; -/* *INDENT-ON* */ /* methods exported from ACL-as-a-service */ static acl_plugin_methods_t acl_plugin; @@ -110,12 +107,10 @@ vl_api_acl_plugin_control_ping_t_handler (vl_api_acl_plugin_control_ping_t * acl_main_t *am = &acl_main; int rv = 0; - /* *INDENT-OFF* */ REPLY_MACRO2 (VL_API_ACL_PLUGIN_CONTROL_PING_REPLY, ({ rmp->vpe_pid = ntohl (getpid ()); })); - /* *INDENT-ON* */ } static void @@ -310,7 +305,9 @@ static int acl_api_invalid_prefix (const vl_api_prefix_t * prefix) { ip_prefix_t ip_prefix; - return ip_prefix_decode2 (prefix, &ip_prefix); + int valid_af = + prefix->address.af == ADDRESS_IP4 || prefix->address.af == ADDRESS_IP6; + return (!valid_af) || ip_prefix_decode2 (prefix, &ip_prefix); } static int @@ -339,6 +336,8 @@ acl_add_list (u32 count, vl_api_acl_rule_t rules[], return VNET_API_ERROR_INVALID_SRC_ADDRESS; if (acl_api_invalid_prefix (&rules[i].dst_prefix)) return VNET_API_ERROR_INVALID_DST_ADDRESS; + if (rules[i].src_prefix.address.af != rules[i].dst_prefix.address.af) + return VNET_API_ERROR_INVALID_SRC_ADDRESS; if (ntohs (rules[i].srcport_or_icmptype_first) > ntohs (rules[i].srcport_or_icmptype_last)) return VNET_API_ERROR_INVALID_VALUE_2; @@ -684,7 +683,6 @@ acl_interface_set_inout_acl_list (acl_main_t * am, u32 sw_if_index, format_bitmap_hex, old_seen_acl_bitmap, format_bitmap_hex, seen_acl_bitmap, format_bitmap_hex, change_acl_bitmap); -/* *INDENT-OFF* */ clib_bitmap_foreach (acln, change_acl_bitmap) { if (clib_bitmap_get(old_seen_acl_bitmap, acln)) { /* ACL is being removed. */ @@ -698,7 +696,6 @@ acl_interface_set_inout_acl_list (acl_main_t * am, u32 sw_if_index, vec_add1((*pinout_sw_if_index_vec_by_acl)[acln], sw_if_index); } } -/* *INDENT-ON* */ vec_free ((*pinout_acl_vec_by_sw_if_index)[sw_if_index]); (*pinout_acl_vec_by_sw_if_index)[sw_if_index] = @@ -1807,12 +1804,10 @@ vl_api_acl_add_replace_t_handler (vl_api_acl_add_replace_t * mp) rv = VNET_API_ERROR_INVALID_VALUE; } - /* *INDENT-OFF* */ REPLY_MACRO2(VL_API_ACL_ADD_REPLACE_REPLY, ({ rmp->acl_index = htonl(acl_list_index); })); - /* *INDENT-ON* */ } static void @@ -1974,13 +1969,11 @@ vl_api_acl_dump_t_handler (vl_api_acl_dump_t * mp) if (mp->acl_index == ~0) { - /* *INDENT-OFF* */ /* Just dump all ACLs */ pool_foreach (acl, am->acls) { send_acl_details(am, reg, acl, mp->context); } - /* *INDENT-ON* */ } else { @@ -2060,12 +2053,10 @@ vl_api_acl_interface_list_dump_t_handler (vl_api_acl_interface_list_dump_t * if (mp->sw_if_index == ~0) { - /* *INDENT-OFF* */ pool_foreach (swif, im->sw_interfaces) { send_acl_interface_list_details(am, reg, swif->sw_if_index, mp->context); } - /* *INDENT-ON* */ } else { @@ -2096,12 +2087,10 @@ vl_api_macip_acl_add_t_handler (vl_api_macip_acl_add_t * mp) rv = VNET_API_ERROR_INVALID_VALUE; } - /* *INDENT-OFF* */ REPLY_MACRO2(VL_API_MACIP_ACL_ADD_REPLY, ({ rmp->acl_index = htonl(acl_list_index); })); - /* *INDENT-ON* */ } static void @@ -2123,12 +2112,10 @@ vl_api_macip_acl_add_replace_t_handler (vl_api_macip_acl_add_replace_t * mp) rv = VNET_API_ERROR_INVALID_VALUE; } - /* *INDENT-OFF* */ REPLY_MACRO2(VL_API_MACIP_ACL_ADD_REPLACE_REPLY, ({ rmp->acl_index = htonl(acl_list_index); })); - /* *INDENT-ON* */ } static void @@ -2225,12 +2212,10 @@ vl_api_macip_acl_dump_t_handler (vl_api_macip_acl_dump_t * mp) if (mp->acl_index == ~0) { /* Just dump all ACLs for now, with sw_if_index = ~0 */ - /* *INDENT-OFF* */ pool_foreach (acl, am->macip_acls) { send_macip_acl_details (am, reg, acl, mp->context); } - /* *INDENT-ON* */ } else { @@ -2434,12 +2419,10 @@ static void if (mp->sw_if_index == ~0) { - /* *INDENT-OFF* */ pool_foreach (swif, im->sw_interfaces) { send_acl_interface_etype_whitelist_details(am, reg, swif->sw_if_index, mp->context); } - /* *INDENT-ON* */ } else { @@ -2841,6 +2824,7 @@ acl_set_aclplugin_interface_fn (vlib_main_t * vm, break; } + unformat_free (line_input); if (~0 == sw_if_index) return (clib_error_return (0, "invalid interface")); if (~0 == acl_index) @@ -2848,7 +2832,6 @@ acl_set_aclplugin_interface_fn (vlib_main_t * vm, acl_interface_add_del_inout_acl (sw_if_index, is_add, is_input, acl_index); - unformat_free (line_input); return (NULL); } @@ -2871,6 +2854,7 @@ acl_set_aclplugin_acl_fn (vlib_main_t * vm, int rv; int rule_idx = 0; int n_rules_override = -1; + u32 acl_index = ~0; u32 proto = 0; u32 port1 = 0; u32 port2 = 0; @@ -2884,7 +2868,13 @@ acl_set_aclplugin_acl_fn (vlib_main_t * vm, while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { - if (unformat (line_input, "permit+reflect")) + if (unformat (line_input, "index %d", &acl_index)) + { + /* operate on this acl index (which must exist), + * If not specified, or set to -1, create a new ACL + */ + } + else if (unformat (line_input, "permit+reflect")) { vec_validate_acl_rules (rules, rule_idx); rules[rule_idx].is_permit = 2; @@ -2972,7 +2962,6 @@ acl_set_aclplugin_acl_fn (vlib_main_t * vm, break; } - u32 acl_index = ~0; if (!tag) vec_add (tag, "cli", 4); @@ -2981,6 +2970,7 @@ acl_set_aclplugin_acl_fn (vlib_main_t * vm, vec_free (rules); vec_free (tag); + unformat_free (line_input); if (rv) return (clib_error_return (0, "failed")); @@ -2990,6 +2980,37 @@ acl_set_aclplugin_acl_fn (vlib_main_t * vm, } static clib_error_t * +acl_delete_aclplugin_acl_fn (vlib_main_t *vm, unformat_input_t *input, + vlib_cli_command_t *cmd) +{ + unformat_input_t _line_input, *line_input = &_line_input; + int rv; + u32 acl_index = ~0; + + if (!unformat_user (input, unformat_line_input, line_input)) + return 0; + + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "index %d", &acl_index)) + { + /* operate on this acl index (which must exist) */ + } + else + break; + } + + rv = acl_del_list (acl_index); + + unformat_free (line_input); + if (rv) + return (clib_error_return (0, "failed")); + + vlib_cli_output (vm, "Deleted ACL index:%d", acl_index); + return (NULL); +} + +static clib_error_t * acl_show_aclplugin_macip_acl_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) @@ -3309,7 +3330,6 @@ acl_plugin_show_sessions (acl_main_t * am, vlib_cli_output (vm, " link list id: %u", sess->link_list_id); } vlib_cli_output (vm, " connection add/del stats:", wk); - /* *INDENT-OFF* */ pool_foreach (swif, im->sw_interfaces) { u32 sw_if_index = swif->sw_if_index; @@ -3334,7 +3354,6 @@ acl_plugin_show_sessions (acl_main_t * am, n_dels, n_epoch_changes); } - /* *INDENT-ON* */ vlib_cli_output (vm, " connection timeout type lists:", wk); u8 tt = 0; @@ -3496,7 +3515,6 @@ acl_clear_aclplugin_fn (vlib_main_t * vm, return error; } - /* *INDENT-OFF* */ VLIB_CLI_COMMAND (aclplugin_set_command, static) = { .path = "set acl-plugin", .short_help = "set acl-plugin session timeout {{udp idle}|tcp {idle|transient}} <seconds>", @@ -3586,26 +3604,45 @@ VLIB_CLI_COMMAND (aclplugin_set_interface_command, static) = { /*? * Create an Access Control List (ACL) - * an ACL is composed of more than one Access control element (ACE). Multiple + * If index is not specified, a new one will be created. Otherwise, replace + * the one at this index. + * + * An ACL is composed of more than one Access control element (ACE). Multiple * ACEs can be specified with this command using a comma separated list. * - * Each ACE describes a tuple of src+dst IP prefix, ip protocol, src+dst port ranges. - * (the ACL plugin also support ICMP types/codes instead of UDP/TCP ports, but - * this CLI does not). + * Each ACE describes a tuple of src+dst IP prefix, ip protocol, src+dst port + * ranges. (the ACL plugin also support ICMP types/codes instead of UDP/TCP + * ports, but this CLI does not). * - * An ACL can optionally be assigned a 'tag' - which is an identifier understood - * by the client. VPP does not examine it in any way. + * An ACL can optionally be assigned a 'tag' - which is an identifier + * understood by the client. VPP does not examine it in any way. * - * @cliexpar - * <b><em> set acl-plugin acl <permit|deny> src <PREFIX> dst <PREFIX> proto <TCP|UDP> sport <X-Y> dport <X-Y> [tag FOO] </b></em> - * @cliexend + * @cliexcmd{set acl-plugin acl <permit|deny|permit+reflect> src <PREFIX> dst + * <PREFIX> proto <TCP|UDP> sport <X-Y> dport <X-Y> tcpflags <X> mask <X> + * [tag FOO]} ?*/ VLIB_CLI_COMMAND (aclplugin_set_acl_command, static) = { - .path = "set acl-plugin acl", - .short_help = "set acl-plugin acl <permit|deny> src <PREFIX> dst <PREFIX> proto X sport X-Y dport X-Y [tag FOO] {use comma separated list for multiple rules}", - .function = acl_set_aclplugin_acl_fn, + .path = "set acl-plugin acl", + .short_help = + "set acl-plugin acl [index <idx>] <permit|deny|permit+reflect> src " + "<PREFIX> dst <PREFIX> [proto X] [sport X[-Y]] [dport X[-Y]] [tcpflags " + "<int> mask <int>] [tag FOO] {use comma separated list for multiple " + "rules}", + .function = acl_set_aclplugin_acl_fn, +}; + +/*? + * Delete an Access Control List (ACL) + * Removes an ACL at the specified index, which must exist but not in use by + * any interface. + * + * @cliexcmd{delete acl-plugin acl index <idx>} + ?*/ +VLIB_CLI_COMMAND (aclplugin_delete_acl_command, static) = { + .path = "delete acl-plugin acl", + .short_help = "delete acl-plugin acl index <idx>", + .function = acl_delete_aclplugin_acl_fn, }; -/* *INDENT-ON* */ static clib_error_t * acl_plugin_config (vlib_main_t * vm, unformat_input_t * input) @@ -3737,7 +3774,7 @@ acl_init (vlib_main_t * vm) vec_validate (pw->expired, ACL_N_TIMEOUTS * am->fa_max_deleted_sessions_per_interval); - _vec_len (pw->expired) = 0; + vec_set_len (pw->expired, 0); vec_validate_init_empty (pw->fa_conn_list_head, ACL_N_TIMEOUTS - 1, FA_SESSION_BOGUS_INDEX); vec_validate_init_empty (pw->fa_conn_list_tail, ACL_N_TIMEOUTS - 1, |