2 * Copyright (c) 2009, 2010, 2011 Nicira Networks.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <arpa/inet.h>
22 #include <netinet/icmp6.h>
25 #include "byte-order.h"
27 #include "dynamic-string.h"
30 #include "openvswitch/tunnel.h"
36 odp_action_len(uint16_t type)
38 if (type > ODP_ACTION_ATTR_MAX) {
42 switch ((enum odp_action_type) type) {
43 case ODP_ACTION_ATTR_OUTPUT: return 4;
44 case ODP_ACTION_ATTR_CONTROLLER: return 8;
45 case ODP_ACTION_ATTR_SET_DL_TCI: return 2;
46 case ODP_ACTION_ATTR_STRIP_VLAN: return 0;
47 case ODP_ACTION_ATTR_SET_DL_SRC: return ETH_ADDR_LEN;
48 case ODP_ACTION_ATTR_SET_DL_DST: return ETH_ADDR_LEN;
49 case ODP_ACTION_ATTR_SET_NW_SRC: return 4;
50 case ODP_ACTION_ATTR_SET_NW_DST: return 4;
51 case ODP_ACTION_ATTR_SET_NW_TOS: return 1;
52 case ODP_ACTION_ATTR_SET_TP_SRC: return 2;
53 case ODP_ACTION_ATTR_SET_TP_DST: return 2;
54 case ODP_ACTION_ATTR_SET_TUNNEL: return 8;
55 case ODP_ACTION_ATTR_SET_PRIORITY: return 4;
56 case ODP_ACTION_ATTR_POP_PRIORITY: return 0;
57 case ODP_ACTION_ATTR_DROP_SPOOFED_ARP: return 0;
59 case ODP_ACTION_ATTR_UNSPEC:
60 case __ODP_ACTION_ATTR_MAX:
68 format_generic_odp_action(struct ds *ds, const struct nlattr *a)
70 size_t len = nl_attr_get_size(a);
72 ds_put_format(ds, "action%"PRId16, nl_attr_type(a));
74 const uint8_t *unspec;
77 unspec = nl_attr_get(a);
78 for (i = 0; i < len; i++) {
79 ds_put_char(ds, i ? ' ': '(');
80 ds_put_format(ds, "%02x", unspec[i]);
87 format_odp_action(struct ds *ds, const struct nlattr *a)
92 if (nl_attr_get_size(a) != odp_action_len(nl_attr_type(a))) {
93 ds_put_format(ds, "bad length %zu, expected %d for: ",
94 nl_attr_get_size(a), odp_action_len(nl_attr_type(a)));
95 format_generic_odp_action(ds, a);
99 switch (nl_attr_type(a)) {
100 case ODP_ACTION_ATTR_OUTPUT:
101 ds_put_format(ds, "%"PRIu16, nl_attr_get_u32(a));
103 case ODP_ACTION_ATTR_CONTROLLER:
104 ds_put_format(ds, "ctl(%"PRIu64")", nl_attr_get_u64(a));
106 case ODP_ACTION_ATTR_SET_TUNNEL:
107 ds_put_format(ds, "set_tunnel(%#"PRIx64")",
108 ntohll(nl_attr_get_be64(a)));
110 case ODP_ACTION_ATTR_SET_DL_TCI:
111 ds_put_format(ds, "set_tci(vid=%"PRIu16",pcp=%d)",
112 vlan_tci_to_vid(nl_attr_get_be16(a)),
113 vlan_tci_to_pcp(nl_attr_get_be16(a)));
115 case ODP_ACTION_ATTR_STRIP_VLAN:
116 ds_put_format(ds, "strip_vlan");
118 case ODP_ACTION_ATTR_SET_DL_SRC:
119 eth = nl_attr_get_unspec(a, ETH_ADDR_LEN);
120 ds_put_format(ds, "set_dl_src("ETH_ADDR_FMT")", ETH_ADDR_ARGS(eth));
122 case ODP_ACTION_ATTR_SET_DL_DST:
123 eth = nl_attr_get_unspec(a, ETH_ADDR_LEN);
124 ds_put_format(ds, "set_dl_dst("ETH_ADDR_FMT")", ETH_ADDR_ARGS(eth));
126 case ODP_ACTION_ATTR_SET_NW_SRC:
127 ip = nl_attr_get_be32(a);
128 ds_put_format(ds, "set_nw_src("IP_FMT")", IP_ARGS(&ip));
130 case ODP_ACTION_ATTR_SET_NW_DST:
131 ip = nl_attr_get_be32(a);
132 ds_put_format(ds, "set_nw_dst("IP_FMT")", IP_ARGS(&ip));
134 case ODP_ACTION_ATTR_SET_NW_TOS:
135 ds_put_format(ds, "set_nw_tos(%"PRIu8")", nl_attr_get_u8(a));
137 case ODP_ACTION_ATTR_SET_TP_SRC:
138 ds_put_format(ds, "set_tp_src(%"PRIu16")", ntohs(nl_attr_get_be16(a)));
140 case ODP_ACTION_ATTR_SET_TP_DST:
141 ds_put_format(ds, "set_tp_dst(%"PRIu16")", ntohs(nl_attr_get_be16(a)));
143 case ODP_ACTION_ATTR_SET_PRIORITY:
144 ds_put_format(ds, "set_priority(%#"PRIx32")", nl_attr_get_u32(a));
146 case ODP_ACTION_ATTR_POP_PRIORITY:
147 ds_put_cstr(ds, "pop_priority");
149 case ODP_ACTION_ATTR_DROP_SPOOFED_ARP:
150 ds_put_cstr(ds, "drop_spoofed_arp");
153 format_generic_odp_action(ds, a);
159 format_odp_actions(struct ds *ds, const struct nlattr *actions,
163 const struct nlattr *a;
166 NL_ATTR_FOR_EACH (a, left, actions, actions_len) {
168 ds_put_char(ds, ',');
170 format_odp_action(ds, a);
173 if (left == actions_len) {
174 ds_put_cstr(ds, "<empty>");
176 ds_put_format(ds, ",***%u leftover bytes***", left);
179 ds_put_cstr(ds, "drop");
183 /* Returns the correct length of the payload for a flow key attribute of the
184 * specified 'type', or -1 if 'type' is unknown. */
186 odp_flow_key_attr_len(uint16_t type)
188 if (type > ODP_KEY_ATTR_MAX) {
192 switch ((enum odp_key_type) type) {
193 case ODP_KEY_ATTR_TUN_ID: return 8;
194 case ODP_KEY_ATTR_IN_PORT: return 4;
195 case ODP_KEY_ATTR_ETHERNET: return sizeof(struct odp_key_ethernet);
196 case ODP_KEY_ATTR_8021Q: return sizeof(struct odp_key_8021q);
197 case ODP_KEY_ATTR_ETHERTYPE: return 2;
198 case ODP_KEY_ATTR_IPV4: return sizeof(struct odp_key_ipv4);
199 case ODP_KEY_ATTR_IPV6: return sizeof(struct odp_key_ipv6);
200 case ODP_KEY_ATTR_TCP: return sizeof(struct odp_key_tcp);
201 case ODP_KEY_ATTR_UDP: return sizeof(struct odp_key_udp);
202 case ODP_KEY_ATTR_ICMP: return sizeof(struct odp_key_icmp);
203 case ODP_KEY_ATTR_ICMPV6: return sizeof(struct odp_key_icmpv6);
204 case ODP_KEY_ATTR_ARP: return sizeof(struct odp_key_arp);
205 case ODP_KEY_ATTR_ND: return sizeof(struct odp_key_nd);
207 case ODP_KEY_ATTR_UNSPEC:
208 case __ODP_KEY_ATTR_MAX:
217 format_generic_odp_key(const struct nlattr *a, struct ds *ds)
219 size_t len = nl_attr_get_size(a);
221 ds_put_format(ds, "key%"PRId16, nl_attr_type(a));
223 const uint8_t *unspec;
226 unspec = nl_attr_get(a);
227 for (i = 0; i < len; i++) {
228 ds_put_char(ds, i ? ' ': '(');
229 ds_put_format(ds, "%02x", unspec[i]);
231 ds_put_char(ds, ')');
236 format_odp_key_attr(const struct nlattr *a, struct ds *ds)
238 const struct odp_key_ethernet *eth_key;
239 const struct odp_key_8021q *q_key;
240 const struct odp_key_ipv4 *ipv4_key;
241 const struct odp_key_ipv6 *ipv6_key;
242 const struct odp_key_tcp *tcp_key;
243 const struct odp_key_udp *udp_key;
244 const struct odp_key_icmp *icmp_key;
245 const struct odp_key_icmpv6 *icmpv6_key;
246 const struct odp_key_arp *arp_key;
247 const struct odp_key_nd *nd_key;
249 if (nl_attr_get_size(a) != odp_flow_key_attr_len(nl_attr_type(a))) {
250 ds_put_format(ds, "bad length %zu, expected %d for: ",
252 odp_flow_key_attr_len(nl_attr_type(a)));
253 format_generic_odp_key(a, ds);
257 switch (nl_attr_type(a)) {
258 case ODP_KEY_ATTR_TUN_ID:
259 ds_put_format(ds, "tun_id(%#"PRIx64")", ntohll(nl_attr_get_be64(a)));
262 case ODP_KEY_ATTR_IN_PORT:
263 ds_put_format(ds, "in_port(%"PRIu32")", nl_attr_get_u32(a));
266 case ODP_KEY_ATTR_ETHERNET:
267 eth_key = nl_attr_get(a);
268 ds_put_format(ds, "eth(src="ETH_ADDR_FMT",dst="ETH_ADDR_FMT")",
269 ETH_ADDR_ARGS(eth_key->eth_src),
270 ETH_ADDR_ARGS(eth_key->eth_dst));
273 case ODP_KEY_ATTR_8021Q:
274 q_key = nl_attr_get(a);
275 ds_put_cstr(ds, "vlan(");
276 if (q_key->q_tpid != htons(ETH_TYPE_VLAN)) {
277 ds_put_format(ds, "tpid=0x%04"PRIx16",", ntohs(q_key->q_tpid));
279 ds_put_format(ds, "vid%"PRIu16",pcp%d)",
280 vlan_tci_to_vid(q_key->q_tci),
281 vlan_tci_to_pcp(q_key->q_tci));
284 case ODP_KEY_ATTR_ETHERTYPE:
285 ds_put_format(ds, "eth_type(0x%04"PRIx16")",
286 ntohs(nl_attr_get_be16(a)));
289 case ODP_KEY_ATTR_IPV4:
290 ipv4_key = nl_attr_get(a);
291 ds_put_format(ds, "ipv4(src="IP_FMT",dst="IP_FMT","
292 "proto=%"PRId8",tos=%"PRIu8")",
293 IP_ARGS(&ipv4_key->ipv4_src),
294 IP_ARGS(&ipv4_key->ipv4_dst),
295 ipv4_key->ipv4_proto, ipv4_key->ipv4_tos);
298 case ODP_KEY_ATTR_IPV6: {
299 char src_str[INET6_ADDRSTRLEN];
300 char dst_str[INET6_ADDRSTRLEN];
302 ipv6_key = nl_attr_get(a);
303 inet_ntop(AF_INET6, ipv6_key->ipv6_src, src_str, sizeof src_str);
304 inet_ntop(AF_INET6, ipv6_key->ipv6_dst, dst_str, sizeof dst_str);
306 ds_put_format(ds, "ipv6(src=%s,dst=%s,proto=%"PRId8",tos=%"PRIu8")",
307 src_str, dst_str, ipv6_key->ipv6_proto,
312 case ODP_KEY_ATTR_TCP:
313 tcp_key = nl_attr_get(a);
314 ds_put_format(ds, "tcp(src=%"PRIu16",dst=%"PRIu16")",
315 ntohs(tcp_key->tcp_src), ntohs(tcp_key->tcp_dst));
318 case ODP_KEY_ATTR_UDP:
319 udp_key = nl_attr_get(a);
320 ds_put_format(ds, "udp(src=%"PRIu16",dst=%"PRIu16")",
321 ntohs(udp_key->udp_src), ntohs(udp_key->udp_dst));
324 case ODP_KEY_ATTR_ICMP:
325 icmp_key = nl_attr_get(a);
326 ds_put_format(ds, "icmp(type=%"PRIu8",code=%"PRIu8")",
327 icmp_key->icmp_type, icmp_key->icmp_code);
330 case ODP_KEY_ATTR_ICMPV6:
331 icmpv6_key = nl_attr_get(a);
332 ds_put_format(ds, "icmpv6(type=%"PRIu8",code=%"PRIu8")",
333 icmpv6_key->icmpv6_type, icmpv6_key->icmpv6_code);
336 case ODP_KEY_ATTR_ARP:
337 arp_key = nl_attr_get(a);
338 ds_put_format(ds, "arp(sip="IP_FMT",tip="IP_FMT",op=%"PRIu16","
339 "sha="ETH_ADDR_FMT",tha="ETH_ADDR_FMT")",
340 IP_ARGS(&arp_key->arp_sip), IP_ARGS(&arp_key->arp_tip),
341 ntohs(arp_key->arp_op), ETH_ADDR_ARGS(arp_key->arp_sha),
342 ETH_ADDR_ARGS(arp_key->arp_tha));
345 case ODP_KEY_ATTR_ND: {
346 char target[INET6_ADDRSTRLEN];
348 nd_key = nl_attr_get(a);
349 inet_ntop(AF_INET6, nd_key->nd_target, target, sizeof target);
351 ds_put_format(ds, "nd(target=%s", target);
352 if (!eth_addr_is_zero(nd_key->nd_sll)) {
353 ds_put_format(ds, ",sll="ETH_ADDR_FMT,
354 ETH_ADDR_ARGS(nd_key->nd_sll));
356 if (!eth_addr_is_zero(nd_key->nd_tll)) {
357 ds_put_format(ds, ",tll="ETH_ADDR_FMT,
358 ETH_ADDR_ARGS(nd_key->nd_tll));
360 ds_put_char(ds, ')');
365 format_generic_odp_key(a, ds);
370 /* Appends to 'ds' a string representation of the 'key_len' bytes of
371 * ODP_KEY_ATTR_* attributes in 'key'. */
373 odp_flow_key_format(const struct nlattr *key, size_t key_len, struct ds *ds)
376 const struct nlattr *a;
379 NL_ATTR_FOR_EACH (a, left, key, key_len) {
381 ds_put_char(ds, ',');
383 format_odp_key_attr(a, ds);
386 if (left == key_len) {
387 ds_put_cstr(ds, "<empty>");
389 ds_put_format(ds, ",***%u leftover bytes***", left);
392 ds_put_cstr(ds, "<empty>");
396 /* Appends a representation of 'flow' as ODP_KEY_ATTR_* attributes to 'buf'. */
398 odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow)
400 struct odp_key_ethernet *eth_key;
402 if (flow->tun_id != htonll(0)) {
403 nl_msg_put_be64(buf, ODP_KEY_ATTR_TUN_ID, flow->tun_id);
406 nl_msg_put_u32(buf, ODP_KEY_ATTR_IN_PORT, flow->in_port);
408 eth_key = nl_msg_put_unspec_uninit(buf, ODP_KEY_ATTR_ETHERNET,
410 memcpy(eth_key->eth_src, flow->dl_src, ETH_ADDR_LEN);
411 memcpy(eth_key->eth_dst, flow->dl_dst, ETH_ADDR_LEN);
413 if (flow->vlan_tci != htons(0)) {
414 struct odp_key_8021q *q_key;
416 q_key = nl_msg_put_unspec_uninit(buf, ODP_KEY_ATTR_8021Q,
418 q_key->q_tpid = htons(ETH_TYPE_VLAN);
419 q_key->q_tci = flow->vlan_tci & ~htons(VLAN_CFI);
422 if (ntohs(flow->dl_type) < ETH_TYPE_MIN) {
426 nl_msg_put_be16(buf, ODP_KEY_ATTR_ETHERTYPE, flow->dl_type);
428 if (flow->dl_type == htons(ETH_TYPE_IP)) {
429 struct odp_key_ipv4 *ipv4_key;
431 ipv4_key = nl_msg_put_unspec_uninit(buf, ODP_KEY_ATTR_IPV4,
433 memset(ipv4_key, 0, sizeof *ipv4_key);
434 ipv4_key->ipv4_src = flow->nw_src;
435 ipv4_key->ipv4_dst = flow->nw_dst;
436 ipv4_key->ipv4_proto = flow->nw_proto;
437 ipv4_key->ipv4_tos = flow->nw_tos;
438 } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
439 struct odp_key_ipv6 *ipv6_key;
441 ipv6_key = nl_msg_put_unspec_uninit(buf, ODP_KEY_ATTR_IPV6,
443 memset(ipv6_key, 0, sizeof *ipv6_key);
444 memcpy(ipv6_key->ipv6_src, &flow->ipv6_src, sizeof ipv6_key->ipv6_src);
445 memcpy(ipv6_key->ipv6_dst, &flow->ipv6_dst, sizeof ipv6_key->ipv6_dst);
446 ipv6_key->ipv6_proto = flow->nw_proto;
447 ipv6_key->ipv6_tos = flow->nw_tos;
448 } else if (flow->dl_type == htons(ETH_TYPE_ARP)) {
449 struct odp_key_arp *arp_key;
451 arp_key = nl_msg_put_unspec_uninit(buf, ODP_KEY_ATTR_ARP,
453 memset(arp_key, 0, sizeof *arp_key);
454 arp_key->arp_sip = flow->nw_src;
455 arp_key->arp_tip = flow->nw_dst;
456 arp_key->arp_op = htons(flow->nw_proto);
457 memcpy(arp_key->arp_sha, flow->arp_sha, ETH_ADDR_LEN);
458 memcpy(arp_key->arp_tha, flow->arp_tha, ETH_ADDR_LEN);
461 if (flow->dl_type == htons(ETH_TYPE_IP)
462 || flow->dl_type == htons(ETH_TYPE_IPV6)) {
464 if (flow->nw_proto == IPPROTO_TCP) {
465 struct odp_key_tcp *tcp_key;
467 tcp_key = nl_msg_put_unspec_uninit(buf, ODP_KEY_ATTR_TCP,
469 tcp_key->tcp_src = flow->tp_src;
470 tcp_key->tcp_dst = flow->tp_dst;
471 } else if (flow->nw_proto == IPPROTO_UDP) {
472 struct odp_key_udp *udp_key;
474 udp_key = nl_msg_put_unspec_uninit(buf, ODP_KEY_ATTR_UDP,
476 udp_key->udp_src = flow->tp_src;
477 udp_key->udp_dst = flow->tp_dst;
478 } else if (flow->dl_type == htons(ETH_TYPE_IP)
479 && flow->nw_proto == IPPROTO_ICMP) {
480 struct odp_key_icmp *icmp_key;
482 icmp_key = nl_msg_put_unspec_uninit(buf, ODP_KEY_ATTR_ICMP,
484 icmp_key->icmp_type = ntohs(flow->tp_src);
485 icmp_key->icmp_code = ntohs(flow->tp_dst);
486 } else if (flow->dl_type == htons(ETH_TYPE_IPV6)
487 && flow->nw_proto == IPPROTO_ICMPV6) {
488 struct odp_key_icmpv6 *icmpv6_key;
490 icmpv6_key = nl_msg_put_unspec_uninit(buf, ODP_KEY_ATTR_ICMPV6,
492 icmpv6_key->icmpv6_type = ntohs(flow->tp_src);
493 icmpv6_key->icmpv6_code = ntohs(flow->tp_dst);
495 if (icmpv6_key->icmpv6_type == ND_NEIGHBOR_SOLICIT
496 || icmpv6_key->icmpv6_type == ND_NEIGHBOR_ADVERT) {
497 struct odp_key_nd *nd_key;
499 nd_key = nl_msg_put_unspec_uninit(buf, ODP_KEY_ATTR_ND,
501 memcpy(nd_key->nd_target, &flow->nd_target,
502 sizeof nd_key->nd_target);
503 memcpy(nd_key->nd_sll, flow->arp_sha, ETH_ADDR_LEN);
504 memcpy(nd_key->nd_tll, flow->arp_tha, ETH_ADDR_LEN);
510 /* Converts the 'key_len' bytes of ODP_KEY_ATTR_* attributes in 'key' to a flow
511 * structure in 'flow'. Returns 0 if successful, otherwise EINVAL. */
513 odp_flow_key_to_flow(const struct nlattr *key, size_t key_len,
516 const struct nlattr *nla;
517 enum odp_key_type prev_type;
520 memset(flow, 0, sizeof *flow);
521 flow->dl_type = htons(FLOW_DL_TYPE_NONE);
523 prev_type = ODP_KEY_ATTR_UNSPEC;
524 NL_ATTR_FOR_EACH (nla, left, key, key_len) {
525 const struct odp_key_ethernet *eth_key;
526 const struct odp_key_8021q *q_key;
527 const struct odp_key_ipv4 *ipv4_key;
528 const struct odp_key_ipv6 *ipv6_key;
529 const struct odp_key_tcp *tcp_key;
530 const struct odp_key_udp *udp_key;
531 const struct odp_key_icmp *icmp_key;
532 const struct odp_key_icmpv6 *icmpv6_key;
533 const struct odp_key_arp *arp_key;
534 const struct odp_key_nd *nd_key;
536 uint16_t type = nl_attr_type(nla);
537 int len = odp_flow_key_attr_len(type);
539 if (nl_attr_get_size(nla) != len && len != -1) {
543 #define TRANSITION(PREV_TYPE, TYPE) (((PREV_TYPE) << 16) | (TYPE))
544 switch (TRANSITION(prev_type, type)) {
545 case TRANSITION(ODP_KEY_ATTR_UNSPEC, ODP_KEY_ATTR_TUN_ID):
546 flow->tun_id = nl_attr_get_be64(nla);
549 case TRANSITION(ODP_KEY_ATTR_UNSPEC, ODP_KEY_ATTR_IN_PORT):
550 case TRANSITION(ODP_KEY_ATTR_TUN_ID, ODP_KEY_ATTR_IN_PORT):
551 if (nl_attr_get_u32(nla) >= UINT16_MAX) {
554 flow->in_port = nl_attr_get_u32(nla);
557 case TRANSITION(ODP_KEY_ATTR_IN_PORT, ODP_KEY_ATTR_ETHERNET):
558 eth_key = nl_attr_get(nla);
559 memcpy(flow->dl_src, eth_key->eth_src, ETH_ADDR_LEN);
560 memcpy(flow->dl_dst, eth_key->eth_dst, ETH_ADDR_LEN);
563 case TRANSITION(ODP_KEY_ATTR_ETHERNET, ODP_KEY_ATTR_8021Q):
564 q_key = nl_attr_get(nla);
565 if (q_key->q_tpid != htons(ETH_TYPE_VLAN)) {
566 /* Only standard 0x8100 VLANs currently supported. */
569 if (q_key->q_tci & htons(VLAN_CFI)) {
572 flow->vlan_tci = q_key->q_tci | htons(VLAN_CFI);
575 case TRANSITION(ODP_KEY_ATTR_8021Q, ODP_KEY_ATTR_ETHERTYPE):
576 case TRANSITION(ODP_KEY_ATTR_ETHERNET, ODP_KEY_ATTR_ETHERTYPE):
577 flow->dl_type = nl_attr_get_be16(nla);
578 if (ntohs(flow->dl_type) < 1536) {
583 case TRANSITION(ODP_KEY_ATTR_ETHERTYPE, ODP_KEY_ATTR_IPV4):
584 if (flow->dl_type != htons(ETH_TYPE_IP)) {
587 ipv4_key = nl_attr_get(nla);
588 flow->nw_src = ipv4_key->ipv4_src;
589 flow->nw_dst = ipv4_key->ipv4_dst;
590 flow->nw_proto = ipv4_key->ipv4_proto;
591 flow->nw_tos = ipv4_key->ipv4_tos;
592 if (flow->nw_tos & IP_ECN_MASK) {
597 case TRANSITION(ODP_KEY_ATTR_ETHERTYPE, ODP_KEY_ATTR_IPV6):
598 if (flow->dl_type != htons(ETH_TYPE_IPV6)) {
601 ipv6_key = nl_attr_get(nla);
602 memcpy(&flow->ipv6_src, ipv6_key->ipv6_src, sizeof flow->ipv6_src);
603 memcpy(&flow->ipv6_dst, ipv6_key->ipv6_dst, sizeof flow->ipv6_dst);
604 flow->nw_proto = ipv6_key->ipv6_proto;
605 flow->nw_tos = ipv6_key->ipv6_tos;
606 if (flow->nw_tos & IP_ECN_MASK) {
611 case TRANSITION(ODP_KEY_ATTR_IPV4, ODP_KEY_ATTR_TCP):
612 case TRANSITION(ODP_KEY_ATTR_IPV6, ODP_KEY_ATTR_TCP):
613 if (flow->nw_proto != IPPROTO_TCP) {
616 tcp_key = nl_attr_get(nla);
617 flow->tp_src = tcp_key->tcp_src;
618 flow->tp_dst = tcp_key->tcp_dst;
621 case TRANSITION(ODP_KEY_ATTR_IPV4, ODP_KEY_ATTR_UDP):
622 case TRANSITION(ODP_KEY_ATTR_IPV6, ODP_KEY_ATTR_UDP):
623 if (flow->nw_proto != IPPROTO_UDP) {
626 udp_key = nl_attr_get(nla);
627 flow->tp_src = udp_key->udp_src;
628 flow->tp_dst = udp_key->udp_dst;
631 case TRANSITION(ODP_KEY_ATTR_IPV4, ODP_KEY_ATTR_ICMP):
632 if (flow->nw_proto != IPPROTO_ICMP) {
635 icmp_key = nl_attr_get(nla);
636 flow->tp_src = htons(icmp_key->icmp_type);
637 flow->tp_dst = htons(icmp_key->icmp_code);
640 case TRANSITION(ODP_KEY_ATTR_IPV6, ODP_KEY_ATTR_ICMPV6):
641 if (flow->nw_proto != IPPROTO_ICMPV6) {
644 icmpv6_key = nl_attr_get(nla);
645 flow->tp_src = htons(icmpv6_key->icmpv6_type);
646 flow->tp_dst = htons(icmpv6_key->icmpv6_code);
649 case TRANSITION(ODP_KEY_ATTR_ETHERTYPE, ODP_KEY_ATTR_ARP):
650 if (flow->dl_type != htons(ETH_TYPE_ARP)) {
653 arp_key = nl_attr_get(nla);
654 flow->nw_src = arp_key->arp_sip;
655 flow->nw_dst = arp_key->arp_tip;
656 if (arp_key->arp_op & htons(0xff00)) {
659 flow->nw_proto = ntohs(arp_key->arp_op);
660 memcpy(flow->arp_sha, arp_key->arp_sha, ETH_ADDR_LEN);
661 memcpy(flow->arp_tha, arp_key->arp_tha, ETH_ADDR_LEN);
664 case TRANSITION(ODP_KEY_ATTR_ICMPV6, ODP_KEY_ATTR_ND):
665 if (flow->tp_src != htons(ND_NEIGHBOR_SOLICIT)
666 && flow->tp_src != htons(ND_NEIGHBOR_ADVERT)) {
669 nd_key = nl_attr_get(nla);
670 memcpy(&flow->nd_target, nd_key->nd_target, sizeof flow->nd_target);
671 memcpy(flow->arp_sha, nd_key->nd_sll, ETH_ADDR_LEN);
672 memcpy(flow->arp_tha, nd_key->nd_tll, ETH_ADDR_LEN);
676 if (type == ODP_KEY_ATTR_UNSPEC
677 || prev_type == ODP_KEY_ATTR_UNSPEC) {
690 case ODP_KEY_ATTR_UNSPEC:
693 case ODP_KEY_ATTR_TUN_ID:
694 case ODP_KEY_ATTR_IN_PORT:
697 case ODP_KEY_ATTR_ETHERNET:
698 case ODP_KEY_ATTR_8021Q:
701 case ODP_KEY_ATTR_ETHERTYPE:
702 if (flow->dl_type == htons(ETH_TYPE_IP)
703 || flow->dl_type == htons(ETH_TYPE_IPV6)
704 || flow->dl_type == htons(ETH_TYPE_ARP)) {
709 case ODP_KEY_ATTR_IPV4:
710 if (flow->nw_proto == IPPROTO_TCP
711 || flow->nw_proto == IPPROTO_UDP
712 || flow->nw_proto == IPPROTO_ICMP) {
717 case ODP_KEY_ATTR_IPV6:
718 if (flow->nw_proto == IPPROTO_TCP
719 || flow->nw_proto == IPPROTO_UDP
720 || flow->nw_proto == IPPROTO_ICMPV6) {
725 case ODP_KEY_ATTR_ICMPV6:
726 if (flow->icmp_type == htons(ND_NEIGHBOR_SOLICIT)
727 || flow->icmp_type == htons(ND_NEIGHBOR_ADVERT)) {
732 case ODP_KEY_ATTR_TCP:
733 case ODP_KEY_ATTR_UDP:
734 case ODP_KEY_ATTR_ICMP:
735 case ODP_KEY_ATTR_ARP:
736 case ODP_KEY_ATTR_ND:
739 case __ODP_KEY_ATTR_MAX: