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.
23 #include "byte-order.h"
25 #include "dynamic-string.h"
28 #include "openvswitch/tunnel.h"
34 odp_action_len(uint16_t type)
36 if (type > ODPAT_MAX) {
40 switch ((enum odp_action_type) type) {
41 case ODPAT_OUTPUT: return 4;
42 case ODPAT_CONTROLLER: return 8;
43 case ODPAT_SET_DL_TCI: return 2;
44 case ODPAT_STRIP_VLAN: return 0;
45 case ODPAT_SET_DL_SRC: return ETH_ADDR_LEN;
46 case ODPAT_SET_DL_DST: return ETH_ADDR_LEN;
47 case ODPAT_SET_NW_SRC: return 4;
48 case ODPAT_SET_NW_DST: return 4;
49 case ODPAT_SET_NW_TOS: return 1;
50 case ODPAT_SET_TP_SRC: return 2;
51 case ODPAT_SET_TP_DST: return 2;
52 case ODPAT_SET_TUNNEL: return 8;
53 case ODPAT_SET_PRIORITY: return 4;
54 case ODPAT_POP_PRIORITY: return 0;
55 case ODPAT_DROP_SPOOFED_ARP: return 0;
66 format_generic_odp_action(struct ds *ds, const struct nlattr *a)
68 size_t len = nl_attr_get_size(a);
70 ds_put_format(ds, "action%"PRId16, nl_attr_type(a));
72 const uint8_t *unspec;
75 unspec = nl_attr_get(a);
76 for (i = 0; i < len; i++) {
77 ds_put_char(ds, i ? ' ': '(');
78 ds_put_format(ds, "%02x", unspec[i]);
85 format_odp_action(struct ds *ds, const struct nlattr *a)
90 if (nl_attr_get_size(a) != odp_action_len(nl_attr_type(a))) {
91 ds_put_format(ds, "bad length %zu, expected %d for: ",
92 nl_attr_get_size(a), odp_action_len(nl_attr_type(a)));
93 format_generic_odp_action(ds, a);
97 switch (nl_attr_type(a)) {
99 ds_put_format(ds, "%"PRIu16, nl_attr_get_u32(a));
101 case ODPAT_CONTROLLER:
102 ds_put_format(ds, "ctl(%"PRIu64")", nl_attr_get_u64(a));
104 case ODPAT_SET_TUNNEL:
105 ds_put_format(ds, "set_tunnel(%#"PRIx64")",
106 ntohll(nl_attr_get_be64(a)));
108 case ODPAT_SET_DL_TCI:
109 ds_put_format(ds, "set_tci(vid=%"PRIu16",pcp=%d)",
110 vlan_tci_to_vid(nl_attr_get_be16(a)),
111 vlan_tci_to_pcp(nl_attr_get_be16(a)));
113 case ODPAT_STRIP_VLAN:
114 ds_put_format(ds, "strip_vlan");
116 case ODPAT_SET_DL_SRC:
117 eth = nl_attr_get_unspec(a, ETH_ADDR_LEN);
118 ds_put_format(ds, "set_dl_src("ETH_ADDR_FMT")", ETH_ADDR_ARGS(eth));
120 case ODPAT_SET_DL_DST:
121 eth = nl_attr_get_unspec(a, ETH_ADDR_LEN);
122 ds_put_format(ds, "set_dl_dst("ETH_ADDR_FMT")", ETH_ADDR_ARGS(eth));
124 case ODPAT_SET_NW_SRC:
125 ip = nl_attr_get_be32(a);
126 ds_put_format(ds, "set_nw_src("IP_FMT")", IP_ARGS(&ip));
128 case ODPAT_SET_NW_DST:
129 ip = nl_attr_get_be32(a);
130 ds_put_format(ds, "set_nw_dst("IP_FMT")", IP_ARGS(&ip));
132 case ODPAT_SET_NW_TOS:
133 ds_put_format(ds, "set_nw_tos(%"PRIu8")", nl_attr_get_u8(a));
135 case ODPAT_SET_TP_SRC:
136 ds_put_format(ds, "set_tp_src(%"PRIu16")", ntohs(nl_attr_get_be16(a)));
138 case ODPAT_SET_TP_DST:
139 ds_put_format(ds, "set_tp_dst(%"PRIu16")", ntohs(nl_attr_get_be16(a)));
141 case ODPAT_SET_PRIORITY:
142 ds_put_format(ds, "set_priority(%#"PRIx32")", nl_attr_get_u32(a));
144 case ODPAT_POP_PRIORITY:
145 ds_put_cstr(ds, "pop_priority");
147 case ODPAT_DROP_SPOOFED_ARP:
148 ds_put_cstr(ds, "drop_spoofed_arp");
151 format_generic_odp_action(ds, a);
157 format_odp_actions(struct ds *ds, const struct nlattr *actions,
161 const struct nlattr *a;
164 NL_ATTR_FOR_EACH (a, left, actions, actions_len) {
166 ds_put_char(ds, ',');
168 format_odp_action(ds, a);
171 if (left == actions_len) {
172 ds_put_cstr(ds, "<empty>");
174 ds_put_format(ds, ",***%u leftover bytes***", left);
177 ds_put_cstr(ds, "drop");
182 format_odp_flow_stats(struct ds *ds, const struct odp_flow_stats *s)
184 ds_put_format(ds, "packets:%llu, bytes:%llu, used:",
185 (unsigned long long int) s->n_packets,
186 (unsigned long long int) s->n_bytes);
188 long long int used = s->used_sec * 1000 + s->used_nsec / 1000000;
189 ds_put_format(ds, "%.3fs", (time_msec() - used) / 1000.0);
191 ds_put_format(ds, "never");
196 format_odp_flow(struct ds *ds, const struct odp_flow *f)
198 odp_flow_key_format(f->key, f->key_len, ds);
199 ds_put_cstr(ds, ", ");
200 format_odp_flow_stats(ds, &f->stats);
201 ds_put_cstr(ds, ", actions:");
202 format_odp_actions(ds, f->actions, f->actions_len);
206 format_odp_port_type(struct ds *ds, const struct odp_port *p)
208 if (!strcmp(p->type, "gre")
209 || !strcmp(p->type, "ipsec_gre")
210 || !strcmp(p->type, "capwap")) {
211 const struct tnl_port_config *config;
213 config = (struct tnl_port_config *)p->config;
215 ds_put_format(ds, " (%s: remote_ip="IP_FMT,
216 p->type, IP_ARGS(&config->daddr));
219 ds_put_format(ds, ", local_ip="IP_FMT, IP_ARGS(&config->saddr));
222 if (config->in_key) {
223 ds_put_format(ds, ", in_key=%#"PRIx64, ntohll(config->in_key));
226 ds_put_cstr(ds, ")");
227 } else if (!strcmp(p->type, "patch")) {
228 ds_put_format(ds, " (%s: peer=%s)", p->type, (char *)p->config);
229 } else if (strcmp(p->type, "system")) {
230 ds_put_format(ds, " (%s)", p->type);
234 /* Returns the correct length of the payload for a flow key attribute of the
235 * specified 'type', or -1 if 'type' is unknown. */
237 odp_flow_key_attr_len(uint16_t type)
239 if (type > ODP_KEY_ATTR_MAX) {
243 switch ((enum odp_key_type) type) {
244 case ODP_KEY_ATTR_TUN_ID: return 8;
245 case ODP_KEY_ATTR_IN_PORT: return 4;
246 case ODP_KEY_ATTR_ETHERNET: return sizeof(struct odp_key_ethernet);
247 case ODP_KEY_ATTR_8021Q: return sizeof(struct odp_key_8021q);
248 case ODP_KEY_ATTR_ETHERTYPE: return 2;
249 case ODP_KEY_ATTR_IPV4: return sizeof(struct odp_key_ipv4);
250 case ODP_KEY_ATTR_TCP: return sizeof(struct odp_key_tcp);
251 case ODP_KEY_ATTR_UDP: return sizeof(struct odp_key_udp);
252 case ODP_KEY_ATTR_ICMP: return sizeof(struct odp_key_icmp);
253 case ODP_KEY_ATTR_ARP: return sizeof(struct odp_key_arp);
255 case ODP_KEY_ATTR_UNSPEC:
256 case __ODP_KEY_ATTR_MAX:
265 format_generic_odp_key(const struct nlattr *a, struct ds *ds)
267 size_t len = nl_attr_get_size(a);
269 ds_put_format(ds, "key%"PRId16, nl_attr_type(a));
271 const uint8_t *unspec;
274 unspec = nl_attr_get(a);
275 for (i = 0; i < len; i++) {
276 ds_put_char(ds, i ? ' ': '(');
277 ds_put_format(ds, "%02x", unspec[i]);
279 ds_put_char(ds, ')');
284 format_odp_key_attr(const struct nlattr *a, struct ds *ds)
286 const struct odp_key_ethernet *eth_key;
287 const struct odp_key_8021q *q_key;
288 const struct odp_key_ipv4 *ipv4_key;
289 const struct odp_key_tcp *tcp_key;
290 const struct odp_key_udp *udp_key;
291 const struct odp_key_icmp *icmp_key;
292 const struct odp_key_arp *arp_key;
294 if (nl_attr_get_size(a) != odp_flow_key_attr_len(nl_attr_type(a))) {
295 ds_put_format(ds, "bad length %zu, expected %d for: ",
297 odp_flow_key_attr_len(nl_attr_type(a)));
298 format_generic_odp_key(a, ds);
302 switch (nl_attr_type(a)) {
303 case ODP_KEY_ATTR_TUN_ID:
304 ds_put_format(ds, "tun_id(%#"PRIx64")", nl_attr_get_be64(a));
307 case ODP_KEY_ATTR_IN_PORT:
308 ds_put_format(ds, "in_port(%"PRIu32")", nl_attr_get_u32(a));
311 case ODP_KEY_ATTR_ETHERNET:
312 eth_key = nl_attr_get(a);
313 ds_put_format(ds, "eth(src="ETH_ADDR_FMT",dst="ETH_ADDR_FMT")",
314 ETH_ADDR_ARGS(eth_key->eth_src),
315 ETH_ADDR_ARGS(eth_key->eth_dst));
318 case ODP_KEY_ATTR_8021Q:
319 q_key = nl_attr_get(a);
320 ds_put_cstr(ds, "vlan(");
321 if (q_key->q_tpid != htons(ETH_TYPE_VLAN)) {
322 ds_put_format(ds, "tpid=%#"PRIx16",", ntohs(q_key->q_tpid));
324 ds_put_format(ds, "vid%"PRIu16",pcp%d)",
325 vlan_tci_to_vid(q_key->q_tci),
326 vlan_tci_to_pcp(q_key->q_tci));
329 case ODP_KEY_ATTR_ETHERTYPE:
330 ds_put_format(ds, "eth_type(%#04"PRIx16")",
331 ntohs(nl_attr_get_be16(a)));
334 case ODP_KEY_ATTR_IPV4:
335 ipv4_key = nl_attr_get(a);
336 ds_put_format(ds, "ipv4(src="IP_FMT",dst="IP_FMT","
337 "proto=%"PRId8",tos=%"PRIu8")",
338 IP_ARGS(&ipv4_key->ipv4_src),
339 IP_ARGS(&ipv4_key->ipv4_dst),
340 ipv4_key->ipv4_proto, ipv4_key->ipv4_tos);
343 case ODP_KEY_ATTR_TCP:
344 tcp_key = nl_attr_get(a);
345 ds_put_format(ds, "tcp(src=%"PRIu16",dst=%"PRIu16")",
346 ntohs(tcp_key->tcp_src), ntohs(tcp_key->tcp_dst));
349 case ODP_KEY_ATTR_UDP:
350 udp_key = nl_attr_get(a);
351 ds_put_format(ds, "udp(src=%"PRIu16",dst=%"PRIu16")",
352 ntohs(udp_key->udp_src), ntohs(udp_key->udp_dst));
355 case ODP_KEY_ATTR_ICMP:
356 icmp_key = nl_attr_get(a);
357 ds_put_format(ds, "icmp(type=%"PRIu8",code=%"PRIu8")",
358 icmp_key->icmp_type, icmp_key->icmp_code);
361 case ODP_KEY_ATTR_ARP:
362 arp_key = nl_attr_get(a);
363 ds_put_format(ds, "arp(sip="IP_FMT",tip="IP_FMT",op=%"PRIu16")",
364 IP_ARGS(&arp_key->arp_sip), IP_ARGS(&arp_key->arp_tip),
365 ntohs(arp_key->arp_op));
369 format_generic_odp_key(a, ds);
374 /* Appends to 'ds' a string representation of the 'key_len' bytes of
375 * ODP_KEY_ATTR_* attributes in 'key'. */
377 odp_flow_key_format(const struct nlattr *key, size_t key_len, struct ds *ds)
380 const struct nlattr *a;
383 NL_ATTR_FOR_EACH (a, left, key, key_len) {
385 ds_put_char(ds, ',');
387 format_odp_key_attr(a, ds);
390 if (left == key_len) {
391 ds_put_cstr(ds, "<empty>");
393 ds_put_format(ds, ",***%u leftover bytes***", left);
396 ds_put_cstr(ds, "<empty>");
400 /* Appends a representation of 'flow' as ODP_KEY_ATTR_* attributes to 'buf'. */
402 odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow)
404 struct odp_key_ethernet *eth_key;
406 if (flow->tun_id != htonll(0)) {
407 nl_msg_put_be64(buf, ODP_KEY_ATTR_TUN_ID, flow->tun_id);
410 nl_msg_put_u32(buf, ODP_KEY_ATTR_IN_PORT, flow->in_port);
412 eth_key = nl_msg_put_unspec_uninit(buf, ODP_KEY_ATTR_ETHERNET,
414 memcpy(eth_key->eth_src, flow->dl_src, ETH_ADDR_LEN);
415 memcpy(eth_key->eth_dst, flow->dl_dst, ETH_ADDR_LEN);
417 if (flow->vlan_tci != htons(0)) {
418 struct odp_key_8021q *q_key;
420 q_key = nl_msg_put_unspec_uninit(buf, ODP_KEY_ATTR_8021Q,
422 q_key->q_tpid = htons(ETH_TYPE_VLAN);
423 q_key->q_tci = flow->vlan_tci & ~htons(VLAN_CFI);
426 if (ntohs(flow->dl_type) < ETH_TYPE_MIN) {
430 nl_msg_put_be16(buf, ODP_KEY_ATTR_ETHERTYPE, flow->dl_type);
432 if (flow->dl_type == htons(ETH_TYPE_IP)) {
433 struct odp_key_ipv4 *ipv4_key;
435 ipv4_key = nl_msg_put_unspec_uninit(buf, ODP_KEY_ATTR_IPV4,
437 ipv4_key->ipv4_src = flow->nw_src;
438 ipv4_key->ipv4_dst = flow->nw_dst;
439 ipv4_key->ipv4_proto = flow->nw_proto;
440 ipv4_key->ipv4_tos = flow->nw_tos;
442 if (flow->nw_proto == IP_TYPE_TCP) {
443 struct odp_key_tcp *tcp_key;
445 tcp_key = nl_msg_put_unspec_uninit(buf, ODP_KEY_ATTR_TCP,
447 tcp_key->tcp_src = flow->tp_src;
448 tcp_key->tcp_dst = flow->tp_dst;
449 } else if (flow->nw_proto == IP_TYPE_UDP) {
450 struct odp_key_udp *udp_key;
452 udp_key = nl_msg_put_unspec_uninit(buf, ODP_KEY_ATTR_UDP,
454 udp_key->udp_src = flow->tp_src;
455 udp_key->udp_dst = flow->tp_dst;
456 } else if (flow->nw_proto == IP_TYPE_ICMP) {
457 struct odp_key_icmp *icmp_key;
459 icmp_key = nl_msg_put_unspec_uninit(buf, ODP_KEY_ATTR_ICMP,
461 icmp_key->icmp_type = ntohs(flow->tp_src);
462 icmp_key->icmp_code = ntohs(flow->tp_dst);
464 } else if (flow->dl_type == htons(ETH_TYPE_ARP)) {
465 struct odp_key_arp *arp_key;
467 arp_key = nl_msg_put_unspec_uninit(buf, ODP_KEY_ATTR_ARP,
469 arp_key->arp_sip = flow->nw_src;
470 arp_key->arp_tip = flow->nw_dst;
471 arp_key->arp_op = htons(flow->nw_proto);
475 /* Converts the 'key_len' bytes of ODP_KEY_ATTR_* attributes in 'key' to a flow
476 * structure in 'flow'. Returns 0 if successful, otherwise EINVAL. */
478 odp_flow_key_to_flow(const struct nlattr *key, size_t key_len,
481 const struct nlattr *nla;
482 enum odp_key_type prev_type;
485 memset(flow, 0, sizeof *flow);
486 flow->dl_type = htons(FLOW_DL_TYPE_NONE);
488 prev_type = ODP_KEY_ATTR_UNSPEC;
489 NL_ATTR_FOR_EACH (nla, left, key, key_len) {
490 const struct odp_key_ethernet *eth_key;
491 const struct odp_key_8021q *q_key;
492 const struct odp_key_ipv4 *ipv4_key;
493 const struct odp_key_tcp *tcp_key;
494 const struct odp_key_udp *udp_key;
495 const struct odp_key_icmp *icmp_key;
496 const struct odp_key_arp *arp_key;
498 uint16_t type = nl_attr_type(nla);
499 int len = odp_flow_key_attr_len(type);
501 if (nl_attr_get_size(nla) != len && len != -1) {
505 #define TRANSITION(PREV_TYPE, TYPE) (((PREV_TYPE) << 16) | (TYPE))
506 switch (TRANSITION(prev_type, type)) {
507 case TRANSITION(ODP_KEY_ATTR_UNSPEC, ODP_KEY_ATTR_TUN_ID):
508 flow->tun_id = nl_attr_get_be64(nla);
511 case TRANSITION(ODP_KEY_ATTR_UNSPEC, ODP_KEY_ATTR_IN_PORT):
512 case TRANSITION(ODP_KEY_ATTR_TUN_ID, ODP_KEY_ATTR_IN_PORT):
513 if (nl_attr_get_u32(nla) >= UINT16_MAX) {
516 flow->in_port = nl_attr_get_u32(nla);
519 case TRANSITION(ODP_KEY_ATTR_IN_PORT, ODP_KEY_ATTR_ETHERNET):
520 eth_key = nl_attr_get(nla);
521 memcpy(flow->dl_src, eth_key->eth_src, ETH_ADDR_LEN);
522 memcpy(flow->dl_dst, eth_key->eth_dst, ETH_ADDR_LEN);
525 case TRANSITION(ODP_KEY_ATTR_ETHERNET, ODP_KEY_ATTR_8021Q):
526 q_key = nl_attr_get(nla);
527 if (q_key->q_tpid != htons(ETH_TYPE_VLAN)) {
528 /* Only standard 0x8100 VLANs currently supported. */
531 if (q_key->q_tci & htons(VLAN_CFI)) {
534 flow->vlan_tci = q_key->q_tci | htons(VLAN_CFI);
537 case TRANSITION(ODP_KEY_ATTR_8021Q, ODP_KEY_ATTR_ETHERTYPE):
538 case TRANSITION(ODP_KEY_ATTR_ETHERNET, ODP_KEY_ATTR_ETHERTYPE):
539 flow->dl_type = nl_attr_get_be16(nla);
540 if (ntohs(flow->dl_type) < 1536) {
545 case TRANSITION(ODP_KEY_ATTR_ETHERTYPE, ODP_KEY_ATTR_IPV4):
546 if (flow->dl_type != htons(ETH_TYPE_IP)) {
549 ipv4_key = nl_attr_get(nla);
550 flow->nw_src = ipv4_key->ipv4_src;
551 flow->nw_dst = ipv4_key->ipv4_dst;
552 flow->nw_proto = ipv4_key->ipv4_proto;
553 flow->nw_tos = ipv4_key->ipv4_tos;
554 if (flow->nw_tos & IP_ECN_MASK) {
559 case TRANSITION(ODP_KEY_ATTR_IPV4, ODP_KEY_ATTR_TCP):
560 if (flow->nw_proto != IP_TYPE_TCP) {
563 tcp_key = nl_attr_get(nla);
564 flow->tp_src = tcp_key->tcp_src;
565 flow->tp_dst = tcp_key->tcp_dst;
568 case TRANSITION(ODP_KEY_ATTR_IPV4, ODP_KEY_ATTR_UDP):
569 if (flow->nw_proto != IP_TYPE_UDP) {
572 udp_key = nl_attr_get(nla);
573 flow->tp_src = udp_key->udp_src;
574 flow->tp_dst = udp_key->udp_dst;
577 case TRANSITION(ODP_KEY_ATTR_IPV4, ODP_KEY_ATTR_ICMP):
578 if (flow->nw_proto != IP_TYPE_ICMP) {
581 icmp_key = nl_attr_get(nla);
582 flow->tp_src = htons(icmp_key->icmp_type);
583 flow->tp_dst = htons(icmp_key->icmp_code);
586 case TRANSITION(ODP_KEY_ATTR_ETHERTYPE, ODP_KEY_ATTR_ARP):
587 if (flow->dl_type != htons(ETH_TYPE_ARP)) {
590 arp_key = nl_attr_get(nla);
591 flow->nw_src = arp_key->arp_sip;
592 flow->nw_dst = arp_key->arp_tip;
593 if (arp_key->arp_op & htons(0xff00)) {
596 flow->nw_proto = ntohs(arp_key->arp_op);
600 if (type == ODP_KEY_ATTR_UNSPEC
601 || prev_type == ODP_KEY_ATTR_UNSPEC) {
614 case ODP_KEY_ATTR_UNSPEC:
617 case ODP_KEY_ATTR_TUN_ID:
618 case ODP_KEY_ATTR_IN_PORT:
621 case ODP_KEY_ATTR_ETHERNET:
622 case ODP_KEY_ATTR_8021Q:
625 case ODP_KEY_ATTR_ETHERTYPE:
626 if (flow->dl_type == htons(ETH_TYPE_IP)
627 || flow->dl_type == htons(ETH_TYPE_ARP)) {
632 case ODP_KEY_ATTR_IPV4:
633 if (flow->nw_proto == IP_TYPE_TCP
634 || flow->nw_proto == IP_TYPE_UDP
635 || flow->nw_proto == IP_TYPE_ICMP) {
640 case ODP_KEY_ATTR_TCP:
641 case ODP_KEY_ATTR_UDP:
642 case ODP_KEY_ATTR_ICMP:
643 case ODP_KEY_ATTR_ARP:
646 case __ODP_KEY_ATTR_MAX: