diff options
Diffstat (limited to 'src/vnet/ipsec/ipsec_spd_fp_lookup.h')
-rw-r--r-- | src/vnet/ipsec/ipsec_spd_fp_lookup.h | 114 |
1 files changed, 103 insertions, 11 deletions
diff --git a/src/vnet/ipsec/ipsec_spd_fp_lookup.h b/src/vnet/ipsec/ipsec_spd_fp_lookup.h index e4ef194d68d..a372ac77a50 100644 --- a/src/vnet/ipsec/ipsec_spd_fp_lookup.h +++ b/src/vnet/ipsec/ipsec_spd_fp_lookup.h @@ -20,9 +20,8 @@ #include <vnet/ipsec/ipsec.h> - static_always_inline int -single_rule_match_5tuple (ipsec_policy_t *policy, ipsec_fp_5tuple_t *match) +single_rule_out_match_5tuple (ipsec_policy_t *policy, ipsec_fp_5tuple_t *match) { if (PREDICT_FALSE (policy->is_ipv6 != match->is_ipv6)) return (0); @@ -138,7 +137,98 @@ static_always_inline u32 ipsec_fp_in_ip6_policy_match_n (void *spd_fp, ipsec_fp_5tuple_t *tuples, ipsec_policy_t **policies, u32 n) { - return 0; + u32 last_priority[n]; + u32 i = 0; + u32 counter = 0; + ipsec_fp_mask_type_entry_t *mte; + ipsec_fp_mask_id_t *mti; + ipsec_fp_5tuple_t *match = tuples; + ipsec_policy_t *policy; + u32 n_left = n; + clib_bihash_kv_40_8_t kv; + /* result of the lookup */ + clib_bihash_kv_40_8_t result; + ipsec_fp_lookup_value_t *result_val = + (ipsec_fp_lookup_value_t *) &result.value; + u64 *pkey, *pmatch, *pmask; + ipsec_main_t *im = &ipsec_main; + ipsec_spd_fp_t *pspd_fp = (ipsec_spd_fp_t *) spd_fp; + ipsec_fp_mask_id_t *mask_type_ids = pspd_fp->fp_mask_ids[match->action]; + clib_bihash_40_8_t *bihash_table = pool_elt_at_index ( + im->fp_ip6_lookup_hashes_pool, pspd_fp->ip6_in_lookup_hash_idx); + + /* clear the list of matched policies pointers */ + clib_memset (policies, 0, n * sizeof (*policies)); + clib_memset (last_priority, 0, n * sizeof (u32)); + n_left = n; + while (n_left) + { + vec_foreach (mti, mask_type_ids) + { + mte = im->fp_mask_types + mti->mask_type_idx; + if (mte->mask.action == 0) + continue; + + pmatch = (u64 *) match->kv_40_8.key; + pmask = (u64 *) mte->mask.kv_40_8.key; + pkey = (u64 *) kv.key; + + *pkey++ = *pmatch++ & *pmask++; + *pkey++ = *pmatch++ & *pmask++; + *pkey++ = *pmatch++ & *pmask++; + *pkey++ = *pmatch++ & *pmask++; + *pkey = *pmatch & *pmask; + + int res = + clib_bihash_search_inline_2_40_8 (bihash_table, &kv, &result); + /* lookup the hash by each packet in the burst for this mask. */ + + if (res == 0) + { + /* There is a hit in the hash table. */ + /* Find the policy with highest priority. */ + /* Store the lookup results in a dedicated array. */ + + if (vec_len (result_val->fp_policies_ids) > 1) + { + u32 *policy_id; + vec_foreach (policy_id, result_val->fp_policies_ids) + { + policy = im->policies + *policy_id; + + if ((last_priority[i] < policy->priority) && + (single_rule_in_match_5tuple (policy, match))) + { + last_priority[i] = policy->priority; + if (policies[i] == 0) + counter++; + policies[i] = policy; + } + } + } + else + { + u32 *policy_id; + ASSERT (vec_len (result_val->fp_policies_ids) == 1); + policy_id = result_val->fp_policies_ids; + policy = im->policies + *policy_id; + if ((last_priority[i] < policy->priority) && + (single_rule_in_match_5tuple (policy, match))) + { + last_priority[i] = policy->priority; + if (policies[i] == 0) + counter++; + policies[i] = policy; + } + } + } + } + + i++; + n_left--; + match++; + } + return counter; } static_always_inline u32 @@ -253,7 +343,7 @@ ipsec_fp_in_policy_match_n (void *spd_fp, u8 is_ipv6, } static_always_inline u32 -ipsec_fp_ip6_out_policy_match_n (void *spd_fp, ipsec_fp_5tuple_t *tuples, +ipsec_fp_out_ip6_policy_match_n (void *spd_fp, ipsec_fp_5tuple_t *tuples, ipsec_policy_t **policies, u32 *ids, u32 n) { @@ -288,6 +378,8 @@ ipsec_fp_ip6_out_policy_match_n (void *spd_fp, ipsec_fp_5tuple_t *tuples, vec_foreach (mti, mask_type_ids) { mte = im->fp_mask_types + mti->mask_type_idx; + if (mte->mask.action != 0) + continue; pmatch = (u64 *) match->kv_40_8.key; pmask = (u64 *) mte->mask.kv_40_8.key; @@ -316,7 +408,7 @@ ipsec_fp_ip6_out_policy_match_n (void *spd_fp, ipsec_fp_5tuple_t *tuples, { policy = im->policies + *policy_id; - if (single_rule_match_5tuple (policy, match)) + if (single_rule_out_match_5tuple (policy, match)) { if (last_priority[i] < policy->priority) { @@ -335,7 +427,7 @@ ipsec_fp_ip6_out_policy_match_n (void *spd_fp, ipsec_fp_5tuple_t *tuples, ASSERT (vec_len (result_val->fp_policies_ids) == 1); policy_id = result_val->fp_policies_ids; policy = im->policies + *policy_id; - if (single_rule_match_5tuple (policy, match)) + if (single_rule_out_match_5tuple (policy, match)) { if (last_priority[i] < policy->priority) { @@ -357,7 +449,7 @@ ipsec_fp_ip6_out_policy_match_n (void *spd_fp, ipsec_fp_5tuple_t *tuples, } static_always_inline u32 -ipsec_fp_ip4_out_policy_match_n (void *spd_fp, ipsec_fp_5tuple_t *tuples, +ipsec_fp_out_ip4_policy_match_n (void *spd_fp, ipsec_fp_5tuple_t *tuples, ipsec_policy_t **policies, u32 *ids, u32 n) { @@ -420,7 +512,7 @@ ipsec_fp_ip4_out_policy_match_n (void *spd_fp, ipsec_fp_5tuple_t *tuples, policy = im->policies + *policy_id; if ((last_priority[i] < policy->priority) && - (single_rule_match_5tuple (policy, match))) + (single_rule_out_match_5tuple (policy, match))) { last_priority[i] = policy->priority; if (policies[i] == 0) @@ -437,7 +529,7 @@ ipsec_fp_ip4_out_policy_match_n (void *spd_fp, ipsec_fp_5tuple_t *tuples, policy_id = result_val->fp_policies_ids; policy = im->policies + *policy_id; if ((last_priority[i] < policy->priority) && - (single_rule_match_5tuple (policy, match))) + (single_rule_out_match_5tuple (policy, match))) { last_priority[i] = policy->priority; if (policies[i] == 0) @@ -469,9 +561,9 @@ ipsec_fp_out_policy_match_n (void *spd_fp, u8 is_ipv6, { if (is_ipv6) - return ipsec_fp_ip6_out_policy_match_n (spd_fp, tuples, policies, ids, n); + return ipsec_fp_out_ip6_policy_match_n (spd_fp, tuples, policies, ids, n); else - return ipsec_fp_ip4_out_policy_match_n (spd_fp, tuples, policies, ids, n); + return ipsec_fp_out_ip4_policy_match_n (spd_fp, tuples, policies, ids, n); } #endif /* !IPSEC_SPD_FP_LOOKUP_H */ |