ROFL-pipeline  v0.6.0dev
of1x_action.c
1 #include "of1x_action.h"
2 #include "../../../common/datapacket.h"
3 #include "../../../common/protocol_constants.h"
4 
5 #include <stdio.h>
6 #include <assert.h>
7 
8 #include "../../../common/packet_matches.h" //TODO: evaluate if this is the best approach to update of1x_matches after actions
9 #include "../../../physical_switch.h"
10 #include "../../../util/logging.h"
11 #include "../../../platform/likely.h"
12 #include "../../../platform/memory.h"
13 #include "../of1x_async_events_hooks.h"
14 #include "of1x_flow_table.h"
15 #include "of1x_utils.h"
16 
17 //Flood port
19 
20 /* Actions init and destroyed */
22 
23  of1x_packet_action_t* action;
24 
25  if( unlikely(type==OF1X_AT_NO_ACTION) )
26  return NULL;
27 
29 
30  if( unlikely(action==NULL) )
31  return NULL;
32 
33  //Set type
34  action->type = type;
35 
36  //Set min max
37  action->ver_req.min_ver = OF1X_MIN_VERSION;
38  action->ver_req.max_ver = OF1X_MAX_VERSION;
39 
40  //Make valgrind happy
41  UINT128__T_HI(action->__field.u128) = UINT128__T_LO(action->__field.u128) = 0x0ULL;
42 
43  /*
44  * Setting the field (for set_field actions) and fast validation flags
45  */
46  switch(type){
47  //16 byte
48  case OF1X_AT_SET_FIELD_IPV6_ND_TARGET:
49  case OF1X_AT_SET_FIELD_IPV6_SRC:
50  case OF1X_AT_SET_FIELD_IPV6_DST:{
51  uint128__t tmp = field.u128;
52  HTONB128(tmp);
53  action->__field.u128 = tmp;
54  action->ver_req.min_ver = OF_VERSION_12;
55  }break;
56 
57  //8 byte
58  case OF1X_AT_SET_FIELD_TUNNEL_ID:
59  action->__field.u64 = field.u64&OF1X_8_BYTE_MASK;
60  action->ver_req.min_ver = OF_VERSION_13;
61  break;
62 
63  //6 byte values
64  case OF1X_AT_SET_FIELD_IPV6_ND_SLL:
65  field.u64 = HTONB64(OF1X_MAC_ALIGN(field.u64));
66  action->__field.u64 = field.u64&OF1X_6_BYTE_MASK;
67  action->ver_req.min_ver = OF_VERSION_12;
68  break;
69  case OF1X_AT_SET_FIELD_IPV6_ND_TLL:
70  field.u64 = HTONB64(OF1X_MAC_ALIGN(field.u64));
71  action->__field.u64 = field.u64&OF1X_6_BYTE_MASK;
72  action->ver_req.min_ver = OF_VERSION_12;
73  break;
74  case OF1X_AT_SET_FIELD_ETH_DST:
75  field.u64 = HTONB64(OF1X_MAC_ALIGN(field.u64));
76  action->__field.u64 = field.u64&OF1X_6_BYTE_MASK;
77  break;
78  case OF1X_AT_SET_FIELD_ETH_SRC:
79  field.u64 = HTONB64(OF1X_MAC_ALIGN(field.u64));
80  action->__field.u64 = field.u64&OF1X_6_BYTE_MASK;
81  break;
82  case OF1X_AT_SET_FIELD_ARP_SHA:
83  field.u64 = HTONB64(OF1X_MAC_ALIGN(field.u64));
84  action->__field.u64 = field.u64&OF1X_6_BYTE_MASK;
85  action->ver_req.min_ver = OF_VERSION_12;
86  break;
87  case OF1X_AT_SET_FIELD_ARP_THA:
88  field.u64 = HTONB64(OF1X_MAC_ALIGN(field.u64));
89  action->__field.u64 = field.u64&OF1X_6_BYTE_MASK;
90  action->ver_req.min_ver = OF_VERSION_12;
91  break;
92  /* Extensions */
93  case OF1X_AT_SET_FIELD_WLAN_ADDRESS_1:
94  case OF1X_AT_SET_FIELD_WLAN_ADDRESS_2:
95  case OF1X_AT_SET_FIELD_WLAN_ADDRESS_3:
96  field.u64 = HTONB64(OF1X_MAC_ALIGN(field.u64));
97  action->__field.u64 = field.u64&OF1X_6_BYTE_MASK;
98  action->ver_req.min_ver = OF_VERSION_12;
99  break;
100  /* Extensions end */
101 
102  //4 byte values
103  case OF1X_AT_SET_FIELD_NW_DST:
104  action->ver_req.min_ver = OF_VERSION_10;
105  action->ver_req.max_ver = OF_VERSION_10;
106  case OF1X_AT_SET_FIELD_IPV4_DST:
107  field.u32 = HTONB32(field.u32);
108  action->__field.u32 = field.u32&OF1X_4_BYTE_MASK;
109  break;
110  case OF1X_AT_SET_FIELD_NW_SRC:
111  action->ver_req.min_ver = OF_VERSION_10;
112  action->ver_req.max_ver = OF_VERSION_10;
113  case OF1X_AT_SET_FIELD_IPV4_SRC:
114  field.u32 = HTONB32(field.u32);
115  action->__field.u32 = field.u32&OF1X_4_BYTE_MASK;
116  break;
117  case OF1X_AT_SET_FIELD_ARP_SPA:
118  field.u32 = HTONB32(field.u32);
119  action->__field.u32 = field.u32&OF1X_4_BYTE_MASK;
120  action->ver_req.min_ver = OF_VERSION_10;
121  break;
122  case OF1X_AT_SET_FIELD_ARP_TPA:
123  field.u32 = HTONB32(field.u32);
124  action->__field.u32 = field.u32&OF1X_4_BYTE_MASK;
125  action->ver_req.min_ver = OF_VERSION_10;
126  break;
127  case OF1X_AT_OUTPUT:
128  action->send_len = output_send_len;
129  action->__field.u32 = field.u32&OF1X_4_BYTE_MASK;
130  break;
131  /* Extensions */
132  case OF1X_AT_SET_FIELD_GTP_TEID:
133  field.u32 = HTONB32(field.u32);
134  action->__field.u32 = field.u32&OF1X_4_BYTE_MASK;
135  action->ver_req.min_ver = OF_VERSION_12;
136  break;
137  case OF1X_AT_SET_FIELD_GRE_KEY:
138  field.u32 = HTONB32(field.u32);
139  action->__field.u32 = field.u32&OF1X_4_BYTE_MASK;
140  action->ver_req.min_ver = OF_VERSION_12;
141  break;
142  /* Extensions end */
143 
144  //3 byte
145  case OF1X_AT_SET_FIELD_PBB_ISID:
146  //TODO Align value
147  action->__field.u32 = field.u32&OF1X_3_BYTE_MASK;
148  action->ver_req.min_ver = OF_VERSION_13;
149  break;
150 
151  //20 bit values
152  case OF1X_AT_SET_FIELD_IPV6_FLABEL:
153  field.u32 = HTONB32(OF1X_IP6_FLABEL_ALIGN(field.u32));
154  action->__field.u32 = field.u32&OF1X_20_BITS_IPV6_FLABEL_MASK;
155  action->ver_req.min_ver = OF_VERSION_12;
156  break;
157  case OF1X_AT_SET_FIELD_MPLS_LABEL:
158  field.u32 = HTONB32(OF1X_MPLS_LABEL_ALIGN(field.u32));
159  action->__field.u32 = field.u32&OF1X_20_BITS_MASK;
160  action->ver_req.min_ver = OF_VERSION_12;
161  break;
162 
163  //2 byte values
164  case OF1X_AT_SET_FIELD_ETH_TYPE:
165  field.u16 = HTONB16(field.u16);
166  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
167  break;
168  case OF1X_AT_SET_FIELD_ARP_OPCODE:
169  field.u16 = HTONB16(field.u16);
170  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; // TODO: lower 8bits of opcode only?
171  action->ver_req.min_ver = OF_VERSION_10;
172  break;
173  case OF1X_AT_SET_FIELD_TP_SRC:
174  field.u16 = HTONB16(field.u16);
175  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
176  action->ver_req.min_ver = OF_VERSION_10;
177  action->ver_req.max_ver = OF_VERSION_10;
178  break;
179  case OF1X_AT_SET_FIELD_TP_DST:
180  field.u16 = HTONB16(field.u16);
181  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
182  action->ver_req.min_ver = OF_VERSION_10;
183  action->ver_req.max_ver = OF_VERSION_10;
184  break;
185  case OF1X_AT_SET_FIELD_TCP_SRC:
186  field.u16 = HTONB16(field.u16);
187  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
188  action->ver_req.min_ver = OF_VERSION_12;
189  break;
190  case OF1X_AT_SET_FIELD_TCP_DST:
191  field.u16 = HTONB16(field.u16);
192  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
193  action->ver_req.min_ver = OF_VERSION_12;
194  break;
195  case OF1X_AT_SET_FIELD_UDP_SRC:
196  field.u16 = HTONB16(field.u16);
197  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
198  action->ver_req.min_ver = OF_VERSION_12;
199  break;
200  case OF1X_AT_SET_FIELD_UDP_DST:
201  field.u16 = HTONB16(field.u16);
202  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
203  action->ver_req.min_ver = OF_VERSION_12;
204  break;
205  case OF1X_AT_SET_FIELD_SCTP_SRC:
206  field.u16 = HTONB16(field.u16);
207  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
208  action->ver_req.min_ver = OF_VERSION_12;
209  break;
210  case OF1X_AT_SET_FIELD_SCTP_DST:
211  field.u16 = HTONB16(field.u16);
212  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
213  action->ver_req.min_ver = OF_VERSION_12;
214  break;
215  /* Extensions */
216  case OF1X_AT_SET_FIELD_PPPOE_SID:
217  field.u16 = HTONB16(field.u16);
218  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
219  action->ver_req.min_ver = OF_VERSION_12;
220  break;
221  case OF1X_AT_SET_FIELD_PPP_PROT:
222  field.u16 = HTONB16(field.u16);
223  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
224  action->ver_req.min_ver = OF_VERSION_12;
225  break;
226  case OF1X_AT_SET_FIELD_CAPWAP_FLAGS:
227  field.u16 = HTONB16(field.u16);
228  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
229  action->ver_req.min_ver = OF_VERSION_12;
230  break;
231  case OF1X_AT_SET_FIELD_WLAN_FC:
232  field.u16 = HTONB16(field.u16);
233  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
234  action->ver_req.min_ver = OF_VERSION_12;
235  break;
236  case OF1X_AT_SET_FIELD_GRE_VERSION:
237  field.u16 = HTONB16(field.u16);
238  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
239  action->ver_req.min_ver = OF_VERSION_12;
240  break;
241  case OF1X_AT_SET_FIELD_GRE_PROT_TYPE:
242  field.u16 = HTONB16(field.u16);
243  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
244  action->ver_req.min_ver = OF_VERSION_12;
245  break;
246  /* Extensions end */
247  /*case OF1X_AT_POP_VLAN: TODO: CHECK THIS*/
248  case OF1X_AT_POP_MPLS:
249  field.u16 = HTONB16(field.u16);
250  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
251  action->ver_req.min_ver = OF_VERSION_12;
252  break;
253  case OF1X_AT_POP_PPPOE:
254  field.u16 = HTONB16(field.u16);
255  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
256  action->ver_req.min_ver = OF_VERSION_12;
257  break;
258  case OF1X_AT_POP_PBB:
259  field.u16 = HTONB16(field.u16);
260  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
261  action->ver_req.min_ver = OF_VERSION_13;
262  break;
263  /* Extensions */
264  case OF1X_AT_POP_GRE:
265  field.u16 = HTONB16(field.u16);
266  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
267  action->ver_req.min_ver = OF_VERSION_12;
268  break;
269  case OF1X_AT_POP_WLAN:
270  field.u16 = HTONB16(field.u16);
271  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
272  action->ver_req.min_ver = OF_VERSION_12;
273  break;
274  case OF1X_AT_POP_GTP:
275  field.u16 = HTONB16(field.u16);
276  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
277  action->ver_req.min_ver = OF_VERSION_12;
278  break;
279  case OF1X_AT_POP_CAPWAP:
280  field.u16 = HTONB16(field.u16);
281  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
282  action->ver_req.min_ver = OF_VERSION_12;
283  break;
284  case OF1X_AT_PUSH_GTP:
285  field.u16 = HTONB16(field.u16);
286  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
287  action->ver_req.min_ver = OF_VERSION_12;
288  break;
289  case OF1X_AT_PUSH_CAPWAP:
290  field.u16 = HTONB16(field.u16);
291  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
292  action->ver_req.min_ver = OF_VERSION_12;
293  break;
294  case OF1X_AT_PUSH_WLAN:
295  field.u16 = HTONB16(field.u16);
296  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
297  action->ver_req.min_ver = OF_VERSION_12;
298  break;
299  case OF1X_AT_PUSH_GRE:
300  field.u16 = HTONB16(field.u16);
301  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
302  action->ver_req.min_ver = OF_VERSION_12;
303  break;
304  /* Extensions end */
305  case OF1X_AT_PUSH_PPPOE:
306  field.u16 = HTONB16(field.u16);
307  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
308  action->ver_req.min_ver = OF_VERSION_12;
309  break;
310  case OF1X_AT_PUSH_MPLS:
311  field.u16 = HTONB16(field.u16);
312  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
313  action->ver_req.min_ver = OF_VERSION_12;
314  break;
315  case OF1X_AT_PUSH_VLAN:
316  field.u16 = HTONB16(field.u16);
317  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
318  action->ver_req.min_ver = OF_VERSION_12;
319  break;
320  case OF1X_AT_PUSH_PBB:
321  field.u16 = HTONB16(field.u16);
322  action->__field.u16 = field.u16&OF1X_2_BYTE_MASK;
323  action->ver_req.min_ver = OF_VERSION_13;
324  break;
325 
326 
327  //12 bit values
328  case OF1X_AT_SET_FIELD_VLAN_VID:
329  field.u16 = HTONB16(field.u16);
330  action->__field.u16 = field.u16&OF1X_12_BITS_MASK;
331  break;
332 
333 
334  //9 bit value
335  case OF1X_AT_SET_FIELD_IPV6_EXTHDR:
336  //TODO align to pipeline -- currently not implemented
337  action->__field.u16 = field.u16&OF1X_9_BITS_MASK;
338  action->ver_req.min_ver = OF_VERSION_13;
339  break;
340 
341  //1 byte values
342  case OF1X_AT_SET_FIELD_NW_PROTO:
343  action->ver_req.min_ver = OF_VERSION_10;
344  action->ver_req.max_ver = OF_VERSION_10;
345  action->__field.u8 = field.u8&OF1X_1_BYTE_MASK;
346  break;
347  case OF1X_AT_SET_FIELD_ICMPV6_TYPE:
348  case OF1X_AT_SET_FIELD_ICMPV6_CODE:
349  case OF1X_AT_SET_FIELD_PPPOE_CODE:
350  case OF1X_AT_SET_FIELD_PPPOE_TYPE:
351  case OF1X_AT_SET_MPLS_TTL:
352  case OF1X_AT_SET_NW_TTL:
353  case OF1X_AT_SET_FIELD_IP_PROTO:
354  case OF1X_AT_SET_FIELD_ICMPV4_TYPE:
355  case OF1X_AT_SET_FIELD_ICMPV4_CODE:
356  action->__field.u8 = field.u8&OF1X_1_BYTE_MASK;
357  action->ver_req.min_ver = OF_VERSION_10;
358  break;
359  /* Extensions */
360  case OF1X_AT_SET_FIELD_GTP_MSG_TYPE:
361  case OF1X_AT_SET_FIELD_CAPWAP_WBID:
362  case OF1X_AT_SET_FIELD_CAPWAP_RID:
363  case OF1X_AT_SET_FIELD_WLAN_TYPE:
364  case OF1X_AT_SET_FIELD_WLAN_SUBTYPE:
365  case OF1X_AT_SET_FIELD_WLAN_DIRECTION:
366  /* Extensions end */
367  action->__field.u8 = field.u8&OF1X_1_BYTE_MASK;
368  action->ver_req.min_ver = OF_VERSION_12;
369  break;
370 
371  //6 bit values
372  case OF1X_AT_SET_FIELD_IP_DSCP:
373  field.u8 = OF1X_IP_DSCP_ALIGN(field.u8);
374  action->__field.u8 = field.u8&OF1X_6MSBITS_MASK;
375  break;
376 
377  //3 bit values
378  case OF1X_AT_SET_FIELD_VLAN_PCP:
379  field.u8 = OF1X_VLAN_PCP_ALIGN(field.u8);
380  action->__field.u8 = field.u8&OF1X_3MSBITS_MASK;
381  break;
382 
383  case OF1X_AT_SET_FIELD_MPLS_TC:
384  field.u8 = OF1X_MPLS_TC_ALIGN(field.u8);
385  action->__field.u8 = field.u8&OF1X_BITS_12AND3_MASK;
386  action->ver_req.min_ver = OF_VERSION_12;
387  break;
388 
389  //2 bit values
390  case OF1X_AT_SET_FIELD_IP_ECN:
391  action->__field.u8 = field.u8&OF1X_2LSBITS_MASK;
392  action->ver_req.min_ver = OF_VERSION_12;
393  break;
394  case OF1X_AT_SET_QUEUE:
395  action->__field.u32 = field.u32&OF1X_4_BYTE_MASK;
396  action->ver_req.min_ver = OF_VERSION_10;
397  break;
398  case OF1X_AT_GROUP:
399  action->__field.u32 = field.u32&OF1X_4_BYTE_MASK; //id of the group
400  action->ver_req.min_ver = OF_VERSION_12;
401  //action->group = of1x_group_search(sw->pipeline->groups, action->__field); // pointer to the group //FIXME evaluate if this can be done here or not
402  break;
403 
404  //1 bit values
405  case OF1X_AT_SET_FIELD_MPLS_BOS:
406  action->__field.u8 = field.u8&OF1X_BIT0_MASK; //id of the group
407  action->ver_req.min_ver = OF_VERSION_13;
408  break;
409 
410  //No value
411  case OF1X_AT_POP_VLAN:
412  action->__field.u64 = 0x0; // action strip vlan
413  break;
414 
415  case OF1X_AT_COPY_TTL_IN:
416  case OF1X_AT_COPY_TTL_OUT:
417  case OF1X_AT_DEC_NW_TTL:
418  case OF1X_AT_DEC_MPLS_TTL:
419  case OF1X_AT_EXPERIMENTER:
420  action->__field.u64 = 0x0;
421  action->ver_req.min_ver = OF_VERSION_12;
422  break;
423 
424  //Shall never happen
425  case OF1X_AT_NO_ACTION:
426  assert(0);
427  action->__field.u64 = 0x0;
428  break;
429  }
430 
431  return action;
432 }
433 
435 
436  platform_free_shared(action);
437 }
438 
439 /* Action group init and destroy */
441 
442  unsigned int number_of_actions=0, number_of_output_actions=0;
443  of1x_action_group_t* action_group;
444 
445  action_group = platform_malloc_shared(sizeof(of1x_action_group_t));
446 
447  if( unlikely(action_group==NULL) )
448  return NULL;
449 
450  if(actions){
451  action_group->head = actions;
452 
453  for(;actions;actions=actions->next, number_of_actions++){
454 
455  if(actions->type == OF1X_AT_OUTPUT /*|| actions->type == OF1X_AT_GROUP*/)
456  number_of_output_actions++;
457 
458  if(!actions->next){
459  action_group->tail = actions;
460  break;
461  }
462  }
463  }else{
464  action_group->head = NULL;
465  action_group->tail = NULL;
466  }
467 
468  action_group->num_of_actions = number_of_actions;
469  action_group->num_of_output_actions = number_of_output_actions;
470 
471  //Fast validation, set min max
472  action_group->ver_req.min_ver = OF1X_MIN_VERSION;
473  action_group->ver_req.max_ver = OF1X_MAX_VERSION;
474  bitmap128_clean(&action_group->bitmap);
475  action_group->has_output_table = false;
476 
477  return action_group;
478 }
479 
481 
482  of1x_packet_action_t* it,*next;
483 
484  if( unlikely(group==NULL) )
485  return;
486 
487  for(it=group->head;it;it=next){
488  next = it->next;
490  }
491  platform_free_shared(group);
492 }
493 
494 /* Addition of an action to an action group */
496 
497  if( unlikely(action==NULL) || action->type >= OF1X_AT_NUMBER ){
498  assert(0);
499  return;
500  }
501 
502  //Set has_output_table for fast validation
503  if(action->type == OF1X_AT_OUTPUT && action->__field.u32 == OF1X_PORT_TABLE){
504  //We only accept an output action to PORT_TABLE
505  if(unlikely(group->has_output_table == true)){
506  ROFL_PIPELINE_ERR("Trying to add an action OUTPUT to port TABLE to action group(%p) when there is already one. Ignoring...", group);
507  assert(0);
508  return;
509  }
510  group->has_output_table = true;
511  }
512 
513  if(!group->tail){
514  group->head = action;
515  }else{
516  group->tail->next = action;
517  }
518 
519  group->tail = action;
520  action->next = NULL;
521 
522  group->num_of_actions++;
523 
524  //This cannot be done here, because the group might NOT exist yet; the sum will happen
525  //during insertion validation (for both action and WRITE_ACTIONS instruction
526  //if(action->type == OF1X_AT_OUTPUT)
527  // group->num_of_output_actions++;
528 
529  //if(action->type == OF1X_AT_GROUP)
530  // group->num_of_output_actions+=action->group->num_of_output_actions;
531 
532  //Update fast validation flags (required versions)
533  if(group->ver_req.min_ver < action->ver_req.min_ver)
534  group->ver_req.min_ver = action->ver_req.min_ver;
535  if(group->ver_req.max_ver > action->ver_req.max_ver)
536  group->ver_req.max_ver = action->ver_req.max_ver;
537  bitmap128_set(&group->bitmap, action->type);
538 
539 }
540 
542 
543  int i;
545 
546  if( unlikely(write_actions==NULL) )
547  return NULL;
548 
549  //Clean actions bitmap
550  bitmap128_clean(&write_actions->bitmap);
551 
552  for(i=0;i<OF1X_AT_NUMBER;i++)
553  write_actions->actions[i].type = (of1x_packet_action_type_t)i;
554 
555  //num of actions and output actions
556  write_actions->num_of_actions = 0;
557  write_actions->num_of_output_actions = 0;
558 
559  //Fast validation, set min max
560  write_actions->ver_req.min_ver = OF1X_MIN_VERSION;
561  write_actions->ver_req.max_ver = OF1X_MAX_VERSION;
562 
563  return write_actions;
564 }
565 
566 void __of1x_destroy_write_actions(of1x_write_actions_t* write_actions){
567  platform_free_shared(write_actions);
568 }
569 
571 
572  if( unlikely(write_actions==NULL) || action->type >= OF1X_AT_NUMBER ){
573  assert(0);
574  return ROFL_FAILURE;
575  }
576 
577  //Ignore write action output OF1X_PORT_TABLE
578  if(action->type == OF1X_AT_OUTPUT && action->__field.u32 == OF1X_PORT_TABLE)
579  return ROFL_FAILURE;
580 
581  //Update field
582  write_actions->actions[action->type].__field = action->__field;
583  write_actions->actions[action->type].send_len = action->send_len;
584 
585  if( !bitmap128_is_bit_set(&write_actions->bitmap, action->type) ){
586  write_actions->num_of_actions++;
587  bitmap128_set(&write_actions->bitmap, action->type);
588  }
589 
590  //This cannot be done here, because the group might NOT exist yet; the sum will happen
591  //during insertion validation (for both action and WRITE_ACTIONS instruction
592  //if (action->type == OF1X_AT_OUTPUT)
593  // write_actions->num_of_output_actions++;
594  //if(action->type == OF1X_AT_GROUP)
595  // write_actions->num_of_output_actions+=action->group->num_of_output_actions;
596 
597  //Update fast validation flags (required versions)
598  if(write_actions->ver_req.min_ver < action->ver_req.min_ver)
599  write_actions->ver_req.min_ver = action->ver_req.min_ver;
600  if(write_actions->ver_req.max_ver > action->ver_req.max_ver)
601  write_actions->ver_req.max_ver = action->ver_req.max_ver;
602 
603  return ROFL_SUCCESS;
604 }
605 
606 //Update apply/write
607 rofl_result_t __of1x_update_apply_actions(of1x_action_group_t** group, of1x_action_group_t* new_group){
608 
609  of1x_action_group_t* old_group = *group;
610 
611  //Transfer
612  *group = new_group;
613 
614  //Release if necessary
615  if(old_group)
616  of1x_destroy_action_group(old_group);
617 
618  return ROFL_SUCCESS;
619 }
620 
621 rofl_result_t __of1x_update_write_actions(of1x_write_actions_t** group, of1x_write_actions_t* new_group){
622 
623  of1x_write_actions_t* old_group = *group;
624 
625  //Transfer
626  *group = new_group;
627 
628  //Destroy old group
629  if(old_group)
630  __of1x_destroy_write_actions(old_group);
631 
632  return ROFL_SUCCESS;
633 }
634 
635 //Checking functions
636 /*TODO specific funcions for 128 bits. So far only used for OUTPUT and GROUP actions, so not really necessary*/
637 bool __of1x_write_actions_has(of1x_write_actions_t* write_actions, of1x_packet_action_type_t type, uint64_t value){
638  if( unlikely(write_actions==NULL))
639  return false;
640 
641  return bitmap128_is_bit_set(&write_actions->bitmap, type);
642 }
643 /*TODO specific funcions for 128 bits. So far only used for OUTPUT and GROUP actions, so not really necessary*/
644 bool __of1x_apply_actions_has(const of1x_action_group_t* apply_actions_group, of1x_packet_action_type_t type, uint64_t value){
645 
647 
648  if( unlikely(apply_actions_group==NULL) )
649  return false;
650 
651  for(it=apply_actions_group->head; it; it=it->next){
652 
653  if(type != OF1X_AT_GROUP){
654  //Filter types where field cannot be 0
655  return (it->type == type) && (value != 0x0 && it->__field.u64 == value);
656  }else{
657  //Groups or anything else
658  return (it->type == type) && (it->__field.u64 == value);
659  }
660  }
661  return false;
662 }
663 
664 //Copy (cloning) methods
665 of1x_packet_action_t* __of1x_copy_packet_action(of1x_packet_action_t* action){
666 
667  of1x_packet_action_t* copy;
668 
670 
671  if( unlikely(copy==NULL) )
672  return NULL;
673 
674  *copy = *action;
675 
676  return copy;
677 }
678 
679 of1x_action_group_t* __of1x_copy_action_group(of1x_action_group_t* origin){
680 
681  of1x_action_group_t* copy;
683 
684  if( unlikely(origin==NULL) )
685  return NULL;
686 
688 
689 
690  if( unlikely(copy==NULL) )
691  return NULL;
692 
693  copy->head = copy->tail = NULL;
694  copy->num_of_actions = origin->num_of_actions;
695  copy->num_of_output_actions = origin->num_of_output_actions;
696 
697  //Copy al apply actions
698  for(it=origin->head;it;it=it->next){
700 
701  act = __of1x_copy_packet_action(it);
702 
703  if(unlikely(act == NULL)){
705  return NULL;
706  }
707 
708 
709  //Insert in the double linked-list
710  if(!copy->tail){
711  copy->head = act;
712  }else{
713  copy->tail->next = act;
714  }
715  act->next = NULL;
716  copy->tail = act;
717  }
718 
719  return copy;
720 }
721 
722 of1x_write_actions_t* __of1x_copy_write_actions(of1x_write_actions_t* origin){
723 
724  of1x_write_actions_t* copy;
725 
726  if( unlikely(origin==NULL) )
727  return NULL;
728 
730 
731  if( unlikely(copy==NULL) )
732  return NULL;
733 
734  //Copy Values
735  *copy = *origin;
736 
737  return copy;
738 }
739 
740 /* Dumping */
741 static void __of1x_dump_packet_action(of1x_packet_action_t* action, bool raw_nbo){
742 
743  ROFL_PIPELINE_INFO_NO_PREFIX("<");
744  switch(action->type){
745  case OF1X_AT_NO_ACTION: /*TODO: print some error traces? */
746  break;
747 
748  case OF1X_AT_COPY_TTL_IN: ROFL_PIPELINE_INFO_NO_PREFIX("TTL_IN");
749  break;
750 
751  case OF1X_AT_POP_VLAN:ROFL_PIPELINE_INFO_NO_PREFIX("POP_VLAN");
752  break;
753  case OF1X_AT_POP_MPLS:ROFL_PIPELINE_INFO_NO_PREFIX("POP_MPLS");
754  break;
755  case OF1X_AT_POP_PPPOE:ROFL_PIPELINE_INFO_NO_PREFIX("POP_PPPOE");
756  break;
757 
758  case OF1X_AT_PUSH_PPPOE:ROFL_PIPELINE_INFO_NO_PREFIX("PUSH_PPPOE");
759  break;
760  case OF1X_AT_PUSH_MPLS:ROFL_PIPELINE_INFO_NO_PREFIX("PUSH_MPLS");
761  break;
762  case OF1X_AT_PUSH_VLAN:ROFL_PIPELINE_INFO_NO_PREFIX("PUSH_VLAN");
763  break;
764 
765  case OF1X_AT_COPY_TTL_OUT:ROFL_PIPELINE_INFO_NO_PREFIX("COPY_TTL_OUT");
766  break;
767 
768  case OF1X_AT_DEC_NW_TTL:ROFL_PIPELINE_INFO_NO_PREFIX("DEC_NW_TTL");
769  break;
770  case OF1X_AT_DEC_MPLS_TTL:ROFL_PIPELINE_INFO_NO_PREFIX("DEC_MPLS_TTL");
771  break;
772 
773  case OF1X_AT_SET_MPLS_TTL:ROFL_PIPELINE_INFO_NO_PREFIX("SET_MPLS_TTL: %u", __of1x_get_packet_action_field8(action, raw_nbo));
774  break;
775  case OF1X_AT_SET_NW_TTL:ROFL_PIPELINE_INFO_NO_PREFIX("SET_NW_TTL: %u", __of1x_get_packet_action_field8(action, raw_nbo));
776  break;
777 
778  case OF1X_AT_SET_QUEUE:ROFL_PIPELINE_INFO_NO_PREFIX("SET_QUEUE: %u", __of1x_get_packet_action_field32(action, raw_nbo));
779  break;
780 
781  case OF1X_AT_SET_FIELD_ETH_DST: ROFL_PIPELINE_INFO_NO_PREFIX("SET_ETH_DST: 0x%"PRIx64, __of1x_get_packet_action_field64(action, raw_nbo));
782  break;
783  case OF1X_AT_SET_FIELD_ETH_SRC: ROFL_PIPELINE_INFO_NO_PREFIX("SET_ETH_SRC: 0x%"PRIx64, __of1x_get_packet_action_field64(action, raw_nbo));
784  break;
785  case OF1X_AT_SET_FIELD_ETH_TYPE:ROFL_PIPELINE_INFO_NO_PREFIX("SET_ETH_TYPE: 0x%x", __of1x_get_packet_action_field16(action, raw_nbo));
786  break;
787 
788  case OF1X_AT_SET_FIELD_VLAN_VID:ROFL_PIPELINE_INFO_NO_PREFIX("SET_VLAN_VID: 0x%x", __of1x_get_packet_action_field16(action, raw_nbo));
789  break;
790  case OF1X_AT_SET_FIELD_VLAN_PCP:ROFL_PIPELINE_INFO_NO_PREFIX("SET_VLAN_PCP: 0x%x", __of1x_get_packet_action_field8(action, raw_nbo));
791  break;
792 
793  case OF1X_AT_SET_FIELD_ARP_OPCODE:ROFL_PIPELINE_INFO_NO_PREFIX("SET_ARP_OPCODE: 0x%x", __of1x_get_packet_action_field16(action, raw_nbo));
794  break;
795  case OF1X_AT_SET_FIELD_ARP_SHA: ROFL_PIPELINE_INFO_NO_PREFIX("SET_ARP_SHA: 0x%"PRIx64, __of1x_get_packet_action_field64(action, raw_nbo));
796  break;
797  case OF1X_AT_SET_FIELD_ARP_SPA: ROFL_PIPELINE_INFO_NO_PREFIX("SET_ARP_SPA: 0x%x", __of1x_get_packet_action_field32(action, raw_nbo));
798  break;
799  case OF1X_AT_SET_FIELD_ARP_THA: ROFL_PIPELINE_INFO_NO_PREFIX("SET_ARP_THA: 0x%"PRIx64, __of1x_get_packet_action_field64(action, raw_nbo));
800  break;
801  case OF1X_AT_SET_FIELD_ARP_TPA: ROFL_PIPELINE_INFO_NO_PREFIX("SET_ARP_TPA: 0x%x", __of1x_get_packet_action_field32(action, raw_nbo));
802  break;
803 
804  /* OF1.0 only */
805  case OF1X_AT_SET_FIELD_NW_PROTO: ROFL_PIPELINE_INFO_NO_PREFIX("SET_NW_PROTO: 0x%x", __of1x_get_packet_action_field8(action, raw_nbo));
806  break;
807  case OF1X_AT_SET_FIELD_NW_SRC: ROFL_PIPELINE_INFO_NO_PREFIX("SET_NW_SRC: 0x%x", __of1x_get_packet_action_field32(action, raw_nbo));
808  break;
809  case OF1X_AT_SET_FIELD_NW_DST: ROFL_PIPELINE_INFO_NO_PREFIX("SET_NW_DST: 0x%x", __of1x_get_packet_action_field32(action, raw_nbo));
810  break;
811  /* OF1.0 only */
812 
813  case OF1X_AT_SET_FIELD_IP_DSCP: ROFL_PIPELINE_INFO_NO_PREFIX("SET_IP_DSCP: 0x%x", __of1x_get_packet_action_field8(action, raw_nbo));
814  break;
815  case OF1X_AT_SET_FIELD_IP_ECN: ROFL_PIPELINE_INFO_NO_PREFIX("SET_IP_ECN: 0x%x", __of1x_get_packet_action_field8(action, raw_nbo));
816  break;
817 
818  case OF1X_AT_SET_FIELD_IP_PROTO:ROFL_PIPELINE_INFO_NO_PREFIX("SET_IP_PROTO: 0x%x", __of1x_get_packet_action_field8(action, raw_nbo));
819  break;
820 
821  case OF1X_AT_SET_FIELD_IPV4_SRC:ROFL_PIPELINE_INFO_NO_PREFIX("SET_IPV4_SRC: 0x%x", __of1x_get_packet_action_field32(action, raw_nbo));
822  break;
823  case OF1X_AT_SET_FIELD_IPV4_DST:ROFL_PIPELINE_INFO_NO_PREFIX("SET_IPV4_DST: 0x%x", __of1x_get_packet_action_field32(action, raw_nbo));
824  break;
825 
826  /* OF1.0 only */
827  case OF1X_AT_SET_FIELD_TP_SRC: ROFL_PIPELINE_INFO_NO_PREFIX("SET_TP_SRC: %u", __of1x_get_packet_action_field16(action, raw_nbo));
828  break;
829  case OF1X_AT_SET_FIELD_TP_DST: ROFL_PIPELINE_INFO_NO_PREFIX("SET_TP_DST: %u", __of1x_get_packet_action_field16(action, raw_nbo));
830  break;
831  /* OF1.0 only */
832  case OF1X_AT_SET_FIELD_TCP_SRC: ROFL_PIPELINE_INFO_NO_PREFIX("SET_TCP_SRC: %u", __of1x_get_packet_action_field16(action, raw_nbo));
833  break;
834  case OF1X_AT_SET_FIELD_TCP_DST: ROFL_PIPELINE_INFO_NO_PREFIX("SET_TCP_DST: %u", __of1x_get_packet_action_field16(action, raw_nbo));
835  break;
836 
837  case OF1X_AT_SET_FIELD_UDP_SRC: ROFL_PIPELINE_INFO_NO_PREFIX("SET_UDP_SRC: %u", __of1x_get_packet_action_field16(action, raw_nbo));
838  break;
839  case OF1X_AT_SET_FIELD_UDP_DST: ROFL_PIPELINE_INFO_NO_PREFIX("SET_UDP_DST: %u", __of1x_get_packet_action_field16(action, raw_nbo));
840  break;
841  case OF1X_AT_SET_FIELD_SCTP_SRC: ROFL_PIPELINE_INFO_NO_PREFIX("SET_SCTP_SRC: %u", __of1x_get_packet_action_field16(action, raw_nbo));
842  break;
843  case OF1X_AT_SET_FIELD_SCTP_DST: ROFL_PIPELINE_INFO_NO_PREFIX("SET_SCTP_DST: %u", __of1x_get_packet_action_field16(action, raw_nbo));
844  break;
845 
846  case OF1X_AT_SET_FIELD_ICMPV4_TYPE:ROFL_PIPELINE_INFO_NO_PREFIX("SET_ICMPV4_TYPE: 0x%x", __of1x_get_packet_action_field8(action, raw_nbo));
847  break;
848  case OF1X_AT_SET_FIELD_ICMPV4_CODE:ROFL_PIPELINE_INFO_NO_PREFIX("SET_ICMPV4_CODE: 0x%x", __of1x_get_packet_action_field8(action, raw_nbo));
849  break;
850 
851  case OF1X_AT_SET_FIELD_MPLS_LABEL:ROFL_PIPELINE_INFO_NO_PREFIX("SET_MPLS_LABEL: 0x%x", __of1x_get_packet_action_field32(action, raw_nbo));
852  break;
853  case OF1X_AT_SET_FIELD_MPLS_TC:ROFL_PIPELINE_INFO_NO_PREFIX("SET_MPLS_TC: 0x%x", __of1x_get_packet_action_field8(action, raw_nbo));
854  break;
855  case OF1X_AT_SET_FIELD_MPLS_BOS:ROFL_PIPELINE_INFO_NO_PREFIX("SET_MPLS_BOS: 0x%x", __of1x_get_packet_action_field8(action, raw_nbo));
856  break;
857 
858  case OF1X_AT_SET_FIELD_PPPOE_CODE:ROFL_PIPELINE_INFO_NO_PREFIX("SET_PPPOE_CODE: 0x%x", __of1x_get_packet_action_field8(action, raw_nbo));
859  break;
860  case OF1X_AT_SET_FIELD_PPPOE_TYPE:ROFL_PIPELINE_INFO_NO_PREFIX("SET_PPPOE_TYPE: 0x%x", __of1x_get_packet_action_field8(action, raw_nbo));
861  break;
862  case OF1X_AT_SET_FIELD_PPPOE_SID:ROFL_PIPELINE_INFO_NO_PREFIX("SET_PPPOE_SID: 0x%x", __of1x_get_packet_action_field16(action, raw_nbo));
863  break;
864 
865  case OF1X_AT_SET_FIELD_PPP_PROT:ROFL_PIPELINE_INFO_NO_PREFIX("SET_PPP_PROT: 0x%x", __of1x_get_packet_action_field16(action, raw_nbo));
866  break;
867 
868  case OF1X_AT_SET_FIELD_IPV6_SRC:
869  {
870  uint128__t addr = __of1x_get_packet_action_field128(action, raw_nbo);
871  (void)addr;
872  COND_NTOHB128(raw_nbo,addr);
873  ROFL_PIPELINE_INFO_NO_PREFIX("SET_IPV6_SRC: 0x%lx %lx",UINT128__T_HI(addr),UINT128__T_LO(addr));
874  }
875  break;
876  case OF1X_AT_SET_FIELD_IPV6_DST:
877  {
878  uint128__t addr = __of1x_get_packet_action_field128(action, raw_nbo);
879  (void)addr;
880  COND_NTOHB128(raw_nbo,addr);
881  ROFL_PIPELINE_INFO_NO_PREFIX("SET_IPV6_DST: 0x%lx %lx",UINT128__T_HI(addr),UINT128__T_LO(addr));
882  }
883  break;
884  case OF1X_AT_SET_FIELD_IPV6_FLABEL:ROFL_PIPELINE_INFO_NO_PREFIX("SET_IPV6_FLABEL: 0x%u", __of1x_get_packet_action_field32(action, raw_nbo));
885  break;
886  case OF1X_AT_SET_FIELD_IPV6_ND_TARGET:
887  {
888  uint128__t addr = __of1x_get_packet_action_field128(action, raw_nbo);
889  (void)addr;
890  COND_NTOHB128(raw_nbo,addr);
891  ROFL_PIPELINE_INFO_NO_PREFIX("SET_IPV6_ND_TARGET: 0x%lx %lx",UINT128__T_HI(addr),UINT128__T_LO(addr));
892  }
893  break;
894  case OF1X_AT_SET_FIELD_IPV6_ND_SLL:ROFL_PIPELINE_INFO_NO_PREFIX("SET_IPV6_ND_SLL: 0x%x", __of1x_get_packet_action_field64(action, raw_nbo));
895  break;
896  case OF1X_AT_SET_FIELD_IPV6_ND_TLL:ROFL_PIPELINE_INFO_NO_PREFIX("SET_IPV6_ND_TLL: 0x%x", __of1x_get_packet_action_field64(action, raw_nbo));
897  break;
898  case OF1X_AT_SET_FIELD_IPV6_EXTHDR:ROFL_PIPELINE_INFO_NO_PREFIX("SET_IPV6_EXTHDR: 0x%x", __of1x_get_packet_action_field16(action, raw_nbo));
899  break;
900 
901  case OF1X_AT_SET_FIELD_ICMPV6_TYPE:ROFL_PIPELINE_INFO_NO_PREFIX("SET_ICMPV6_TYPE: 0x%u", __of1x_get_packet_action_field8(action, raw_nbo));
902  break;
903  case OF1X_AT_SET_FIELD_ICMPV6_CODE:ROFL_PIPELINE_INFO_NO_PREFIX("SET_ICMPV6_CODE: 0x%u", __of1x_get_packet_action_field8(action, raw_nbo));
904  break;
905  case OF1X_AT_POP_PBB:ROFL_PIPELINE_INFO_NO_PREFIX("POP_PBB");
906  break;
907  case OF1X_AT_PUSH_PBB:ROFL_PIPELINE_INFO_NO_PREFIX("PUSH_PBB");
908  break;
909  case OF1X_AT_SET_FIELD_PBB_ISID:ROFL_PIPELINE_INFO_NO_PREFIX("SET_PBB_ISID: 0x%u", __of1x_get_packet_action_field64(action, raw_nbo));
910  break;
911  case OF1X_AT_SET_FIELD_TUNNEL_ID:ROFL_PIPELINE_INFO_NO_PREFIX("SET_TUNNEL_ID: 0x%u", __of1x_get_packet_action_field64(action, raw_nbo));
912  break;
913 
914 
915  case OF1X_AT_SET_FIELD_GTP_MSG_TYPE:ROFL_PIPELINE_INFO_NO_PREFIX("SET_GTP_MSG_TYPE: 0x%x", __of1x_get_packet_action_field8(action, raw_nbo));
916  break;
917  case OF1X_AT_SET_FIELD_GTP_TEID:ROFL_PIPELINE_INFO_NO_PREFIX("SET_GTP_TEID: 0x%x", __of1x_get_packet_action_field32(action, raw_nbo));
918  break;
919  case OF1X_AT_POP_GTP:ROFL_PIPELINE_INFO_NO_PREFIX("POP_GTP");
920  break;
921  case OF1X_AT_PUSH_GTP:ROFL_PIPELINE_INFO_NO_PREFIX("PUSH_GTP");
922  break;
923 
924  case OF1X_AT_SET_FIELD_CAPWAP_WBID:ROFL_PIPELINE_INFO_NO_PREFIX("SET_CAPWAP_WBID: 0x%x", __of1x_get_packet_action_field8(action, raw_nbo));
925  break;
926  case OF1X_AT_SET_FIELD_CAPWAP_RID:ROFL_PIPELINE_INFO_NO_PREFIX("SET_CAPWAP_RID: 0x%x", __of1x_get_packet_action_field8(action, raw_nbo));
927  break;
928  case OF1X_AT_SET_FIELD_CAPWAP_FLAGS:ROFL_PIPELINE_INFO_NO_PREFIX("SET_CAPWAP_FLAGS: 0x%x", __of1x_get_packet_action_field16(action, raw_nbo));
929  break;
930  case OF1X_AT_POP_CAPWAP:ROFL_PIPELINE_INFO_NO_PREFIX("POP_CAPWAP");
931  break;
932  case OF1X_AT_PUSH_CAPWAP:ROFL_PIPELINE_INFO_NO_PREFIX("PUSH_CAPWAP");
933  break;
934 
935  case OF1X_AT_SET_FIELD_WLAN_FC:ROFL_PIPELINE_INFO_NO_PREFIX("SET_WLAN_FC: 0x%x", __of1x_get_packet_action_field16(action, raw_nbo));
936  break;
937  case OF1X_AT_SET_FIELD_WLAN_TYPE:ROFL_PIPELINE_INFO_NO_PREFIX("SET_WLAN_TYPE: 0x%x", __of1x_get_packet_action_field8(action, raw_nbo));
938  break;
939  case OF1X_AT_SET_FIELD_WLAN_SUBTYPE:ROFL_PIPELINE_INFO_NO_PREFIX("SET_WLAN_SUBTYPE: 0x%x", __of1x_get_packet_action_field8(action, raw_nbo));
940  break;
941  case OF1X_AT_SET_FIELD_WLAN_DIRECTION:ROFL_PIPELINE_INFO_NO_PREFIX("SET_WLAN_DIRECTION: 0x%x", __of1x_get_packet_action_field8(action, raw_nbo));
942  break;
943  case OF1X_AT_SET_FIELD_WLAN_ADDRESS_1:ROFL_PIPELINE_INFO_NO_PREFIX("SET_WLAN_ADDRESS_1: 0x%x", __of1x_get_packet_action_field64(action, raw_nbo));
944  break;
945  case OF1X_AT_SET_FIELD_WLAN_ADDRESS_2:ROFL_PIPELINE_INFO_NO_PREFIX("SET_WLAN_ADDRESS_2: 0x%x", __of1x_get_packet_action_field64(action, raw_nbo));
946  break;
947  case OF1X_AT_SET_FIELD_WLAN_ADDRESS_3:ROFL_PIPELINE_INFO_NO_PREFIX("SET_WLAN_ADDRESS_3: 0x%x", __of1x_get_packet_action_field64(action, raw_nbo));
948  break;
949  case OF1X_AT_POP_WLAN:ROFL_PIPELINE_INFO_NO_PREFIX("POP_WLAN");
950  break;
951  case OF1X_AT_PUSH_WLAN:ROFL_PIPELINE_INFO_NO_PREFIX("PUSH_WLAN");
952  break;
953 
954  case OF1X_AT_SET_FIELD_GRE_VERSION:ROFL_PIPELINE_INFO_NO_PREFIX("SET_GRE_VERSION: 0x%x", __of1x_get_packet_action_field16(action, raw_nbo));
955  break;
956  case OF1X_AT_SET_FIELD_GRE_PROT_TYPE:ROFL_PIPELINE_INFO_NO_PREFIX("SET_GRE_PROT_TYPE: 0x%x", __of1x_get_packet_action_field16(action, raw_nbo));
957  break;
958  case OF1X_AT_SET_FIELD_GRE_KEY:ROFL_PIPELINE_INFO_NO_PREFIX("SET_GRE_KEY: 0x%x", __of1x_get_packet_action_field32(action, raw_nbo));
959  break;
960  case OF1X_AT_POP_GRE:ROFL_PIPELINE_INFO_NO_PREFIX("POP_GRE");
961  break;
962  case OF1X_AT_PUSH_GRE:ROFL_PIPELINE_INFO_NO_PREFIX("PUSH_GRE");
963  break;
964 
965  case OF1X_AT_GROUP:ROFL_PIPELINE_INFO_NO_PREFIX("GROUP:%u", __of1x_get_packet_action_field32(action, raw_nbo));
966  break;
967 
968  case OF1X_AT_EXPERIMENTER:ROFL_PIPELINE_INFO_NO_PREFIX("EXPERIMENTER");
969  break;
970 
971  case OF1X_AT_OUTPUT:
972  ROFL_PIPELINE_INFO_NO_PREFIX("OUTPUT port: ");
973  switch(__of1x_get_packet_action_field32(action, raw_nbo)){
974 
975  case OF1X_PORT_FLOOD:
976  ROFL_PIPELINE_INFO_NO_PREFIX("FLOOD");
977  break;
978  case OF1X_PORT_NORMAL:
979  ROFL_PIPELINE_INFO_NO_PREFIX("NORMAL");
980  break;
981  case OF1X_PORT_CONTROLLER:
982  ROFL_PIPELINE_INFO_NO_PREFIX("CONTROLLER");
983  break;
984  case OF1X_PORT_ALL:
985  ROFL_PIPELINE_INFO_NO_PREFIX("ALL");
986  break;
987  case OF1X_PORT_TABLE:
988  ROFL_PIPELINE_INFO_NO_PREFIX("TABLE");
989  break;
990  case OF1X_PORT_IN_PORT:
991  ROFL_PIPELINE_INFO_NO_PREFIX("IN-PORT");
992  break;
993  default:
994  ROFL_PIPELINE_INFO_NO_PREFIX("%u", __of1x_get_packet_action_field32(action, raw_nbo));
995  break;
996  }
997  break;
998  }
999  ROFL_PIPELINE_INFO_NO_PREFIX(">,");
1000 
1001 }
1002 
1003 void __of1x_dump_write_actions(of1x_write_actions_t* write_actions, bool raw_nbo){
1004 
1005  int i,j;
1006 
1007  for(i=0,j=0;i<write_actions->num_of_actions && j < OF1X_AT_NUMBER;j++){
1008  if( bitmap128_is_bit_set(&write_actions->bitmap, j) ){
1009  //Process action
1010  __of1x_dump_packet_action(&write_actions->actions[j], raw_nbo);
1011  i++;
1012  }
1013  }
1014 }
1015 
1016 void __of1x_dump_action_group(of1x_action_group_t* action_group, bool raw_nbo){
1017 
1018  of1x_packet_action_t* action;
1019 
1020  if( unlikely(action_group==NULL) )
1021  return;
1022  for(action=action_group->head;action;action=action->next){
1023  __of1x_dump_packet_action(action, raw_nbo);
1024  }
1025 }
1026 
1027 rofl_result_t __of1x_validate_action_group(bitmap128_t* supported, of1x_action_group_t *ag, of1x_group_table_t *gt, bool is_pkt_out_al){
1028  of1x_packet_action_t *pa_it;
1029 
1030  if(unlikely(ag == NULL))
1031  return ROFL_FAILURE;
1032 
1033  //Check supported bitmap (if defined). Won't be defined for packet_outs
1034  if( supported && !bitmap128_check_mask(&ag->bitmap, supported) )
1035  return ROFL_FAILURE;
1036 
1037  for(pa_it=ag->head; pa_it; pa_it=pa_it->next){
1038  if(pa_it->type == OF1X_AT_OUTPUT)
1039  ag->num_of_output_actions++;
1040  else if(pa_it->type == OF1X_AT_GROUP && gt){
1041  if((pa_it->group=__of1x_group_search(gt,pa_it->__field.u64))==NULL)
1042  return ROFL_FAILURE;
1043  else{
1044  //If there is a group, FORCE cloning of the packet; state between
1045  //group num of actions and entry "num_of_output_actions cache"
1046  ag->num_of_output_actions+=2;
1047  }
1048  }
1049  }
1050 
1051  //Only pkt_out action lists can have output to table
1052  if(!is_pkt_out_al && ag->has_output_table)
1053  return ROFL_FAILURE;
1054 
1055  return ROFL_SUCCESS;
1056 }
1057 
1058 rofl_result_t __of1x_validate_write_actions(bitmap128_t* supported, of1x_write_actions_t *wa, of1x_group_table_t *gt){
1059 
1060  if(unlikely(wa == NULL))
1061  return ROFL_FAILURE;
1062 
1063  if(wa->num_of_actions == 0)
1064  return ROFL_SUCCESS;
1065 
1066  if( !bitmap128_check_mask(&wa->bitmap, supported) )
1067  return ROFL_FAILURE;
1068 
1069  if( bitmap128_is_bit_set(&wa->bitmap, OF1X_AT_OUTPUT) )
1070  wa->num_of_output_actions++;
1071 
1072  if(gt && bitmap128_is_bit_set(&wa->bitmap, OF1X_AT_GROUP)){
1073  if((wa->actions[OF1X_AT_GROUP].group=__of1x_group_search(gt,wa->actions[OF1X_AT_GROUP].__field.u64))==NULL )
1074  return ROFL_FAILURE;
1075  else{
1076  //If there is a group, FORCE cloning of the packet; state between
1077  //group num of actions and entry "num_of_output_actions cache"
1078  wa->num_of_output_actions+=2;
1079  }
1080  }
1081 
1082  return ROFL_SUCCESS;
1083 }
of1x_packet_action_type_t
Actions over a packet as per defined in OF10, OF12, OF13.
Definition: of1x_action.h:89
OpenFlow v1.0, 1.2 and 1.3.2 flow table abstraction.
Packet action abstraction data structure.
Definition: of1x_action.h:278
of1x_action_group_t * of1x_init_action_group(of1x_packet_action_t *actions)
Create an action group (apply actions)
Definition: of1x_action.c:440
static void bitmap128_clean(bitmap128_t *bitmap)
Set bitmap to 0.
Definition: bitmap.h:29
void of1x_push_packet_action_to_group(of1x_action_group_t *group, of1x_packet_action_t *action)
Push an action to the group.
Definition: of1x_action.c:495
Write actions structure.
Definition: of1x_action.h:330
void of1x_destroy_action_group(of1x_action_group_t *group)
Destroy an action group.
Definition: of1x_action.c:480
static bool bitmap128_is_bit_set(const bitmap128_t *bitmap, unsigned int pos)
Check if bit is set in the 128bit bitmap.
Definition: bitmap.h:45
OpenFlow v1.0, 1.2 and 1.3.2 actions.
Port abstraction.
Definition: switch_port.h:145
static bool bitmap128_check_mask(bitmap128_t *bitmap, bitmap128_t *mask)
Check whether a bitmap is within a certain mask (bitmap&mask == bitmap)
Definition: bitmap.h:99
#define OF1X_MAC_ALIGN(x)
ALIGNING FUNCTIONS FOR THE PROTOCOL VALUES ///.
Definition: of1x_utils.h:166
Action group (apply-actions) structure.
Definition: of1x_action.h:303
void of1x_destroy_packet_action(of1x_packet_action_t *action)
Destroys packet action (OF action)
Definition: of1x_action.c:434
rofl_result_t of1x_set_packet_action_on_write_actions(of1x_write_actions_t *write_actions, of1x_packet_action_t *action)
Set (copy) the action to the write actions.
Definition: of1x_action.c:570
of1x_write_actions_t * of1x_init_write_actions()
Create a write actions group.
Definition: of1x_action.c:541
void * platform_malloc_shared(size_t length)
Allocates a chunk of dynamic memory of size length, which must be accessible (R/W) for all the thread...
void platform_free_shared(void *data)
Frees a chunk of dynamic memory previously allocated with platform_malloc_shared().
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...
switch_port_t * flood_meta_port
Special meta port: FLOOD.
of1x_packet_action_t * of1x_init_packet_action(of1x_packet_action_type_t type, wrap_uint_t field, uint16_t output_send_len)
Initializes a packet action (OF action)
Definition: of1x_action.c:21
static void bitmap128_set(bitmap128_t *bitmap, unsigned int pos)
Set a bit in the 128bit bitmap.
Definition: bitmap.h:55