1 #include "of1x_l2hash_ma.h"
5 #include "../../of1x_pipeline.h"
6 #include "../../of1x_flow_table.h"
7 #include "../../of1x_flow_entry.h"
8 #include "../../of1x_match.h"
9 #include "../../of1x_group_table.h"
10 #include "../../of1x_instruction.h"
11 #include "../../../of1x_async_events_hooks.h"
12 #include "../../../../../platform/lock.h"
13 #include "../../../../../platform/likely.h"
14 #include "../../../../../platform/memory.h"
15 #include "../matching_algorithms.h"
16 #include "../loop/of1x_loop_ma.h"
18 #define L2HASH_DESCRIPTION "The l2hash algorithm searches the list of entries by its priority order. On the worst case the performance is o(N) with the number of entries"
46 if(ht->num_of_entries)
50 for(i=0;i<L2HASH_MAX_ENTRIES;i++){
51 if(ht->table[i].num_of_buckets){
52 bucket = ht->table[i].bucket_list;
54 next_bucket = bucket->next;
68 uint32_t priority = bucket->entry->priority;
71 bucket->ht_entry = ht_e;
73 if(ht_e->bucket_list){
74 it = ht_e->bucket_list;
77 if(it->entry->priority <= priority)
84 bucket->prev = it->prev;
89 it->prev->next = bucket;
91 ht_e->bucket_list = bucket;
94 ht_e->bucket_list = bucket;
95 bucket->next = bucket->prev = NULL;
98 ht_e->num_of_buckets++;
108 bucket->next->prev = bucket->prev;
111 bucket->prev->next = bucket->next;
113 ht_e->bucket_list = bucket->next;
116 ht_e->num_of_buckets--;
123 rofl_result_t of1x_destroy_l2hash(
struct of1x_flow_table *
const table){
143 for(match = entry->matches.head;match;){
146 if(match->type == OF1X_MATCH_VLAN_VID){
148 }
else if(match->type == OF1X_MATCH_ETH_DST){
154 if(unlikely(eth_dst == NULL)){
164 if(unlikely(ps == NULL) || unlikely(bucket == NULL)){
170 assert(
bitmap128_is_bit_set(&entry->matches.match_bm, OF1X_MATCH_VLAN_VID) == (vlan != NULL) );
174 bucket->entry = entry;
179 key.vid = vlan->__tern->value.u16 & vlan->__tern->mask.u16;
180 key.eth_dst = eth_dst->__tern->value.u64 & eth_dst->__tern->mask.u64;
184 ps->has_vlan =
false;
187 bucket->eth_dst = key.eth_dst;
188 bucket->vid = key.vid;
191 l2hash_ht_add_bucket(&state->vlan, hash, bucket);
194 state->vlan.num_of_entries++;
198 key.eth_dst = eth_dst->__tern->value.u64 & eth_dst->__tern->mask.u64;
203 ps->has_vlan =
false;
206 bucket->eth_dst = key.eth_dst;
209 l2hash_ht_add_bucket(&state->no_vlan, hash, bucket);
212 state->no_vlan.num_of_entries++;
217 entry->platform_state = (
void*)ps;
226 if(unlikely(entry->platform_state == NULL)){
234 l2hash_ht_remove_bucket(ps->bucket);
237 state->vlan.num_of_entries--;
239 state->no_vlan.num_of_entries--;
243 entry->platform_state = NULL;
254 return __of1x_add_flow_entry_loop(table, entry, check_overlap, reset_counts, of1x_add_hook_l2hash);
259 return __of1x_modify_flow_entry_loop(table, entry, strict, reset_counts, of1x_add_hook_l2hash, of1x_modify_hook_l2hash);
264 return __of1x_remove_flow_entry_loop(table, entry, specific_entry, strict, out_port, out_group, reason, mutex_acquired, of1x_remove_hook_l2hash);
268 OF1X_REGISTER_MATCHING_ALGORITHM(l2hash) = {
270 .init_hook = of1x_init_l2hash,
271 .destroy_hook = of1x_destroy_l2hash,
274 .add_flow_entry_hook = of1x_add_flow_entry_l2hash,
275 .modify_flow_entry_hook = of1x_modify_flow_entry_l2hash,
276 .remove_flow_entry_hook = of1x_remove_flow_entry_l2hash,
279 .get_flow_stats_hook = of1x_get_flow_stats_loop,
280 .get_flow_aggregate_stats_hook = of1x_get_flow_aggregate_stats_loop,
283 .find_entry_using_group_hook = of1x_find_entry_using_group_loop,
287 .description = L2HASH_DESCRIPTION,
291 uint16_t l2hash_ht_T[L2HASH_MAX_ENTRIES] = {
293 98, 6, 85,150, 36, 23,112,164,135,207,169, 5, 26, 64,165,219,
295 61, 20, 68, 89,130, 63, 52,102, 24,229,132,245, 80,216,195,115,
297 90,168,156,203,177,120, 2,190,188, 7,100,185,174,243,162, 10,
299 237, 18,253,225, 8,208,172,244,255,126,101, 79,145,235,228,121,
301 123,251, 67,250,161, 0,107, 97,241,111,181, 82,249, 33, 69, 55,
303 59,153, 29, 9,213,167, 84, 93, 30, 46, 94, 75,151,114, 73,222,
305 197, 96,210, 45, 16,227,248,202, 51,152,252,125, 81,206,215,186,
307 39,158,178,187,131,136, 1, 49, 50, 17,141, 91, 47,129, 60, 99,
309 154, 35, 86,171,105, 34, 38,200,147, 58, 77,118,173,246, 76,254,
311 133,232,196,144,198,124, 53, 4,108, 74,223,234,134,230,157,139,
313 189,205,199,128,176, 19,211,236,127,192,231, 70,233, 88,146, 44,
315 183,201, 22, 83, 13,214,116,109,159, 32, 95,226,140,220, 57, 12,
317 221, 31,209,182,143, 92,149,184,148, 62,113, 65, 37, 27,106,166,
319 3, 14,204, 72, 21, 41, 56, 66, 28,193, 40,217, 25, 54,179,117,
321 238, 87,240,155,180,170,242,212,191,163, 78,218,137,194,175,110,
323 43,119,224, 71,122,142, 42,160,104, 48,247,103, 15, 11,138,239
OpenFlow v1.0, 1.2 and 1.3.2 flow entry structure.
enum of1x_flow_remove_reason of1x_flow_remove_reason_t
Flow remove reasons (enum ofp_flow_removed_reason)
static void bitmap128_clean(bitmap128_t *bitmap)
Set bitmap to 0.
OpenFlow v1.0, 1.2 and 1.3.2 flow table abstraction.
of1x_flow_removal_strictness
Flow removal operations strictness.
static bool bitmap128_is_bit_set(const bitmap128_t *bitmap, unsigned int pos)
Check if bit is set in the 128bit bitmap.
matching_auxiliary_t * matching_aux[2]
Place-holder to allow matching algorithms keep its own state.
enum rofl_of1x_fm_result rofl_of1x_fm_result_t
Extended flowmod return codes.
static void bitmap128_set(bitmap128_t *bitmap, unsigned int pos)
Set a bit in the 128bit bitmap.