23 #if VALIDATION_SCAFFOLDING 37 vnet_classify_entry_t * v, * save_v;
38 u32 active_elements = 0;
61 clib_warning (
"found %u expected %u elts", active_elements,
73 vec_add1 (cm->unformat_l2_next_index_fns, fn);
80 vec_add1 (cm->unformat_ip_next_index_fns, fn);
88 vec_add1 (cm->unformat_acl_next_index_fns, fn);
96 vec_add1 (cm->unformat_policer_next_index_fns, fn);
103 vec_add1 (cm->unformat_opaque_index_fns, fn);
108 u8 * mask,
u32 nbuckets,
u32 memory_size,
115 nbuckets = 1 << (
max_log2 (nbuckets));
118 memset(t, 0,
sizeof (*t));
163 static vnet_classify_entry_t *
166 vnet_classify_entry_t * rv = 0;
168 vnet_classify_entry_##size##_t * rv##size = 0; 186 vec_validate_aligned \ 187 (rv##size, ((1<<log2_pages)*t->entries_per_page) - 1, \ 188 CLIB_CACHE_LINE_BYTES); \ 189 rv = (vnet_classify_entry_t *) rv##size; \ 213 memset (rv, 0xff, sizeof (*rv##size) * vec_len(rv)); \ 227 vnet_classify_entry_t * v)
237 v->next_free = t->
freelists[free_list_index];
244 vnet_classify_entry_t * v;
247 vnet_classify_entry_t * working_copy;
249 vnet_classify_entry_##size##_t * working_copy##size = 0; 278 working_copy##size = (void *) working_copy; \ 279 vec_validate_aligned \ 280 (working_copy##size, \ 281 ((1<<b->log2_pages)*t->entries_per_page) - 1, \ 282 CLIB_CACHE_LINE_BYTES); \ 283 working_copy = (void *) working_copy##size; \ 303 clib_memcpy (working_copy, v, \ 304 sizeof (vnet_classify_entry_##size##_t) \ 305 * (1<<b->log2_pages) \ 306 * (t->entries_per_page)); \ 315 working_bucket.as_u64 = b->
as_u64;
318 b->
as_u64 = working_bucket.as_u64;
322 static vnet_classify_entry_t *
324 vnet_classify_entry_t * old_values,
327 vnet_classify_entry_t * new_values, * v, * new_v;
345 key_minus_skip = (
u8 *) v->key;
350 new_hash &= (1<<new_log2_pages) - 1;
359 clib_memcpy (new_v, v,
sizeof (vnet_classify_entry_t)
377 vnet_classify_entry_t * add_v,
382 vnet_classify_entry_t * v, * new_v, * save_new_v, * working_copy, * save_v;
393 key_minus_skip = (
u8 *) add_v->key;
398 bucket_index = hash & (t->
nbuckets-1);
403 while (__sync_lock_test_and_set (t->
writer_lock, 1))
416 clib_memcpy (v, add_v,
sizeof (vnet_classify_entry_t) +
447 clib_memcpy (v, add_v,
sizeof (vnet_classify_entry_t) +
463 clib_memcpy (v, add_v,
sizeof (vnet_classify_entry_t) +
482 memset (v, 0xff,
sizeof (vnet_classify_entry_t) +
511 key_minus_skip = (
u8 *) add_v->key;
524 clib_memcpy (new_v, add_v,
sizeof (vnet_classify_entry_t) +
554 }) classify_data_or_mask_t;
561 vnet_classify_entry_t *
571 vnet_classify_entry_t * e = va_arg (*args, vnet_classify_entry_t *);
574 (s,
"[%u]: next_index %d advance %d opaque %d\n",
583 s =
format (s,
" hits %lld, last_heard %.2f\n",
584 e->hits, e->last_heard);
586 s =
format (s,
" entry is free\n");
593 int verbose = va_arg (*args,
int);
595 vnet_classify_entry_t * v, * save_v;
597 u64 active_elements = 0;
605 s =
format (s,
"[%d]: empty\n", i);
611 s =
format (s,
"[%d]: heap offset %d, len %d\n", i,
627 s =
format (s,
" %d: empty\n",
633 s =
format (s,
" %d: %U\n",
642 s =
format (s,
" %lld active elements\n", active_elements);
653 u32 next_table_index,
663 if (memory_size == 0)
664 return VNET_API_ERROR_INVALID_MEMORY_SIZE;
667 return VNET_API_ERROR_INVALID_VALUE;
673 *table_index = t - cm->tables;
681 #define foreach_ip4_proto_field \ 693 u8 ** maskp = va_arg (*args,
u8 **);
695 u8 found_something = 0;
709 else if (
unformat (input,
"hdr_length"))
718 #define _(a) else if (unformat (input, #a)) a=1; 725 #define _(a) found_something += a; 729 if (found_something == 0)
736 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a)); 752 #define foreach_ip6_proto_field \ 761 u8 ** maskp = va_arg (*args,
u8 **);
763 u8 found_something = 0;
765 u32 ip_version_traffic_class_and_flow_label;
771 u8 traffic_class = 0;
778 else if (
unformat (input,
"traffic-class"))
780 else if (
unformat (input,
"flow-label"))
789 #define _(a) else if (unformat (input, #a)) a=1; 796 #define _(a) found_something += a; 800 if (found_something == 0)
807 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a)); 811 ip_version_traffic_class_and_flow_label = 0;
814 ip_version_traffic_class_and_flow_label |= 0xF0000000;
817 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
820 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
823 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
831 u8 ** maskp = va_arg (*args,
u8 **);
846 u8 ** maskp = va_arg (*args,
u8 **);
872 else if (
unformat (input,
"ignore-tag1"))
874 else if (
unformat (input,
"ignore-tag2"))
882 else if (
unformat (input,
"dot1ad"))
887 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
888 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
891 if (tag1 || ignore_tag1 || cos1 || dot1q)
893 if (tag2 || ignore_tag2 || cos2 || dot1ad)
899 memset (mask, 0xff, 6);
902 memset (mask + 6, 0xff, 6);
915 mask[21] = mask [20] = 0xff;
936 mask[16] = mask [17] = 0xff;
945 mask[12] = mask [13] = 0xff;
955 u8 ** maskp = va_arg (*args,
u8 **);
956 u32 * skipp = va_arg (*args,
u32 *);
957 u32 * matchp = va_arg (*args,
u32 *);
975 if (mask || l2 || l3)
991 for (i = 0; i <
vec_len (mask); i++)
996 *skipp = i /
sizeof(
u32x4);
1000 while (vec_len (mask) %
sizeof (
u32x4))
1005 for (i = match*
sizeof(
u32x4); i > 0; i-=
sizeof(
u32x4))
1008 if (*tmp || *(tmp+1))
1015 _vec_len (mask) = match *
sizeof(
u32x4);
1026 #define foreach_l2_next \ 1028 _(ethernet, ETHERNET_INPUT) \ 1036 u32 * miss_next_indexp = va_arg (*args,
u32 *);
1042 for (i = 0; i <
vec_len (cm->unformat_l2_next_index_fns); i++)
1044 if (
unformat (input,
"%U", cm->unformat_l2_next_index_fns[i], &tmp))
1052 if (unformat (input, #n)) { next_index = L2_CLASSIFY_NEXT_##N; goto out;} 1065 *miss_next_indexp = next_index;
1069 #define foreach_ip_next \ 1077 u32 * miss_next_indexp = va_arg (*args,
u32 *);
1084 for (i = 0; i <
vec_len (cm->unformat_ip_next_index_fns); i++)
1086 if (
unformat (input,
"%U", cm->unformat_ip_next_index_fns[i], &tmp))
1094 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;} 1107 *miss_next_indexp = next_index;
1111 #define foreach_acl_next \ 1116 u32 * next_indexp = va_arg (*args,
u32 *);
1123 for (i = 0; i <
vec_len (cm->unformat_acl_next_index_fns); i++)
1125 if (
unformat (input,
"%U", cm->unformat_acl_next_index_fns[i], &tmp))
1133 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;} 1142 else if (
unformat (input,
"%d", &tmp))
1151 *next_indexp = next_index;
1157 u32 * next_indexp = va_arg (*args,
u32 *);
1164 for (i = 0; i <
vec_len (cm->unformat_policer_next_index_fns); i++)
1166 if (
unformat (input,
"%U", cm->unformat_policer_next_index_fns[i], &tmp))
1182 *next_indexp = next_index;
1195 u32 table_index = ~0;
1196 u32 next_table_index = ~0;
1197 u32 miss_next_index = ~0;
1198 u32 memory_size = 2<<20;
1208 else if (
unformat (input,
"buckets %d", &nbuckets))
1210 else if (
unformat (input,
"skip %d", &skip))
1212 else if (
unformat (input,
"match %d", &match))
1214 else if (
unformat (input,
"table %d", &table_index))
1217 cm, &mask, &skip, &match))
1219 else if (
unformat (input,
"memory-size %uM", &tmp))
1220 memory_size = tmp<<20;
1221 else if (
unformat (input,
"memory-size %uG", &tmp))
1222 memory_size = tmp<<30;
1223 else if (
unformat (input,
"next-table %d", &next_table_index))
1239 if (is_add && mask == 0)
1242 if (is_add && skip == ~0)
1245 if (is_add && match == ~0)
1248 if (!is_add && table_index == ~0)
1252 skip, match, next_table_index, miss_next_index,
1253 &table_index, is_add);
1267 .path =
"classify table",
1269 "classify table [miss-next|l2-miss_next|acl-miss-next <next_index>]" 1270 "\n mask <mask-value> buckets <nn> [skip <n>] [match <n>] [del]",
1277 int verbose = va_arg (*args,
int);
1278 u32 index = va_arg (*args,
u32);
1283 s =
format (s,
"%10s%10s%10s%10s",
"TableIdx",
"Sessions",
"NextTbl",
1284 "NextNode", verbose ?
"Details" :
"");
1294 s =
format (s,
"\n nbuckets %d, skip %d match %d",
1314 u32 match_index = ~0;
1321 if (
unformat (input,
"index %d", &match_index))
1323 else if (
unformat (input,
"verbose %d", &verbose))
1325 else if (
unformat (input,
"verbose"))
1333 if (match_index == ~0 || (match_index == t - cm->tables))
1334 vec_add1 (indices, t - cm->tables);
1341 for (i = 0; i <
vec_len (indices); i++)
1343 verbose, indices[i]);
1354 .path =
"show classify tables",
1355 .short_help =
"show classify tables [index <nn>]",
1361 u8 ** matchp = va_arg (*args,
u8 **);
1368 int src = 0, dst = 0;
1376 int fragment_id = 0;
1377 u32 fragment_id_val;
1385 if (
unformat (input,
"version %d", &version_val))
1387 else if (
unformat (input,
"hdr_length %d", &hdr_length_val))
1393 else if (
unformat (input,
"proto %d", &proto_val))
1395 else if (
unformat (input,
"tos %d", &tos_val))
1397 else if (
unformat (input,
"length %d", &length_val))
1399 else if (
unformat (input,
"fragment_id %d", &fragment_id_val))
1401 else if (
unformat (input,
"ttl %d", &ttl_val))
1403 else if (
unformat (input,
"checksum %d", &checksum_val))
1409 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
1410 + ttl + checksum == 0)
1456 u8 ** matchp = va_arg (*args,
u8 **);
1461 u8 traffic_class = 0;
1462 u32 traffic_class_val;
1465 int src = 0, dst = 0;
1469 int payload_length = 0;
1470 u32 payload_length_val;
1473 u32 ip_version_traffic_class_and_flow_label;
1477 if (
unformat (input,
"version %d", &version_val))
1479 else if (
unformat (input,
"traffic_class %d", &traffic_class_val))
1481 else if (
unformat (input,
"flow_label %d", &flow_label_val))
1487 else if (
unformat (input,
"proto %d", &proto_val))
1489 else if (
unformat (input,
"payload_length %d", &payload_length_val))
1491 else if (
unformat (input,
"hop_limit %d", &hop_limit_val))
1497 if (version + traffic_class + flow_label + src + dst + proto +
1498 payload_length + hop_limit == 0)
1517 ip_version_traffic_class_and_flow_label = 0;
1520 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
1523 ip_version_traffic_class_and_flow_label |= (traffic_class_val & 0xFF) << 20;
1526 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
1529 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
1543 u8 ** matchp = va_arg (*args,
u8 **);
1559 u8 * tagp = va_arg (*args,
u8 *);
1564 tagp[0] = (tag>>8) & 0x0F;
1565 tagp[1] = tag & 0xFF;
1574 u8 ** matchp = va_arg (*args,
u8 **);
1599 else if (
unformat (input,
"proto %U",
1606 else if (
unformat (input,
"ignore-tag1"))
1608 else if (
unformat (input,
"ignore-tag2"))
1610 else if (
unformat (input,
"cos1 %d", &cos1_val))
1612 else if (
unformat (input,
"cos2 %d", &cos2_val))
1617 if ((src + dst + proto + tag1 + tag2 +
1618 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
1621 if (tag1 || ignore_tag1 || cos1)
1623 if (tag2 || ignore_tag2 || cos2)
1637 match[19] = tag2_val[1];
1638 match[18] = tag2_val[0];
1640 match [18] |= (cos2_val & 0x7) << 5;
1643 match[21] = proto_val & 0xff;
1644 match[20] = proto_val >> 8;
1648 match [15] = tag1_val[1];
1649 match [14] = tag1_val[0];
1652 match [14] |= (cos1_val & 0x7) << 5;
1658 match [15] = tag1_val[1];
1659 match [14] = tag1_val[0];
1662 match[17] = proto_val & 0xff;
1663 match[16] = proto_val >> 8;
1666 match [14] |= (cos1_val & 0x7) << 5;
1672 match [18] |= (cos2_val & 0x7) << 5;
1674 match [14] |= (cos1_val & 0x7) << 5;
1677 match[13] = proto_val & 0xff;
1678 match[12] = proto_val >> 8;
1689 u8 ** matchp = va_arg (*args,
u8 **);
1690 u32 table_index = va_arg (*args,
u32);
1713 if (match || l2 || l3)
1753 vnet_classify_entry_5_t _max_e __attribute__((aligned (16)));
1754 vnet_classify_entry_t * e;
1758 return VNET_API_ERROR_NO_SUCH_TABLE;
1762 e = (vnet_classify_entry_t *)&_max_e;
1763 e->next_index = hit_next_index;
1764 e->opaque_index = opaque_index;
1765 e->advance = advance;
1776 e->key[i] &= t->
mask[i];
1780 return VNET_API_ERROR_NO_SUCH_ENTRY;
1791 u32 table_index = ~0;
1792 u32 hit_next_index = ~0;
1793 u64 opaque_index = ~0;
1811 else if (
unformat (input,
"policer-hit-next %U",
1814 else if (
unformat (input,
"opaque-index %lld", &opaque_index))
1817 cm, &match, table_index))
1819 else if (
unformat (input,
"advance %d", &advance))
1821 else if (
unformat (input,
"table-index %d", &table_index))
1826 for (i = 0; i <
vec_len (cm->unformat_opaque_index_fns); i++)
1828 if (
unformat (input,
"%U", cm->unformat_opaque_index_fns[i],
1838 if (table_index == ~0)
1841 if (is_add && match == 0)
1846 opaque_index, advance, is_add);
1862 .path =
"classify session",
1864 "classify session [hit-next|l2-hit-next|acl-hit-next <next_index>|" 1865 "policer-hit-next <policer_name>]" 1866 "\n table-index <nn> match [hex] [l2] [l3 ip4] [opaque-index <index>]",
1873 u64 * opaquep = va_arg (*args,
u64 *);
1879 *opaquep = sw_if_index;
1889 u32 * next_indexp = va_arg (*args,
u32 *);
1894 cm->vlib_main, &node_index))
1900 ASSERT(rv == next_index);
1902 *next_indexp = next_index;
1912 u32 * next_indexp = va_arg (*args,
u32 *);
1917 cm->vlib_main, &node_index))
1923 ASSERT(rv == next_index);
1925 *next_indexp = next_index;
1935 u32 * next_indexp = va_arg (*args,
u32 *);
1940 cm->vlib_main, &node_index))
1945 *next_indexp = next_index;
1989 classify_data_or_mask_t * mask;
1990 classify_data_or_mask_t * data;
1991 u8 *mp = 0, *dp = 0;
1993 vnet_classify_entry_t * e;
1996 u32 table_index = ~0;
1999 u32 memory_size = 64<<20;
2002 src.
as_u32 = clib_net_to_host_u32 (0x0100000A);
2005 if (
unformat (input,
"sessions %d", &sessions))
2009 else if (
unformat (input,
"buckets %d", &buckets))
2011 else if (
unformat (input,
"memory-size %uM", &tmp))
2012 memory_size = tmp<<20;
2013 else if (
unformat (input,
"memory-size %uG", &tmp))
2014 memory_size = tmp<<30;
2017 else if (
unformat (input,
"table %d", &table_index))
2026 mask = (classify_data_or_mask_t *) mp;
2027 data = (classify_data_or_mask_t *) dp;
2029 data->ip.src_address.as_u32 = src.
as_u32;
2032 memset (&mask->ip.src_address, 0xff, 4);
2036 if (table_index != ~0)
2061 for (i = 0; i < sessions; i++)
2072 tmp = clib_net_to_host_u32 (data->ip.src_address.as_u32) + 1;
2073 data->ip.src_address.as_u32 = clib_net_to_host_u32 (tmp);
2086 for (i = 0; i < sessions; i++)
2088 u8 * key_minus_skip;
2097 ASSERT (e->opaque_index == (i+100));
2099 key_minus_skip = (
u8 *)e->key;
2110 tmp = clib_net_to_host_u32 (data->ip.src_address.as_u32) + 1;
2111 data->ip.src_address.as_u32 = clib_net_to_host_u32 (tmp);
2125 .path =
"test classify",
2127 "test classify [src <ip>] [sessions <nn>] [buckets <nn>] [table <nn>] [del]",
u64 vnet_classify_hash_packet(vnet_classify_table_t *t, u8 *h)
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
vnet_classify_entry_t ** working_copies
void clib_mem_validate(void)
uword unformat_classify_mask(unformat_input_t *input, va_list *args)
sll srl srl sll sra u16x4 i
void rogue(vnet_classify_table_t *t)
static clib_error_t * show_classify_tables_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static vnet_classify_entry_t * vnet_classify_find_entry_inline(vnet_classify_table_t *t, u8 *h, u64 hash, f64 now)
void * mheap_alloc(void *memory, uword size)
#define VNET_CLASSIFY_ENTRY_FREE
static u8 * format_vnet_classify_table(u8 *s, va_list *args)
uword unformat_vlan_tag(unformat_input_t *input, va_list *args)
static clib_error_t * classify_table_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
unformat_function_t unformat_vnet_sw_interface
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
#define foreach_ip6_proto_field
void vnet_classify_register_unformat_acl_next_index_fn(unformat_function_t *fn)
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
u8 * format_mheap(u8 *s, va_list *va)
static uword min_log2(uword x)
vlib_node_registration_t ip4_classify_node
(constructor) VLIB_REGISTER_NODE (ip4_classify_node)
Adjacency to drop this packet.
vnet_main_t * vnet_get_main(void)
void mv(vnet_classify_table_t *t)
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
#define VLIB_INIT_FUNCTION(x)
int vnet_classify_add_del(vnet_classify_table_t *t, vnet_classify_entry_t *add_v, int is_add)
static clib_error_t * classify_session_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
uword unformat_l2_mask(unformat_input_t *input, va_list *args)
uword unformat_classify_match(unformat_input_t *input, va_list *args)
vnet_classify_table_t * vnet_classify_new_table(vnet_classify_main_t *cm, u8 *mask, u32 nbuckets, u32 memory_size, u32 skip_n_vectors, u32 match_n_vectors)
#define foreach_ip4_proto_field
#define clib_warning(format, args...)
This packet is for one of our own IP addresses.
static uword unformat_opaque_sw_if_index(unformat_input_t *input, va_list *args)
static int vnet_classify_entry_is_free(vnet_classify_entry_t *e)
static u64 vnet_classify_hash_packet_inline(vnet_classify_table_t *t, u8 *h)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
uword unformat_ip4_mask(unformat_input_t *input, va_list *args)
int vnet_classify_add_del_table(vnet_classify_main_t *cm, u8 *mask, u32 nbuckets, u32 memory_size, u32 skip, u32 match, u32 next_table_index, u32 miss_next_index, u32 *table_index, int is_add)
void vnet_classify_delete_table_index(vnet_classify_main_t *cm, u32 table_index)
uword unformat_ip6_mask(unformat_input_t *input, va_list *args)
uword os_get_cpu_number(void)
#define pool_put(P, E)
Free an object E in pool P.
void vnet_classify_register_unformat_opaque_index_fn(unformat_function_t *fn)
static vnet_classify_entry_t * vnet_classify_entry_at_index(vnet_classify_table_t *t, vnet_classify_entry_t *e, u32 index)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
uword unformat_policer_next_index(unformat_input_t *input, va_list *args)
vlib_node_registration_t ip4_inacl_node
(constructor) VLIB_REGISTER_NODE (ip4_inacl_node)
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P (general version).
static uword vnet_classify_get_offset(vnet_classify_table_t *t, vnet_classify_entry_t *v)
static u8 * format_classify_entry(u8 *s, va_list *args)
uword unformat_l2_match(unformat_input_t *input, va_list *args)
vnet_classify_bucket_t saved_bucket
static uword unformat_acl_next_node(unformat_input_t *input, va_list *args)
vlib_node_registration_t ip6_inacl_node
(constructor) VLIB_REGISTER_NODE (ip6_inacl_node)
#define vec_free(V)
Free vector's memory (no header).
uword unformat_acl_next_index(unformat_input_t *input, va_list *args)
static void * clib_mem_set_heap(void *heap)
static uword unformat_ip_next_node(unformat_input_t *input, va_list *args)
u8 * format_classify_table(u8 *s, va_list *args)
#define clib_memcpy(a, b, c)
uword unformat_l3_match(unformat_input_t *input, va_list *args)
uword unformat_ip4_match(unformat_input_t *input, va_list *args)
vlib_node_registration_t l2_classify_node
(constructor) VLIB_REGISTER_NODE (l2_classify_node)
typedef CLIB_PACKED(struct{ethernet_header_t eh;ip4_header_t ip;})
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
static clib_error_t * vnet_classify_init(vlib_main_t *vm)
struct _vnet_classify_main vnet_classify_main_t
static void make_working_copy(vnet_classify_table_t *t, vnet_classify_bucket_t *b)
uword unformat_l3_mask(unformat_input_t *input, va_list *args)
uword unformat_ethernet_address(unformat_input_t *input, va_list *args)
#define vec_delete(V, N, M)
Delete N elements starting at element M.
uword unformat_ip6_match(unformat_input_t *input, va_list *args)
#define vec_append(v1, v2)
Append v2 after v1.
uword unformat_ip_next_index(unformat_input_t *input, va_list *args)
vnet_classify_main_t vnet_classify_main
int vnet_classify_add_del_session(vnet_classify_main_t *cm, u32 table_index, u8 *match, u32 hit_next_index, u32 opaque_index, i32 advance, int is_add)
static int vnet_classify_entry_is_busy(vnet_classify_entry_t *e)
static clib_error_t * test_classify_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
VLIB_CLI_COMMAND(set_interface_ip_source_and_port_range_check_command, static)
uword unformat_ethernet_type_host_byte_order(unformat_input_t *input, va_list *args)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
vnet_classify_bucket_t * buckets
void vnet_classify_register_unformat_ip_next_index_fn(unformat_function_t *fn)
static uword max_log2(uword x)
static uword unformat_l2_next_node(unformat_input_t *input, va_list *args)
#define vec_append_aligned(v1, v2, align)
Append v2 after v1.
volatile u32 * writer_lock
static vnet_classify_entry_t * vnet_classify_entry_alloc(vnet_classify_table_t *t, u32 log2_pages)
unformat_function_t unformat_vlib_node
static void vnet_classify_entry_free(vnet_classify_table_t *t, vnet_classify_entry_t *v)
static void * clib_mem_alloc_aligned(uword size, uword align)
#define CLIB_MEMORY_BARRIER()
void vnet_classify_register_unformat_policer_next_index_fn(unformat_function_t *fn)
#define clib_error_return(e, args...)
vlib_node_registration_t ip6_classify_node
(constructor) VLIB_REGISTER_NODE (ip6_classify_node)
#define CLIB_CACHE_LINE_BYTES
uword unformat_l2_next_index(unformat_input_t *input, va_list *args)
vnet_classify_entry_t ** freelists
vnet_classify_entry_t * vnet_classify_find_entry(vnet_classify_table_t *t, u8 *h, u64 hash, f64 now)
static vnet_classify_entry_t * split_and_rehash(vnet_classify_table_t *t, vnet_classify_entry_t *old_values, u32 new_log2_pages)
void vnet_classify_register_unformat_l2_next_index_fn(unformat_function_t *fn)
static vnet_classify_entry_t * vnet_classify_get_entry(vnet_classify_table_t *t, uword offset)