24 #if VALIDATION_SCAFFOLDING 38 vnet_classify_entry_t *
v, * save_v;
39 u32 active_elements = 0;
62 clib_warning (
"found %u expected %u elts", active_elements,
74 vec_add1 (cm->unformat_l2_next_index_fns, fn);
81 vec_add1 (cm->unformat_ip_next_index_fns, fn);
89 vec_add1 (cm->unformat_acl_next_index_fns, fn);
97 vec_add1 (cm->unformat_policer_next_index_fns, fn);
104 vec_add1 (cm->unformat_opaque_index_fns, fn);
116 nbuckets = 1 << (
max_log2 (nbuckets));
119 memset(t, 0,
sizeof (*t));
145 u32 table_index,
int del_chain)
165 static vnet_classify_entry_t *
168 vnet_classify_entry_t * rv = 0;
193 memset (rv, 0xff, required_length);
212 vnet_classify_entry_t *
v;
215 vnet_classify_entry_t * working_copy;
217 int working_copy_length, required_length;
242 if (required_length > working_copy_length)
257 working_bucket.as_u64 = b->
as_u64;
260 b->
as_u64 = working_bucket.as_u64;
264 static vnet_classify_entry_t *
266 vnet_classify_entry_t * old_values,
u32 old_log2_pages,
269 vnet_classify_entry_t * new_values, *
v, * new_v;
270 int i, j, length_in_entries;
275 for (i = 0; i < length_in_entries; i++)
285 key_minus_skip = (
u8 *) v->key;
290 new_hash &= (1<<new_log2_pages) - 1;
299 clib_memcpy (new_v, v,
sizeof (vnet_classify_entry_t)
315 static vnet_classify_entry_t *
317 vnet_classify_entry_t * old_values,
321 vnet_classify_entry_t * new_values, *
v, * new_v;
322 int i, j, new_length_in_entries, old_length_in_entries;
329 for (i = 0; i < old_length_in_entries; i++)
335 for (; j < new_length_in_entries; j++)
341 clib_warning (
"BUG: linear rehash new entry not free!");
344 clib_memcpy (new_v, v,
sizeof (vnet_classify_entry_t)
394 vnet_classify_entry_t * add_v,
399 vnet_classify_entry_t *
v, * new_v, * save_new_v, * working_copy, * save_v;
405 u32 old_log2_pages, new_log2_pages;
408 int resplit_once = 0;
409 int mark_bucket_linear;
413 key_minus_skip = (
u8 *) add_v->key;
418 bucket_index = hash & (t->
nbuckets-1);
423 while (__sync_lock_test_and_set (t->
writer_lock, 1))
436 clib_memcpy (v, add_v,
sizeof (vnet_classify_entry_t) +
458 limit *= (1<<b->log2_pages);
468 for (i = 0; i < limit; i++)
474 clib_memcpy (v, add_v,
sizeof (vnet_classify_entry_t) +
485 for (i = 0; i < limit; i++)
491 clib_memcpy (v, add_v,
sizeof (vnet_classify_entry_t) +
506 for (i = 0; i < limit; i++)
513 memset (v, 0xff,
sizeof (vnet_classify_entry_t) +
529 new_log2_pages = old_log2_pages + 1;
535 mark_bucket_linear = 0;
559 mark_bucket_linear = 1;
566 key_minus_skip = (
u8 *) add_v->key;
571 new_hash &= (1<<new_log2_pages) - 1;
574 if (mark_bucket_linear)
576 limit *= (1<<new_log2_pages);
580 for (i = 0; i < limit; i++)
586 clib_memcpy (new_v, add_v,
sizeof (vnet_classify_entry_t) +
623 }) classify_data_or_mask_t;
630 vnet_classify_entry_t *
640 vnet_classify_entry_t * e = va_arg (*args, vnet_classify_entry_t *);
643 (s,
"[%u]: next_index %d advance %d opaque %d action %d metadata %d\n",
645 e->opaque_index, e->action, e->metadata);
652 s =
format (s,
" hits %lld, last_heard %.2f\n",
653 e->hits, e->last_heard);
655 s =
format (s,
" entry is free\n");
662 int verbose = va_arg (*args,
int);
664 vnet_classify_entry_t *
v, * save_v;
666 u64 active_elements = 0;
674 s =
format (s,
"[%d]: empty\n", i);
680 s =
format (s,
"[%d]: heap offset %d, elts %d, %s\n", i,
697 s =
format (s,
" %d: empty\n",
703 s =
format (s,
" %d: %U\n",
712 s =
format (s,
" %lld active elements\n", active_elements);
724 u32 next_table_index,
727 u8 current_data_flag,
728 i16 current_data_offset,
736 if (*table_index == ~0)
738 if (memory_size == 0)
739 return VNET_API_ERROR_INVALID_MEMORY_SIZE;
742 return VNET_API_ERROR_INVALID_VALUE;
750 *table_index = t - cm->tables;
766 #define foreach_tcp_proto_field \ 770 #define foreach_udp_proto_field \ 774 #define foreach_ip4_proto_field \ 786 u8 ** maskp = va_arg (*args,
u8 **);
788 u8 found_something = 0;
798 #define _(a) else if (unformat (input, #a)) a=1; 805 #define _(a) found_something += a; 809 if (found_something == 0)
816 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a)); 826 u8 ** maskp = va_arg (*args,
u8 **);
828 u8 found_something = 0;
838 #define _(a) else if (unformat (input, #a)) a=1; 845 #define _(a) found_something += a; 849 if (found_something == 0)
856 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a)); 870 u8 ** maskp = va_arg (*args,
u8 **);
871 u16 src_port = 0, dst_port = 0;
880 else if (
unformat (input,
"src_port"))
882 else if (
unformat (input,
"dst_port"))
888 if (!src_port && !dst_port)
905 u8 ** maskp = va_arg (*args,
u8 **);
907 u8 found_something = 0;
921 else if (
unformat (input,
"hdr_length"))
930 #define _(a) else if (unformat (input, #a)) a=1; 937 #define _(a) found_something += a; 941 if (found_something == 0)
948 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a)); 964 #define foreach_ip6_proto_field \ 973 u8 ** maskp = va_arg (*args,
u8 **);
975 u8 found_something = 0;
977 u32 ip_version_traffic_class_and_flow_label;
983 u8 traffic_class = 0;
990 else if (
unformat (input,
"traffic-class"))
992 else if (
unformat (input,
"flow-label"))
1001 #define _(a) else if (unformat (input, #a)) a=1; 1008 #define _(a) found_something += a; 1012 if (found_something == 0)
1019 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a)); 1023 ip_version_traffic_class_and_flow_label = 0;
1026 ip_version_traffic_class_and_flow_label |= 0xF0000000;
1029 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
1032 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
1035 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
1043 u8 ** maskp = va_arg (*args,
u8 **);
1058 u8 ** maskp = va_arg (*args,
u8 **);
1078 else if (
unformat (input,
"proto"))
1084 else if (
unformat (input,
"ignore-tag1"))
1086 else if (
unformat (input,
"ignore-tag2"))
1092 else if (
unformat (input,
"dot1q"))
1094 else if (
unformat (input,
"dot1ad"))
1099 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
1100 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
1103 if (tag1 || ignore_tag1 || cos1 || dot1q)
1105 if (tag2 || ignore_tag2 || cos2 || dot1ad)
1111 memset (mask, 0xff, 6);
1114 memset (mask + 6, 0xff, 6);
1127 mask[21] = mask [20] = 0xff;
1148 mask[16] = mask [17] = 0xff;
1157 mask[12] = mask [13] = 0xff;
1165 u8 ** maskp = va_arg (*args,
u8 **);
1166 u32 * skipp = va_arg (*args,
u32 *);
1167 u32 * matchp = va_arg (*args,
u32 *);
1195 if (mask || l2 || l3 || l4)
1216 for (i = 0; i <
vec_len (mask); i++)
1221 *skipp = i /
sizeof(
u32x4);
1225 while (vec_len (mask) %
sizeof (
u32x4))
1230 for (i = match*
sizeof(
u32x4); i > 0; i-=
sizeof(
u32x4))
1233 if (*tmp || *(tmp+1))
1240 _vec_len (mask) = match *
sizeof(
u32x4);
1251 #define foreach_l2_input_next \ 1253 _(ethernet, ETHERNET_INPUT) \ 1261 u32 * miss_next_indexp = va_arg (*args,
u32 *);
1267 for (i = 0; i <
vec_len (cm->unformat_l2_next_index_fns); i++)
1269 if (
unformat (input,
"%U", cm->unformat_l2_next_index_fns[i], &tmp))
1277 if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;} 1290 *miss_next_indexp = next_index;
1294 #define foreach_l2_output_next \ 1300 u32 * miss_next_indexp = va_arg (*args,
u32 *);
1306 for (i = 0; i <
vec_len (cm->unformat_l2_next_index_fns); i++)
1308 if (
unformat (input,
"%U", cm->unformat_l2_next_index_fns[i], &tmp))
1316 if (unformat (input, #n)) { next_index = L2_OUTPUT_CLASSIFY_NEXT_##N; goto out;} 1329 *miss_next_indexp = next_index;
1333 #define foreach_ip_next \ 1339 u32 * miss_next_indexp = va_arg (*args,
u32 *);
1346 for (i = 0; i <
vec_len (cm->unformat_ip_next_index_fns); i++)
1348 if (
unformat (input,
"%U", cm->unformat_ip_next_index_fns[i], &tmp))
1356 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;} 1369 *miss_next_indexp = next_index;
1373 #define foreach_acl_next \ 1378 u32 * next_indexp = va_arg (*args,
u32 *);
1385 for (i = 0; i <
vec_len (cm->unformat_acl_next_index_fns); i++)
1387 if (
unformat (input,
"%U", cm->unformat_acl_next_index_fns[i], &tmp))
1395 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;} 1404 else if (
unformat (input,
"%d", &tmp))
1413 *next_indexp = next_index;
1419 u32 * next_indexp = va_arg (*args,
u32 *);
1426 for (i = 0; i <
vec_len (cm->unformat_policer_next_index_fns); i++)
1428 if (
unformat (input,
"%U", cm->unformat_policer_next_index_fns[i], &tmp))
1444 *next_indexp = next_index;
1458 u32 table_index = ~0;
1459 u32 next_table_index = ~0;
1460 u32 miss_next_index = ~0;
1463 u32 current_data_flag = 0;
1464 int current_data_offset = 0;
1473 else if (
unformat (input,
"del-chain"))
1478 else if (
unformat (input,
"buckets %d", &nbuckets))
1480 else if (
unformat (input,
"skip %d", &skip))
1482 else if (
unformat (input,
"match %d", &match))
1484 else if (
unformat (input,
"table %d", &table_index))
1487 &mask, &skip, &match))
1489 else if (
unformat (input,
"memory-size %uM", &tmp))
1490 memory_size = tmp<<20;
1491 else if (
unformat (input,
"memory-size %uG", &tmp))
1492 memory_size = tmp<<30;
1493 else if (
unformat (input,
"next-table %d", &next_table_index))
1507 else if (
unformat (input,
"current-data-flag %d", ¤t_data_flag))
1509 else if (
unformat (input,
"current-data-offset %d", ¤t_data_offset))
1516 if (is_add && mask == 0 && table_index == ~0)
1519 if (is_add && skip == ~0 && table_index == ~0)
1522 if (is_add && match == ~0 && table_index == ~0)
1525 if (!is_add && table_index == ~0)
1529 skip, match, next_table_index, miss_next_index, &table_index,
1530 current_data_flag, current_data_offset, is_add, del_chain);
1544 .path =
"classify table",
1546 "classify table [miss-next|l2-miss_next|acl-miss-next <next_index>]" 1547 "\n mask <mask-value> buckets <nn> [skip <n>] [match <n>]" 1548 "\n [current-data-flag <n>] [current-data-offset <n>] [table <n>]" 1549 "\n [del] [del-chain]",
1556 int verbose = va_arg (*args,
int);
1557 u32 index = va_arg (*args,
u32);
1562 s =
format (s,
"%10s%10s%10s%10s",
"TableIdx",
"Sessions",
"NextTbl",
1563 "NextNode", verbose ?
"Details" :
"");
1573 s =
format (s,
"\n nbuckets %d, skip %d match %d flag %d offset %d",
1595 u32 match_index = ~0;
1602 if (
unformat (input,
"index %d", &match_index))
1604 else if (
unformat (input,
"verbose %d", &verbose))
1606 else if (
unformat (input,
"verbose"))
1614 if (match_index == ~0 || (match_index == t - cm->tables))
1615 vec_add1 (indices, t - cm->tables);
1622 for (i = 0; i <
vec_len (indices); i++)
1624 verbose, indices[i]);
1635 .path =
"show classify tables",
1636 .short_help =
"show classify tables [index <nn>]",
1642 u8 ** matchp = va_arg (*args,
u8 **);
1644 u8 * proto_header = 0;
1652 if (
unformat (input,
"src_port %d", &src_port))
1654 else if (
unformat (input,
"dst_port %d", &dst_port))
1660 h.
src_port = clib_host_to_net_u16(src_port);
1661 h.
dst_port = clib_host_to_net_u16(dst_port);
1663 memcpy(proto_header, &h,
sizeof(h));
1665 *matchp = proto_header;
1672 u8 ** matchp = va_arg (*args,
u8 **);
1679 int src = 0, dst = 0;
1687 int fragment_id = 0;
1688 u32 fragment_id_val;
1696 if (
unformat (input,
"version %d", &version_val))
1698 else if (
unformat (input,
"hdr_length %d", &hdr_length_val))
1704 else if (
unformat (input,
"proto %d", &proto_val))
1706 else if (
unformat (input,
"tos %d", &tos_val))
1708 else if (
unformat (input,
"length %d", &length_val))
1710 else if (
unformat (input,
"fragment_id %d", &fragment_id_val))
1712 else if (
unformat (input,
"ttl %d", &ttl_val))
1714 else if (
unformat (input,
"checksum %d", &checksum_val))
1720 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
1721 + ttl + checksum == 0)
1753 ip->
length = clib_host_to_net_u16 (length_val);
1759 ip->
checksum = clib_host_to_net_u16 (checksum_val);
1767 u8 ** matchp = va_arg (*args,
u8 **);
1772 u8 traffic_class = 0;
1773 u32 traffic_class_val;
1776 int src = 0, dst = 0;
1780 int payload_length = 0;
1781 u32 payload_length_val;
1784 u32 ip_version_traffic_class_and_flow_label;
1788 if (
unformat (input,
"version %d", &version_val))
1790 else if (
unformat (input,
"traffic_class %d", &traffic_class_val))
1792 else if (
unformat (input,
"flow_label %d", &flow_label_val))
1798 else if (
unformat (input,
"proto %d", &proto_val))
1800 else if (
unformat (input,
"payload_length %d", &payload_length_val))
1802 else if (
unformat (input,
"hop_limit %d", &hop_limit_val))
1808 if (version + traffic_class + flow_label + src + dst + proto +
1809 payload_length + hop_limit == 0)
1828 ip_version_traffic_class_and_flow_label = 0;
1831 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
1834 ip_version_traffic_class_and_flow_label |= (traffic_class_val & 0xFF) << 20;
1837 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
1840 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
1854 u8 ** matchp = va_arg (*args,
u8 **);
1870 u8 * tagp = va_arg (*args,
u8 *);
1875 tagp[0] = (tag>>8) & 0x0F;
1876 tagp[1] = tag & 0xFF;
1885 u8 ** matchp = va_arg (*args,
u8 **);
1910 else if (
unformat (input,
"proto %U",
1917 else if (
unformat (input,
"ignore-tag1"))
1919 else if (
unformat (input,
"ignore-tag2"))
1921 else if (
unformat (input,
"cos1 %d", &cos1_val))
1923 else if (
unformat (input,
"cos2 %d", &cos2_val))
1928 if ((src + dst + proto + tag1 + tag2 +
1929 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
1932 if (tag1 || ignore_tag1 || cos1)
1934 if (tag2 || ignore_tag2 || cos2)
1948 match[19] = tag2_val[1];
1949 match[18] = tag2_val[0];
1951 match [18] |= (cos2_val & 0x7) << 5;
1954 match[21] = proto_val & 0xff;
1955 match[20] = proto_val >> 8;
1959 match [15] = tag1_val[1];
1960 match [14] = tag1_val[0];
1963 match [14] |= (cos1_val & 0x7) << 5;
1969 match [15] = tag1_val[1];
1970 match [14] = tag1_val[0];
1973 match[17] = proto_val & 0xff;
1974 match[16] = proto_val >> 8;
1977 match [14] |= (cos1_val & 0x7) << 5;
1983 match [18] |= (cos2_val & 0x7) << 5;
1985 match [14] |= (cos1_val & 0x7) << 5;
1988 match[13] = proto_val & 0xff;
1989 match[12] = proto_val >> 8;
2000 u8 ** matchp = va_arg (*args,
u8 **);
2001 u32 table_index = va_arg (*args,
u32);
2034 if (match || l2 || l3 || l4)
2081 vnet_classify_entry_5_t _max_e __attribute__((aligned (16)));
2082 vnet_classify_entry_t * e;
2086 return VNET_API_ERROR_NO_SUCH_TABLE;
2090 e = (vnet_classify_entry_t *)&_max_e;
2091 e->next_index = hit_next_index;
2092 e->opaque_index = opaque_index;
2093 e->advance = advance;
2111 e->key[i] &= t->
mask[i];
2118 return VNET_API_ERROR_NO_SUCH_ENTRY;
2129 u32 table_index = ~0;
2130 u32 hit_next_index = ~0;
2131 u64 opaque_index = ~0;
2154 else if (
unformat (input,
"policer-hit-next %U",
2157 else if (
unformat (input,
"opaque-index %lld", &opaque_index))
2160 cm, &match, table_index))
2162 else if (
unformat (input,
"advance %d", &advance))
2164 else if (
unformat (input,
"table-index %d", &table_index))
2166 else if (
unformat (input,
"action set-ip4-fib-id %d", &metadata))
2168 else if (
unformat (input,
"action set-ip6-fib-id %d", &metadata))
2173 for (i = 0; i <
vec_len (cm->unformat_opaque_index_fns); i++)
2175 if (
unformat (input,
"%U", cm->unformat_opaque_index_fns[i],
2185 if (table_index == ~0)
2188 if (is_add && match == 0)
2193 opaque_index, advance,
2194 action, metadata, is_add);
2210 .path =
"classify session",
2212 "classify session [hit-next|l2-hit-next|" 2213 "acl-hit-next <next_index>|policer-hit-next <policer_name>]" 2214 "\n table-index <nn> match [hex] [l2] [l3 ip4] [opaque-index <index>]" 2215 "\n [action set-ip4-fib-id <n>] [action set-ip6-fib-id <n>] [del]",
2222 u64 * opaquep = va_arg (*args,
u64 *);
2228 *opaquep = sw_if_index;
2238 u32 * next_indexp = va_arg (*args,
u32 *);
2240 u32 next_index = ~0;
2243 cm->vlib_main, &node_index))
2249 cm->vlib_main, &node_index))
2257 *next_indexp = next_index;
2265 u32 * next_indexp = va_arg (*args,
u32 *);
2270 cm->vlib_main, &node_index))
2276 cm->vlib_main, &node_index))
2284 *next_indexp = next_index;
2292 u32 * next_indexp = va_arg (*args,
u32 *);
2297 cm->vlib_main, &node_index))
2302 *next_indexp = next_index;
2312 u32 * next_indexp = va_arg (*args,
u32 *);
2317 cm->vlib_main, &node_index))
2322 *next_indexp = next_index;
2398 classify_data_or_mask_t *mask, *data;
2401 u8 *mp = 0, *dp = 0;
2408 mask = (classify_data_or_mask_t *) mp;
2409 data = (classify_data_or_mask_t *) dp;
2412 memset (&mask->ip.src_address, 0xff, 4);
2414 tmp = clib_host_to_net_u32 (tm->
src.
as_u32);
2419 ep->
addr.
as_u32 = clib_host_to_net_u32 (tmp);
2435 vlib_cli_output (vm,
"Initialize: add %d (approx. half of %d sessions)...",
2438 for (i = 0; i < tm->
sessions/2; i++)
2442 data->ip.src_address.as_u32 = ep->
addr.
as_u32;
2475 data->ip.src_address.as_u32 = ep->
addr.
as_u32;
2482 is_add ?
"add" :
"del",
2497 "%s[%d]: %U returned %d", is_add ?
"add" :
"del",
2510 u8 * key_minus_skip;
2512 vnet_classify_entry_t * e;
2518 data->ip.src_address.as_u32 = ep->
addr.
as_u32;
2523 (
u8 *) data, hash, 0 );
2526 clib_warning (
"Couldn't find %U index %d which should be present",
2531 key_minus_skip = (
u8 *)e->key;
2584 tm->
src.
as_u32 = clib_net_to_host_u32 (0x0100000A);
2586 tm->
seed = 0xDEADDABE;
2594 if (
unformat (input,
"sessions %d", &tmp))
2600 else if (
unformat (input,
"memory-size %uM", &tmp))
2602 else if (
unformat (input,
"memory-size %uG", &tmp))
2606 else if (
unformat (input,
"verbose"))
2611 else if (
unformat (input,
"churn-test"))
2631 .path =
"test classify",
2633 "test classify [src <ip>] [sessions <nn>] [buckets <nn>] [seed <nnn>]\n" 2634 " [memory-size <nn>[M|G]]\n" 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)
vnet_main_t * vnet_get_main(void)
void fib_table_lock(u32 fib_index, fib_protocol_t proto)
Release a reference counting lock on the table.
classify_data_or_mask_t * mask
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)
static void vnet_classify_entry_claim_resource(vnet_classify_entry_t *e)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
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
static clib_error_t * test_classify_churn(test_classify_main_t *tm)
void vnet_classify_register_unformat_acl_next_index_fn(unformat_function_t *fn)
struct _tcp_header tcp_header_t
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
u8 * format_mheap(u8 *s, va_list *va)
vlib_node_registration_t ip4_classify_node
(constructor) VLIB_REGISTER_NODE (ip4_classify_node)
uword unformat_l2_output_next_index(unformat_input_t *input, va_list *args)
vnet_classify_main_t * classify_main
void mv(vnet_classify_table_t *t)
vlib_node_registration_t l2_input_classify_node
(constructor) VLIB_REGISTER_NODE (l2_input_classify_node)
#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)
vlib_node_registration_t l2_output_classify_node
(constructor) VLIB_REGISTER_NODE (l2_output_classify_node)
static uword unformat_l2_input_next_node(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 vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
#define clib_error_return(e, args...)
#define foreach_ip4_proto_field
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)
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, u8 action, u32 metadata, int is_add)
static u64 vnet_classify_hash_packet_inline(vnet_classify_table_t *t, u8 *h)
void fib_table_unlock(u32 fib_index, fib_protocol_t proto)
Take a reference counting lock on the table.
uword unformat_l4_match(unformat_input_t *input, va_list *args)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
static test_classify_main_t test_classify_main
uword unformat_ip4_mask(unformat_input_t *input, va_list *args)
uword unformat_l2_input_next_index(unformat_input_t *input, va_list *args)
uword unformat_ip6_mask(unformat_input_t *input, va_list *args)
void vnet_classify_delete_table_index(vnet_classify_main_t *cm, u32 table_index, int del_chain)
#define pool_put(P, E)
Free an object E in pool P.
static vnet_classify_entry_t * split_and_rehash_linear(vnet_classify_table_t *t, vnet_classify_entry_t *old_values, u32 old_log2_pages, u32 new_log2_pages)
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)
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 foreach_udp_proto_field
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P (general version).
static vnet_classify_entry_t * split_and_rehash(vnet_classify_table_t *t, vnet_classify_entry_t *old_values, u32 old_log2_pages, u32 new_log2_pages)
uword unformat_udp_mask(unformat_input_t *input, va_list *args)
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
Adjacency to drop this packet.
static uword unformat_acl_next_node(unformat_input_t *input, va_list *args)
static_always_inline uword vlib_get_thread_index(void)
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)
classify_data_or_mask_t * data
static void * clib_mem_set_heap(void *heap)
static uword unformat_ip_next_node(unformat_input_t *input, va_list *args)
static void vnet_classify_entry_free(vnet_classify_table_t *t, vnet_classify_entry_t *v, u32 log2_pages)
u8 * format_classify_table(u8 *s, va_list *args)
#define clib_warning(format, 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)
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)
#define VLIB_CLI_COMMAND(x,...)
struct _vnet_classify_main vnet_classify_main_t
static uword unformat_l2_output_next_node(unformat_input_t *input, va_list *args)
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)
static void clib_mem_free(void *p)
u32 fib_table_find_or_create_and_lock(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
#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
static void vnet_classify_entry_release_resource(vnet_classify_entry_t *e)
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, u8 current_data_flag, i16 current_data_offset, int is_add, int del_chain)
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)
uword unformat_tcp_mask(unformat_input_t *input, va_list *args)
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)
uword unformat_l4_mask(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 * clib_mem_alloc_aligned(uword size, uword align)
static u32 random_u32(u32 *seed)
32-bit random number generator
#define foreach_l2_output_next
#define foreach_l2_input_next
int * working_copy_lengths
#define CLIB_MEMORY_BARRIER()
void vnet_classify_register_unformat_policer_next_index_fn(unformat_function_t *fn)
vlib_node_registration_t ip6_classify_node
(constructor) VLIB_REGISTER_NODE (ip6_classify_node)
#define foreach_tcp_proto_field
#define CLIB_CACHE_LINE_BYTES
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
vnet_classify_entry_t ** freelists
vnet_classify_entry_t * vnet_classify_find_entry(vnet_classify_table_t *t, u8 *h, u64 hash, f64 now)
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)
vnet_classify_table_t * table