3 #include "../../../platform/likely.h"
4 #include "../../../platform/lock.h"
5 #include "../../../platform/memory.h"
6 #include "../of1x_async_events_hooks.h"
9 #include "../of1x_switch.h"
15 #include "../../../util/logging.h"
26 if( unlikely(entry==NULL) )
32 if( unlikely(NULL==entry->rwlock) ){
39 __of1x_init_match_group(&entry->matches);
42 __of1x_init_instruction_group(&entry->inst_grp);
48 entry->notify_removal = notify_removal;
65 if(entry->notify_removal && (reason != OF1X_FLOW_REMOVE_NO_REASON ) ){
67 if(entry->table && entry->table->pipeline && entry->table->pipeline->sw){
71 __of1x_stats_flow_consolidate(&entry->stats, &consolidated_stats);
73 entry->stats.s.counters = consolidated_stats;
84 __of1x_destroy_match_group(&entry->matches);
87 __of1x_destroy_instruction_group(&entry->inst_grp);
100 return __of1x_destroy_flow_entry_with_reason(entry, OF1X_FLOW_REMOVE_NO_REASON);
106 __of1x_match_group_push_back(&entry->matches, match);
121 __of1x_update_instructions(&entry_to_update->inst_grp, &mod->inst_grp);
126 __of1x_reset_last_packet_count_idle_timeout(&entry_to_update->timer_info);
130 entry_to_update->flags = mod->flags;
147 if(check_cookie && entry->cookie != OF1X_DO_NOT_CHECK_COOKIE && entry->cookie_mask){
148 if( (entry->cookie&entry->cookie_mask) != (original->cookie&entry->cookie_mask) )
153 if(check_priority && ((entry->priority&OF1X_2_BYTE_MASK) != (original->priority&OF1X_2_BYTE_MASK)))
157 for( it_entry = entry->matches.head; it_entry; it_entry = it_entry->next ){
158 for( it_orig = original->matches.head; it_orig; it_orig = it_orig->next ){
161 if( it_entry->type != it_orig->type)
164 if( !__of1x_is_submatch( it_entry, it_orig ) && !__of1x_is_submatch( it_orig, it_entry ) )
171 if( out_group != OF1X_GROUP_ANY && (
172 !__of1x_write_actions_has(original->inst_grp.instructions[OF1X_IT_WRITE_ACTIONS].write_actions, OF1X_AT_GROUP, out_group) &&
173 !__of1x_apply_actions_has(original->inst_grp.instructions[OF1X_IT_APPLY_ACTIONS].apply_actions, OF1X_AT_GROUP, out_group)
180 if( out_port != OF1X_PORT_ANY && (
181 !__of1x_write_actions_has(original->inst_grp.instructions[OF1X_IT_WRITE_ACTIONS].write_actions, OF1X_AT_OUTPUT, out_port) &&
182 !__of1x_apply_actions_has(original->inst_grp.instructions[OF1X_IT_APPLY_ACTIONS].apply_actions, OF1X_AT_OUTPUT, out_port)
199 if(check_cookie && subentry->cookie != OF1X_DO_NOT_CHECK_COOKIE && subentry->cookie_mask){
200 if( (subentry->cookie&subentry->cookie_mask) != (original->cookie&subentry->cookie_mask) )
205 if(check_priority && (original->priority != subentry->priority))
209 for( it_subentry = subentry->matches.head; it_subentry; it_subentry = it_subentry->next ){
210 for( it_orig = original->matches.head; it_orig; it_orig = it_orig->next ){
213 if( it_subentry->type != it_orig->type)
216 if( !__of1x_is_submatch( it_subentry, it_orig ) )
222 if( out_group != OF1X_GROUP_ANY){
230 if( out_port != OF1X_PORT_ANY){
249 if(check_cookie && entry->cookie != OF1X_DO_NOT_CHECK_COOKIE && entry->cookie_mask){
250 if( (entry->cookie&entry->cookie_mask) != (original->cookie&entry->cookie_mask) )
255 if(entry->priority != original->priority)
259 if(original->matches.num_elements != entry->matches.num_elements)
263 for(it_original = original->matches.head, it_entry = entry->matches.head; it_entry != NULL; it_original = it_original->next, it_entry = it_entry->next){
264 if(!__of1x_equal_matches(it_original,it_entry))
269 if( out_group != OF1X_GROUP_ANY && (
270 !__of1x_write_actions_has(original->inst_grp.instructions[OF1X_IT_WRITE_ACTIONS].write_actions, OF1X_AT_GROUP, out_group) &&
271 !__of1x_apply_actions_has(original->inst_grp.instructions[OF1X_IT_APPLY_ACTIONS].apply_actions, OF1X_AT_GROUP, out_group)
278 if( out_port != OF1X_PORT_ANY && (
279 !__of1x_write_actions_has(original->inst_grp.instructions[OF1X_IT_WRITE_ACTIONS].write_actions, OF1X_AT_OUTPUT, out_port) &&
280 !__of1x_apply_actions_has(original->inst_grp.instructions[OF1X_IT_APPLY_ACTIONS].apply_actions, OF1X_AT_OUTPUT, out_port)
294 __of1x_stats_flow_consolidate(&entry->stats, &c);
296 ROFL_PIPELINE_INFO_NO_PREFIX(
"Entry (%p), prior. %u, cookie 0x%"PRIx64
", pkts.matched %u. Matches:{",entry, entry->priority, entry->cookie, c.packet_count, entry->matches.num_elements);
299 __of1x_dump_matches(entry->matches.head, raw_nbo);
300 ROFL_PIPELINE_INFO_NO_PREFIX(
"}\n");
301 __of1x_dump_instructions(entry->inst_grp, raw_nbo);
309 of_version_t version = pipeline->sw->of_ver;
315 if( entry->matches.head)
316 if( (version < entry->matches.ver_req.min_ver) ||
317 (version > entry->matches.ver_req.max_ver) )
331 if(__of1x_validate_instructions(&entry->inst_grp, pipeline, table_id)!=ROFL_SUCCESS)
334 if(version == OF_VERSION_10 && entry->matches.head && !__of10_is_wildcard(&entry->matches))
335 entry->priority |= OF10_NON_WILDCARDED_PRIORITY_FLAG;
rofl_result_t __of1x_destroy_timer_entries(struct of1x_flow_entry *entry)
of1x_destroy_timer_entry When a flow entry is removed from the table this function will be called in ...
of1x_flow_entry_t * of1x_init_flow_entry(bool notify_removal)
Create an empty flow entry.
OpenFlow v1.0, 1.2 and 1.3.2 pipeline abstraction.
bool __of1x_instruction_has(of1x_instruction_group_t *inst_grp, of1x_packet_action_type_t type, uint64_t value)
OpenFlow v1.0, 1.2 and 1.3.2 flow table abstraction.
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)
void __of1x_stats_flow_reset_counts(struct of1x_flow_entry *entry)
of1x_stats_flow_reset_counts
void platform_of1x_modify_entry_hook(of1x_flow_entry_t *old_entry, of1x_flow_entry_t *mod, int reset_count)
It can be used by hardware or other software (non rofl-pipeline) pipelines, to modify an entry (singl...
void of1x_dump_flow_entry(of1x_flow_entry_t *entry, bool raw_nbo)
Dumps the flow entry for debugging purposes.
OpenFlow v1.0, 1.2 and 1.3.2 flow table abstraction.
bool __of1x_flow_entry_check_contained(of1x_flow_entry_t *const original, of1x_flow_entry_t *const subentry, bool check_priority, bool check_cookie, uint32_t out_port, uint32_t out_group, bool reverse_out_check)
Checks whether an entry is contained in the other.
bool __of1x_flow_entry_check_overlap(of1x_flow_entry_t *const original, of1x_flow_entry_t *const entry, bool check_priority, bool check_cookie, uint32_t out_port, uint32_t out_group)
Checks whether two entries overlap overlapping.
OpenFlow v1.0, 1.2 and 1.3.2 actions.
static bool bitmap128_check_mask(bitmap128_t *bitmap, bitmap128_t *mask)
Check whether a bitmap is within a certain mask (bitmap&mask == bitmap)
void platform_of1x_notify_flow_removed(const of1x_switch_t *sw, of1x_flow_remove_reason_t reason, of1x_flow_entry_t *removed_flow_entry)
Flow removed event notification.
void __of1x_destroy_flow_stats(struct of1x_flow_entry *entry)
of1x_stats_flow_destroy basically destroys the mutex
OpenFlow v1.0, 1.2 and 1.3.2 flow entry abstraction.
rofl_result_t of1x_add_match_to_entry(of1x_flow_entry_t *entry, of1x_match_t *match)
Adds a match to the flow_entry.
ROFL_BEGIN_DECLS void __of1x_init_flow_stats(struct of1x_flow_entry *entry)
operations in statistics.c
rofl_result_t of1x_destroy_flow_entry(of1x_flow_entry_t *entry)
Destroy the flow entry, including stats, instructions and actions.
OpenFlow v1.0, 1.2 and 1.3.2 pipeline abstraction data structure.
bool __of1x_flow_entry_check_equal(of1x_flow_entry_t *const original, of1x_flow_entry_t *const entry, uint32_t out_port, uint32_t out_group, bool check_cookie)
Checks if entry is identical to another one out_port and out_grouap are ALWAYS checked against origin...
OpenFlow v1.0, 1.2 and 1.3.2 group table subsystem.
rofl_result_t __of1x_validate_flow_entry(of1x_flow_entry_t *entry, struct of1x_pipeline *pipeline, unsigned int table_id)
Check if the entry(matches, actions and instructions is valid for insertion)