14 #include "../of1x_switch.h"
15 #include "../../../platform/lock.h"
16 #include "../../../platform/memory.h"
17 #include "../../../platform/likely.h"
18 #include "../../../util/logging.h"
28 bitmap128_set(>->config.supported_actions, OF1X_AT_COPY_TTL_IN);
29 bitmap128_set(>->config.supported_actions, OF1X_AT_POP_VLAN);
30 bitmap128_set(>->config.supported_actions, OF1X_AT_POP_MPLS);
31 bitmap128_set(>->config.supported_actions, OF1X_AT_POP_GRE);
32 bitmap128_set(>->config.supported_actions, OF1X_AT_POP_GTP);
33 bitmap128_set(>->config.supported_actions, OF1X_AT_POP_PPPOE);
34 bitmap128_set(>->config.supported_actions, OF1X_AT_PUSH_PPPOE);
35 bitmap128_set(>->config.supported_actions, OF1X_AT_PUSH_GTP);
36 bitmap128_set(>->config.supported_actions, OF1X_AT_PUSH_GRE);
37 bitmap128_set(>->config.supported_actions, OF1X_AT_PUSH_MPLS);
38 bitmap128_set(>->config.supported_actions, OF1X_AT_PUSH_VLAN);
39 bitmap128_set(>->config.supported_actions, OF1X_AT_COPY_TTL_OUT);
40 bitmap128_set(>->config.supported_actions, OF1X_AT_DEC_NW_TTL);
41 bitmap128_set(>->config.supported_actions, OF1X_AT_DEC_MPLS_TTL);
42 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_MPLS_TTL);
43 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_NW_TTL);
44 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_QUEUE);
45 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_ETH_DST);
46 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_ETH_SRC);
47 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_ETH_TYPE);
48 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_MPLS_LABEL);
49 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_MPLS_TC);
50 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_VLAN_VID);
51 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_VLAN_PCP);
52 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_ARP_OPCODE);
53 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_ARP_SHA);
54 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_ARP_SPA);
55 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_ARP_THA);
56 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_ARP_TPA);
57 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_NW_PROTO);
58 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_NW_SRC);
59 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_NW_DST);
60 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_IP_DSCP);
61 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_IP_ECN);
62 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_IP_PROTO);
63 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_IPV4_SRC);
64 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_IPV4_DST);
65 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_IPV6_SRC);
66 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_IPV6_DST);
67 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_IPV6_FLABEL);
68 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_IPV6_ND_TARGET);
69 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_IPV6_ND_SLL);
70 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_IPV6_ND_TLL);
71 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_TCP_SRC);
72 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_TCP_DST);
73 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_UDP_SRC);
74 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_UDP_DST);
75 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_SCTP_SRC);
76 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_SCTP_DST);
77 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_TP_SRC);
78 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_TP_DST);
79 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_ICMPV4_TYPE);
80 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_ICMPV4_CODE);
81 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_ICMPV6_TYPE);
82 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_ICMPV6_CODE);
83 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_PPPOE_CODE);
84 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_PPPOE_TYPE);
85 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_PPPOE_SID);
86 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_PPP_PROT);
87 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_GTP_MSG_TYPE);
88 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_GTP_TEID);
89 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_GRE_VERSION);
90 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_GRE_PROT_TYPE);
91 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_GRE_KEY);
98 __of12_set_group_table_defaults(gt);
100 bitmap128_set(>->config.supported_actions, OF1X_AT_POP_PBB);
101 bitmap128_set(>->config.supported_actions, OF1X_AT_PUSH_PBB);
102 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_MPLS_BOS);
103 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_PBB_ISID);
104 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_TUNNEL_ID);
105 bitmap128_set(>->config.supported_actions, OF1X_AT_SET_FIELD_IPV6_EXTHDR);
112 if( unlikely(gt==NULL) ){
116 gt->num_of_entries = 0;
123 switch(pipeline->sw->of_ver){
127 __of12_set_group_table_defaults(gt);
130 __of13_set_group_table_defaults(gt);
140 gt->pipeline = pipeline;
152 for(iterator=gt->head; iterator!=NULL; iterator=next){
154 __of1x_destroy_group(gt,iterator);
171 for(it=actions->head; it; it=it->next){
172 if(it->type == OF1X_AT_GROUP)
173 return ROFL_OF1X_GM_CHAIN;
174 if(it->type == OF1X_AT_OUTPUT && it->__field.u64 == OF1X_PORT_TABLE)
175 return ROFL_OF1X_GM_INVAL;
179 if(__of1x_validate_action_group(>->config.supported_actions, actions, gt,
false) != ROFL_SUCCESS)
180 return ROFL_OF1X_GM_INVAL;
182 return ROFL_OF1X_GM_OK;
195 for(iterator=gt->head; iterator!=NULL; iterator=next){
197 if(iterator->id ==
id){
210 rofl_of1x_gm_result_t ret_val;
212 if(
id == OF1X_GROUP_ALL ||
id == OF1X_GROUP_ANY ||
id > OF1X_GROUP_MAX)
213 return ROFL_OF1X_GM_INVAL;
216 for(bu_it=buckets->head;bu_it!=NULL;bu_it=bu_it->next){
217 if((ret_val=__of1x_validate_group(gt, bu_it->actions))!=ROFL_OF1X_GM_OK)
222 if (type == OF1X_GROUP_TYPE_SELECT || type == OF1X_GROUP_TYPE_FF){
223 ROFL_PIPELINE_ERR(
"Warning; group type %u NOT supported\n", type);
224 return ROFL_OF1X_GM_INVAL;
228 if(type == OF1X_GROUP_TYPE_INDIRECT && buckets->num_of_buckets>1)
229 return ROFL_OF1X_GM_INVAL;
230 if( (type == OF1X_GROUP_TYPE_ALL || type == OF1X_GROUP_TYPE_INDIRECT) && __of1x_bucket_list_has_weights(buckets))
231 return ROFL_OF1X_GM_INVAL;
232 if (type == OF1X_GROUP_TYPE_SELECT && __of1x_bucket_list_has_weights(buckets) ==
false)
233 return ROFL_OF1X_GM_INVAL;
235 return ROFL_OF1X_GM_OK;
241 rofl_of1x_gm_result_t ret_val;
245 if ( unlikely(ge==NULL) ){
246 return ROFL_OF1X_GM_OGRUPS;
249 if((ret_val=__of1x_check_group_parameters(gt,type,
id,buckets))!=ROFL_OF1X_GM_OK){
254 ge->bc_list = buckets;
257 ge->group_table = gt;
259 __of1x_init_group_stats(&ge->stats);
262 ge->num_of_output_actions = 0;
264 for( bc=buckets->head; bc !=NULL; bc=bc->next){
265 ge->num_of_output_actions += bc->actions->num_of_output_actions;
271 if (gt->head == NULL && gt->tail == NULL){
281 gt->num_of_entries++;
285 return ROFL_OF1X_GM_OK;
289 rofl_of1x_gm_result_t ret_val;
290 ROFL_PIPELINE_INFO(
"[groupmod-add(%p)] Starting operation at switch %s(%p), group id: %u\n", *buckets, gt->pipeline->sw->name, gt->pipeline->sw,
id);
298 ROFL_PIPELINE_INFO(
"[groupmod-add(%p)] FAILED validation. Group exists...\n", *buckets);
299 return ROFL_OF1X_GM_EXISTS;
302 ret_val = __of1x_init_group(gt,type,
id,*buckets);
303 if (ret_val!=ROFL_OF1X_GM_OK){
305 ROFL_PIPELINE_INFO(
"[groupmod-add(%p)] FAILED, reason %u\n", *buckets, ret_val);
309 ROFL_PIPELINE_INFO(
"[groupmod-add(%p)] Successful\n", *buckets);
317 return ROFL_OF1X_GM_OK;
328 __of1x_destroy_group_stats(&ge->stats);
342 if( unlikely(ge->group_table==NULL) ){
346 ge->group_table = NULL;
350 ge->next->prev = ge->prev;
352 ge->prev->next = ge->next;
360 gt->num_of_entries--;
374 if(
id == OF1X_GROUP_ALL){
375 for(ge = gt->head; ge; ge=next){
378 if(__of1x_extract_group(gt, ge)==ROFL_FAILURE){
380 return ROFL_OF1X_GM_OK;
384 for(i=0; i<pipeline->num_of_tables; i++){
385 while((entry=of1x_matching_algorithms[pipeline->tables[i].matching_algorithm].
find_entry_using_group_hook(&pipeline->tables[i],ge->id))!=NULL){
386 __of1x_remove_specific_flow_entry_table(pipeline,i,entry, OF1X_FLOW_REMOVE_GROUP_DELETE, MUTEX_NOT_ACQUIRED);
390 __of1x_destroy_group(gt,ge);
393 return ROFL_OF1X_GM_OK;
399 return ROFL_OF1X_GM_OK;
403 if(__of1x_extract_group(gt, ge)==ROFL_FAILURE){
405 return ROFL_OF1X_GM_OK;
409 for(i=0; i<pipeline->num_of_tables; i++){
410 while((entry=of1x_matching_algorithms[pipeline->tables[i].matching_algorithm].
find_entry_using_group_hook(&pipeline->tables[i],ge->id))!=NULL){
411 __of1x_remove_specific_flow_entry_table(pipeline,i,entry, OF1X_FLOW_REMOVE_GROUP_DELETE, MUTEX_NOT_ACQUIRED);
416 __of1x_destroy_group(gt,ge);
420 return ROFL_OF1X_GM_OK;
429 rofl_of1x_gm_result_t ret_val;
431 if((ret_val=__of1x_check_group_parameters(gt,type,
id,*buckets))!=ROFL_OF1X_GM_OK)
436 return ROFL_OF1X_GM_UNKGRP;
442 ge->bc_list = *buckets;
445 ge->group_table = gt;
453 return ROFL_OF1X_GM_OK;
458 if ( unlikely(bl==NULL) )
461 bl->num_of_buckets=0;
469 if(bu_list->head==NULL && bu_list->tail==NULL){
470 bu_list->head = bucket;
471 bu_list->tail = bucket;
474 bu_list->tail->next = bucket;
475 bu_list->tail = bucket;
477 bu_list->num_of_buckets++;
484 if ( unlikely(bk==NULL) )
491 bk->actions = actions;
492 __of1x_init_bucket_stats(&bk->stats);
500 for(bk_it=bc_list->head;bk_it!=NULL;bk_it=next){
504 __of1x_destroy_buckets_stats(&bk_it->stats);
512 for(bu_it = bl->head; bu_it!=NULL; bu_it=bu_it->next){
522 __of1x_stats_bucket_consolidate(&bc->stats, &c);
524 ROFL_PIPELINE_INFO_NO_PREFIX(
"Weight %u, port %u, actions: ", bc->weight, bc->port);
525 __of1x_dump_action_group(bc->actions, raw_nbo);
526 ROFL_PIPELINE_INFO_NO_PREFIX(
" statistics {pkt_count: %u}", c.packet_count);
527 ROFL_PIPELINE_INFO_NO_PREFIX(
"\n");
530 void of1x_dump_group(
of1x_group_t* group,
bool raw_nbo){
535 ROFL_PIPELINE_INFO_NO_PREFIX(
"id %u, ", group->id);
537 case OF1X_GROUP_TYPE_ALL:
538 ROFL_PIPELINE_INFO_NO_PREFIX(
"GROUP_TYPE_ALL, ");
540 case OF1X_GROUP_TYPE_SELECT:
541 ROFL_PIPELINE_INFO_NO_PREFIX(
"GROUP_TYPE_SELECT, ");
543 case OF1X_GROUP_TYPE_INDIRECT:
544 ROFL_PIPELINE_INFO_NO_PREFIX(
"GROUP_TYPE_INDIRECT, ");
546 case OF1X_GROUP_TYPE_FF:
547 ROFL_PIPELINE_INFO_NO_PREFIX(
"GROUP_TYPE_FF, ");
550 ROFL_PIPELINE_INFO_NO_PREFIX(
"UNEXPECTED GROUP_TYPE (%u), ", group->type);
554 __of1x_stats_group_consolidate(&group->stats, &c);
556 ROFL_PIPELINE_INFO_NO_PREFIX(
"num of buckets %u, statistics {pkt_count: %u} \n", group->bc_list->num_of_buckets, c.packet_count);
558 for(bc_it=group->bc_list->head, i=0; bc_it; bc_it=bc_it->next, i++){
559 ROFL_PIPELINE_INFO(
"\t\t[%u] Bucket (%p). ", i, bc_it);
560 of1x_dump_bucket(bc_it, raw_nbo);
562 ROFL_PIPELINE_INFO(
"\n");
569 ROFL_PIPELINE_INFO(
"Dumping group table. Num of group entries: %u\n",gt->num_of_entries);
570 if (gt->num_of_entries > 0){
571 for(it=gt->head, i=0; it; it=it->next, i++){
572 ROFL_PIPELINE_INFO(
"\t[%u] Group (%p). ", i, it);
573 of1x_dump_group(it, raw_nbo);
577 ROFL_PIPELINE_INFO(
"\t[*] No entries\n");
578 ROFL_PIPELINE_INFO(
"\n");
OpenFlow v1.0, 1.2 and 1.3.2 pipeline abstraction.
Packet action abstraction data structure.
Group structure definition.
OpenFlow v1.0, 1.2 and 1.3.2 flow entry structure.
of1x_bucket_t * of1x_init_bucket(uint16_t weight, uint32_t port, uint32_t group, of1x_action_group_t *actions)
Initializes a bucket.
static void bitmap128_clean(bitmap128_t *bitmap)
Set bitmap to 0.
of1x_flow_entry_t *(* find_entry_using_group_hook)(struct of1x_flow_table *const table, const unsigned int group_id)
The find_entry_using_group_hook() must retrieve the first entry in the table that contain actions ref...
rofl_result_t of1x_insert_bucket_in_list(of1x_bucket_list_t *bu_list, of1x_bucket_t *bucket)
Inserts an initialized bucket in the list of buckets.
void of1x_destroy_action_group(of1x_action_group_t *group)
Destroy an action group.
rofl_of1x_gm_result_t of1x_group_modify(of1x_group_table_t *gt, of1x_group_type_t type, uint32_t id, of1x_bucket_list_t **buckets)
Function that searches a group and modifies the action buckets inside.
enum of1x_group_type of1x_group_type_t
Group type.
of1x_bucket_list_t * of1x_init_bucket_list(void)
Initializes a list of buckets.
of1x_group_table_t * of1x_init_group_table(struct of1x_pipeline *pipeline)
Initializes the group table.
void of1x_destroy_group_table(of1x_group_table_t *gt)
Destroys the group table.
Action group (apply-actions) structure.
rofl_of1x_gm_result_t of1x_group_delete(of1x_pipeline_t *pipeline, of1x_group_table_t *gt, uint32_t id)
Deletes a group of the table.
rofl_of1x_gm_result_t of1x_group_add(of1x_group_table_t *gt, of1x_group_type_t type, uint32_t id, of1x_bucket_list_t **buckets)
Adds a group to the table.
OpenFlow v1.0, 1.2 and 1.3.2 pipeline abstraction data structure.
void of1x_destroy_bucket_list(of1x_bucket_list_t *bc_list)
Destroys the bucket list.
of1x_group_t * __of1x_group_search(of1x_group_table_t *gt, uint32_t id)
Searches in the table for an entry with a specific id returns pointer if found or NULL if not...
OpenFlow v1.0, 1.2 and 1.3.2 group table subsystem.
static void bitmap128_set(bitmap128_t *bitmap, unsigned int pos)
Set a bit in the 128bit bitmap.