31 #if VALIDATION_SCAFFOLDING 47 vnet_classify_entry_t *v, *save_v;
48 u32 active_elements = 0;
71 clib_warning (
"found %u expected %u elts", active_elements,
91 vec_add1 (cm->unformat_l2_next_index_fns, fn);
99 vec_add1 (cm->unformat_ip_next_index_fns, fn);
107 vec_add1 (cm->unformat_acl_next_index_fns, fn);
116 vec_add1 (cm->unformat_policer_next_index_fns, fn);
124 vec_add1 (cm->unformat_opaque_index_fns, fn);
130 u32 skip_n_vectors,
u32 match_n_vectors)
135 nbuckets = 1 << (
max_log2 (nbuckets));
164 u32 table_index,
int del_chain)
183 static vnet_classify_entry_t *
186 vnet_classify_entry_t *rv = 0;
230 vnet_classify_entry_t *v;
233 vnet_classify_entry_t *working_copy;
235 int working_copy_length, required_length;
260 if (required_length > working_copy_length)
275 working_bucket.as_u64 = b->
as_u64;
278 b->
as_u64 = working_bucket.as_u64;
282 static vnet_classify_entry_t *
284 vnet_classify_entry_t * old_values,
u32 old_log2_pages,
287 vnet_classify_entry_t *new_values, *v, *new_v;
288 int i, j, length_in_entries;
293 for (i = 0; i < length_in_entries; i++)
303 key_minus_skip = (
u8 *) v->key;
308 new_hash &= (1 << new_log2_pages) - 1;
333 static vnet_classify_entry_t *
335 vnet_classify_entry_t * old_values,
336 u32 old_log2_pages,
u32 new_log2_pages)
338 vnet_classify_entry_t *new_values, *v, *new_v;
339 int i, j, new_length_in_entries, old_length_in_entries;
346 for (i = 0; i < old_length_in_entries; i++)
352 for (; j < new_length_in_entries; j++)
358 clib_warning (
"BUG: linear rehash new entry not free!");
416 vnet_classify_entry_t * add_v,
int is_add)
420 vnet_classify_entry_t *v, *new_v, *save_new_v, *working_copy, *save_v;
426 u32 old_log2_pages, new_log2_pages;
429 int resplit_once = 0;
430 int mark_bucket_linear;
434 key_minus_skip = (
u8 *) add_v->key;
439 bucket_index = hash & (t->
nbuckets - 1);
478 limit *= (1 << b->log2_pages);
488 for (i = 0; i < limit; i++)
506 for (i = 0; i < limit; i++)
527 for (i = 0; i < limit; i++)
535 clib_memset (v, 0xff,
sizeof (vnet_classify_entry_t) +
551 new_log2_pages = old_log2_pages + 1;
557 mark_bucket_linear = 0;
581 mark_bucket_linear = 1;
588 key_minus_skip = (
u8 *) add_v->key;
593 new_hash &= (1 << new_log2_pages) - 1;
596 if (mark_bucket_linear)
598 limit *= (1 << new_log2_pages);
602 for (i = 0; i < limit; i++)
644 }) classify_data_or_mask_t;
653 vnet_classify_entry_t *
664 vnet_classify_entry_t *e = va_arg (*args, vnet_classify_entry_t *);
667 (s,
"[%u]: next_index %d advance %d opaque %d action %d metadata %d\n",
669 e->opaque_index, e->action, e->metadata);
676 s =
format (s,
" hits %lld, last_heard %.2f\n",
677 e->hits, e->last_heard);
679 s =
format (s,
" entry is free\n");
687 int verbose = va_arg (*args,
int);
689 vnet_classify_entry_t *v, *save_v;
691 u64 active_elements = 0;
699 s =
format (s,
"[%d]: empty\n", i);
705 s =
format (s,
"[%d]: heap offset %d, elts %d, %s\n", i,
722 s =
format (s,
" %d: empty\n",
728 s =
format (s,
" %d: %U\n",
737 s =
format (s,
" %lld active elements\n", active_elements);
750 u32 next_table_index,
753 u8 current_data_flag,
754 i16 current_data_offset,
755 int is_add,
int del_chain)
761 if (*table_index == ~0)
763 if (memory_size == 0)
764 return VNET_API_ERROR_INVALID_MEMORY_SIZE;
767 return VNET_API_ERROR_INVALID_VALUE;
769 if (match < 1 || match > 5)
770 return VNET_API_ERROR_INVALID_VALUE;
778 *table_index = t - cm->tables;
794 #define foreach_tcp_proto_field \ 798 #define foreach_udp_proto_field \ 802 #define foreach_ip4_proto_field \ 815 u8 **maskp = va_arg (*args,
u8 **);
817 u8 found_something = 0;
827 #define _(a) else if (unformat (input, #a)) a=1; 834 #define _(a) found_something += a; 838 if (found_something == 0)
845 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a)); 856 u8 **maskp = va_arg (*args,
u8 **);
858 u8 found_something = 0;
868 #define _(a) else if (unformat (input, #a)) a=1; 875 #define _(a) found_something += a; 879 if (found_something == 0)
886 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a)); 902 u8 **maskp = va_arg (*args,
u8 **);
912 else if (
unformat (input,
"src_port"))
914 else if (
unformat (input,
"dst_port"))
938 u8 **maskp = va_arg (*args,
u8 **);
940 u8 found_something = 0;
942 u32 src_prefix_len = 32;
943 u32 src_prefix_mask = ~0;
944 u32 dst_prefix_len = 32;
945 u32 dst_prefix_mask = ~0;
958 else if (
unformat (input,
"hdr_length"))
960 else if (
unformat (input,
"src/%d", &src_prefix_len))
963 src_prefix_mask &= ~((1 << (32 - src_prefix_len)) - 1);
964 src_prefix_mask = clib_host_to_net_u32 (src_prefix_mask);
966 else if (
unformat (input,
"dst/%d", &dst_prefix_len))
969 dst_prefix_mask &= ~((1 << (32 - dst_prefix_len)) - 1);
970 dst_prefix_mask = clib_host_to_net_u32 (dst_prefix_mask);
979 #define _(a) else if (unformat (input, #a)) a=1; 986 #define _(a) found_something += a; 990 if (found_something == 0)
997 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a)); 1019 #define foreach_ip6_proto_field \ 1029 u8 **maskp = va_arg (*args,
u8 **);
1033 u32 ip_version_traffic_class_and_flow_label;
1035 #define _(a) u8 a=0; 1039 u8 traffic_class = 0;
1046 else if (
unformat (input,
"traffic-class"))
1048 else if (
unformat (input,
"flow-label"))
1054 else if (
unformat (input,
"proto"))
1057 #define _(a) else if (unformat (input, #a)) a=1; 1065 found_something = version + traffic_class + flow_label
1068 #define _(a) found_something += a; 1072 if (found_something == 0)
1079 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a)); 1083 ip_version_traffic_class_and_flow_label = 0;
1086 ip_version_traffic_class_and_flow_label |= 0xF0000000;
1089 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
1092 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
1095 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
1104 u8 **maskp = va_arg (*args,
u8 **);
1121 u8 **maskp = va_arg (*args,
u8 **);
1142 else if (
unformat (input,
"proto"))
1148 else if (
unformat (input,
"ignore-tag1"))
1150 else if (
unformat (input,
"ignore-tag2"))
1156 else if (
unformat (input,
"dot1q"))
1158 else if (
unformat (input,
"dot1ad"))
1163 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
1164 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
1167 if (tag1 || ignore_tag1 || cos1 || dot1q)
1169 if (tag2 || ignore_tag2 || cos2 || dot1ad)
1191 mask[21] = mask[20] = 0xff;
1212 mask[16] = mask[17] = 0xff;
1221 mask[12] = mask[13] = 0xff;
1230 u8 **maskp = va_arg (*args,
u8 **);
1231 u32 *skipp = va_arg (*args,
u32 *);
1232 u32 *matchp = va_arg (*args,
u32 *);
1262 if (mask || l2 || l3 || l4)
1283 for (i = 0; i <
vec_len (mask); i++)
1288 *skipp = i /
sizeof (
u32x4);
1292 while (vec_len (mask) %
sizeof (
u32x4))
1297 for (i = match *
sizeof (
u32x4); i > 0; i -=
sizeof (
u32x4))
1300 if (*tmp || *(tmp + 1))
1307 _vec_len (mask) = match *
sizeof (
u32x4);
1318 #define foreach_l2_input_next \ 1320 _(ethernet, ETHERNET_INPUT) \ 1329 u32 *miss_next_indexp = va_arg (*args,
u32 *);
1335 for (i = 0; i <
vec_len (cm->unformat_l2_next_index_fns); i++)
1337 if (
unformat (input,
"%U", cm->unformat_l2_next_index_fns[i], &tmp))
1345 if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;} 1358 *miss_next_indexp = next_index;
1362 #define foreach_l2_output_next \ 1369 u32 *miss_next_indexp = va_arg (*args,
u32 *);
1375 for (i = 0; i <
vec_len (cm->unformat_l2_next_index_fns); i++)
1377 if (
unformat (input,
"%U", cm->unformat_l2_next_index_fns[i], &tmp))
1385 if (unformat (input, #n)) { next_index = L2_OUTPUT_CLASSIFY_NEXT_##N; goto out;} 1398 *miss_next_indexp = next_index;
1402 #define foreach_ip_next \ 1409 u32 *miss_next_indexp = va_arg (*args,
u32 *);
1416 for (i = 0; i <
vec_len (cm->unformat_ip_next_index_fns); i++)
1418 if (
unformat (input,
"%U", cm->unformat_ip_next_index_fns[i], &tmp))
1426 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;} 1439 *miss_next_indexp = next_index;
1443 #define foreach_acl_next \ 1449 u32 *next_indexp = va_arg (*args,
u32 *);
1456 for (i = 0; i <
vec_len (cm->unformat_acl_next_index_fns); i++)
1458 if (
unformat (input,
"%U", cm->unformat_acl_next_index_fns[i], &tmp))
1466 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;} 1475 else if (
unformat (input,
"%d", &tmp))
1484 *next_indexp = next_index;
1491 u32 *next_indexp = va_arg (*args,
u32 *);
1498 for (i = 0; i <
vec_len (cm->unformat_policer_next_index_fns); i++)
1501 (input,
"%U", cm->unformat_policer_next_index_fns[i], &tmp))
1517 *next_indexp = next_index;
1530 u32 table_index = ~0;
1531 u32 next_table_index = ~0;
1532 u32 miss_next_index = ~0;
1535 u32 current_data_flag = 0;
1536 int current_data_offset = 0;
1546 else if (
unformat (input,
"del-chain"))
1551 else if (
unformat (input,
"buckets %d", &nbuckets))
1553 else if (
unformat (input,
"skip %d", &skip))
1555 else if (
unformat (input,
"match %d", &match))
1557 else if (
unformat (input,
"table %d", &table_index))
1560 &mask, &skip, &match))
1562 else if (
unformat (input,
"memory-size %uM", &tmp))
1563 memory_size = tmp << 20;
1564 else if (
unformat (input,
"memory-size %uG", &tmp))
1565 memory_size = tmp << 30;
1566 else if (
unformat (input,
"next-table %d", &next_table_index))
1584 else if (
unformat (input,
"current-data-flag %d", ¤t_data_flag))
1587 if (
unformat (input,
"current-data-offset %d", ¤t_data_offset))
1594 if (is_add && mask == 0 && table_index == ~0)
1597 if (is_add && skip == ~0 && table_index == ~0)
1600 if (is_add && match == ~0 && table_index == ~0)
1603 if (!is_add && table_index == ~0)
1607 skip, match, next_table_index,
1608 miss_next_index, &table_index,
1609 current_data_flag, current_data_offset,
1626 .path =
"classify table",
1628 "classify table [miss-next|l2-miss_next|acl-miss-next <next_index>]" 1629 "\n mask <mask-value> buckets <nn> [skip <n>] [match <n>]" 1630 "\n [current-data-flag <n>] [current-data-offset <n>] [table <n>]" 1631 "\n [memory-size <nn>[M][G]] [next-table <n>]" 1632 "\n [del] [del-chain]",
1688 u32 table_index = ~0;
1689 u32 next_table_index = ~0;
1690 u32 miss_next_index = ~0;
1691 u32 current_data_flag = 0;
1692 int current_data_offset = 0;
1708 else if (
unformat (input,
"pcap %=", &pcap, 1))
1710 else if (
unformat (input,
"trace"))
1715 if (sw_if_index == 0)
1718 else if (
unformat (input,
"buckets %d", &nbuckets))
1721 &mask, &skip, &match))
1730 if (is_add && mask == 0 && table_index == ~0)
1733 if (is_add && skip == ~0 && table_index == ~0)
1736 if (is_add && match == ~0 && table_index == ~0)
1739 if (sw_if_index == ~0 && pkt_trace == 0 && pcap == 0)
1742 if (pkt_trace && pcap)
1744 (0,
"Packet trace and pcap are mutually exclusive...");
1746 if (pkt_trace && sw_if_index != ~0)
1754 else if (sw_if_index <
vec_len (cm->filter_set_by_sw_if_index))
1755 set_index = cm->filter_set_by_sw_if_index[
sw_if_index];
1757 if (set_index == ~0)
1761 "No pkt trace classify filter set...");
1762 if (sw_if_index == 0)
1773 ASSERT (set->refcnt >= 0);
1774 if (set->refcnt == 0)
1777 table_index =
set->table_indices[0];
1788 if (sw_if_index > 0)
1802 else if (sw_if_index <
vec_len (cm->filter_set_by_sw_if_index))
1803 set_index = cm->filter_set_by_sw_if_index[
sw_if_index];
1806 if (set_index == ~0)
1809 set_index =
set - cm->filter_sets;
1815 for (i = 0; i <
vec_len (set->table_indices); i++)
1822 if (vec_len (t->
mask) != vec_len (mask))
1825 if (memcmp (t->
mask, mask, vec_len (mask)))
1835 skip, match, next_table_index,
1836 miss_next_index, &table_index,
1837 current_data_flag, current_data_offset,
1855 vec_add1 (set->table_indices, table_index);
1863 cm->filter_set_by_sw_if_index[
sw_if_index] =
set - cm->filter_sets;
1867 if (sw_if_index > 0 && pkt_trace == 0)
1880 for (i = 0; i <
vec_len (set->table_indices); i++)
1884 if ((i + 1) < vec_len (set->table_indices))
1894 cm, &match_vector, table_index) == 0)
1924 if (set_index == ~0)
1929 set->table_indices[0];
2014 .path =
"classify filter",
2016 "classify filter <intfc> | pcap mask <mask-value> match <match-value>\n" 2017 " | trace mask <mask-value> match <match-value> [del]\n" 2018 " [buckets <nn>] [memory-size <n>]",
2038 (void)
unformat (input,
"verbose %=", &verbose, 1);
2043 limit =
vec_len (cm->filter_set_by_sw_if_index);
2045 for (i = -1; i < limit; i++)
2050 set_index = cm->filter_set_by_sw_if_index[
i];
2052 if (set_index == ~0)
2060 name =
format (0,
"packet tracer:");
2063 name =
format (0,
"pcap rx/tx/drop:");
2074 for (j = 0; j <
vec_len (set->table_indices); j++)
2076 table_index =
set->table_indices[j];
2077 if (table_index != ~0)
2078 s =
format (s,
" %u", table_index);
2088 table_index =
set->table_indices ?
set->table_indices[0] : ~0;
2090 if (table_index != ~0)
2091 s =
format (s,
" %u", table_index);
2109 .path =
"show classify filter",
2110 .short_help =
"show classify filter [verbose [nn]]",
2122 int verbose = va_arg (*args,
int);
2128 s =
format (s,
"%10s%10s%10s%10s",
"TableIdx",
"Sessions",
"NextTbl",
2129 "NextNode", verbose ?
"Details" :
"");
2139 s =
format (s,
"\n nbuckets %d, skip %d match %d flag %d offset %d",
2161 u32 match_index = ~0;
2168 if (
unformat (input,
"index %d", &match_index))
2170 else if (
unformat (input,
"verbose %d", &verbose))
2172 else if (
unformat (input,
"verbose"))
2181 if (match_index == ~0 || (match_index == t - cm->tables))
2182 vec_add1 (indices, t - cm->tables);
2190 for (i = 0; i <
vec_len (indices); i++)
2192 verbose, indices[i]);
2204 .path =
"show classify tables",
2205 .short_help =
"show classify tables [index <nn>]",
2213 u8 **matchp = va_arg (*args,
u8 **);
2215 u8 *proto_header = 0;
2223 if (
unformat (input,
"src_port %d", &src_port))
2225 else if (
unformat (input,
"dst_port %d", &dst_port))
2231 h.
src_port = clib_host_to_net_u16 (src_port);
2232 h.
dst_port = clib_host_to_net_u16 (dst_port);
2234 memcpy (proto_header, &h,
sizeof (h));
2236 *matchp = proto_header;
2244 u8 **matchp = va_arg (*args,
u8 **);
2259 int fragment_id = 0;
2260 u32 fragment_id_val;
2268 if (
unformat (input,
"version %d", &version_val))
2270 else if (
unformat (input,
"hdr_length %d", &hdr_length_val))
2276 else if (
unformat (input,
"proto %d", &proto_val))
2278 else if (
unformat (input,
"tos %d", &tos_val))
2280 else if (
unformat (input,
"length %d", &length_val))
2282 else if (
unformat (input,
"fragment_id %d", &fragment_id_val))
2284 else if (
unformat (input,
"ttl %d", &ttl_val))
2286 else if (
unformat (input,
"checksum %d", &checksum_val))
2292 if (version + hdr_length + src +
dst + proto + tos + length + fragment_id
2293 + ttl + checksum == 0)
2325 ip->
length = clib_host_to_net_u16 (length_val);
2331 ip->
checksum = clib_host_to_net_u16 (checksum_val);
2340 u8 **matchp = va_arg (*args,
u8 **);
2345 u8 traffic_class = 0;
2346 u32 traffic_class_val;
2350 ip6_address_t src_val, dst_val;
2353 int payload_length = 0;
2354 u32 payload_length_val;
2357 u32 ip_version_traffic_class_and_flow_label;
2361 if (
unformat (input,
"version %d", &version_val))
2363 else if (
unformat (input,
"traffic_class %d", &traffic_class_val))
2365 else if (
unformat (input,
"flow_label %d", &flow_label_val))
2371 else if (
unformat (input,
"proto %d", &proto_val))
2373 else if (
unformat (input,
"payload_length %d", &payload_length_val))
2375 else if (
unformat (input,
"hop_limit %d", &hop_limit_val))
2381 if (version + traffic_class + flow_label + src +
dst + proto +
2382 payload_length + hop_limit == 0)
2401 ip_version_traffic_class_and_flow_label = 0;
2404 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
2407 ip_version_traffic_class_and_flow_label |=
2408 (traffic_class_val & 0xFF) << 20;
2411 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
2414 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
2429 u8 **matchp = va_arg (*args,
u8 **);
2447 u8 *tagp = va_arg (*args,
u8 *);
2452 tagp[0] = (tag >> 8) & 0x0F;
2453 tagp[1] = tag & 0xFF;
2463 u8 **matchp = va_arg (*args,
u8 **);
2490 else if (
unformat (input,
"proto %U",
2497 else if (
unformat (input,
"ignore-tag1"))
2499 else if (
unformat (input,
"ignore-tag2"))
2501 else if (
unformat (input,
"cos1 %d", &cos1_val))
2503 else if (
unformat (input,
"cos2 %d", &cos2_val))
2508 if ((src + dst + proto + tag1 + tag2 +
2509 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
2512 if (tag1 || ignore_tag1 || cos1)
2514 if (tag2 || ignore_tag2 || cos2)
2528 match[19] = tag2_val[1];
2529 match[18] = tag2_val[0];
2531 match[18] |= (cos2_val & 0x7) << 5;
2534 match[21] = proto_val & 0xff;
2535 match[20] = proto_val >> 8;
2539 match[15] = tag1_val[1];
2540 match[14] = tag1_val[0];
2543 match[14] |= (cos1_val & 0x7) << 5;
2549 match[15] = tag1_val[1];
2550 match[14] = tag1_val[0];
2553 match[17] = proto_val & 0xff;
2554 match[16] = proto_val >> 8;
2557 match[14] |= (cos1_val & 0x7) << 5;
2563 match[18] |= (cos2_val & 0x7) << 5;
2565 match[14] |= (cos1_val & 0x7) << 5;
2568 match[13] = proto_val & 0xff;
2569 match[12] = proto_val >> 8;
2581 u8 **matchp = va_arg (*args,
u8 **);
2582 u32 table_index = va_arg (*args,
u32);
2617 if (match || l2 || l3 || l4)
2665 vnet_classify_entry_5_t _max_e __attribute__ ((aligned (16)));
2666 vnet_classify_entry_t *e;
2670 return VNET_API_ERROR_NO_SUCH_TABLE;
2674 e = (vnet_classify_entry_t *) & _max_e;
2675 e->next_index = hit_next_index;
2676 e->opaque_index = opaque_index;
2677 e->advance = advance;
2691 e->metadata = metadata;
2701 e->key[i] &= t->
mask[i];
2708 return VNET_API_ERROR_NO_SUCH_ENTRY;
2719 u32 table_index = ~0;
2720 u32 hit_next_index = ~0;
2721 u64 opaque_index = ~0;
2748 else if (
unformat (input,
"policer-hit-next %U",
2751 else if (
unformat (input,
"opaque-index %lld", &opaque_index))
2754 cm, &match, table_index))
2756 else if (
unformat (input,
"advance %d", &advance))
2758 else if (
unformat (input,
"table-index %d", &table_index))
2760 else if (
unformat (input,
"action set-ip4-fib-id %d", &metadata))
2762 else if (
unformat (input,
"action set-ip6-fib-id %d", &metadata))
2764 else if (
unformat (input,
"action set-sr-policy-index %d", &metadata))
2769 for (i = 0; i <
vec_len (cm->unformat_opaque_index_fns); i++)
2771 if (
unformat (input,
"%U", cm->unformat_opaque_index_fns[i],
2781 if (table_index == ~0)
2784 if (is_add && match == 0)
2789 opaque_index, advance,
2790 action, metadata, is_add);
2799 "vnet_classify_add_del_session returned %d",
2808 .path =
"classify session",
2810 "classify session [hit-next|l2-input-hit-next|l2-output-hit-next|" 2811 "acl-hit-next <next_index>|policer-hit-next <policer_name>]" 2812 "\n table-index <nn> match [hex] [l2] [l3 ip4] [opaque-index <index>]" 2813 "\n [action set-ip4-fib-id|set-ip6-fib-id|set-sr-policy-index <n>] [del]",
2821 u64 *opaquep = va_arg (*args,
u64 *);
2837 u32 *next_indexp = va_arg (*args,
u32 *);
2839 u32 next_index = ~0;
2842 cm->vlib_main, &node_index))
2848 cm->vlib_main, &node_index))
2856 *next_indexp = next_index;
2864 u32 *next_indexp = va_arg (*args,
u32 *);
2869 cm->vlib_main, &node_index))
2875 cm->vlib_main, &node_index))
2883 *next_indexp = next_index;
2891 u32 *next_indexp = va_arg (*args,
u32 *);
2896 cm->vlib_main, &node_index))
2901 *next_indexp = next_index;
2911 u32 *next_indexp = va_arg (*args,
u32 *);
2916 cm->vlib_main, &node_index))
2921 *next_indexp = next_index;
2951 set->refcnt = 0x7FFFFFFF;
2954 cm->filter_set_by_sw_if_index[0] = 0;
2998 classify_data_or_mask_t *
mask;
2999 classify_data_or_mask_t *
data;
3005 } test_classify_main_t;
3007 static test_classify_main_t test_classify_main;
3010 test_classify_churn (test_classify_main_t * tm)
3012 classify_data_or_mask_t *
mask, *
data;
3015 u8 *mp = 0, *dp = 0;
3022 mask = (classify_data_or_mask_t *) mp;
3023 data = (classify_data_or_mask_t *) dp;
3028 tmp = clib_host_to_net_u32 (tm->src.as_u32);
3030 for (i = 0; i < tm->sessions; i++)
3033 ep->addr.as_u32 = clib_host_to_net_u32 (tmp);
3041 tm->memory_size, 0 ,
3044 tm->table_index = tm->table - tm->classify_main->tables;
3046 tm->table_index, tm->buckets);
3048 vlib_cli_output (vm,
"Initialize: add %d (approx. half of %d sessions)...",
3049 tm->sessions / 2, tm->sessions);
3051 for (i = 0; i < tm->sessions / 2; i++)
3055 data->ip.src_address.as_u32 = ep->addr.as_u32;
3078 for (i = 0; i < tm->iterations; i++)
3083 index =
random_u32 (&tm->seed) % tm->sessions;
3087 data->ip.src_address.as_u32 = ep->addr.as_u32;
3090 is_add = !ep->in_table;
3094 is_add ?
"add" :
"del",
3108 "%s[%d]: %U returned %d", is_add ?
"add" :
"del",
3111 ep->in_table = is_add;
3115 tm->table->active_elements);
3117 for (i = 0; i < tm->sessions; i++)
3121 vnet_classify_entry_t *e;
3123 ep = tm->entries +
i;
3124 if (ep->in_table == 0)
3127 data->ip.src_address.as_u32 = ep->addr.as_u32;
3132 (
u8 *) data, hash, 0 );
3135 clib_warning (
"Couldn't find %U index %d which should be present",
3140 key_minus_skip = (
u8 *) e->key;
3141 key_minus_skip -= tm->table->skip_n_vectors * sizeof (
u32x4);
3158 tm->table->active_elements);
3167 tm->table_index, 1 );
3169 tm->table_index = ~0;
3179 test_classify_main_t *tm = &test_classify_main;
3186 tm->sessions = 8192;
3187 tm->iterations = 8192;
3188 tm->memory_size = 64 << 20;
3189 tm->src.as_u32 = clib_net_to_host_u32 (0x0100000A);
3191 tm->seed = 0xDEADDABE;
3192 tm->classify_main =
cm;
3200 if (
unformat (input,
"sessions %d", &tmp))
3205 else if (
unformat (input,
"buckets %d", &tm->buckets))
3207 else if (
unformat (input,
"memory-size %uM", &tmp))
3208 tm->memory_size = tmp << 20;
3209 else if (
unformat (input,
"memory-size %uG", &tmp))
3210 tm->memory_size = tmp << 30;
3211 else if (
unformat (input,
"seed %d", &tm->seed))
3213 else if (
unformat (input,
"verbose"))
3216 else if (
unformat (input,
"iterations %d", &tm->iterations))
3218 else if (
unformat (input,
"churn-test"))
3227 error = test_classify_churn (tm);
3239 .path =
"test classify",
3241 "test classify [src <ip>] [sessions <nn>] [buckets <nn>] [seed <nnn>]\n" 3242 " [memory-size <nn>[M|G]]\n" 3244 .function = test_classify_command_fn,
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
vlib_main_t vlib_global_main
void clib_mem_validate(void)
uword unformat_classify_mask(unformat_input_t *input, va_list *args)
static_always_inline void clib_spinlock_unlock(clib_spinlock_t *p)
static_always_inline void clib_spinlock_lock(clib_spinlock_t *p)
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 clib_error_t * classify_filter_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
vnet_main_t * vnet_get_main(void)
static vnet_hw_interface_t * vnet_get_sup_hw_interface(vnet_main_t *vnm, u32 sw_if_index)
#define pool_get_zero(P, E)
Allocate an object E from a pool P and zero it.
static vnet_classify_entry_t * vnet_classify_find_entry_inline(vnet_classify_table_t *t, u8 *h, u64 hash, f64 now)
#define VNET_CLASSIFY_ENTRY_FREE
vl_api_ip_port_and_mask_t dst_port
#define clib_memcpy_fast(a, b, c)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
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).
int vnet_is_packet_traced(vlib_buffer_t *b, u32 classify_table_index, int func)
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
for(i=1;i<=collision_buckets;i++)
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)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
struct _tcp_header tcp_header_t
format_function_t format_vnet_sw_if_index_name
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
vlib_node_registration_t ip4_classify_node
(constructor) VLIB_REGISTER_NODE (ip4_classify_node)
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
uword unformat_l2_output_next_index(unformat_input_t *input, va_list *args)
vl_api_ip_proto_t protocol
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)
clib_spinlock_t writer_lock
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
Use the vpp classifier to decide whether to trace packets.
static void clib_spinlock_init(clib_spinlock_t *p)
static uword unformat_opaque_sw_if_index(unformat_input_t *input, va_list *args)
u32 trace_filter_set_index
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)
u8 * format_mheap(u8 *s, va_list *va)
static u64 vnet_classify_hash_packet_inline(vnet_classify_table_t *t, u8 *h)
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.
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)
DLMALLOC_EXPORT void mspace_disable_expand(mspace msp)
void vnet_classify_delete_table_index(vnet_classify_main_t *cm, u32 table_index, int del_chain)
static clib_error_t * show_classify_filter_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#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)
vl_api_address_union_t src_address
static vnet_classify_entry_t * vnet_classify_entry_at_index(vnet_classify_table_t *t, vnet_classify_entry_t *e, u32 index)
void fib_table_unlock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Take a reference counting lock on the table.
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 with alignment A.
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)
vl_api_ip_port_and_mask_t src_port
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)
DLMALLOC_EXPORT mspace create_mspace(size_t capacity, int locked)
static_always_inline uword vlib_get_thread_index(void)
vlib_node_registration_t ip6_inacl_node
(constructor) VLIB_REGISTER_NODE (ip6_inacl_node)
sll srl srl sll sra u16x4 i
#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)
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...)
uword unformat_l3_match(unformat_input_t *input, va_list *args)
uword unformat_ip4_match(unformat_input_t *input, va_list *args)
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
static int vnet_is_packet_traced_inline(vlib_buffer_t *b, u32 classify_table_index, int func)
vnet_is_packet_traced
static clib_error_t * vnet_classify_init(vlib_main_t *vm)
u32 trace_classify_table_index
void fib_table_lock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Release a reference counting lock on the table.
#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)
static int filter_table_mask_compare(void *a1, void *a2)
uword unformat_ethernet_address(unformat_input_t *input, va_list *args)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
#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, fib_source_t src)
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)
int vlib_main(vlib_main_t *volatile vm, unformat_input_t *input)
static int vnet_classify_entry_is_busy(vnet_classify_entry_t *e)
#define CLIB_SPINLOCK_ASSERT_LOCKED(_p)
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)
vl_api_mac_event_action_t action
#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)
typedef CLIB_PACKED(struct { ethernet_header_t eh;ip4_header_t ip;})
VLIB buffer representation.
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
uword unformat_l4_mask(unformat_input_t *input, va_list *args)
#define vec_append_aligned(v1, v2, align)
Append v2 after v1.
static vnet_classify_entry_t * vnet_classify_entry_alloc(vnet_classify_table_t *t, u32 log2_pages)
unformat_function_t unformat_vlib_node
DLMALLOC_EXPORT size_t destroy_mspace(mspace msp)
static void * clib_mem_alloc_aligned(uword size, uword align)
int vlib_enable_disable_pkt_trace_filter(int enable)
Enable / disable packet trace filter.
static u32 random_u32(u32 *seed)
32-bit random number generator
vlib_trace_filter_t trace_filter
static uword count_set_bits(uword x)
#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 vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
#define CLIB_CACHE_LINE_BYTES
vnet_classify_entry_t ** freelists
vnet_classify_entry_t * vnet_classify_find_entry(vnet_classify_table_t *t, u8 *h, u64 hash, f64 now)
u32 trace_classify_table_index
vl_api_interface_index_t sw_if_index
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)