ROFL-pipeline  v0.6.0dev
of1x_match_pp.h
Go to the documentation of this file.
1 #ifndef __OF1X_MATCH_PP_H__
2 #define __OF1X_MATCH_PP_H__
3 
4 #include <stdlib.h>
5 #include <inttypes.h>
6 #include <string.h>
7 #include <stdbool.h>
8 #include "rofl.h"
9 #include "../../../util/pp_guard.h" //Never forget to include the guard
10 #include "../../../common/packet_matches.h"
11 #include "../../../common/protocol_constants.h"
12 #include "../../../common/ternary_fields.h"
13 #include "../../../platform/likely.h"
14 #include "../../../platform/packet.h"
15 #include "of1x_match.h"
16 #include "of1x_utils.h"
17 
42 //C++ extern C
43 ROFL_BEGIN_DECLS
44 
45 /*
46 * CHECK fields against packet
47 *
48 * @warning: it MUST BE != NULL
49 */
50 static inline bool __of1x_check_match(datapacket_t *const pkt, of1x_match_t* it){
51 
52  switch(it->type){
53  //Phy
54  case OF1X_MATCH_IN_PORT: return __utern_compare32(it->__tern, platform_packet_get_port_in(pkt));
55  case OF1X_MATCH_IN_PHY_PORT: if(!platform_packet_get_port_in(pkt)) return false; //According to spec
56  return __utern_compare32(it->__tern, platform_packet_get_phy_port_in(pkt));
57  //Metadata
58  case OF1X_MATCH_METADATA: return __utern_compare64(it->__tern, &pkt->__metadata);
59 
60  //802
61  case OF1X_MATCH_ETH_DST: return __utern_compare64(it->__tern, platform_packet_get_eth_dst(pkt));
62  case OF1X_MATCH_ETH_SRC: return __utern_compare64(it->__tern, platform_packet_get_eth_src(pkt));
63  case OF1X_MATCH_ETH_TYPE: return __utern_compare16(it->__tern, platform_packet_get_eth_type(pkt));
64 
65  //802.1q
66  case OF1X_MATCH_VLAN_VID: if( it->vlan_present == OF1X_MATCH_VLAN_SPECIFIC )
67  return platform_packet_has_vlan(pkt) && __utern_compare16(it->__tern, platform_packet_get_vlan_vid(pkt));
68  else
69  return platform_packet_has_vlan(pkt) == it->vlan_present;
70  case OF1X_MATCH_VLAN_PCP: return platform_packet_has_vlan(pkt) && __utern_compare8(it->__tern, platform_packet_get_vlan_pcp(pkt));
71 
72  //MPLS
73  case OF1X_MATCH_MPLS_LABEL:{
74  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
75  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_MPLS_UNICAST || *ptr_ether_type == ETH_TYPE_MPLS_MULTICAST )) return false;
76  return __utern_compare32(it->__tern, platform_packet_get_mpls_label(pkt));
77  }
78  case OF1X_MATCH_MPLS_TC:{
79  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
80  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_MPLS_UNICAST || *ptr_ether_type == ETH_TYPE_MPLS_MULTICAST )) return false;
81  return __utern_compare8(it->__tern, platform_packet_get_mpls_tc(pkt));
82  }
83  case OF1X_MATCH_MPLS_BOS:{
84  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
85  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_MPLS_UNICAST || *ptr_ether_type == ETH_TYPE_MPLS_MULTICAST )) return false;
86  uint8_t bos = platform_packet_get_mpls_bos(pkt);
87  return __utern_compare8(it->__tern, &bos);
88  }
89 
90  //ARP
91  case OF1X_MATCH_ARP_OP:{
92  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
93  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_ARP)) return false;
94  return __utern_compare16(it->__tern, platform_packet_get_arp_opcode(pkt));
95  }
96  case OF1X_MATCH_ARP_SHA:{
97  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
98  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_ARP)) return false;
99  return __utern_compare64(it->__tern, platform_packet_get_arp_sha(pkt));
100  }
101  case OF1X_MATCH_ARP_SPA:{
102  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
103  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_ARP)) return false;
104  return __utern_compare32(it->__tern, platform_packet_get_arp_spa(pkt));
105  }
106  case OF1X_MATCH_ARP_THA:{
107  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
108  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_ARP)) return false;
109  return __utern_compare64(it->__tern, platform_packet_get_arp_tha(pkt));
110  }
111  case OF1X_MATCH_ARP_TPA:{
112  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
113  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_ARP)) return false;
114  return __utern_compare32(it->__tern, platform_packet_get_arp_tpa(pkt));
115  }
116 
117  //NW (OF1.0 only)
118  case OF1X_MATCH_NW_PROTO:{
119 #ifdef ROFL_EXPERIMENTAL
120  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
121  uint16_t *ptr_ppp_proto = platform_packet_get_ppp_proto(pkt);
122  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_IPV4 || *ptr_ether_type == ETH_TYPE_IPV6 || *ptr_ether_type == ETH_TYPE_ARP || (*ptr_ether_type == ETH_TYPE_PPPOE_SESSION && ptr_ppp_proto && (*ptr_ppp_proto == PPP_PROTO_IP4 || *ptr_ppp_proto == PPP_PROTO_IP6) ))) return false;
123  if(*ptr_ether_type == ETH_TYPE_ARP){
124  uint8_t *low_byte = ((uint8_t*)(platform_packet_get_arp_opcode(pkt)));
125  return __utern_compare8(it->__tern, ++low_byte);
126  }
127  else
128  return __utern_compare8(it->__tern, platform_packet_get_ip_proto(pkt));
129 #else
130  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
131  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_IPV4 || *ptr_ether_type == ETH_TYPE_IPV6 || *ptr_ether_type == ETH_TYPE_ARP )) return false;
132  if(*ptr_ether_type == ETH_TYPE_ARP){
133  uint8_t *low_byte = ((uint8_t*)(platform_packet_get_arp_opcode(pkt)));
134  return __utern_compare8(it->__tern, ++low_byte);
135  }
136  else
137  return __utern_compare8(it->__tern, platform_packet_get_ip_proto(pkt));
138 #endif
139  }
140  case OF1X_MATCH_NW_SRC:{
141 #ifdef ROFL_EXPERIMENTAL
142  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
143  uint16_t *ptr_ppp_proto = platform_packet_get_ppp_proto(pkt);
144  if( ptr_ether_type && (*ptr_ether_type == ETH_TYPE_IPV4 || (*ptr_ether_type == ETH_TYPE_PPPOE_SESSION && ptr_ppp_proto && *ptr_ppp_proto == PPP_PROTO_IP4 )))
145  return __utern_compare32(it->__tern, platform_packet_get_ipv4_src(pkt));
146  if(ptr_ether_type && *ptr_ether_type == ETH_TYPE_ARP)
147  return __utern_compare32(it->__tern, platform_packet_get_arp_spa(pkt));
148  return false;
149 #else
150  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
151  if( ptr_ether_type && (*ptr_ether_type == ETH_TYPE_IPV4))
152  return __utern_compare32(it->__tern, platform_packet_get_ipv4_src(pkt));
153  if(ptr_ether_type && *ptr_ether_type == ETH_TYPE_ARP)
154  return __utern_compare32(it->__tern, platform_packet_get_arp_spa(pkt));
155  return false;
156 #endif
157  }
158  case OF1X_MATCH_NW_DST:{
159 #ifdef ROFL_EXPERIMENTAL
160  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
161  uint16_t *ptr_ppp_proto = platform_packet_get_ppp_proto(pkt);
162  if( ptr_ether_type && (*ptr_ether_type == ETH_TYPE_IPV4 ||(*ptr_ether_type == ETH_TYPE_PPPOE_SESSION && ptr_ppp_proto && *ptr_ppp_proto == PPP_PROTO_IP4 )))
163  return __utern_compare32(it->__tern, platform_packet_get_ipv4_dst(pkt));
164  if( ptr_ether_type && *ptr_ether_type == ETH_TYPE_ARP)
165  return __utern_compare32(it->__tern, platform_packet_get_arp_tpa(pkt));
166  return false;
167 #else
168  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
169  if( ptr_ether_type && (*ptr_ether_type == ETH_TYPE_IPV4))
170  return __utern_compare32(it->__tern, platform_packet_get_ipv4_dst(pkt));
171  if( ptr_ether_type && *ptr_ether_type == ETH_TYPE_ARP)
172  return __utern_compare32(it->__tern, platform_packet_get_arp_tpa(pkt));
173  return false;
174 #endif
175  }
176 
177  //IP
178  case OF1X_MATCH_IP_PROTO:{
179 #ifdef ROFL_EXPERIMENTAL
180  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
181  uint16_t *ptr_ppp_proto = platform_packet_get_ppp_proto(pkt);
182  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_IPV4 || *ptr_ether_type == ETH_TYPE_IPV6 || (*ptr_ether_type == ETH_TYPE_PPPOE_SESSION && ptr_ppp_proto && (*ptr_ppp_proto == PPP_PROTO_IP4 || *ptr_ppp_proto == PPP_PROTO_IP6) ))) return false;
183  return __utern_compare8(it->__tern, platform_packet_get_ip_proto(pkt));
184 #else
185  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
186  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_IPV4 || *ptr_ether_type == ETH_TYPE_IPV6)) return false;
187  return __utern_compare8(it->__tern, platform_packet_get_ip_proto(pkt));
188 #endif
189  }
190  case OF1X_MATCH_IP_ECN:{
191 #ifdef ROFL_EXPERIMENTAL
192  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
193  uint16_t *ptr_ppp_proto = platform_packet_get_ppp_proto(pkt);
194  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_IPV4 || *ptr_ether_type == ETH_TYPE_IPV6 || (*ptr_ether_type == ETH_TYPE_PPPOE_SESSION && ptr_ppp_proto && *ptr_ppp_proto == PPP_PROTO_IP4 ))) return false; //NOTE PPP_PROTO_IP6
195  {
196  uint8_t ecn = platform_packet_get_ip_ecn(pkt);
197  return __utern_compare8(it->__tern, &ecn);
198  }
199 #else
200  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
201  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_IPV4 || *ptr_ether_type == ETH_TYPE_IPV6)) return false; //NOTE PPP_PROTO_IP6
202  {
203  uint8_t ecn = platform_packet_get_ip_ecn(pkt);
204  return __utern_compare8(it->__tern, &ecn);
205  }
206 #endif
207  }
208  case OF1X_MATCH_IP_DSCP:{
209 #ifdef ROFL_EXPERIMENTAL
210  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
211  uint16_t *ptr_ppp_proto = platform_packet_get_ppp_proto(pkt);
212  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_IPV4 || *ptr_ether_type == ETH_TYPE_IPV6 || (*ptr_ether_type == ETH_TYPE_PPPOE_SESSION && ptr_ppp_proto && *ptr_ppp_proto == PPP_PROTO_IP4 ))) return false; //NOTE PPP_PROTO_IP6
213  {
214  uint8_t dscp = platform_packet_get_ip_dscp(pkt);
215  return __utern_compare8(it->__tern, &dscp);
216  }
217 #else
218  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
219  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_IPV4 || *ptr_ether_type == ETH_TYPE_IPV6)) return false; //NOTE PPP_PROTO_IP6
220  {
221  uint8_t dscp = platform_packet_get_ip_dscp(pkt);
222  return __utern_compare8(it->__tern, &dscp);
223  }
224 #endif
225  }
226 
227  //IPv4
228  case OF1X_MATCH_IPV4_SRC:{
229 #ifdef ROFL_EXPERIMENTAL
230  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
231  uint16_t *ptr_ppp_proto = platform_packet_get_ppp_proto(pkt);
232  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_IPV4 || (*ptr_ether_type == ETH_TYPE_PPPOE_SESSION && ptr_ppp_proto && *ptr_ppp_proto == PPP_PROTO_IP4 ))) return false;
233  return __utern_compare32(it->__tern, platform_packet_get_ipv4_src(pkt));
234 #else
235  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
236  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_IPV4)) return false;
237  return __utern_compare32(it->__tern, platform_packet_get_ipv4_src(pkt));
238 #endif
239  }
240  case OF1X_MATCH_IPV4_DST:{
241 #ifdef ROFL_EXPERIMENTAL
242  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
243  uint16_t *ptr_ppp_proto = platform_packet_get_ppp_proto(pkt);
244  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_IPV4 ||(*ptr_ether_type == ETH_TYPE_PPPOE_SESSION && ptr_ppp_proto && *ptr_ppp_proto == PPP_PROTO_IP4 ))) return false;
245  return __utern_compare32(it->__tern, platform_packet_get_ipv4_dst(pkt));
246 #else
247  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
248  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_IPV4)) return false;
249  return __utern_compare32(it->__tern, platform_packet_get_ipv4_dst(pkt));
250 #endif
251  }
252 
253  //TCP
254  case OF1X_MATCH_TCP_SRC:{
255  uint8_t *ptr_ip_proto = platform_packet_get_ip_proto(pkt);
256  if( !ptr_ip_proto || !(*ptr_ip_proto == IP_PROTO_TCP)) return false;
257  return __utern_compare16(it->__tern, platform_packet_get_tcp_src(pkt));
258  }
259  case OF1X_MATCH_TCP_DST:{
260  uint8_t *ptr_ip_proto = platform_packet_get_ip_proto(pkt);
261  if( !ptr_ip_proto || !(*ptr_ip_proto == IP_PROTO_TCP)) return false;
262  return __utern_compare16(it->__tern, platform_packet_get_tcp_dst(pkt));
263  }
264 
265  //UDP
266  case OF1X_MATCH_UDP_SRC:{
267  uint8_t *ptr_ip_proto = platform_packet_get_ip_proto(pkt);
268  if( !ptr_ip_proto || !(*ptr_ip_proto == IP_PROTO_UDP)) return false;
269  return __utern_compare16(it->__tern, platform_packet_get_udp_src(pkt));
270  }
271  case OF1X_MATCH_UDP_DST:{
272  uint8_t *ptr_ip_proto = platform_packet_get_ip_proto(pkt);
273  if( !ptr_ip_proto || !(*ptr_ip_proto == IP_PROTO_UDP)) return false;
274  return __utern_compare16(it->__tern, platform_packet_get_udp_dst(pkt));
275  }
276  //SCTP
277  case OF1X_MATCH_SCTP_SRC:{
278  uint8_t *ptr_ip_proto = platform_packet_get_ip_proto(pkt);
279  if( !ptr_ip_proto || !(*ptr_ip_proto == IP_PROTO_SCTP)) return false;
280  return __utern_compare16(it->__tern, platform_packet_get_sctp_src(pkt));
281  }
282  case OF1X_MATCH_SCTP_DST:{
283  uint8_t *ptr_ip_proto = platform_packet_get_ip_proto(pkt);
284  if( !ptr_ip_proto || !(*ptr_ip_proto == IP_PROTO_SCTP)) return false;
285  return __utern_compare16(it->__tern, platform_packet_get_sctp_dst(pkt));
286  }
287 
288  //TP (OF1.0 only)
289  case OF1X_MATCH_TP_SRC:{
290  uint8_t *ptr_ip_proto = platform_packet_get_ip_proto(pkt);
291  if(ptr_ip_proto && (*ptr_ip_proto == IP_PROTO_TCP))
292  return __utern_compare16(it->__tern, platform_packet_get_tcp_src(pkt));
293  if(ptr_ip_proto && (*ptr_ip_proto == IP_PROTO_UDP))
294  return __utern_compare16(it->__tern, platform_packet_get_udp_src(pkt));
295  if(ptr_ip_proto && (*ptr_ip_proto == IP_PROTO_ICMPV4)){
296  uint8_t two_byte[2] = {0,*platform_packet_get_icmpv4_type(pkt)};
297  return __utern_compare16(it->__tern, (uint16_t*)&two_byte);
298  }
299  return false;
300  }
301  case OF1X_MATCH_TP_DST:{
302  uint8_t *ptr_ip_proto = platform_packet_get_ip_proto(pkt);
303  if(ptr_ip_proto && (*ptr_ip_proto == IP_PROTO_TCP))
304  return __utern_compare16(it->__tern, platform_packet_get_tcp_dst(pkt));
305  if(ptr_ip_proto && (*ptr_ip_proto == IP_PROTO_UDP))
306  return __utern_compare16(it->__tern, platform_packet_get_udp_dst(pkt));
307  if(ptr_ip_proto && (*ptr_ip_proto == IP_PROTO_ICMPV4)){
308  uint8_t two_byte[2] = {0,*platform_packet_get_icmpv4_code(pkt)};
309  return __utern_compare16(it->__tern, (uint16_t*)&two_byte);
310  }
311  return false;
312  }
313 
314  //ICMPv4
315  case OF1X_MATCH_ICMPV4_TYPE:{
316  uint8_t *ptr_ip_proto = platform_packet_get_ip_proto(pkt);
317  if( !ptr_ip_proto || !(*ptr_ip_proto == IP_PROTO_ICMPV4)) return false;
318  return __utern_compare8(it->__tern, platform_packet_get_icmpv4_type(pkt));
319  }
320  case OF1X_MATCH_ICMPV4_CODE:{
321  uint8_t *ptr_ip_proto = platform_packet_get_ip_proto(pkt);
322  if( !ptr_ip_proto || !(*ptr_ip_proto == IP_PROTO_ICMPV4)) return false;
323  return __utern_compare8(it->__tern, platform_packet_get_icmpv4_code(pkt));
324  }
325 
326  //IPv6
327  case OF1X_MATCH_IPV6_SRC:{
328 #ifdef ROFL_EXPERIMENTAL
329  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
330  uint16_t *ptr_ppp_proto = platform_packet_get_ppp_proto(pkt);
331  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_IPV6 || (*ptr_ether_type == ETH_TYPE_PPPOE_SESSION && ptr_ppp_proto && *ptr_ppp_proto == PPP_PROTO_IP6 ))) return false;
332  return __utern_compare128(it->__tern, platform_packet_get_ipv6_src(pkt));
333 #else
334  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
335  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_IPV6)) return false;
336  return __utern_compare128(it->__tern, platform_packet_get_ipv6_src(pkt));
337 #endif
338  }
339  case OF1X_MATCH_IPV6_DST:{
340 #ifdef ROFL_EXPERIMENTAL
341  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
342  uint16_t *ptr_ppp_proto = platform_packet_get_ppp_proto(pkt);
343  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_IPV6 || (*ptr_ether_type == ETH_TYPE_PPPOE_SESSION && ptr_ppp_proto && *ptr_ppp_proto == PPP_PROTO_IP6 ))) return false;
344  return __utern_compare128(it->__tern, platform_packet_get_ipv6_dst(pkt));
345 #else
346  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
347  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_IPV6)) return false;
348  return __utern_compare128(it->__tern, platform_packet_get_ipv6_dst(pkt));
349 #endif
350  }
351  case OF1X_MATCH_IPV6_FLABEL:{
352 #ifdef ROFL_EXPERIMENTAL
353  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
354  uint16_t *ptr_ppp_proto = platform_packet_get_ppp_proto(pkt);
355  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_IPV6 || (*ptr_ether_type == ETH_TYPE_PPPOE_SESSION && ptr_ppp_proto && *ptr_ppp_proto == PPP_PROTO_IP6 ))) return false;
356  return __utern_compare32(it->__tern, platform_packet_get_ipv6_flabel(pkt));
357 #else
358  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
359  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_IPV6)) return false;
360  return __utern_compare32(it->__tern, platform_packet_get_ipv6_flabel(pkt));
361 #endif
362  }
363  case OF1X_MATCH_IPV6_ND_TARGET:{
364  uint8_t *ptr_ip_proto = platform_packet_get_ip_proto(pkt);
365  if( !ptr_ip_proto || !(*ptr_ip_proto == IP_PROTO_ICMPV6)) return false;
366  return __utern_compare128(it->__tern, platform_packet_get_ipv6_nd_target(pkt));
367  }
368  case OF1X_MATCH_IPV6_ND_SLL:{
369  uint8_t *ptr_ip_proto = platform_packet_get_ip_proto(pkt);
370  if( !ptr_ip_proto || !(*ptr_ip_proto == IP_PROTO_ICMPV6 && platform_packet_get_ipv6_nd_sll(pkt))) return false; //NOTE OPTION SLL active
371  return __utern_compare64(it->__tern, platform_packet_get_ipv6_nd_sll(pkt));
372  }
373  case OF1X_MATCH_IPV6_ND_TLL:{
374  uint8_t *ptr_ip_proto = platform_packet_get_ip_proto(pkt);
375  if( !ptr_ip_proto || !(*ptr_ip_proto == IP_PROTO_ICMPV6 && platform_packet_get_ipv6_nd_tll(pkt))) return false; //NOTE OPTION TLL active
376  return __utern_compare64(it->__tern, platform_packet_get_ipv6_nd_tll(pkt));
377  }
378  case OF1X_MATCH_IPV6_EXTHDR: //TODO not yet implemented.
379  return false;
380  break;
381 
382  //ICMPv6
383  case OF1X_MATCH_ICMPV6_TYPE:{
384  uint8_t *ptr_ip_proto = platform_packet_get_ip_proto(pkt);
385  if( !ptr_ip_proto || !(*ptr_ip_proto == IP_PROTO_ICMPV6)) return false;
386  return __utern_compare8(it->__tern, platform_packet_get_icmpv6_type(pkt));
387  }
388  case OF1X_MATCH_ICMPV6_CODE:{
389  uint8_t *ptr_ip_proto = platform_packet_get_ip_proto(pkt);
390  if( !ptr_ip_proto || !(*ptr_ip_proto == IP_PROTO_ICMPV6 )) return false;
391  return __utern_compare8(it->__tern, platform_packet_get_icmpv6_code(pkt));
392  }
393 
394  //PBB
395  case OF1X_MATCH_PBB_ISID:{
396  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
397  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_PBB)) return false;
398  return __utern_compare32(it->__tern, platform_packet_get_pbb_isid(pkt));
399  }
400  //TUNNEL id
401  case OF1X_MATCH_TUNNEL_ID: return __utern_compare64(it->__tern, platform_packet_get_tunnel_id(pkt));
402 
403 #ifdef ROFL_EXPERIMENTAL
404  //PPPoE related extensions
405  case OF1X_MATCH_PPPOE_CODE:{
406  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
407  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_PPPOE_DISCOVERY || *ptr_ether_type == ETH_TYPE_PPPOE_SESSION )) return false;
408  return __utern_compare8(it->__tern, platform_packet_get_pppoe_code(pkt));
409  }
410  case OF1X_MATCH_PPPOE_TYPE:{
411  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
412  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_PPPOE_DISCOVERY || *ptr_ether_type == ETH_TYPE_PPPOE_SESSION )) return false;
413  return __utern_compare8(it->__tern, platform_packet_get_pppoe_type(pkt));
414  }
415  case OF1X_MATCH_PPPOE_SID:{
416  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
417  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_PPPOE_DISCOVERY || *ptr_ether_type == ETH_TYPE_PPPOE_SESSION )) return false;
418  return __utern_compare16(it->__tern, platform_packet_get_pppoe_sid(pkt));
419  }
420 
421  //PPP
422  case OF1X_MATCH_PPP_PROT:{
423  uint16_t *ptr_ether_type = platform_packet_get_eth_type(pkt);
424  if( !ptr_ether_type || !(*ptr_ether_type == ETH_TYPE_PPPOE_SESSION )) return false;
425  return __utern_compare16(it->__tern, platform_packet_get_ppp_proto(pkt));
426  }
427 
428  //GTP
429  case OF1X_MATCH_GTP_MSG_TYPE:{
430  uint8_t *ptr_ip_proto = platform_packet_get_ip_proto(pkt);
431  uint16_t *ptr_udp_dst = platform_packet_get_udp_dst(pkt);
432  if (!ptr_ip_proto || !(*ptr_ip_proto == IP_PROTO_UDP || (ptr_udp_dst && *ptr_udp_dst == UDP_DST_PORT_GTPU))) return false;
433  return __utern_compare8(it->__tern, platform_packet_get_gtp_msg_type(pkt));
434  }
435  case OF1X_MATCH_GTP_TEID:{
436  uint8_t *ptr_ip_proto = platform_packet_get_ip_proto(pkt);
437  uint16_t *ptr_udp_dst = platform_packet_get_udp_dst(pkt);
438  if ( !ptr_ip_proto || !(*ptr_ip_proto == IP_PROTO_UDP || (ptr_udp_dst && *ptr_udp_dst == UDP_DST_PORT_GTPU))) return false;
439  return __utern_compare32(it->__tern, platform_packet_get_gtp_teid(pkt));
440  }
441 
442  //CAPWAP
443  case OF1X_MATCH_CAPWAP_WBID:{
444  uint8_t *ptr_ip_proto = platform_packet_get_ip_proto(pkt);
445  uint16_t *ptr_udp_dst = platform_packet_get_udp_dst(pkt);
446  // TODO: for CAPWAP-control or CAPWAP-data or both?
447  if (!ptr_ip_proto || !(*ptr_ip_proto == IP_PROTO_UDP || (ptr_udp_dst && *ptr_udp_dst == UDP_DST_PORT_CAPWAPC))) return false;
448  return __utern_compare8(it->__tern, platform_packet_get_capwap_wbid(pkt));
449  }
450  case OF1X_MATCH_CAPWAP_RID:{
451  uint8_t *ptr_ip_proto = platform_packet_get_ip_proto(pkt);
452  uint16_t *ptr_udp_dst = platform_packet_get_udp_dst(pkt);
453  // TODO: for CAPWAP-control or CAPWAP-data or both?
454  if (!ptr_ip_proto || !(*ptr_ip_proto == IP_PROTO_UDP || (ptr_udp_dst && *ptr_udp_dst == UDP_DST_PORT_CAPWAPC))) return false;
455  return __utern_compare8(it->__tern, platform_packet_get_capwap_rid(pkt));
456  }
457  case OF1X_MATCH_CAPWAP_FLAGS:{
458  uint8_t *ptr_ip_proto = platform_packet_get_ip_proto(pkt);
459  uint16_t *ptr_udp_dst = platform_packet_get_udp_dst(pkt);
460  // TODO: for CAPWAP-control or CAPWAP-data or both?
461  if (!ptr_ip_proto || !(*ptr_ip_proto == IP_PROTO_UDP || (ptr_udp_dst && *ptr_udp_dst == UDP_DST_PORT_CAPWAPC))) return false;
462  return __utern_compare16(it->__tern, platform_packet_get_capwap_flags(pkt));
463  }
464  //WLAN
465  case OF1X_MATCH_WLAN_FC:{
466  // TODO: check prerequisites for WLAN frame
467  return __utern_compare16(it->__tern, platform_packet_get_wlan_fc(pkt));
468  }
469  case OF1X_MATCH_WLAN_TYPE:{
470  // TODO: check prerequisites for WLAN frame
471  return __utern_compare8(it->__tern, platform_packet_get_wlan_type(pkt));
472  }
473  case OF1X_MATCH_WLAN_SUBTYPE:{
474  // TODO: check prerequisites for WLAN frame
475  return __utern_compare8(it->__tern, platform_packet_get_wlan_subtype(pkt));
476  }
477  case OF1X_MATCH_WLAN_DIRECTION:{
478  // TODO: check prerequisites for WLAN frame
479  return __utern_compare8(it->__tern, platform_packet_get_wlan_direction(pkt));
480  }
481  case OF1X_MATCH_WLAN_ADDRESS_1:{
482  // TODO: check prerequisites for WLAN frame
483  return __utern_compare64(it->__tern, platform_packet_get_wlan_address_1(pkt));
484  }
485  case OF1X_MATCH_WLAN_ADDRESS_2:{
486  // TODO: check prerequisites for WLAN frame
487  return __utern_compare64(it->__tern, platform_packet_get_wlan_address_2(pkt));
488  }
489  case OF1X_MATCH_WLAN_ADDRESS_3:{
490  // TODO: check prerequisites for WLAN frame
491  return __utern_compare64(it->__tern, platform_packet_get_wlan_address_3(pkt));
492  }
493 
494  //GRE
495  case OF1X_MATCH_GRE_VERSION:{
496  uint8_t *ptr_ip_proto = platform_packet_get_ip_proto(pkt);
497  if (!ptr_ip_proto || !(*ptr_ip_proto == IP_PROTO_GRE)) return false;
498  return __utern_compare16(it->__tern, platform_packet_get_gre_version(pkt));
499  }
500  case OF1X_MATCH_GRE_PROT_TYPE:{
501  uint8_t *ptr_ip_proto = platform_packet_get_ip_proto(pkt);
502  if (!ptr_ip_proto || !(*ptr_ip_proto == IP_PROTO_GRE)) return false;
503  return __utern_compare16(it->__tern, platform_packet_get_gre_prot_type(pkt));
504  }
505  case OF1X_MATCH_GRE_KEY:{
506  uint8_t *ptr_ip_proto = platform_packet_get_ip_proto(pkt);
507  if (!ptr_ip_proto || !(*ptr_ip_proto == IP_PROTO_GRE)) return false;
508  return __utern_compare32(it->__tern, platform_packet_get_gre_key(pkt));
509  }
510 #else
511  case OF1X_MATCH_PPPOE_CODE:
512  case OF1X_MATCH_PPPOE_TYPE:
513  case OF1X_MATCH_PPPOE_SID:
514  case OF1X_MATCH_PPP_PROT:
515  case OF1X_MATCH_GTP_MSG_TYPE:
516  case OF1X_MATCH_GTP_TEID:
517  case OF1X_MATCH_CAPWAP_WBID:
518  case OF1X_MATCH_CAPWAP_RID:
519  case OF1X_MATCH_CAPWAP_FLAGS:
520  case OF1X_MATCH_WLAN_FC:
521  case OF1X_MATCH_WLAN_TYPE:
522  case OF1X_MATCH_WLAN_SUBTYPE:
523  case OF1X_MATCH_WLAN_DIRECTION:
524  case OF1X_MATCH_WLAN_ADDRESS_1:
525  case OF1X_MATCH_WLAN_ADDRESS_2:
526  case OF1X_MATCH_WLAN_ADDRESS_3:
527  case OF1X_MATCH_GRE_VERSION:
528  case OF1X_MATCH_GRE_PROT_TYPE:
529  case OF1X_MATCH_GRE_KEY:
530  break;
531 
532 #endif
533  case OF1X_MATCH_MAX:
534  break;
535  //Add more here ...
536  //Warning: NEVER add a default clause
537  }
538 
539  assert(0);
540  return false;
541 }
542 
543 //C++ extern C
544 ROFL_END_DECLS
545 
546 #endif //OF1X_MATCH_PP
uint32_t * platform_packet_get_arp_tpa(datapacket_t *const pkt)
Get the ARP TPA value of the packet.
uint64_t * platform_packet_get_arp_tha(datapacket_t *const pkt)
Get the ARP THA value of the packet.
uint32_t * platform_packet_get_mpls_label(datapacket_t *const pkt)
Retrieves the outer-most MPLS tag label.
uint32_t * platform_packet_get_phy_port_in(datapacket_t *const pkt)
Retrieves the PHY port in identifier where the packet got in.
uint16_t * platform_packet_get_sctp_dst(datapacket_t *const pkt)
Get the SCTP dst port.
uint8_t * platform_packet_get_vlan_pcp(datapacket_t *const pkt)
Retrieves the VLAN PCP of the outer-most 802.1q VLAN tag.
uint16_t * platform_packet_get_sctp_src(datapacket_t *const pkt)
Get the SCTP src port.
uint8_t platform_packet_get_ip_dscp(datapacket_t *const pkt)
Get the ip DSCP value of the packet.
uint16_t * platform_packet_get_arp_opcode(datapacket_t *const pkt)
Get the ARP OPCODE value of the packet.
bool platform_packet_has_vlan(datapacket_t *const pkt)
Retrieves boolean if the packet contains a 802.1q VLAN tag.
uint32_t * platform_packet_get_arp_spa(datapacket_t *const pkt)
Get the ARP SPA value of the packet.
uint128__t * platform_packet_get_ipv6_nd_target(datapacket_t *const pkt)
Get the IPv6 nd target of the packet.
uint64_t * platform_packet_get_arp_sha(datapacket_t *const pkt)
Get the ARP SHA value of the packet.
uint16_t * platform_packet_get_tcp_dst(datapacket_t *const pkt)
Get the TCP dst port.
uint128__t * platform_packet_get_ipv6_dst(datapacket_t *const pkt)
Get the IPv6 dst address of the packet.
uint16_t * platform_packet_get_eth_type(datapacket_t *const pkt)
Retrieve the Ethernet ETH_TYPE of the packet.
uint64_t * platform_packet_get_eth_src(datapacket_t *const pkt)
Retrieve the Ethernet src MAC address of the packet.
uint64_t * platform_packet_get_ipv6_nd_sll(datapacket_t *const pkt)
Get the IPv6 nd sll of the packet.
uint8_t * platform_packet_get_ip_proto(datapacket_t *const pkt)
Get the ip proto value of the packet.
uint8_t * platform_packet_get_icmpv4_type(datapacket_t *const pkt)
Get the ICMPv4 type.
uint16_t * platform_packet_get_tcp_src(datapacket_t *const pkt)
Get the TCP src port.
bool platform_packet_get_mpls_bos(datapacket_t *const pkt)
Retrieves the outer-most MPLS tag BoS flag.
uint32_t * platform_packet_get_pbb_isid(datapacket_t *const pkt)
Get PBB I-SID value of the packet.
uint8_t platform_packet_get_ip_ecn(datapacket_t *const pkt)
Get the ip ECN value of the packet.
uint32_t * platform_packet_get_ipv4_dst(datapacket_t *const pkt)
Get the IPv4 dst address of the packet.
uint64_t * platform_packet_get_tunnel_id(datapacket_t *const pkt)
Get Tunnel ID.
uint16_t * platform_packet_get_udp_src(datapacket_t *const pkt)
Get the UDP src port.
uint32_t * platform_packet_get_port_in(datapacket_t *const pkt)
Retrieves the port in identifier (position in the of1x_switch_t->logical_ports array) where the packe...
uint8_t * platform_packet_get_icmpv4_code(datapacket_t *const pkt)
Get the ICMPv4 code.
uint8_t * platform_packet_get_mpls_tc(datapacket_t *const pkt)
Retrieves the outer-most MPLS tag tc flag.
uint8_t * platform_packet_get_icmpv6_code(datapacket_t *const pkt)
Get the ICMPv6 code.
uint16_t * platform_packet_get_udp_dst(datapacket_t *const pkt)
Get the UDP dst port.
uint8_t * platform_packet_get_icmpv6_type(datapacket_t *const pkt)
Get the ICMPv6 type.
OpenFlow v1.0, 1.2 and 1.3.2 matches.
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
uint64_t * platform_packet_get_ipv6_nd_tll(datapacket_t *const pkt)
Get the IPv6 nd tll of the packet.
uint16_t * platform_packet_get_vlan_vid(datapacket_t *const pkt)
Retrieves the VLAN id of the outer-most 802.1q VLAN tag.
uint32_t * platform_packet_get_ipv4_src(datapacket_t *const pkt)
Get the IPv4 src address of the packet.
uint128__t * platform_packet_get_ipv6_src(datapacket_t *const pkt)
Get the IPv6 src address of the packet.
uint32_t * platform_packet_get_ipv6_flabel(datapacket_t *const pkt)
Get the IPv6 label of the packet.