ROFL-pipeline  v0.6.0dev
of1x_l2hash_ma_pp.h
1 #ifndef __OF1X_L2HASH_MATCH_PP_H__
2 #define __OF1X_L2HASH_MATCH_PP_H__
3 
4 #include "rofl.h"
5 #include "../../of1x_pipeline.h"
6 #include "../../of1x_flow_table.h"
7 #include "../../of1x_flow_entry.h"
8 #include "../../of1x_match_pp.h"
9 #include "../../of1x_group_table.h"
10 #include "../../of1x_instruction_pp.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 "of1x_l2hash_ma.h"
16 
17 //C++ extern C
18 ROFL_BEGIN_DECLS
19 
20 static inline void l2_hash_check_all_buckets_no_vlan(l2hash_ht_bucket_t* bucket, l2hash_novlan_key_t* key, of1x_flow_entry_t** best_match){
21 
22  while(bucket){
23  if(key->eth_dst == bucket->eth_dst){
24  *best_match = bucket->entry;
25  return;
26  }
27  bucket = bucket->next;
28  }
29 }
30 
31 static inline void l2_hash_check_all_buckets_vlan(l2hash_ht_bucket_t* bucket, l2hash_vlan_key_t* key, of1x_flow_entry_t** best_match){
32 
33  while(bucket){
34  if(key->eth_dst == bucket->eth_dst && key->vid == bucket->vid){
35  *best_match = bucket->entry;
36  return;
37  }
38  bucket = bucket->next;
39  }
40 }
41 
42 /* FLOW entry lookup entry point */
43 static inline of1x_flow_entry_t* of1x_find_best_match_l2hash_ma(of1x_flow_table_t *const table, datapacket_t *const pkt){
44 
45  l2hash_novlan_key_t key_novlan;
46  l2hash_vlan_key_t key_vlan;
47  of1x_flow_entry_t *best_match = NULL, *tmp=NULL;
48  l2hash_ht_entry_t* ht_entry;
49  uint16_t* vid;
50 
51  //Table hash table
52  l2hash_state_t* state = (l2hash_state_t*)table->matching_aux[0];
53 
54  //Recover keys
55  key_novlan.eth_dst = key_vlan.eth_dst = *platform_packet_get_eth_dst(pkt) & OF1X_6_BYTE_MASK;
56 
58 
59  if(vid)
60  key_vlan.vid = *vid&OF1X_VLAN_ID_MASK;
61 
62  //Check no-VLAN table-hash
63  if(state->no_vlan.num_of_entries > 0){
64  ht_entry = &state->no_vlan.table[l2hash_ht_hash64((const char*)&key_novlan, sizeof(key_novlan))];
65  //Check buckets
66  l2_hash_check_all_buckets_no_vlan(ht_entry->bucket_list, &key_novlan, &best_match);
67  }
68 
69  //Check VLAN table-hash
70  if(state->vlan.num_of_entries > 0){
71  ht_entry = &state->vlan.table[l2hash_ht_hash96((const char*)&key_vlan, sizeof(key_vlan))];
72  if(best_match){
73  l2_hash_check_all_buckets_vlan(ht_entry->bucket_list, &key_vlan, &tmp);
74  if(tmp && (tmp->priority > best_match->priority))
75  best_match = tmp;
76  }else{
77  l2_hash_check_all_buckets_vlan(ht_entry->bucket_list, &key_vlan, &best_match);
78  }
79  }
80  return best_match;
81 }
82 
83 //C++ extern C
84 ROFL_END_DECLS
85 
86 #endif //OF1X_L2HASH_MATCH_PP
OpenFlow v1.0, 1.2 and 1.3.2 flow entry structure.
OpenFlow v1.0, 1.2 and 1.3.2 flow table abstraction.
matching_auxiliary_t * matching_aux[2]
Place-holder to allow matching algorithms keep its own state.
uint64_t * platform_packet_get_eth_dst(datapacket_t *const pkt)
Retrieve the Ethernet dst MAC address of the packet.
Data packet abstraction.
Definition: datapacket.h:49
uint16_t * platform_packet_get_vlan_vid(datapacket_t *const pkt)
Retrieves the VLAN id of the outer-most 802.1q VLAN tag.