25 #include <vpp/app/version.h>
36 #include <acl/acl.api_enum.h>
37 #include <acl/acl.api_types.h>
39 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
46 #define REPLY_MSG_ID_BASE am->msg_id_base
58 .version = VPP_BUILD_VER,
59 .description =
"Access Control Lists (ACL)",
70 u16 *v = va_arg (*va,
u16 *);
71 char *
fmt = va_arg (*va,
char *);
87 int msg_size =
sizeof (*rmp);
97 ntohs (VL_API_ACL_PLUGIN_GET_VERSION_REPLY +
am->msg_id_base);
116 rmp->
vpe_pid = ntohl (getpid ());
149 s =
format (s,
"permit+reflect");
167 for (j = 0; j <
vec_len (acl_rules); j++)
170 out0 =
format (out0,
" %9d: %s ", j,
r->is_ipv6 ?
"ipv6" :
"ipv4");
178 out0 =
format (out0,
" proto %d",
r->proto);
179 out0 =
format (out0,
" sport %d",
r->src_port_or_type_first);
180 if (
r->src_port_or_type_first !=
r->src_port_or_type_last)
182 out0 =
format (out0,
"-%d",
r->src_port_or_type_last);
184 out0 =
format (out0,
" dport %d",
r->dst_port_or_code_first);
185 if (
r->dst_port_or_code_first !=
r->dst_port_or_code_last)
187 out0 =
format (out0,
"-%d",
r->dst_port_or_code_last);
189 if (
r->tcp_flags_mask ||
r->tcp_flags_value)
192 format (out0,
" tcpflags %d mask %d",
r->tcp_flags_value,
195 out0 =
format (out0,
"\n");
206 int msg_size =
sizeof (*rmp);
214 memset (rmp, 0, msg_size);
216 ntohs (VL_API_ACL_PLUGIN_GET_CONN_TABLE_MAX_ENTRIES_REPLY +
220 clib_net_to_host_u64 (
am->fa_conn_table_max_entries);
241 u32 **ppolicy_epoch_by_swi =
242 is_input ? &
am->input_policy_epoch_by_sw_if_index :
243 &
am->output_policy_epoch_by_sw_if_index;
255 u32 ***p_swi_vec_by_acl = is_input ? &
am->input_sw_if_index_vec_by_acl
256 : &
am->output_sw_if_index_vec_by_acl;
257 if (acl_num <
vec_len (*p_swi_vec_by_acl))
283 int old_len =
vec_len (
am->combined_acl_counters);
287 for (
i = old_len;
i <
vec_len (
am->combined_acl_counters);
i++)
289 am->combined_acl_counters[
i].name = 0;
291 am->combined_acl_counters[
i].stat_segment_name = (
void *)
292 format (0,
"/acl/%d/matches%c",
i, 0);
318 u32 * acl_list_index,
u8 * tag)
327 tag_len =
clib_strnlen ((
const char *) tag,
sizeof (
a->tag));
328 if (tag_len ==
sizeof (
a->tag))
329 return VNET_API_ERROR_INVALID_VALUE;
331 if (
am->trace_acl > 255)
332 clib_warning (
"API dbg: acl_add_list index %d tag %s", *acl_list_index,
339 return VNET_API_ERROR_INVALID_SRC_ADDRESS;
341 return VNET_API_ERROR_INVALID_DST_ADDRESS;
344 return VNET_API_ERROR_INVALID_VALUE_2;
347 return VNET_API_ERROR_INVALID_VALUE_2;
350 if (*acl_list_index != ~0)
357 (
"acl-plugin-error: Trying to replace nonexistent ACL %d (tag %s)",
358 *acl_list_index, tag);
359 return VNET_API_ERROR_NO_SUCH_ENTRY;
365 (
"acl-plugin-warning: supplied no rules for ACL %d (tag %s)",
366 *acl_list_index, tag);
377 r->is_permit =
rules[
i].is_permit;
378 r->is_ipv6 =
rules[
i].src_prefix.address.af;
381 r->src_prefixlen =
rules[
i].src_prefix.len;
382 r->dst_prefixlen =
rules[
i].dst_prefix.len;
388 r->tcp_flags_value =
rules[
i].tcp_flags_value;
389 r->tcp_flags_mask =
rules[
i].tcp_flags_mask;
392 if (~0 == *acl_list_index)
398 *acl_list_index =
a -
am->acls;
402 a =
am->acls + *acl_list_index;
407 a->rules = acl_new_rules;
408 memcpy (
a->tag, tag, tag_len + 1);
409 if (
am->trace_acl > 255)
411 if (
am->reclassify_sessions)
442 return VNET_API_ERROR_NO_SUCH_ENTRY;
445 return VNET_API_ERROR_ACL_IN_USE_INBOUND;
447 return VNET_API_ERROR_ACL_IN_USE_OUTBOUND;
450 return VNET_API_ERROR_ACL_IN_USE_BY_LOOKUP_CONTEXT;
470 while ((0ULL == *p64) && ((
u8 *) p64 - p) <
size)
474 return (p64 - (
u64 *) p) / 2;
479 u32 mask_len,
u32 next_table_index,
480 u32 miss_next_index,
u32 * table_index,
486 u32 match = (mask_len / 16) - skip;
487 u8 *skip_mask_ptr =
mask + 16 * skip;
488 u32 current_data_flag = 0;
489 int current_data_offset = 0;
496 next_table_index, miss_next_index,
497 table_index, current_data_flag,
498 current_data_offset, is_add,
507 ?
am->input_etype_whitelist_by_sw_if_index
508 :
am->output_etype_whitelist_by_sw_if_index;
510 return vec_len (whitelist) > 0;
531 return VNET_API_ERROR_INVALID_SW_IF_INDEX;
551 enable_disable, 0, 0);
552 am->in_acl_on_sw_if_index =
567 return VNET_API_ERROR_INVALID_SW_IF_INDEX;
588 enable_disable, 0, 0);
589 am->out_acl_on_sw_if_index =
600 am->interface_acl_counters_enabled = enable_disable;
607 int is_input,
int enable_disable)
623 u8 is_input,
u32 * vec_acl_list_index,
624 int *may_clear_sessions)
627 uword *seen_acl_bitmap = 0;
628 uword *old_seen_acl_bitmap = 0;
629 uword *change_acl_bitmap = 0;
634 if (
am->trace_acl > 255)
636 (
"API dbg: acl_interface_set_inout_acl_list: sw_if_index %d is_input %d acl_vec: [%U]",
645 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
651 clib_warning (
"ERROR: ACL %d being applied twice", *pacln);
652 rv = VNET_API_ERROR_ENTRY_ALREADY_EXISTS;
659 u32 **pinout_lc_index_by_sw_if_index =
660 is_input ? &
am->input_lc_index_by_sw_if_index : &
am->
661 output_lc_index_by_sw_if_index;
663 u32 ***pinout_acl_vec_by_sw_if_index =
664 is_input ? &
am->input_acl_vec_by_sw_if_index : &
am->
665 output_acl_vec_by_sw_if_index;
667 u32 ***pinout_sw_if_index_vec_by_acl =
668 is_input ? &
am->input_sw_if_index_vec_by_acl : &
am->
669 output_sw_if_index_vec_by_acl;
677 old_seen_acl_bitmap =
clib_bitmap_set (old_seen_acl_bitmap, *pacln, 1);
682 if (
am->trace_acl > 255)
683 clib_warning (
"bitmaps: old seen %U new seen %U changed %U",
691 if (acln <
vec_len((*pinout_sw_if_index_vec_by_acl))) {
707 if (
am->reclassify_sessions)
715 if (may_clear_sessions && *may_clear_sessions
719 *may_clear_sessions = 0;
728 if (
vec_len (vec_acl_list_index) > 0)
734 acl_plugin.get_lookup_context_index (
am->interface_acl_user_id,
736 (*pinout_lc_index_by_sw_if_index)[
sw_if_index] = lc_index;
738 acl_plugin.set_acl_vec_for_context (lc_index, vec_acl_list_index);
742 if (~0 != (*pinout_lc_index_by_sw_if_index)[
sw_if_index])
745 put_lookup_context_index ((*pinout_lc_index_by_sw_if_index)
747 (*pinout_lc_index_by_sw_if_index)[
sw_if_index] = ~0;
752 vec_len (vec_acl_list_index) > 0);
763 int *may_clear_sessions)
777 int may_clear_sessions = 1;
779 int error_already_applied = is_input ? VNET_API_ERROR_ACL_IN_USE_INBOUND
780 : VNET_API_ERROR_ACL_IN_USE_OUTBOUND;
782 u32 ***pinout_acl_vec_by_sw_if_index =
783 is_input ? &
am->input_acl_vec_by_sw_if_index : &
am->
784 output_acl_vec_by_sw_if_index;
794 rv = error_already_applied;
805 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
814 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
823 &may_clear_sessions);
839 am->input_etype_whitelist_by_sw_if_index[
sw_if_index] = vec_in;
840 am->output_etype_whitelist_by_sw_if_index[
sw_if_index] = vec_out;
898 if ((
mv[
i].prefix_len == prefix_len) && (
mv[
i].is_ipv6 ==
is_ipv6)
899 && (0 == memcmp (
mv[
i].mac_mask, mac_mask, 6)))
914 unsigned int mac_bits_set = 0;
915 unsigned int mac_byte;
917 for (
i = 0;
i < 6;
i++)
920 for (; mac_byte; mac_byte >>= 1)
921 mac_bits_set += mac_byte & 1;
971 return (is_permit == 3);
981 u32 match_type_index;
988 for (
i = 0;
i <
a->count;
i++)
993 a->rules[
i].src_prefixlen,
994 a->rules[
i].is_ipv6)))
996 match_type_index =
vec_len (mvec);
998 memcpy (mvec[match_type_index].mac_mask,
999 a->rules[
i].src_mac_mask, 6);
1000 mvec[match_type_index].
prefix_len =
a->rules[
i].src_prefixlen;
1001 mvec[match_type_index].
is_ipv6 =
a->rules[
i].is_ipv6;
1016 mvec[match_type_index].
count++;
1024 out_last_table = ~0;
1031 u32 *last_tag_table;
1032 u32 *out_last_tag_table;
1064 for (tags = 2; tags >= 0; tags--)
1097 mask[l3_offset + 14 +
i] = 0xff;
1100 0xff - ((1 << (8 - mt->
prefix_len % 8)) - 1);
1102 mask_len = ((l3_offset + 14 + ((mt->
prefix_len + 7) / 8) +
1106 (~0 == last_table) ? 0 : ~0,
1108 last_table = *last_tag_table;
1139 mask_len = ((l3_offset +
1145 out_last_table) ? 0 : ~0,
1146 out_last_tag_table, 1);
1147 out_last_table = *out_last_tag_table;
1160 u32 *last_tag_table;
1161 u32 *out_last_tag_table;
1166 for (tags = 2; tags >= 0; tags--)
1192 mask[l3_src_offs +
i] = 0xff;
1197 0xff - ((1 << (8 - mt->
prefix_len % 8)) - 1);
1203 mask_len = ((l3_src_offs + ((mt->
prefix_len + 7) / 8) +
1206 (~0 == last_table) ? 0 : ~0,
1208 last_table = *last_tag_table;
1212 for (tags = 2; tags >= 0; tags--)
1239 mask[l3_dst_offs +
i] = 0xff;
1244 0xff - ((1 << (8 - mt->
prefix_len % 8)) - 1);
1250 mask_len = ((l3_dst_offs + ((mt->
prefix_len + 7) / 8) +
1255 (~0 == out_last_table) ? 0 : ~0,
1256 out_last_tag_table, 1);
1257 out_last_table = *out_last_tag_table;
1261 a->ip4_table_index = last_table;
1262 a->ip6_table_index = last_table;
1263 a->l2_table_index = last_table;
1265 a->out_ip4_table_index = out_last_table;
1266 a->out_ip6_table_index = out_last_table;
1267 a->out_l2_table_index = out_last_table;
1270 for (
i = 0;
i <
a->count;
i++)
1274 int is6 =
a->rules[
i].is_ipv6;
1282 a->rules[
i].src_prefixlen,
1283 a->rules[
i].is_ipv6);
1284 ASSERT (match_type_index != ~0);
1286 for (tags = 2; tags >= 0; tags--)
1290 memcpy (&
mask[6],
a->rules[
i].src_mac, 6);
1315 memcpy (&
mask[l3_src_offs], &
a->rules[
i].src_ip_addr.ip6, 16);
1317 mask[eth + 1] = 0xdd;
1321 memcpy (&
mask[l3_src_offs], &
a->rules[
i].src_ip_addr.ip4, 4);
1323 mask[eth + 1] = 0x00;
1328 mask,
a->rules[
i].is_permit ? ~0 : 0,
1334 if (!is6 && (mvec[match_type_index].arp_table_index != ~0))
1337 memcpy (&
mask[6],
a->rules[
i].src_mac, 6);
1339 for (tags = 2; tags >= 0; tags--)
1370 memcpy (&
mask[l3_src_offs + 8],
a->rules[
i].src_mac, 6);
1371 memcpy (&
mask[l3_src_offs + 14], &
a->rules[
i].src_ip_addr.ip4,
1374 a->rules[
i].is_permit ? ~0 : 0,
1381 for (tags = 2; tags >= 0; tags--)
1386 memcpy (&
mask[0],
a->rules[
i].src_mac, 6);
1411 memcpy (&
mask[l3_dst_offs], &
a->rules[
i].src_ip_addr.ip6,
1414 mask[eth + 1] = 0xdd;
1418 memcpy (&
mask[l3_dst_offs], &
a->rules[
i].src_ip_addr.ip4,
1421 mask[eth + 1] = 0x00;
1427 a->rules[
i].is_permit ? ~0 : 0,
1433 if (!is6 && (mvec[match_type_index].out_arp_table_index != ~0))
1435 for (tags = 2; tags >= 0; tags--)
1469 is_permit ? ~0 : 0,
i, 0,
1484 if (
a->ip4_table_index != ~0)
1487 &
a->ip4_table_index, 0);
1488 a->ip4_table_index = ~0;
1490 if (
a->ip6_table_index != ~0)
1493 &
a->ip6_table_index, 0);
1494 a->ip6_table_index = ~0;
1496 if (
a->l2_table_index != ~0)
1500 a->l2_table_index = ~0;
1502 if (
a->out_ip4_table_index != ~0)
1505 &
a->out_ip4_table_index, 0);
1506 a->out_ip4_table_index = ~0;
1508 if (
a->out_ip6_table_index != ~0)
1511 &
a->out_ip6_table_index, 0);
1512 a->out_ip6_table_index = ~0;
1514 if (
a->out_l2_table_index != ~0)
1517 &
a->out_l2_table_index, 0);
1518 a->out_l2_table_index = ~0;
1531 for (
i = 0;
i <
vec_len (
am->macip_acl_by_sw_if_index);
i++)
1535 a->ip6_table_index,
a->l2_table_index,
1541 a->out_ip6_table_index,
1542 a->out_l2_table_index, is_apply);
1551 u32 * acl_list_index,
u8 * tag)
1561 tag_len =
clib_strnlen ((
const char *) tag,
sizeof (
a->tag));
1562 if (tag_len ==
sizeof (
a->tag))
1563 return VNET_API_ERROR_INVALID_VALUE;
1565 if (*acl_list_index != ~0)
1572 (
"acl-plugin-error: Trying to replace nonexistent MACIP ACL %d (tag %s)",
1573 *acl_list_index, tag);
1574 return VNET_API_ERROR_NO_SUCH_ENTRY;
1581 (
"acl-plugin-warning: Trying to create empty MACIP ACL (tag %s)",
1585 if (~0 != *acl_list_index)
1593 r = &acl_new_rules[
i];
1594 r->is_permit =
rules[
i].is_permit;
1595 r->is_ipv6 =
rules[
i].src_prefix.address.af;
1600 r->src_prefixlen =
rules[
i].src_prefix.len;
1603 if (~0 == *acl_list_index)
1609 *acl_list_index =
a -
am->macip_acls;
1621 a->rules = acl_new_rules;
1623 memcpy (
a->tag, tag, tag_len + 1);
1644 u32 macip_acl_index;
1649 return VNET_API_ERROR_NO_SUCH_ENTRY;
1651 macip_acl_index =
am->macip_acl_by_sw_if_index[
sw_if_index];
1653 if (~0 == macip_acl_index)
1654 return VNET_API_ERROR_NO_SUCH_ENTRY;
1660 a->ip6_table_index,
a->l2_table_index, 0);
1663 a->out_ip4_table_index,
a->out_ip6_table_index,
1664 a->out_l2_table_index, 0);
1679 u32 macip_acl_index)
1685 return VNET_API_ERROR_NO_SUCH_ENTRY;
1689 vec_validate (
am->sw_if_index_vec_by_macip_acl, macip_acl_index);
1694 am->macip_acl_by_sw_if_index[
sw_if_index] = macip_acl_index;
1699 a->ip6_table_index,
a->l2_table_index, 1);
1702 a->out_ip4_table_index,
a->out_ip6_table_index,
1703 a->out_l2_table_index, 1);
1715 return VNET_API_ERROR_NO_SUCH_ENTRY;
1719 for (
i = 0;
i <
vec_len (
am->macip_acl_by_sw_if_index);
i++)
1721 if (
am->macip_acl_by_sw_if_index[
i] == acl_list_index)
1778 if (supplied_len < expected_len)
1780 clib_warning (
"%s: Supplied message length %d is less than expected %d",
1781 where, supplied_len, expected_len);
1799 u64 expected_len =
sizeof (*mp) + acl_count *
sizeof (mp->
r[0]);
1807 rv = VNET_API_ERROR_INVALID_VALUE;
1822 vl_api_acl_del_reply_t *rmp;
1836 vl_api_acl_stats_intf_counters_enable_reply_t *rmp;
1851 vl_api_acl_interface_add_del_reply_t *rmp;
1855 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
1869 vl_api_acl_interface_set_acl_list_reply_t *rmp;
1876 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
1879 int may_clear_sessions = 1;
1885 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1890 u32 *in_acl_vec = 0;
1891 u32 *out_acl_vec = 0;
1893 if (i < mp->n_input)
1900 &may_clear_sessions);
1904 &may_clear_sessions);
1910 REPLY_MACRO (VL_API_ACL_INTERFACE_SET_ACL_LIST_REPLY);
1916 api_rule->is_permit =
r->is_permit;
1918 &api_rule->src_prefix.address);
1920 &api_rule->dst_prefix.address);
1921 api_rule->src_prefix.len =
r->src_prefixlen;
1922 api_rule->dst_prefix.len =
r->dst_prefixlen;
1923 api_rule->proto =
r->proto;
1924 api_rule->srcport_or_icmptype_first = htons (
r->src_port_or_type_first);
1925 api_rule->srcport_or_icmptype_last = htons (
r->src_port_or_type_last);
1926 api_rule->dstport_or_icmpcode_first = htons (
r->dst_port_or_code_first);
1927 api_rule->dstport_or_icmpcode_last = htons (
r->dst_port_or_code_last);
1928 api_rule->tcp_flags_mask =
r->tcp_flags_mask;
1929 api_rule->tcp_flags_value =
r->tcp_flags_value;
1937 vl_api_acl_rule_t *
rules;
1940 int msg_size =
sizeof (*mp) +
sizeof (mp->
r[0]) *
vec_len (acl_rules);
1944 mp->_vl_msg_id =
ntohs (VL_API_ACL_DETAILS +
am->msg_id_base);
1950 snprintf ((
char *) mp->
tag, sizeof (mp->
tag),
"%s", acl->
tag);
2019 count = n_input + n_output;
2021 msg_size =
sizeof (*mp);
2022 msg_size +=
sizeof (mp->
acls[0]) *
count;
2027 ntohs (VL_API_ACL_INTERFACE_LIST_DETAILS +
am->msg_id_base);
2034 for (
i = 0;
i < n_input;
i++)
2038 for (
i = 0;
i < n_output;
i++)
2040 mp->
acls[n_input +
i] =
2086 u32 acl_list_index = ~0;
2088 u64 expected_len =
sizeof (*mp) + acl_count *
sizeof (mp->
r[0]);
2096 rv = VNET_API_ERROR_INVALID_VALUE;
2115 u64 expected_len =
sizeof (*mp) + acl_count *
sizeof (mp->
r[0]);
2123 rv = VNET_API_ERROR_INVALID_VALUE;
2138 vl_api_macip_acl_del_reply_t *rmp;
2151 vl_api_macip_acl_interface_add_del_reply_t *rmp;
2157 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
2163 REPLY_MACRO (VL_API_MACIP_ACL_INTERFACE_ADD_DEL_REPLY);
2171 vl_api_macip_acl_rule_t *
rules;
2174 int msg_size =
sizeof (*mp) + (acl ?
sizeof (mp->
r[0]) * acl->
count : 0);
2178 mp->_vl_msg_id =
ntohs (VL_API_MACIP_ACL_DETAILS +
am->msg_id_base);
2184 snprintf ((
char *) mp->
tag, sizeof (mp->
tag),
"%s", acl->
tag);
2191 rules[
i].is_permit =
r->is_permit;
2198 &
rules[
i].src_prefix.address);
2199 rules[
i].src_prefix.len =
r->src_prefixlen;
2253 int msg_size =
sizeof (*rmp) +
sizeof (rmp->
acls[0]) *
count;
2264 ntohs (VL_API_MACIP_ACL_INTERFACE_GET_REPLY +
am->msg_id_base);
2269 rmp->
acls[
i] = htonl (
am->macip_acl_by_sw_if_index[
i]);
2283 int msg_size =
sizeof (*rmp) +
sizeof (rmp->
acls[0]);
2288 ntohs (VL_API_MACIP_ACL_INTERFACE_LIST_DETAILS +
am->msg_id_base);
2319 macip_acl_by_sw_if_index
2330 am->macip_acl_by_sw_if_index
2341 vl_api_acl_interface_set_etype_whitelist_reply_t *rmp;
2346 u16 *vec_in = 0, *vec_out = 0;
2349 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
2354 if (i < mp->n_input)
2362 REPLY_MACRO (VL_API_ACL_INTERFACE_SET_ETYPE_WHITELIST_REPLY);
2377 u16 *whitelist_in = 0;
2378 u16 *whitelist_out = 0;
2388 if ((0 == whitelist_in) && (0 == whitelist_out))
2391 n_input =
vec_len (whitelist_in);
2392 n_output =
vec_len (whitelist_out);
2393 count = n_input + n_output;
2395 msg_size =
sizeof (*mp);
2401 ntohs (VL_API_ACL_INTERFACE_ETYPE_WHITELIST_DETAILS +
am->msg_id_base);
2408 for (
i = 0;
i < n_input;
i++)
2412 for (
i = 0;
i < n_output;
i++)
2414 mp->
whitelist[n_input +
i] = htons (whitelist_out[
i]);
2461 am->session_timeout_sec[timeout_type] =
value;
2465 clib_warning (
"Unknown timeout type %d", timeout_type);
2468 am->session_timeout[timeout_type] =
2476 am->fa_conn_table_max_entries =
value;
2484 if ((eh < 256) && (
value < 2))
2486 am->fa_ipv6_known_eh_bitmap =
2501 int may_clear_sessions = 1;
2528 if (
unformat (input,
"skip-ipv6-extension-header %u %u", &eh_val, &val))
2536 if (
unformat (input,
"use-hash-acl-matching %u", &val))
2538 am->use_hash_acl_matching = (val != 0);
2541 if (
unformat (input,
"l4-match-nonfirst-fragment %u", &val))
2543 am->l4_match_nonfirst_fragment = (val != 0);
2546 if (
unformat (input,
"reclassify-sessions %u", &val))
2548 am->reclassify_sessions = (val != 0);
2551 if (
unformat (input,
"event-trace"))
2556 "expecting trace level, got `%U`",
2562 am->trace_acl = val;
2570 if (
unformat (input,
"validate %u", &val))
2572 else if (
unformat (input,
"trace %u", &val))
2578 if (
unformat (input,
"validate %u", &val))
2580 else if (
unformat (input,
"trace %u", &val))
2591 if (
unformat (input,
"max-entries"))
2596 "expecting maximum number of entries, got `%U`",
2606 if (
unformat (input,
"hash-table-buckets"))
2611 "expecting maximum number of hash table buckets, got `%U`",
2617 am->fa_conn_table_hash_num_buckets = val;
2621 if (
unformat (input,
"hash-table-memory"))
2626 "expecting maximum amount of hash table memory, got `%U`",
2636 if (
unformat (input,
"event-trace"))
2641 "expecting trace level, got `%U`",
2647 am->trace_sessions = val;
2659 if (!
unformat (input,
"%u", &timeout))
2662 "expecting timeout value in seconds, got `%U`",
2678 if (!
unformat (input,
"%u", &timeout))
2681 "expecting timeout value in seconds, got `%U`",
2694 if (!
unformat (input,
"%u", &timeout))
2697 "expecting timeout value in seconds, got `%U`",
2720 u8 *
a = va_arg (*args,
u8 *);
2721 return format (s,
"%02x:%02x:%02x:%02x:%02x:%02x",
2722 a[0],
a[1],
a[2],
a[3],
a[4],
a[5]);
2730 out =
format (out,
"%s action %d ip %U/%d mac %U mask %U",
2731 a->is_ipv6 ?
"ipv6" :
"ipv4",
a->is_permit,
2747 if (macip_acl_index >=
vec_len (
am->macip_acls))
2754 "MACIP acl_index: %d, count: %d (true len %d) tag {%s} is free pool slot: %d\n",
2755 macip_acl_index,
a->count,
vec_len (
a->rules),
a->tag,
2758 " ip4_table_index %d, ip6_table_index %d, l2_table_index %d\n",
2759 a->ip4_table_index,
a->ip6_table_index,
a->l2_table_index);
2761 " out_ip4_table_index %d, out_ip6_table_index %d, out_l2_table_index %d\n",
2762 a->out_ip4_table_index,
a->out_ip6_table_index,
2763 a->out_l2_table_index);
2779 is_add = is_input = 1;
2791 else if (
unformat (line_input,
"add"))
2793 else if (
unformat (line_input,
"del"))
2797 else if (
unformat (line_input,
"input"))
2799 else if (
unformat (line_input,
"output"))
2816 #define vec_validate_acl_rules(v, idx) \
2818 if (vec_len(v) < idx+1) { \
2819 vec_validate(v, idx); \
2820 v[idx].is_permit = 0x1; \
2821 v[idx].srcport_or_icmptype_last = 0xffff; \
2822 v[idx].dstport_or_icmpcode_last = 0xffff; \
2831 vl_api_acl_rule_t *
rules = 0;
2834 int n_rules_override = -1;
2839 u32 tcpflags, tcpmask;
2840 u32 src_prefix_length = 0, dst_prefix_length = 0;
2849 if (
unformat (line_input,
"permit+reflect"))
2852 rules[rule_idx].is_permit = 2;
2854 else if (
unformat (line_input,
"permit"))
2857 rules[rule_idx].is_permit = 1;
2859 else if (
unformat (line_input,
"deny"))
2862 rules[rule_idx].is_permit = 0;
2864 else if (
unformat (line_input,
"count %d", &n_rules_override))
2873 else if (
unformat (line_input,
"src %U/%d",
2875 &src_prefix_length))
2881 rules[rule_idx].src_prefix.len = src_prefix_length;
2883 else if (
unformat (line_input,
"dst %U/%d",
2885 &dst_prefix_length))
2891 rules[rule_idx].dst_prefix.len = dst_prefix_length;
2893 else if (
unformat (line_input,
"sport %d-%d", &port1, &port2))
2896 rules[rule_idx].srcport_or_icmptype_first = htons (port1);
2897 rules[rule_idx].srcport_or_icmptype_last = htons (port2);
2899 else if (
unformat (line_input,
"sport %d", &port1))
2902 rules[rule_idx].srcport_or_icmptype_first = htons (port1);
2903 rules[rule_idx].srcport_or_icmptype_last = htons (port1);
2905 else if (
unformat (line_input,
"dport %d-%d", &port1, &port2))
2908 rules[rule_idx].dstport_or_icmpcode_first = htons (port1);
2909 rules[rule_idx].dstport_or_icmpcode_last = htons (port2);
2911 else if (
unformat (line_input,
"dport %d", &port1))
2914 rules[rule_idx].dstport_or_icmpcode_first = htons (port1);
2915 rules[rule_idx].dstport_or_icmpcode_last = htons (port1);
2917 else if (
unformat (line_input,
"tcpflags %d %d", &tcpflags, &tcpmask))
2920 rules[rule_idx].tcp_flags_value = tcpflags;
2921 rules[rule_idx].tcp_flags_mask = tcpmask;
2924 if (
unformat (line_input,
"tcpflags %d mask %d", &tcpflags, &tcpmask))
2927 rules[rule_idx].tcp_flags_value = tcpflags;
2928 rules[rule_idx].tcp_flags_mask = tcpmask;
2935 else if (
unformat (line_input,
"tag %s", &tag))
2938 else if (
unformat (line_input,
","))
2988 if (
i <
vec_len (
am->sw_if_index_vec_by_macip_acl))
2992 vec_elt (
am->sw_if_index_vec_by_macip_acl,
i),
3008 for (
i = 0;
i <
vec_len (
am->macip_acl_by_sw_if_index);
i++)
3035 if (
i <
vec_len (
am->input_sw_if_index_vec_by_acl))
3041 if (
i <
vec_len (
am->output_sw_if_index_vec_by_acl))
3077 (void)
unformat (input,
"index %u", &lc_index);
3091 (void)
unformat (input,
"index %u", &lc_index);
3105 for (swi = 0; (swi <
vec_len (
am->input_acl_vec_by_sw_if_index)) ||
3106 (swi <
vec_len (
am->output_acl_vec_by_sw_if_index)); swi++)
3113 if (swi <
vec_len (
am->input_policy_epoch_by_sw_if_index))
3115 vec_elt (
am->input_policy_epoch_by_sw_if_index,
3117 if (swi <
vec_len (
am->output_policy_epoch_by_sw_if_index))
3119 vec_elt (
am->output_policy_epoch_by_sw_if_index,
3126 am->input_etype_whitelist_by_sw_if_index[swi],
3132 am->output_etype_whitelist_by_sw_if_index[swi],
3136 if ((swi <
vec_len (
am->input_acl_vec_by_sw_if_index)) &&
3137 (
vec_len (
am->input_acl_vec_by_sw_if_index[swi]) > 0))
3140 am->input_acl_vec_by_sw_if_index[swi],
"%d");
3152 if ((swi <
vec_len (
am->output_acl_vec_by_sw_if_index)) &&
3153 (
vec_len (
am->output_acl_vec_by_sw_if_index[swi]) > 0))
3156 am->output_acl_vec_by_sw_if_index[swi],
"%d");
3167 if (detail && (swi <
vec_len (
am->input_lc_index_by_sw_if_index)))
3170 am->input_lc_index_by_sw_if_index[swi]);
3172 if (detail && (swi <
vec_len (
am->output_lc_index_by_sw_if_index)))
3175 am->output_lc_index_by_sw_if_index[swi]);
3188 u64 five_tuple[6] = { 0, 0, 0, 0, 0, 0 };
3191 (input,
"%llx %llx %llx %llx %llx %llx", &five_tuple[0], &five_tuple[1],
3192 &five_tuple[2], &five_tuple[3], &five_tuple[4], &five_tuple[5]))
3211 int show_acl =
unformat (input,
"acl");
3212 int detail =
unformat (input,
"detail");
3230 u32 show_session_thread_id,
3231 u32 show_session_session_index)
3238 u64 clocks_per_second =
am->vlib_main->clib_time.clocks_per_second;
3241 u64 n_adds =
am->fa_session_total_adds;
3242 u64 n_dels =
am->fa_session_total_dels;
3243 u64 n_deact =
am->fa_session_total_deactivations;
3245 n_dels, n_adds - n_dels);
3247 n_deact, n_adds - n_deact);
3249 n_deact, n_dels, n_deact - n_dels);
3254 for (wk = 0; wk <
vec_len (
am->per_worker_data); wk++)
3258 if (show_session_thread_id == wk
3262 show_session_session_index);
3267 " info: %016llx %016llx %016llx %016llx %016llx %016llx",
3268 m[0], m[1], m[2], m[3], m[4], m[5]);
3296 u64 n_epoch_changes =
3301 " sw_if_index %d: add %lu - del %lu = %lu; epoch chg: %lu",
3317 head_session_index);
3318 if (~0 != head_session_index)
3361 #define _(cnt, desc) vlib_cli_output(vm, " %20lu: %s", am->cnt, desc);
3365 am->fa_interrupt_generation);
3367 "Sessions per interval: min %lu max %lu increment: %f ms current: %f ms",
3368 am->fa_min_deleted_sessions_per_interval,
3369 am->fa_max_deleted_sessions_per_interval,
3370 am->fa_cleaner_wait_time_increment * 1000.0,
3371 ((
f64)
am->fa_current_cleaner_timer_wait_interval) *
3384 u32 show_bihash_verbose = 0;
3385 u32 show_session_thread_id = ~0;
3386 u32 show_session_session_index = ~0;
3387 (void)
unformat (input,
"thread %u index %u", &show_session_thread_id,
3388 &show_session_session_index);
3389 (void)
unformat (input,
"verbose %u", &show_bihash_verbose);
3392 show_session_session_index);
3406 int show_acl_hash_info = 0;
3407 int show_applied_info = 0;
3408 int show_mask_type = 0;
3409 int show_bihash = 0;
3410 u32 show_bihash_verbose = 0;
3414 show_acl_hash_info = 1;
3419 else if (
unformat (input,
"applied"))
3421 show_applied_info = 1;
3422 unformat (input,
"lc_index %u", &lc_index);
3431 unformat (input,
"verbose %u", &show_bihash_verbose);
3435 (show_mask_type || show_acl_hash_info || show_applied_info
3440 show_acl_hash_info = 1;
3441 show_applied_info = 1;
3448 if (show_acl_hash_info)
3450 if (show_applied_info)
3471 .path =
"set acl-plugin",
3472 .short_help =
"set acl-plugin session timeout {{udp idle}|tcp {idle|transient}} <seconds>",
3477 .path =
"show acl-plugin acl",
3478 .short_help =
"show acl-plugin acl [index N]",
3483 .path =
"show acl-plugin lookup context",
3484 .short_help =
"show acl-plugin lookup context [index N]",
3489 .path =
"show acl-plugin lookup user",
3490 .short_help =
"show acl-plugin lookup user [index N]",
3495 .path =
"show acl-plugin decode 5tuple",
3496 .short_help =
"show acl-plugin decode 5tuple XXXX XXXX XXXX XXXX XXXX XXXX",
3501 .path =
"show acl-plugin interface",
3502 .short_help =
"show acl-plugin interface [sw_if_index N] [acl]",
3507 .path =
"show acl-plugin memory",
3508 .short_help =
"show acl-plugin memory",
3513 .path =
"show acl-plugin sessions",
3514 .short_help =
"show acl-plugin sessions",
3519 .path =
"show acl-plugin tables",
3520 .short_help =
"show acl-plugin tables [ acl [index N] | applied [ lc_index N ] | mask | hash [verbose N] ]",
3525 .path =
"show acl-plugin macip acl",
3526 .short_help =
"show acl-plugin macip acl [index N]",
3531 .path =
"show acl-plugin macip interface",
3532 .short_help =
"show acl-plugin macip interface",
3537 .path =
"clear acl-plugin sessions",
3538 .short_help =
"clear acl-plugin sessions",
3552 .path =
"set acl-plugin interface",
3553 .short_help =
"set acl-plugin interface <interface> <input|output> <acl INDEX> [del] ",
3574 .path =
"set acl-plugin acl",
3575 .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}",
3584 u32 conn_table_hash_buckets;
3585 uword conn_table_hash_memory_size;
3586 u32 conn_table_max_entries;
3587 uword main_heap_size;
3588 uword hash_heap_size;
3589 u32 hash_lookup_hash_buckets;
3590 uword hash_lookup_hash_memory;
3591 u32 reclassify_sessions;
3592 u32 use_tuple_merge;
3593 u32 tuple_merge_split_threshold;
3598 (input,
"connection hash buckets %d", &conn_table_hash_buckets))
3599 am->fa_conn_table_hash_num_buckets = conn_table_hash_buckets;
3603 &conn_table_hash_memory_size))
3604 am->fa_conn_table_hash_memory_size = conn_table_hash_memory_size;
3605 else if (
unformat (input,
"connection count max %d",
3606 &conn_table_max_entries))
3607 am->fa_conn_table_max_entries = conn_table_max_entries;
3613 (
"WARNING: ACL heap is now part of the main heap. 'main heap size' is ineffective.");
3619 (
"WARNING: ACL heap is now part of the main heap. 'hash lookup heap size' is ineffective.");
3622 (input,
"hash lookup hash buckets %d", &hash_lookup_hash_buckets))
3623 am->hash_lookup_hash_buckets = hash_lookup_hash_buckets;
3627 &hash_lookup_hash_memory))
3628 am->hash_lookup_hash_memory = hash_lookup_hash_memory;
3629 else if (
unformat (input,
"use tuple merge %d", &use_tuple_merge))
3630 am->use_tuple_merge = use_tuple_merge;
3633 (input,
"tuple merge split threshold %d",
3634 &tuple_merge_split_threshold))
3635 am->tuple_merge_split_threshold = tuple_merge_split_threshold;
3637 else if (
unformat (input,
"reclassify sessions %d",
3638 &reclassify_sessions))
3639 am->reclassify_sessions = reclassify_sessions;
3652 #include <acl/acl.api.c>
3682 am->fa_conn_table_hash_num_buckets =
3684 am->fa_conn_table_hash_memory_size =
3687 am->reclassify_sessions = 0;
3690 am->fa_min_deleted_sessions_per_interval =
3692 am->fa_max_deleted_sessions_per_interval =
3694 am->fa_cleaner_wait_time_increment =
3700 for (wk = 0; wk <
vec_len (
am->per_worker_data); wk++)
3709 am->fa_max_deleted_sessions_per_interval);
3720 am->fa_cleaner_cnt_delete_by_sw_index = 0;
3721 am->fa_cleaner_cnt_delete_by_sw_index_ok = 0;
3722 am->fa_cleaner_cnt_unknown_event = 0;
3723 am->fa_cleaner_cnt_timer_restarted = 0;
3724 am->fa_cleaner_cnt_wait_with_timeout = 0;
3727 #define _(N, v, s) am->fa_ipv6_known_eh_bitmap = clib_bitmap_set(am->fa_ipv6_known_eh_bitmap, v, 1);
3730 am->l4_match_nonfirst_fragment = 1;
3733 am->use_hash_acl_matching = 1;
3735 am->use_tuple_merge = 1;
3739 am->interface_acl_user_id =
3740 acl_plugin.register_user_module (
"interface ACL",
"sw_if_index",
3745 am->acl_counter_lock[0] = 0;