X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Facl%2Facl.c;h=064741c32be946bc08bb984cb738b51fb5ab70a7;hb=9a8d12d9b317379cfff56fd415a5f7a13bb58453;hp=b18e8515cde5026e964b80a8349331f31c459ff6;hpb=df87f8092f5b6b54eef0d5acf3c27c2e398a401a;p=vpp.git diff --git a/src/plugins/acl/acl.c b/src/plugins/acl/acl.c index b18e8515cde..064741c32be 100644 --- a/src/plugins/acl/acl.c +++ b/src/plugins/acl/acl.c @@ -36,7 +36,6 @@ #include #include -#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) #include "fa_node.h" #include "public_inlines.h" @@ -216,7 +215,8 @@ static void ntohs (VL_API_ACL_PLUGIN_GET_CONN_TABLE_MAX_ENTRIES_REPLY + am->msg_id_base); rmp->context = mp->context; - rmp->conn_table_max_entries = __bswap_64 (am->fa_conn_table_max_entries); + rmp->conn_table_max_entries = + clib_net_to_host_u64 (am->fa_conn_table_max_entries); vl_api_send_msg (rp, (u8 *) rmp); } @@ -309,7 +309,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 @@ -320,8 +322,13 @@ acl_add_list (u32 count, vl_api_acl_rule_t rules[], acl_list_t *a; acl_rule_t *r; acl_rule_t *acl_new_rules = 0; + size_t tag_len; int i; + tag_len = clib_strnlen ((const char *) tag, sizeof (a->tag)); + if (tag_len == sizeof (a->tag)) + return VNET_API_ERROR_INVALID_VALUE; + if (am->trace_acl > 255) clib_warning ("API dbg: acl_add_list index %d tag %s", *acl_list_index, tag); @@ -333,6 +340,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; @@ -399,7 +408,7 @@ acl_add_list (u32 count, vl_api_acl_rule_t rules[], vec_free (a->rules); } a->rules = acl_new_rules; - memcpy (a->tag, tag, sizeof (a->tag)); + memcpy (a->tag, tag, tag_len + 1); if (am->trace_acl > 255) warning_acl_print_acl (am->vlib_main, am, *acl_list_index); if (am->reclassify_sessions) @@ -679,7 +688,7 @@ acl_interface_set_inout_acl_list (acl_main_t * am, u32 sw_if_index, seen_acl_bitmap, format_bitmap_hex, change_acl_bitmap); /* *INDENT-OFF* */ - clib_bitmap_foreach(acln, change_acl_bitmap, ({ + clib_bitmap_foreach (acln, change_acl_bitmap) { if (clib_bitmap_get(old_seen_acl_bitmap, acln)) { /* ACL is being removed. */ if (acln < vec_len((*pinout_sw_if_index_vec_by_acl))) { @@ -691,7 +700,7 @@ acl_interface_set_inout_acl_list (acl_main_t * am, u32 sw_if_index, vec_validate((*pinout_sw_if_index_vec_by_acl), acln); 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]); @@ -1548,9 +1557,14 @@ macip_acl_add_list (u32 count, vl_api_macip_acl_rule_t rules[], macip_acl_list_t *a; macip_acl_rule_t *r; macip_acl_rule_t *acl_new_rules = 0; + size_t tag_len; int i; int rv = 0; + tag_len = clib_strnlen ((const char *) tag, sizeof (a->tag)); + if (tag_len == sizeof (a->tag)) + return VNET_API_ERROR_INVALID_VALUE; + if (*acl_list_index != ~0) { /* They supplied some number, let's see if this MACIP ACL exists */ @@ -1609,7 +1623,7 @@ macip_acl_add_list (u32 count, vl_api_macip_acl_rule_t rules[], a->rules = acl_new_rules; a->count = count; - memcpy (a->tag, tag, sizeof (a->tag)); + memcpy (a->tag, tag, tag_len + 1); /* Create and populate the classifier tables */ macip_create_classify_tables (am, *acl_list_index); @@ -1761,7 +1775,7 @@ macip_acl_interface_add_del_acl (u32 sw_if_index, u8 is_add, * */ static int -verify_message_len (void *mp, u32 expected_len, char *where) +verify_message_len (void *mp, u64 expected_len, char *where) { u32 supplied_len = vl_msg_api_get_msg_length (mp); if (supplied_len < expected_len) @@ -1785,7 +1799,7 @@ vl_api_acl_add_replace_t_handler (vl_api_acl_add_replace_t * mp) int rv; u32 acl_list_index = ntohl (mp->acl_index); u32 acl_count = ntohl (mp->count); - u32 expected_len = sizeof (*mp) + acl_count * sizeof (mp->r[0]); + u64 expected_len = sizeof (*mp) + acl_count * sizeof (mp->r[0]); if (verify_message_len (mp, expected_len, "acl_add_replace")) { @@ -1936,7 +1950,7 @@ send_acl_details (acl_main_t * am, vl_api_registration_t * reg, mp->context = context; mp->count = htonl (vec_len (acl_rules)); mp->acl_index = htonl (acl - am->acls); - memcpy (mp->tag, acl->tag, sizeof (mp->tag)); + snprintf ((char *) mp->tag, sizeof (mp->tag), "%s", acl->tag); // clib_memcpy (mp->r, acl->rules, acl->count * sizeof(acl->rules[0])); rules = mp->r; for (i = 0; i < vec_len (acl_rules); i++) @@ -1965,10 +1979,10 @@ vl_api_acl_dump_t_handler (vl_api_acl_dump_t * mp) { /* *INDENT-OFF* */ /* Just dump all ACLs */ - pool_foreach (acl, am->acls, - ({ + pool_foreach (acl, am->acls) + { send_acl_details(am, reg, acl, mp->context); - })); + } /* *INDENT-ON* */ } else @@ -2050,10 +2064,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, - ({ + pool_foreach (swif, im->sw_interfaces) + { send_acl_interface_list_details(am, reg, swif->sw_if_index, mp->context); - })); + } /* *INDENT-ON* */ } else @@ -2074,7 +2088,7 @@ vl_api_macip_acl_add_t_handler (vl_api_macip_acl_add_t * mp) int rv; u32 acl_list_index = ~0; u32 acl_count = ntohl (mp->count); - u32 expected_len = sizeof (*mp) + acl_count * sizeof (mp->r[0]); + u64 expected_len = sizeof (*mp) + acl_count * sizeof (mp->r[0]); if (verify_message_len (mp, expected_len, "macip_acl_add")) { @@ -2101,7 +2115,7 @@ vl_api_macip_acl_add_replace_t_handler (vl_api_macip_acl_add_replace_t * mp) int rv; u32 acl_list_index = ntohl (mp->acl_index); u32 acl_count = ntohl (mp->count); - u32 expected_len = sizeof (*mp) + acl_count * sizeof (mp->r[0]); + u64 expected_len = sizeof (*mp) + acl_count * sizeof (mp->r[0]); if (verify_message_len (mp, expected_len, "macip_acl_add_replace")) { @@ -2170,7 +2184,7 @@ send_macip_acl_details (acl_main_t * am, vl_api_registration_t * reg, mp->context = context; if (acl) { - memcpy (mp->tag, acl->tag, sizeof (mp->tag)); + snprintf ((char *) mp->tag, sizeof (mp->tag), "%s", acl->tag); mp->count = htonl (acl->count); mp->acl_index = htonl (acl - am->macip_acls); rules = mp->r; @@ -2215,10 +2229,10 @@ vl_api_macip_acl_dump_t_handler (vl_api_macip_acl_dump_t * mp) { /* Just dump all ACLs for now, with sw_if_index = ~0 */ /* *INDENT-OFF* */ - pool_foreach (acl, am->macip_acls, - ({ + pool_foreach (acl, am->macip_acls) + { send_macip_acl_details (am, reg, acl, mp->context); - })); + } /* *INDENT-ON* */ } else @@ -2424,10 +2438,10 @@ static void if (mp->sw_if_index == ~0) { /* *INDENT-OFF* */ - pool_foreach (swif, im->sw_interfaces, - ({ + pool_foreach (swif, im->sw_interfaces) + { send_acl_interface_etype_whitelist_details(am, reg, swif->sw_if_index, mp->context); - })); + } /* *INDENT-ON* */ } else @@ -2439,6 +2453,45 @@ static void } } +static void +vl_api_acl_plugin_use_hash_lookup_set_t_handler ( + vl_api_acl_plugin_use_hash_lookup_set_t *mp) +{ + acl_main_t *am = &acl_main; + vl_api_acl_plugin_use_hash_lookup_set_reply_t *rmp; + vl_api_registration_t *reg; + int rv = 0; + + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) + return; + + am->use_hash_acl_matching = mp->enable; + REPLY_MACRO (VL_API_ACL_PLUGIN_USE_HASH_LOOKUP_SET_REPLY); +} + +static void +vl_api_acl_plugin_use_hash_lookup_get_t_handler ( + vl_api_acl_plugin_use_hash_lookup_get_t *mp) +{ + acl_main_t *am = &acl_main; + vl_api_acl_plugin_use_hash_lookup_get_reply_t *rmp; + int msg_size = sizeof (*rmp); + vl_api_registration_t *reg; + + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) + return; + + rmp = vl_msg_api_alloc (msg_size); + clib_memset (rmp, 0, msg_size); + rmp->_vl_msg_id = + ntohs (VL_API_ACL_PLUGIN_USE_HASH_LOOKUP_GET_REPLY + am->msg_id_base); + rmp->context = mp->context; + rmp->enable = am->use_hash_acl_matching; + vl_api_send_msg (reg, (u8 *) rmp); +} + static void acl_set_timeout_sec (int timeout_type, u32 value) { @@ -2791,6 +2844,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) @@ -2798,7 +2852,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); } @@ -2826,9 +2879,8 @@ acl_set_aclplugin_acl_fn (vlib_main_t * vm, u32 port2 = 0; u32 action = 0; u32 tcpflags, tcpmask; - u32 src_prefix_length = 0, dst_prefix_length = 0; - ip46_address_t src, dst; - u8 *tag = (u8 *) "cli"; + ip_prefix_t src, dst; + u8 *tag = 0; if (!unformat_user (input, unformat_line_input, line_input)) return 0; @@ -2859,25 +2911,15 @@ acl_set_aclplugin_acl_fn (vlib_main_t * vm, vec_validate_acl_rules (rules, rule_idx); rules[rule_idx].is_permit = action; } - else if (unformat (line_input, "src %U/%d", - unformat_ip46_address, &src, IP46_TYPE_ANY, - &src_prefix_length)) + else if (unformat (line_input, "src %U", unformat_ip_prefix, &src)) { vec_validate_acl_rules (rules, rule_idx); - ip_address_encode (&src, IP46_TYPE_ANY, - &rules[rule_idx].src_prefix.address); - rules[rule_idx].src_prefix.address.af = ADDRESS_IP4; - rules[rule_idx].src_prefix.len = src_prefix_length; + ip_prefix_encode2 (&src, &rules[rule_idx].src_prefix); } - else if (unformat (line_input, "dst %U/%d", - unformat_ip46_address, &dst, IP46_TYPE_ANY, - &dst_prefix_length)) + else if (unformat (line_input, "dst %U", unformat_ip_prefix, &dst)) { vec_validate_acl_rules (rules, rule_idx); - ip_address_encode (&dst, IP46_TYPE_ANY, - &rules[rule_idx].dst_prefix.address); - rules[rule_idx].dst_prefix.address.af = ADDRESS_IP4; - rules[rule_idx].dst_prefix.len = dst_prefix_length; + ip_prefix_encode2 (&dst, &rules[rule_idx].dst_prefix); } else if (unformat (line_input, "sport %d-%d", &port1, &port2)) { @@ -2934,11 +2976,15 @@ acl_set_aclplugin_acl_fn (vlib_main_t * vm, } u32 acl_index = ~0; + if (!tag) + vec_add (tag, "cli", 4); rv = acl_add_list (vec_len (rules), rules, &acl_index, tag); vec_free (rules); + vec_free (tag); + unformat_free (line_input); if (rv) return (clib_error_return (0, "failed")); @@ -3268,8 +3314,8 @@ acl_plugin_show_sessions (acl_main_t * am, } vlib_cli_output (vm, " connection add/del stats:", wk); /* *INDENT-OFF* */ - pool_foreach (swif, im->sw_interfaces, - ({ + pool_foreach (swif, im->sw_interfaces) + { u32 sw_if_index = swif->sw_if_index; u64 n_adds = (sw_if_index < vec_len (pw->fa_session_adds_by_sw_if_index) ? @@ -3291,7 +3337,7 @@ acl_plugin_show_sessions (acl_main_t * am, n_adds - n_dels, n_epoch_changes); - })); + } /* *INDENT-ON* */ vlib_cli_output (vm, " connection timeout type lists:", wk); @@ -3429,6 +3475,8 @@ acl_show_aclplugin_tables_fn (vlib_main_t * vm, } vlib_cli_output (vm, "Stats counters enabled for interface ACLs: %d", acl_main.interface_acl_counters_enabled); + vlib_cli_output (vm, "Use hash-based lookup for ACLs: %d", + acl_main.use_hash_acl_matching); if (show_mask_type) acl_plugin_show_tables_mask_type (); if (show_acl_hash_info) @@ -3545,16 +3593,15 @@ VLIB_CLI_COMMAND (aclplugin_set_interface_command, static) = { * 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 - * set acl-plugin acl src dst proto sport dport [tag FOO] - * @cliexend + * @cliexcmd{set acl-plugin acl src dst proto + * sport dport [tag FOO]} ?*/ VLIB_CLI_COMMAND (aclplugin_set_acl_command, static) = { .path = "set acl-plugin acl", @@ -3693,7 +3740,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,