2 * Copyright (c) 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.
19 #include "ofp-parse.h"
26 #include "byte-order.h"
27 #include "dynamic-string.h"
29 #include "multipath.h"
33 #include "openflow/openflow.h"
35 #include "socket-util.h"
39 VLOG_DEFINE_THIS_MODULE(ofp_parse
);
42 str_to_u32(const char *str
)
48 ovs_fatal(0, "missing required numeric argument");
52 value
= strtoul(str
, &tail
, 0);
53 if (errno
== EINVAL
|| errno
== ERANGE
|| *tail
) {
54 ovs_fatal(0, "invalid numeric format %s", str
);
60 str_to_u64(const char *str
)
66 ovs_fatal(0, "missing required numeric argument");
70 value
= strtoull(str
, &tail
, 0);
71 if (errno
== EINVAL
|| errno
== ERANGE
|| *tail
) {
72 ovs_fatal(0, "invalid numeric format %s", str
);
78 str_to_mac(const char *str
, uint8_t mac
[6])
80 if (sscanf(str
, ETH_ADDR_SCAN_FMT
, ETH_ADDR_SCAN_ARGS(mac
))
81 != ETH_ADDR_SCAN_COUNT
) {
82 ovs_fatal(0, "invalid mac address %s", str
);
87 str_to_ip(const char *str_
, ovs_be32
*ip
, ovs_be32
*maskp
)
89 char *str
= xstrdup(str_
);
90 char *save_ptr
= NULL
;
91 const char *name
, *netmask
;
92 struct in_addr in_addr
;
96 name
= strtok_r(str
, "/", &save_ptr
);
97 retval
= name
? lookup_ip(name
, &in_addr
) : EINVAL
;
99 ovs_fatal(0, "%s: could not convert to IP address", str
);
101 *ip
= in_addr
.s_addr
;
103 netmask
= strtok_r(NULL
, "/", &save_ptr
);
106 if (sscanf(netmask
, "%"SCNu8
".%"SCNu8
".%"SCNu8
".%"SCNu8
,
107 &o
[0], &o
[1], &o
[2], &o
[3]) == 4) {
108 mask
= htonl((o
[0] << 24) | (o
[1] << 16) | (o
[2] << 8) | o
[3]);
110 int prefix
= atoi(netmask
);
111 if (prefix
<= 0 || prefix
> 32) {
112 ovs_fatal(0, "%s: network prefix bits not between 1 and 32",
114 } else if (prefix
== 32) {
115 mask
= htonl(UINT32_MAX
);
117 mask
= htonl(((1u << prefix
) - 1) << (32 - prefix
));
121 mask
= htonl(UINT32_MAX
);
128 if (mask
!= htonl(UINT32_MAX
)) {
129 ovs_fatal(0, "%s: netmask not allowed here", str_
);
137 str_to_tun_id(const char *str
, ovs_be64
*tun_idp
, ovs_be64
*maskp
)
139 uint64_t tun_id
, mask
;
143 tun_id
= strtoull(str
, &tail
, 0);
144 if (errno
|| (*tail
!= '\0' && *tail
!= '/')) {
149 mask
= strtoull(tail
+ 1, &tail
, 0);
150 if (errno
|| *tail
!= '\0') {
157 *tun_idp
= htonll(tun_id
);
158 *maskp
= htonll(mask
);
162 ovs_fatal(0, "%s: bad syntax for tunnel id", str
);
166 str_to_ipv6(const char *str_
, struct in6_addr
*addrp
, struct in6_addr
*maskp
)
168 char *str
= xstrdup(str_
);
169 char *save_ptr
= NULL
;
170 const char *name
, *netmask
;
171 struct in6_addr addr
, mask
;
174 name
= strtok_r(str
, "/", &save_ptr
);
175 retval
= name
? lookup_ipv6(name
, &addr
) : EINVAL
;
177 ovs_fatal(0, "%s: could not convert to IPv6 address", str
);
180 netmask
= strtok_r(NULL
, "/", &save_ptr
);
182 int prefix
= atoi(netmask
);
183 if (prefix
<= 0 || prefix
> 128) {
184 ovs_fatal(0, "%s: network prefix bits not between 1 and 128",
187 mask
= ipv6_create_mask(prefix
);
190 mask
= in6addr_exact
;
192 *addrp
= ipv6_addr_bitand(&addr
, &mask
);
197 if (!ipv6_mask_is_exact(&mask
)) {
198 ovs_fatal(0, "%s: netmask not allowed here", str_
);
206 put_action(struct ofpbuf
*b
, size_t size
, uint16_t type
)
208 struct ofp_action_header
*ah
= ofpbuf_put_zeros(b
, size
);
209 ah
->type
= htons(type
);
210 ah
->len
= htons(size
);
214 static struct ofp_action_output
*
215 put_output_action(struct ofpbuf
*b
, uint16_t port
)
217 struct ofp_action_output
*oao
= put_action(b
, sizeof *oao
, OFPAT_OUTPUT
);
218 oao
->port
= htons(port
);
223 put_enqueue_action(struct ofpbuf
*b
, uint16_t port
, uint32_t queue
)
225 struct ofp_action_enqueue
*oae
= put_action(b
, sizeof *oae
, OFPAT_ENQUEUE
);
226 oae
->port
= htons(port
);
227 oae
->queue_id
= htonl(queue
);
231 put_dl_addr_action(struct ofpbuf
*b
, uint16_t type
, const char *addr
)
233 struct ofp_action_dl_addr
*oada
= put_action(b
, sizeof *oada
, type
);
234 str_to_mac(addr
, oada
->dl_addr
);
239 parse_port_name(const char *name
, uint16_t *port
)
245 static const struct pair pairs
[] = {
246 #define DEF_PAIR(NAME) {#NAME, OFPP_##NAME}
252 DEF_PAIR(CONTROLLER
),
257 static const int n_pairs
= ARRAY_SIZE(pairs
);
260 for (i
= 0; i
< n_pairs
; i
++) {
261 if (!strcasecmp(name
, pairs
[i
].name
)) {
262 *port
= pairs
[i
].value
;
270 str_to_action(char *str
, struct ofpbuf
*b
)
279 char empty_string
[] = "";
284 pos
+= strspn(pos
, ", \t\r\n");
290 ovs_fatal(0, "Drop actions must not be followed by other actions");
294 actlen
= strcspn(pos
, ":(, \t\r\n");
295 if (act
[actlen
] == ':') {
296 /* The argument can be separated by a colon. */
299 arg
= act
+ actlen
+ 1;
300 arglen
= strcspn(arg
, ", \t\r\n");
301 pos
= arg
+ arglen
+ (arg
[arglen
] != '\0');
303 } else if (act
[actlen
] == '(') {
304 /* The argument can be surrounded by balanced parentheses. The
305 * outermost set of parentheses is removed. */
309 arg
= act
+ actlen
+ 1;
310 for (arglen
= 0; level
> 0; arglen
++) {
311 switch (arg
[arglen
]) {
313 ovs_fatal(0, "unbalanced parentheses in argument to %s "
325 arg
[arglen
- 1] = '\0';
328 /* There might be no argument at all. */
330 pos
= act
+ actlen
+ (act
[actlen
] != '\0');
334 if (!strcasecmp(act
, "mod_vlan_vid")) {
335 struct ofp_action_vlan_vid
*va
;
336 va
= put_action(b
, sizeof *va
, OFPAT_SET_VLAN_VID
);
337 va
->vlan_vid
= htons(str_to_u32(arg
));
338 } else if (!strcasecmp(act
, "mod_vlan_pcp")) {
339 struct ofp_action_vlan_pcp
*va
;
340 va
= put_action(b
, sizeof *va
, OFPAT_SET_VLAN_PCP
);
341 va
->vlan_pcp
= str_to_u32(arg
);
342 } else if (!strcasecmp(act
, "strip_vlan")) {
343 struct ofp_action_header
*ah
;
344 ah
= put_action(b
, sizeof *ah
, OFPAT_STRIP_VLAN
);
345 ah
->type
= htons(OFPAT_STRIP_VLAN
);
346 } else if (!strcasecmp(act
, "mod_dl_src")) {
347 put_dl_addr_action(b
, OFPAT_SET_DL_SRC
, arg
);
348 } else if (!strcasecmp(act
, "mod_dl_dst")) {
349 put_dl_addr_action(b
, OFPAT_SET_DL_DST
, arg
);
350 } else if (!strcasecmp(act
, "mod_nw_src")) {
351 struct ofp_action_nw_addr
*na
;
352 na
= put_action(b
, sizeof *na
, OFPAT_SET_NW_SRC
);
353 str_to_ip(arg
, &na
->nw_addr
, NULL
);
354 } else if (!strcasecmp(act
, "mod_nw_dst")) {
355 struct ofp_action_nw_addr
*na
;
356 na
= put_action(b
, sizeof *na
, OFPAT_SET_NW_DST
);
357 str_to_ip(arg
, &na
->nw_addr
, NULL
);
358 } else if (!strcasecmp(act
, "mod_tp_src")) {
359 struct ofp_action_tp_port
*ta
;
360 ta
= put_action(b
, sizeof *ta
, OFPAT_SET_TP_SRC
);
361 ta
->tp_port
= htons(str_to_u32(arg
));
362 } else if (!strcasecmp(act
, "mod_tp_dst")) {
363 struct ofp_action_tp_port
*ta
;
364 ta
= put_action(b
, sizeof *ta
, OFPAT_SET_TP_DST
);
365 ta
->tp_port
= htons(str_to_u32(arg
));
366 } else if (!strcasecmp(act
, "mod_nw_tos")) {
367 struct ofp_action_nw_tos
*nt
;
368 nt
= put_action(b
, sizeof *nt
, OFPAT_SET_NW_TOS
);
369 nt
->nw_tos
= str_to_u32(arg
);
370 } else if (!strcasecmp(act
, "resubmit")) {
371 struct nx_action_resubmit
*nar
;
372 nar
= put_action(b
, sizeof *nar
, OFPAT_VENDOR
);
373 nar
->vendor
= htonl(NX_VENDOR_ID
);
374 nar
->subtype
= htons(NXAST_RESUBMIT
);
375 nar
->in_port
= htons(str_to_u32(arg
));
376 } else if (!strcasecmp(act
, "set_tunnel")
377 || !strcasecmp(act
, "set_tunnel64")) {
378 uint64_t tun_id
= str_to_u64(arg
);
379 if (!strcasecmp(act
, "set_tunnel64") || tun_id
> UINT32_MAX
) {
380 struct nx_action_set_tunnel64
*nast64
;
381 nast64
= put_action(b
, sizeof *nast64
, OFPAT_VENDOR
);
382 nast64
->vendor
= htonl(NX_VENDOR_ID
);
383 nast64
->subtype
= htons(NXAST_SET_TUNNEL64
);
384 nast64
->tun_id
= htonll(tun_id
);
386 struct nx_action_set_tunnel
*nast
;
387 nast
= put_action(b
, sizeof *nast
, OFPAT_VENDOR
);
388 nast
->vendor
= htonl(NX_VENDOR_ID
);
389 nast
->subtype
= htons(NXAST_SET_TUNNEL
);
390 nast
->tun_id
= htonl(tun_id
);
392 } else if (!strcasecmp(act
, "drop_spoofed_arp")) {
393 struct nx_action_header
*nah
;
394 nah
= put_action(b
, sizeof *nah
, OFPAT_VENDOR
);
395 nah
->vendor
= htonl(NX_VENDOR_ID
);
396 nah
->subtype
= htons(NXAST_DROP_SPOOFED_ARP
);
397 } else if (!strcasecmp(act
, "set_queue")) {
398 struct nx_action_set_queue
*nasq
;
399 nasq
= put_action(b
, sizeof *nasq
, OFPAT_VENDOR
);
400 nasq
->vendor
= htonl(NX_VENDOR_ID
);
401 nasq
->subtype
= htons(NXAST_SET_QUEUE
);
402 nasq
->queue_id
= htonl(str_to_u32(arg
));
403 } else if (!strcasecmp(act
, "pop_queue")) {
404 struct nx_action_header
*nah
;
405 nah
= put_action(b
, sizeof *nah
, OFPAT_VENDOR
);
406 nah
->vendor
= htonl(NX_VENDOR_ID
);
407 nah
->subtype
= htons(NXAST_POP_QUEUE
);
408 } else if (!strcasecmp(act
, "note")) {
409 size_t start_ofs
= b
->size
;
410 struct nx_action_note
*nan
;
414 nan
= put_action(b
, sizeof *nan
, OFPAT_VENDOR
);
415 nan
->vendor
= htonl(NX_VENDOR_ID
);
416 nan
->subtype
= htons(NXAST_NOTE
);
418 b
->size
-= sizeof nan
->note
;
419 while (*arg
!= '\0') {
430 byte
= hexits_value(arg
, 2, &ok
);
432 ovs_fatal(0, "bad hex digit in `note' argument");
434 ofpbuf_put(b
, &byte
, 1);
439 len
= b
->size
- start_ofs
;
440 remainder
= len
% OFP_ACTION_ALIGN
;
442 ofpbuf_put_zeros(b
, OFP_ACTION_ALIGN
- remainder
);
444 nan
->len
= htons(b
->size
- start_ofs
);
445 } else if (!strcasecmp(act
, "move")) {
446 struct nx_action_reg_move
*move
;
447 move
= ofpbuf_put_uninit(b
, sizeof *move
);
448 nxm_parse_reg_move(move
, arg
);
449 } else if (!strcasecmp(act
, "load")) {
450 struct nx_action_reg_load
*load
;
451 load
= ofpbuf_put_uninit(b
, sizeof *load
);
452 nxm_parse_reg_load(load
, arg
);
453 } else if (!strcasecmp(act
, "multipath")) {
454 struct nx_action_multipath
*nam
;
455 nam
= ofpbuf_put_uninit(b
, sizeof *nam
);
456 multipath_parse(nam
, arg
);
457 } else if (!strcasecmp(act
, "autopath")) {
458 struct nx_action_autopath
*naa
;
459 naa
= ofpbuf_put_uninit(b
, sizeof *naa
);
460 autopath_parse(naa
, arg
);
461 } else if (!strcasecmp(act
, "output")) {
462 put_output_action(b
, str_to_u32(arg
));
463 } else if (!strcasecmp(act
, "enqueue")) {
465 char *port_s
= strtok_r(arg
, ":q", &sp
);
466 char *queue
= strtok_r(NULL
, "", &sp
);
467 if (port_s
== NULL
|| queue
== NULL
) {
468 ovs_fatal(0, "\"enqueue\" syntax is \"enqueue:PORT:QUEUE\"");
470 put_enqueue_action(b
, str_to_u32(port_s
), str_to_u32(queue
));
471 } else if (!strcasecmp(act
, "drop")) {
472 /* A drop action in OpenFlow occurs by just not setting
476 ovs_fatal(0, "Drop actions must not be preceded by other "
479 } else if (!strcasecmp(act
, "CONTROLLER")) {
480 struct ofp_action_output
*oao
;
481 oao
= put_output_action(b
, OFPP_CONTROLLER
);
483 /* Unless a numeric argument is specified, we send the whole
484 * packet to the controller. */
485 if (arg
[0] && (strspn(arg
, "0123456789") == strlen(arg
))) {
486 oao
->max_len
= htons(str_to_u32(arg
));
488 oao
->max_len
= htons(UINT16_MAX
);
490 } else if (parse_port_name(act
, &port
)) {
491 put_output_action(b
, port
);
492 } else if (strspn(act
, "0123456789") == strlen(act
)) {
493 put_output_action(b
, str_to_u32(act
));
495 ovs_fatal(0, "Unknown action: %s", act
);
508 parse_protocol(const char *name
, const struct protocol
**p_out
)
510 static const struct protocol protocols
[] = {
511 { "ip", ETH_TYPE_IP
, 0 },
512 { "arp", ETH_TYPE_ARP
, 0 },
513 { "icmp", ETH_TYPE_IP
, IPPROTO_ICMP
},
514 { "tcp", ETH_TYPE_IP
, IPPROTO_TCP
},
515 { "udp", ETH_TYPE_IP
, IPPROTO_UDP
},
516 { "ipv6", ETH_TYPE_IPV6
, 0 },
517 { "ip6", ETH_TYPE_IPV6
, 0 },
518 { "icmp6", ETH_TYPE_IPV6
, IPPROTO_ICMPV6
},
519 { "tcp6", ETH_TYPE_IPV6
, IPPROTO_TCP
},
520 { "udp6", ETH_TYPE_IPV6
, IPPROTO_UDP
},
522 const struct protocol
*p
;
524 for (p
= protocols
; p
< &protocols
[ARRAY_SIZE(protocols
)]; p
++) {
525 if (!strcmp(p
->name
, name
)) {
535 FIELD(F_TUN_ID, "tun_id", 0) \
536 FIELD(F_IN_PORT, "in_port", FWW_IN_PORT) \
537 FIELD(F_DL_VLAN, "dl_vlan", 0) \
538 FIELD(F_DL_VLAN_PCP, "dl_vlan_pcp", 0) \
539 FIELD(F_DL_SRC, "dl_src", FWW_DL_SRC) \
540 FIELD(F_DL_DST, "dl_dst", FWW_DL_DST) \
541 FIELD(F_DL_TYPE, "dl_type", FWW_DL_TYPE) \
542 FIELD(F_NW_SRC, "nw_src", 0) \
543 FIELD(F_NW_DST, "nw_dst", 0) \
544 FIELD(F_NW_PROTO, "nw_proto", FWW_NW_PROTO) \
545 FIELD(F_NW_TOS, "nw_tos", FWW_NW_TOS) \
546 FIELD(F_TP_SRC, "tp_src", FWW_TP_SRC) \
547 FIELD(F_TP_DST, "tp_dst", FWW_TP_DST) \
548 FIELD(F_ICMP_TYPE, "icmp_type", FWW_TP_SRC) \
549 FIELD(F_ICMP_CODE, "icmp_code", FWW_TP_DST) \
550 FIELD(F_ARP_SHA, "arp_sha", FWW_ARP_SHA) \
551 FIELD(F_ARP_THA, "arp_tha", FWW_ARP_THA) \
552 FIELD(F_IPV6_SRC, "ipv6_src", 0) \
553 FIELD(F_IPV6_DST, "ipv6_dst", 0) \
554 FIELD(F_ND_TARGET, "nd_target", FWW_ND_TARGET) \
555 FIELD(F_ND_SLL, "nd_sll", FWW_ARP_SHA) \
556 FIELD(F_ND_TLL, "nd_tll", FWW_ARP_THA)
559 #define FIELD(ENUM, NAME, WILDCARD) ENUM,
566 enum field_index index
;
568 flow_wildcards_t wildcard
; /* FWW_* bit. */
572 parse_field_name(const char *name
, const struct field
**f_out
)
574 static const struct field fields
[N_FIELDS
] = {
575 #define FIELD(ENUM, NAME, WILDCARD) { ENUM, NAME, WILDCARD },
579 const struct field
*f
;
581 for (f
= fields
; f
< &fields
[ARRAY_SIZE(fields
)]; f
++) {
582 if (!strcmp(f
->name
, name
)) {
592 parse_field_value(struct cls_rule
*rule
, enum field_index index
,
595 uint8_t mac
[ETH_ADDR_LEN
];
596 ovs_be64 tun_id
, tun_mask
;
598 struct in6_addr ipv6
, ipv6_mask
;
603 str_to_tun_id(value
, &tun_id
, &tun_mask
);
604 cls_rule_set_tun_id_masked(rule
, tun_id
, tun_mask
);
608 if (!parse_port_name(value
, &port_no
)) {
609 port_no
= atoi(value
);
611 cls_rule_set_in_port(rule
, port_no
);
615 cls_rule_set_dl_vlan(rule
, htons(str_to_u32(value
)));
619 cls_rule_set_dl_vlan_pcp(rule
, str_to_u32(value
));
623 str_to_mac(value
, mac
);
624 cls_rule_set_dl_src(rule
, mac
);
628 str_to_mac(value
, mac
);
629 cls_rule_set_dl_dst(rule
, mac
);
633 cls_rule_set_dl_type(rule
, htons(str_to_u32(value
)));
637 str_to_ip(value
, &ip
, &mask
);
638 cls_rule_set_nw_src_masked(rule
, ip
, mask
);
642 str_to_ip(value
, &ip
, &mask
);
643 cls_rule_set_nw_dst_masked(rule
, ip
, mask
);
647 cls_rule_set_nw_proto(rule
, str_to_u32(value
));
651 cls_rule_set_nw_tos(rule
, str_to_u32(value
));
655 cls_rule_set_tp_src(rule
, htons(str_to_u32(value
)));
659 cls_rule_set_tp_dst(rule
, htons(str_to_u32(value
)));
663 cls_rule_set_icmp_type(rule
, str_to_u32(value
));
667 cls_rule_set_icmp_code(rule
, str_to_u32(value
));
671 str_to_mac(value
, mac
);
672 cls_rule_set_arp_sha(rule
, mac
);
676 str_to_mac(value
, mac
);
677 cls_rule_set_arp_tha(rule
, mac
);
681 str_to_ipv6(value
, &ipv6
, &ipv6_mask
);
682 cls_rule_set_ipv6_src_masked(rule
, &ipv6
, &ipv6_mask
);
686 str_to_ipv6(value
, &ipv6
, &ipv6_mask
);
687 cls_rule_set_ipv6_dst_masked(rule
, &ipv6
, &ipv6_mask
);
691 str_to_ipv6(value
, &ipv6
, NULL
);
692 cls_rule_set_nd_target(rule
, ipv6
);
696 str_to_mac(value
, mac
);
697 cls_rule_set_arp_sha(rule
, mac
);
701 str_to_mac(value
, mac
);
702 cls_rule_set_arp_tha(rule
, mac
);
711 parse_reg_value(struct cls_rule
*rule
, int reg_idx
, const char *value
)
713 uint32_t reg_value
, reg_mask
;
715 if (!strcmp(value
, "ANY") || !strcmp(value
, "*")) {
716 cls_rule_set_reg_masked(rule
, reg_idx
, 0, 0);
717 } else if (sscanf(value
, "%"SCNi32
"/%"SCNi32
,
718 ®_value
, ®_mask
) == 2) {
719 cls_rule_set_reg_masked(rule
, reg_idx
, reg_value
, reg_mask
);
720 } else if (sscanf(value
, "%"SCNi32
, ®_value
)) {
721 cls_rule_set_reg(rule
, reg_idx
, reg_value
);
723 ovs_fatal(0, "register fields must take the form <value> "
724 "or <value>/<mask>");
728 /* Convert 'string' (as described in the Flow Syntax section of the ovs-ofctl
729 * man page) into 'pf'. If 'actions' is specified, an action must be in
730 * 'string' and may be expanded or reallocated. */
732 parse_ofp_str(struct flow_mod
*fm
, struct ofpbuf
*actions
, char *string
)
734 char *save_ptr
= NULL
;
737 cls_rule_init_catchall(&fm
->cr
, OFP_DEFAULT_PRIORITY
);
738 fm
->cookie
= htonll(0);
740 fm
->command
= UINT16_MAX
;
741 fm
->idle_timeout
= OFP_FLOW_PERMANENT
;
742 fm
->hard_timeout
= OFP_FLOW_PERMANENT
;
743 fm
->buffer_id
= UINT32_MAX
;
744 fm
->out_port
= OFPP_NONE
;
747 char *act_str
= strstr(string
, "action");
749 ovs_fatal(0, "must specify an action");
753 act_str
= strchr(act_str
+ 1, '=');
755 ovs_fatal(0, "must specify an action");
760 str_to_action(act_str
, actions
);
761 fm
->actions
= actions
->data
;
762 fm
->n_actions
= actions
->size
/ sizeof(union ofp_action
);
767 for (name
= strtok_r(string
, "=, \t\r\n", &save_ptr
); name
;
768 name
= strtok_r(NULL
, "=, \t\r\n", &save_ptr
)) {
769 const struct protocol
*p
;
771 if (parse_protocol(name
, &p
)) {
772 cls_rule_set_dl_type(&fm
->cr
, htons(p
->dl_type
));
774 cls_rule_set_nw_proto(&fm
->cr
, p
->nw_proto
);
777 const struct field
*f
;
780 value
= strtok_r(NULL
, ", \t\r\n", &save_ptr
);
782 ovs_fatal(0, "field %s missing value", name
);
785 if (!strcmp(name
, "table")) {
786 fm
->table_id
= atoi(value
);
787 } else if (!strcmp(name
, "out_port")) {
788 fm
->out_port
= atoi(value
);
789 } else if (!strcmp(name
, "priority")) {
790 fm
->cr
.priority
= atoi(value
);
791 } else if (!strcmp(name
, "idle_timeout")) {
792 fm
->idle_timeout
= atoi(value
);
793 } else if (!strcmp(name
, "hard_timeout")) {
794 fm
->hard_timeout
= atoi(value
);
795 } else if (!strcmp(name
, "cookie")) {
796 fm
->cookie
= htonll(str_to_u64(value
));
797 } else if (parse_field_name(name
, &f
)) {
798 if (!strcmp(value
, "*") || !strcmp(value
, "ANY")) {
800 fm
->cr
.wc
.wildcards
|= f
->wildcard
;
801 cls_rule_zero_wildcarded_fields(&fm
->cr
);
802 } else if (f
->index
== F_NW_SRC
) {
803 cls_rule_set_nw_src_masked(&fm
->cr
, 0, 0);
804 } else if (f
->index
== F_NW_DST
) {
805 cls_rule_set_nw_dst_masked(&fm
->cr
, 0, 0);
806 } else if (f
->index
== F_IPV6_SRC
) {
807 cls_rule_set_ipv6_src_masked(&fm
->cr
,
808 &in6addr_any
, &in6addr_any
);
809 } else if (f
->index
== F_IPV6_DST
) {
810 cls_rule_set_ipv6_dst_masked(&fm
->cr
,
811 &in6addr_any
, &in6addr_any
);
812 } else if (f
->index
== F_DL_VLAN
) {
813 cls_rule_set_any_vid(&fm
->cr
);
814 } else if (f
->index
== F_DL_VLAN_PCP
) {
815 cls_rule_set_any_pcp(&fm
->cr
);
820 parse_field_value(&fm
->cr
, f
->index
, value
);
822 } else if (!strncmp(name
, "reg", 3)
823 && isdigit((unsigned char) name
[3])) {
824 unsigned int reg_idx
= atoi(name
+ 3);
825 if (reg_idx
>= FLOW_N_REGS
) {
826 ovs_fatal(0, "only %d registers supported", FLOW_N_REGS
);
828 parse_reg_value(&fm
->cr
, reg_idx
, value
);
830 ovs_fatal(0, "unknown keyword %s", name
);
836 /* Parses 'string' as an OFPT_FLOW_MOD or NXT_FLOW_MOD with command 'command'
837 * (one of OFPFC_*) and appends the parsed OpenFlow message to 'packets'.
838 * '*cur_format' should initially contain the flow format currently configured
839 * on the connection; this function will add a message to change the flow
840 * format and update '*cur_format', if this is necessary to add the parsed
843 parse_ofp_flow_mod_str(struct list
*packets
, enum nx_flow_format
*cur_format
,
844 bool *flow_mod_table_id
, char *string
, uint16_t command
)
846 bool is_del
= command
== OFPFC_DELETE
|| command
== OFPFC_DELETE_STRICT
;
847 enum nx_flow_format min_format
, next_format
;
848 struct ofpbuf actions
;
852 ofpbuf_init(&actions
, 64);
853 parse_ofp_str(&fm
, is_del
? NULL
: &actions
, string
);
854 fm
.command
= command
;
856 min_format
= ofputil_min_flow_format(&fm
.cr
);
857 next_format
= MAX(*cur_format
, min_format
);
858 if (next_format
!= *cur_format
) {
859 struct ofpbuf
*sff
= ofputil_make_set_flow_format(next_format
);
860 list_push_back(packets
, &sff
->list_node
);
861 *cur_format
= next_format
;
864 if (fm
.table_id
!= 0xff && !*flow_mod_table_id
) {
865 struct ofpbuf
*sff
= ofputil_make_flow_mod_table_id(true);
866 list_push_back(packets
, &sff
->list_node
);
867 *flow_mod_table_id
= true;
870 ofm
= ofputil_encode_flow_mod(&fm
, *cur_format
, *flow_mod_table_id
);
871 list_push_back(packets
, &ofm
->list_node
);
873 ofpbuf_uninit(&actions
);
876 /* Similar to parse_ofp_flow_mod_str(), except that the string is read from
877 * 'stream' and the command is always OFPFC_ADD. Returns false if end-of-file
878 * is reached before reading a flow, otherwise true. */
880 parse_ofp_flow_mod_file(struct list
*packets
,
881 enum nx_flow_format
*cur
, bool *flow_mod_table_id
,
882 FILE *stream
, uint16_t command
)
888 ok
= ds_get_preprocessed_line(&s
, stream
) == 0;
890 parse_ofp_flow_mod_str(packets
, cur
, flow_mod_table_id
,
891 ds_cstr(&s
), command
);
899 parse_ofp_flow_stats_request_str(struct flow_stats_request
*fsr
,
900 bool aggregate
, char *string
)
904 parse_ofp_str(&fm
, NULL
, string
);
905 fsr
->aggregate
= aggregate
;
907 fsr
->out_port
= fm
.out_port
;
908 fsr
->table_id
= fm
.table_id
;