19 #include <netinet/in.h>
42 return applied_hash_aces;
49 DBG(
"HASH ADD/DEL: %016llx %016llx %016llx %016llx %016llx %016llx %016llx add %d",
88 for (
i = 0;
i < 2;
i++)
103 for (
i=0;
i<6;
i++) {
167 return clib_host_to_net_u32((clib_net_to_host_u32(
mask) << numshifts) & 0xFFFFFFFF);
174 int shifts_per_relax[2][4] = { { 6, 5, 4, 2 }, { 3, 2, 1, 1 } };
176 int *shifts = shifts_per_relax[relax2];
177 if(ip4_mask->
as_u32 == 0xffffffff)
178 ip4_mask->
as_u32 = clib_host_to_net_u32((clib_net_to_host_u32(ip4_mask->
as_u32) << shifts[0])&0xFFFFFFFF);
192 if (ip6_mask->as_u64[0] == 0xffffffffffffffffULL) {
193 if (ip6_mask->as_u64[1] == 0xffffffffffffffffULL) {
195 ip6_mask->as_u64[1] = 0;
196 }
else if (ip6_mask->as_u64[1] == 0) {
198 ip6_mask->as_u64[0] = clib_host_to_net_u64(0xffffffffffffff00ULL);
207 int counter_s = 0, counter_d = 0;
227 const int deltaThreshold = 4;
229 int delta = counter_s - counter_d;
230 if (-delta > deltaThreshold) {
232 mask->ip6_addr[0].as_u64[1] =
mask->ip6_addr[0].as_u64[0] = 0;
234 mask->ip4_addr[0].as_u32 = 0;
235 mask->l4.port[0] = 0;
236 }
else if (delta > deltaThreshold) {
238 mask->ip6_addr[1].as_u64[1] =
mask->ip6_addr[1].as_u64[0] = 0;
240 mask->ip4_addr[1].as_u32 = 0;
241 mask->l4.port[1] = 0;
251 mask->pkt.is_nonfirst_fragment = 0;
252 mask->pkt.l4_valid = 0;
254 DBG(
"TM-relaxing-ERROR");
257 DBG(
"TM-relaxing-end");
268 return (mte -
am->ace_mask_type_pool);
279 if(~0 == mask_type_index) {
281 mask_type_index = mte -
am->ace_mask_type_pool;
290 ASSERT(mask_type_index < 32768);
292 mte =
am->ace_mask_type_pool + mask_type_index;
294 DBG0(
"ASSIGN MTE index %d new refcount %d", mask_type_index, mte->
refcount);
295 return mask_type_index;
301 DBG0(
"LOCK MTE index %d", mask_type_index);
304 DBG0(
"LOCK MTE index %d new refcount %d", mask_type_index, mte->
refcount);
311 DBG0(
"RELEAS MTE index %d", mask_type_index);
314 DBG0(
"RELEAS MTE index %d new refcount %d", mask_type_index, mte->
refcount);
326 u32 mask_type_index = ~0;
327 u32 for_mask_type_index = ~0;
335 if (
vec_len(*hash_applied_mask_info_vec) > 0) {
336 for(order_index =
vec_len((*hash_applied_mask_info_vec)) -1; order_index >= 0; order_index--) {
341 mask_type_index = (mte -
am->ace_mask_type_pool);
348 if(~0 == mask_type_index) {
350 DBG(
"TM-assigning mask type index-new one");
357 int spot =
vec_len((*hash_applied_mask_info_vec));
370 ASSERT(mask_type_index < 32768);
372 mte =
am->ace_mask_type_pool + mask_type_index;
373 DBG0(
"TM-ASSIGN MTE index %d new refcount %d", mask_type_index, mte->
refcount);
374 return mask_type_index;
397 *pkey++ = *pmatch++ & *pmask++;
398 *pkey++ = *pmatch++ & *pmask++;
399 *pkey++ = *pmatch++ & *pmask++;
400 *pkey++ = *pmatch++ & *pmask++;
401 *pkey++ = *pmatch++ & *pmask++;
402 *pkey++ = *pmatch++ & *pmask++;
407 kv_val->applied_entry_index = new_index;
426 applied_hash_aces,
u32 lc_index)
428 DBG0(
"remake applied hash mask info lc_index %d", lc_index);
434 for (
i = 0;
i <
vec_len ((*applied_hash_aces));
i++)
440 u32 new_pointer =
vec_len (new_hash_applied_mask_info_vec);
442 for (search = 0; search <
vec_len (new_hash_applied_mask_info_vec);
450 vec_validate ((new_hash_applied_mask_info_vec), search);
452 if (search == new_pointer)
454 DBG0(
"remaking index %d", search);
473 vec_free ((*hash_applied_mask_info_vec));
474 (*hash_applied_mask_info_vec) = new_hash_applied_mask_info_vec;
479 u32 applied_entry_index)
483 while (
i < _vec_len ((*pvec)))
491 DBG0(
"vec_del_collision_rule deleting one at index %d",
i);
506 u32 head_index,
u32 applied_entry_index)
508 DBG0(
"DEL COLLIDING RULE: head_index %d applied index %d", head_index, applied_entry_index);
526 u32 head_index,
u32 applied_entry_index)
532 DBG0(
"ADD COLLIDING RULE: head_index %d applied index %d", head_index, applied_entry_index);
557 DBG(
"activate_applied_ace_hash_entry lc_index %d new_index %d", lc_index, new_index);
561 DBG(
"APPLY ADD KY: %016llx %016llx %016llx %016llx %016llx %016llx",
567 int res = BV (clib_bihash_search) (&
am->acl_lookup_hash, &kv, &result);
572 ASSERT(first_index != ~0);
575 DBG(
"A key already exists, with applied entry index: %d", first_index);
602 if (
am->use_tuple_merge)
628 DBG0(
"HASH ACL apply: lc_index %d acl %d", lc_index,
acl_index);
629 if (!
am->acl_lookup_hash_initialized) {
631 am->hash_lookup_hash_buckets,
am->hash_lookup_hash_memory);
632 am->acl_lookup_hash_initialized = 1;
642 int base_offset =
vec_len(*applied_hash_aces);
653 clib_warning(
"BUG: trying to apply twice acl_index %d on lc_index %d, according to lc",
659 u32 index2 =
vec_search((*hash_acl_applied_lc_index), lc_index);
661 clib_warning(
"BUG: trying to apply twice acl_index %d on lc_index %d, according to hash h-acl info",
666 vec_add1((*hash_acl_applied_lc_index), lc_index);
679 vec_validate(
am->hash_applied_mask_info_vec_by_lc_index, lc_index);
683 int old_vec_len =
vec_len(*applied_hash_aces);
685 _vec_len((*applied_hash_aces)) = old_vec_len;
697 u32 new_index = base_offset +
i;
711 if (
am->use_tuple_merge)
741 u32 old_index,
u32 new_index)
753 clib_warning(
"Moving pae from %d to %d", old_index, new_index);
760 applied_hash_aces, new_index, 1);
783 clib_warning(
"Head pae at index %d after adjustment", head_index);
799 DBG(
"UNAPPLY DEACTIVATE: lc_index %d applied index %d", lc_index, old_index);
801 clib_warning(
"Deactivating pae at index %d", old_index);
823 applied_hash_aces, next_pae_index, 1);
827 applied_hash_aces, old_index, 0);
830 DBG0(
"Releasing mask type index %d for pae index %d on lc_index %d", pae->
mask_type_index, old_index, lc_index);
845 DBG0(
"HASH ACL unapply: lc_index %d acl %d", lc_index,
acl_index);
862 clib_warning(
"BUG: trying to unapply unapplied acl_index %d on lc_index %d, according to lc",
868 u32 index2 =
vec_search((*hash_acl_applied_lc_index), lc_index);
870 clib_warning(
"BUG: trying to unapply twice acl_index %d on lc_index %d, according to h-acl info",
874 vec_del1((*hash_acl_applied_lc_index), index2);
878 for(
i=0;
i <
vec_len((*applied_hash_aces));
i++) {
880 DBG(
"Found applied ACL#%d at applied index %d",
acl_index,
i);
884 if (
vec_len((*applied_hash_aces)) <=
i) {
885 DBG(
"Did not find applied ACL#%d at lc_index %d",
acl_index, lc_index);
892 int tail_len =
vec_len((*applied_hash_aces)) - tail_offset;
893 DBG(
"base_offset: %d, tail_offset: %d, tail_len: %d", base_offset, tail_offset, tail_len);
897 applied_hash_aces, base_offset +
i);
899 for(
i=0;
i < tail_len;
i ++) {
902 DBG0(
"UNAPPLY MOVE: lc_index %d, applied index %d -> %d", lc_index, tail_offset+
i, base_offset +
i);
910 if (
vec_len((*applied_hash_aces)) == 0) {
932 DBG0(
"Start index for acl %d in lc_index %d is %d",
acl_index, lc_index, start_index);
940 for(
i =
vec_len(*applied_acls) - 1;
i > start_index;
i--) {
943 for(
i = start_index;
i <
vec_len(*applied_acls);
i++) {
959 int i, byte, bit, bitnum;
962 for (
i = 0;
i < width;
i++)
964 bitnum = (7 - (
i & 7));
967 a->as_u8[byte] |= bit;
981 if (port_first == port_last) {
996 hi->action =
r->is_permit;
999 mask->pkt.lc_index = ~0;
1001 mask->pkt.mask_type_index_lsb = ~0;
1003 mask->pkt.is_ip6 = 1;
1004 hi->match.pkt.is_ip6 =
r->is_ipv6;
1007 hi->match.ip6_addr[0] =
r->src.ip6;
1009 hi->match.ip6_addr[1] =
r->dst.ip6;
1013 hi->match.ip4_addr[0] =
r->src.ip4;
1015 hi->match.ip4_addr[1] =
r->dst.ip4;
1018 if (
r->proto != 0) {
1019 mask->l4.proto = ~0;
1020 hi->match.l4.proto =
r->proto;
1024 hi->match.l4.port[0] =
r->src_port_or_type_first &
mask->l4.port[0];
1027 hi->match.l4.port[1] =
r->dst_port_or_code_first &
mask->l4.port[1];
1029 mask->pkt.l4_valid = 1;
1030 hi->match.pkt.l4_valid = 1;
1032 mask->pkt.is_nonfirst_fragment = 1;
1033 hi->match.pkt.is_nonfirst_fragment = 0;
1034 if ((
r->proto == IPPROTO_TCP) && (
r->tcp_flags_mask != 0)) {
1036 mask->pkt.tcp_flags =
r->tcp_flags_mask;
1037 hi->match.pkt.tcp_flags =
r->tcp_flags_value;
1039 mask->pkt.tcp_flags_valid = 1;
1040 hi->match.pkt.tcp_flags_valid = 1;
1047 for(j=0; j<6; j++) {
1048 pmatch[j] = pmatch[j] & pmask[j];
1089 mask.pkt.flags_reserved = 0b000;
1125 u32 *lc_list_copy = 0;
1151 BV (format_bihash), &
am->acl_lookup_hash, verbose);
1165 vlib_cli_output(
vm,
" %3d: %016llx %016llx %016llx %016llx %016llx %016llx refcount %d",
1166 mte -
am->ace_mask_type_pool,
1196 " %4d: %016llx %016llx %016llx %016llx %016llx %016llx base mask index %d acl %d rule %d action %d\n",
1197 j, m[0], m[1], m[2], m[3], m[4], m[5],
1207 " %4d: acl %d ace %d acl pos %d pae index: %d",
1215 " %4d: acl %d rule %d action %d bitmask-ready rule %d mask type index: %d colliding_rules: %d collision_head_ae_idx %d hitcount %lld acl_pos: %d",
1228 " %4d: mask type index %d first rule index %d num_entries %d max_collisions %d",
1241 (lci <
vec_len(
am->applied_hash_acl_info_by_lc_index)); lci++)
1243 if ((lc_index != ~0) && (lc_index != lci))
1248 if (lci <
vec_len (
am->applied_hash_acl_info_by_lc_index))
1251 &
am->applied_hash_acl_info_by_lc_index[lci];
1255 if (lci <
vec_len (
am->hash_applied_mask_info_vec_by_lc_index))
1259 j <
vec_len (
am->hash_applied_mask_info_vec_by_lc_index[lci]);
1263 &
am->hash_applied_mask_info_vec_by_lc_index
1267 if (lci <
vec_len (
am->hash_entry_vec_by_lc_index))
1271 j <
vec_len (
am->hash_entry_vec_by_lc_index[lci]);
1275 &
am->hash_entry_vec_by_lc_index
1313 (clib_net_to_host_u64 (mask_addr->as_u64[0]) <
1314 clib_net_to_host_u64 (min_addr->as_u64[0]))
1316 ((clib_net_to_host_u64 (mask_addr->as_u64[0]) ==
1317 clib_net_to_host_u64 (min_addr->as_u64[0]))
1318 && (clib_net_to_host_u64 (mask_addr->as_u64[1]) <
1319 clib_net_to_host_u64 (min_addr->as_u64[1])));
1322 min_addr->as_u64[0] = mask_addr->as_u64[0];
1323 min_addr->as_u64[1] = mask_addr->as_u64[1];
1331 (clib_net_to_host_u64 (mask_addr->as_u64[0]) >
1332 clib_net_to_host_u64 (max_addr->as_u64[0]))
1334 ((clib_net_to_host_u64 (mask_addr->as_u64[0]) ==
1335 clib_net_to_host_u64 (max_addr->as_u64[0]))
1336 && (clib_net_to_host_u64 (mask_addr->as_u64[1]) >
1337 clib_net_to_host_u64 (max_addr->as_u64[1])));
1340 max_addr->as_u64[0] = mask_addr->as_u64[0];
1341 max_addr->as_u64[1] = mask_addr->as_u64[1];
1349 (clib_net_to_host_u32 (mask_addr->
as_u32) <
1350 clib_net_to_host_u32 (min_addr->
as_u32));
1359 (clib_net_to_host_u32 (mask_addr->
as_u32) >
1360 clib_net_to_host_u32 (max_addr->
as_u32));
1378 DBG(
"TM-split_partition - first_entry:%d", first_index);
1381 fa_5tuple_t the_min_tuple, *min_tuple = &the_min_tuple;
1382 fa_5tuple_t the_max_tuple, *max_tuple = &the_max_tuple;
1387 clib_memset(&the_min_tuple, 0,
sizeof(the_min_tuple));
1388 clib_memset(&the_max_tuple, 0,
sizeof(the_max_tuple));
1393 for(
i=0;
i<collisions;
i++){
1395 pae =
vec_elt_at_index((*applied_hash_aces), colliding_rules[
i].applied_entry_index);
1398 DBG(
"TM-collision: base_ace:%d (ace_mask:%d, first_collision_mask:%d)",
1418 if ((
mask->l4.port[j] < min_tuple->
l4.
port[j]))
1435 if ((
mask->l4.port[j] > max_tuple->
l4.
port[j]))
1448 int best_dim=-1, best_delta=0, delta=0;
1459 if(delta > best_delta){
1474 if(delta > best_delta){
1481 if(delta > best_delta){
1488 if(delta > best_delta){
1495 if(delta > best_delta){
1503 shifting = (best_delta)/2;
1506 clib_host_to_net_u32((clib_net_to_host_u32(max_tuple->
ip4_addr[0].
as_u32) << (shifting))&0xFFFFFFFF);
1510 shifting = (best_delta)/2;
1524 clib_host_to_net_u32((clib_net_to_host_u32(max_tuple->
ip4_addr[1].
as_u32) << (shifting))&0xFFFFFFFF);
1545 for (search=0; search <
vec_len((*hash_applied_mask_info_vec)); search++){
1558 DBG(
"TM-split_partition - mask type index-assigned!! -> %d", new_mask_type_index);
1560 if(coll_mask_type_index == new_mask_type_index){
1567 DBG(
"TM-Populate new partition");
1568 u32 r_ace_index = first_index;
1569 int repopulate_count = 0;
1572 collisions =
vec_len(temp_colliding_rules);
1574 for(
i=0;
i<collisions;
i++){
1580 DBG(
"TM-Population-collision: base_ace:%d (ace_mask:%d, first_collision_mask:%d)",
1592 DBG(
"TM-new partition can insert -> applied_ace:%d", r_ace_index);
1600 if (++repopulate_count > 1)
1608 DBG(
"TM-Populate new partition-END");
1609 DBG(
"TM-split_partition - END");