]> git.proxmox.com Git - mirror_ovs.git/blob - lib/ofp-parse.c
ofp-parse: Fix small memory leak when calling parse_ofp_meter_mod_str().
[mirror_ovs.git] / lib / ofp-parse.c
1 /*
2 * Copyright (c) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 Nicira, Inc.
3 *
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:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17 #include <config.h>
18
19 #include <ctype.h>
20 #include <errno.h>
21 #include <stdlib.h>
22 #include <netinet/in.h>
23
24 #include "byte-order.h"
25 #include "dp-packet.h"
26 #include "learn.h"
27 #include "multipath.h"
28 #include "netdev.h"
29 #include "nx-match.h"
30 #include "openflow/openflow.h"
31 #include "openvswitch/dynamic-string.h"
32 #include "openvswitch/meta-flow.h"
33 #include "openvswitch/ofp-actions.h"
34 #include "openvswitch/ofp-parse.h"
35 #include "openvswitch/ofp-util.h"
36 #include "openvswitch/ofpbuf.h"
37 #include "openvswitch/vconn.h"
38 #include "ovs-thread.h"
39 #include "packets.h"
40 #include "simap.h"
41 #include "socket-util.h"
42 #include "util.h"
43
44 /* Parses 'str' as an 8-bit unsigned integer into '*valuep'.
45 *
46 * 'name' describes the value parsed in an error message, if any.
47 *
48 * Returns NULL if successful, otherwise a malloc()'d string describing the
49 * error. The caller is responsible for freeing the returned string. */
50 char * OVS_WARN_UNUSED_RESULT
51 str_to_u8(const char *str, const char *name, uint8_t *valuep)
52 {
53 int value;
54
55 if (!str_to_int(str, 0, &value) || value < 0 || value > 255) {
56 return xasprintf("invalid %s \"%s\"", name, str);
57 }
58 *valuep = value;
59 return NULL;
60 }
61
62 /* Parses 'str' as a 16-bit unsigned integer into '*valuep'.
63 *
64 * 'name' describes the value parsed in an error message, if any.
65 *
66 * Returns NULL if successful, otherwise a malloc()'d string describing the
67 * error. The caller is responsible for freeing the returned string. */
68 char * OVS_WARN_UNUSED_RESULT
69 str_to_u16(const char *str, const char *name, uint16_t *valuep)
70 {
71 int value;
72
73 if (!str_to_int(str, 0, &value) || value < 0 || value > 65535) {
74 return xasprintf("invalid %s \"%s\"", name, str);
75 }
76 *valuep = value;
77 return NULL;
78 }
79
80 /* Parses 'str' as a 32-bit unsigned integer into '*valuep'.
81 *
82 * Returns NULL if successful, otherwise a malloc()'d string describing the
83 * error. The caller is responsible for freeing the returned string. */
84 char * OVS_WARN_UNUSED_RESULT
85 str_to_u32(const char *str, uint32_t *valuep)
86 {
87 char *tail;
88 uint32_t value;
89
90 if (!str[0]) {
91 return xstrdup("missing required numeric argument");
92 }
93
94 errno = 0;
95 value = strtoul(str, &tail, 0);
96 if (errno == EINVAL || errno == ERANGE || *tail) {
97 return xasprintf("invalid numeric format %s", str);
98 }
99 *valuep = value;
100 return NULL;
101 }
102
103 /* Parses 'str' as an 64-bit unsigned integer into '*valuep'.
104 *
105 * Returns NULL if successful, otherwise a malloc()'d string describing the
106 * error. The caller is responsible for freeing the returned string. */
107 char * OVS_WARN_UNUSED_RESULT
108 str_to_u64(const char *str, uint64_t *valuep)
109 {
110 char *tail;
111 uint64_t value;
112
113 if (!str[0]) {
114 return xstrdup("missing required numeric argument");
115 }
116
117 errno = 0;
118 value = strtoull(str, &tail, 0);
119 if (errno == EINVAL || errno == ERANGE || *tail) {
120 return xasprintf("invalid numeric format %s", str);
121 }
122 *valuep = value;
123 return NULL;
124 }
125
126 /* Parses 'str' as an 64-bit unsigned integer in network byte order into
127 * '*valuep'.
128 *
129 * Returns NULL if successful, otherwise a malloc()'d string describing the
130 * error. The caller is responsible for freeing the returned string. */
131 char * OVS_WARN_UNUSED_RESULT
132 str_to_be64(const char *str, ovs_be64 *valuep)
133 {
134 uint64_t value = 0;
135 char *error;
136
137 error = str_to_u64(str, &value);
138 if (!error) {
139 *valuep = htonll(value);
140 }
141 return error;
142 }
143
144 /* Parses 'str' as an Ethernet address into 'mac'.
145 *
146 * Returns NULL if successful, otherwise a malloc()'d string describing the
147 * error. The caller is responsible for freeing the returned string. */
148 char * OVS_WARN_UNUSED_RESULT
149 str_to_mac(const char *str, struct eth_addr *mac)
150 {
151 if (!ovs_scan(str, ETH_ADDR_SCAN_FMT, ETH_ADDR_SCAN_ARGS(*mac))) {
152 return xasprintf("invalid mac address %s", str);
153 }
154 return NULL;
155 }
156
157 /* Parses 'str' as an IP address into '*ip'.
158 *
159 * Returns NULL if successful, otherwise a malloc()'d string describing the
160 * error. The caller is responsible for freeing the returned string. */
161 char * OVS_WARN_UNUSED_RESULT
162 str_to_ip(const char *str, ovs_be32 *ip)
163 {
164 struct in_addr in_addr;
165
166 if (lookup_ip(str, &in_addr)) {
167 return xasprintf("%s: could not convert to IP address", str);
168 }
169 *ip = in_addr.s_addr;
170 return NULL;
171 }
172
173 /* Parses 'str' as a conntrack helper into 'alg'.
174 *
175 * Returns NULL if successful, otherwise a malloc()'d string describing the
176 * error. The caller is responsible for freeing the returned string. */
177 char * OVS_WARN_UNUSED_RESULT
178 str_to_connhelper(const char *str, uint16_t *alg)
179 {
180 if (!strcmp(str, "ftp")) {
181 *alg = IPPORT_FTP;
182 return NULL;
183 }
184 if (!strcmp(str, "tftp")) {
185 *alg = IPPORT_TFTP;
186 return NULL;
187 }
188 return xasprintf("invalid conntrack helper \"%s\"", str);
189 }
190
191 struct protocol {
192 const char *name;
193 uint16_t dl_type;
194 uint8_t nw_proto;
195 };
196
197 static bool
198 parse_protocol(const char *name, const struct protocol **p_out)
199 {
200 static const struct protocol protocols[] = {
201 { "ip", ETH_TYPE_IP, 0 },
202 { "ipv4", ETH_TYPE_IP, 0 },
203 { "ip4", ETH_TYPE_IP, 0 },
204 { "arp", ETH_TYPE_ARP, 0 },
205 { "icmp", ETH_TYPE_IP, IPPROTO_ICMP },
206 { "tcp", ETH_TYPE_IP, IPPROTO_TCP },
207 { "udp", ETH_TYPE_IP, IPPROTO_UDP },
208 { "sctp", ETH_TYPE_IP, IPPROTO_SCTP },
209 { "ipv6", ETH_TYPE_IPV6, 0 },
210 { "ip6", ETH_TYPE_IPV6, 0 },
211 { "icmp6", ETH_TYPE_IPV6, IPPROTO_ICMPV6 },
212 { "tcp6", ETH_TYPE_IPV6, IPPROTO_TCP },
213 { "udp6", ETH_TYPE_IPV6, IPPROTO_UDP },
214 { "sctp6", ETH_TYPE_IPV6, IPPROTO_SCTP },
215 { "rarp", ETH_TYPE_RARP, 0},
216 { "mpls", ETH_TYPE_MPLS, 0 },
217 { "mplsm", ETH_TYPE_MPLS_MCAST, 0 },
218 };
219 const struct protocol *p;
220
221 for (p = protocols; p < &protocols[ARRAY_SIZE(protocols)]; p++) {
222 if (!strcmp(p->name, name)) {
223 *p_out = p;
224 return true;
225 }
226 }
227 *p_out = NULL;
228 return false;
229 }
230
231 /* Parses 's' as the (possibly masked) value of field 'mf', and updates
232 * 'match' appropriately. Restricts the set of usable protocols to ones
233 * supporting the parsed field.
234 *
235 * Returns NULL if successful, otherwise a malloc()'d string describing the
236 * error. The caller is responsible for freeing the returned string. */
237 static char * OVS_WARN_UNUSED_RESULT
238 parse_field(const struct mf_field *mf, const char *s,
239 const struct ofputil_port_map *port_map, struct match *match,
240 enum ofputil_protocol *usable_protocols)
241 {
242 union mf_value value, mask;
243 char *error;
244
245 if (!*s) {
246 /* If there's no string, we're just trying to match on the
247 * existence of the field, so use a no-op value. */
248 s = "0/0";
249 }
250
251 error = mf_parse(mf, s, port_map, &value, &mask);
252 if (!error) {
253 *usable_protocols &= mf_set(mf, &value, &mask, match, &error);
254 match_add_ethernet_prereq(match, mf);
255 }
256 return error;
257 }
258
259 /* Parses 'str_value' as the value of subfield 'name', and updates
260 * 'match' appropriately. Restricts the set of usable protocols to ones
261 * supporting the parsed field.
262 *
263 * Returns NULL if successful, otherwise a malloc()'d string describing the
264 * error. The caller is responsible for freeing the returned string. */
265 static char * OVS_WARN_UNUSED_RESULT
266 parse_subfield(const char *name, const char *str_value, struct match *match,
267 enum ofputil_protocol *usable_protocols)
268 {
269 struct mf_subfield sf;
270 char *error;
271
272 error = mf_parse_subfield(&sf, name);
273 if (!error) {
274 union mf_value val;
275 char *tail;
276 if (parse_int_string(str_value, (uint8_t *)&val, sf.field->n_bytes,
277 &tail) || *tail != 0) {
278 return xasprintf("%s: cannot parse integer value: %s", name,
279 str_value);
280 }
281 if (!bitwise_is_all_zeros(&val, sf.field->n_bytes, sf.n_bits,
282 sf.field->n_bytes * 8 - sf.n_bits)) {
283 struct ds ds;
284
285 ds_init(&ds);
286 mf_format(sf.field, &val, NULL, NULL, &ds);
287 error = xasprintf("%s: value %s does not fit into %d bits",
288 name, ds_cstr(&ds), sf.n_bits);
289 ds_destroy(&ds);
290 return error;
291 }
292
293 const struct mf_field *field = sf.field;
294 union mf_value value, mask;
295 unsigned int size = field->n_bytes;
296
297 mf_get(field, match, &value, &mask);
298 bitwise_copy(&val, size, 0, &value, size, sf.ofs, sf.n_bits);
299 bitwise_one ( &mask, size, sf.ofs, sf.n_bits);
300 *usable_protocols &= mf_set(field, &value, &mask, match, &error);
301
302 match_add_ethernet_prereq(match, sf.field);
303 }
304 return error;
305 }
306
307 static char *
308 extract_actions(char *s)
309 {
310 s = strstr(s, "action");
311 if (s) {
312 *s = '\0';
313 s = strchr(s + 1, '=');
314 return s ? s + 1 : NULL;
315 } else {
316 return NULL;
317 }
318 }
319
320
321 static char * OVS_WARN_UNUSED_RESULT
322 parse_ofp_str__(struct ofputil_flow_mod *fm, int command, char *string,
323 const struct ofputil_port_map *port_map,
324 enum ofputil_protocol *usable_protocols)
325 {
326 enum {
327 F_OUT_PORT = 1 << 0,
328 F_ACTIONS = 1 << 1,
329 F_IMPORTANCE = 1 << 2,
330 F_TIMEOUT = 1 << 3,
331 F_PRIORITY = 1 << 4,
332 F_FLAGS = 1 << 5,
333 } fields;
334 char *act_str = NULL;
335 char *name, *value;
336
337 *usable_protocols = OFPUTIL_P_ANY;
338
339 if (command == -2) {
340 size_t len;
341
342 string += strspn(string, " \t\r\n"); /* Skip white space. */
343 len = strcspn(string, ", \t\r\n"); /* Get length of the first token. */
344
345 if (!strncmp(string, "add", len)) {
346 command = OFPFC_ADD;
347 } else if (!strncmp(string, "delete", len)) {
348 command = OFPFC_DELETE;
349 } else if (!strncmp(string, "delete_strict", len)) {
350 command = OFPFC_DELETE_STRICT;
351 } else if (!strncmp(string, "modify", len)) {
352 command = OFPFC_MODIFY;
353 } else if (!strncmp(string, "modify_strict", len)) {
354 command = OFPFC_MODIFY_STRICT;
355 } else {
356 len = 0;
357 command = OFPFC_ADD;
358 }
359 string += len;
360 }
361
362 switch (command) {
363 case -1:
364 fields = F_OUT_PORT;
365 break;
366
367 case OFPFC_ADD:
368 fields = F_ACTIONS | F_TIMEOUT | F_PRIORITY | F_FLAGS | F_IMPORTANCE;
369 break;
370
371 case OFPFC_DELETE:
372 fields = F_OUT_PORT;
373 break;
374
375 case OFPFC_DELETE_STRICT:
376 fields = F_OUT_PORT | F_PRIORITY;
377 break;
378
379 case OFPFC_MODIFY:
380 fields = F_ACTIONS | F_TIMEOUT | F_PRIORITY | F_FLAGS;
381 break;
382
383 case OFPFC_MODIFY_STRICT:
384 fields = F_ACTIONS | F_TIMEOUT | F_PRIORITY | F_FLAGS;
385 break;
386
387 default:
388 OVS_NOT_REACHED();
389 }
390
391 *fm = (struct ofputil_flow_mod) {
392 .match = MATCH_CATCHALL_INITIALIZER,
393 .priority = OFP_DEFAULT_PRIORITY,
394 .table_id = 0xff,
395 .command = command,
396 .buffer_id = UINT32_MAX,
397 .out_port = OFPP_ANY,
398 .out_group = OFPG_ANY,
399 };
400 /* For modify, by default, don't update the cookie. */
401 if (command == OFPFC_MODIFY || command == OFPFC_MODIFY_STRICT) {
402 fm->new_cookie = OVS_BE64_MAX;
403 }
404
405 if (fields & F_ACTIONS) {
406 act_str = extract_actions(string);
407 if (!act_str) {
408 return xstrdup("must specify an action");
409 }
410 }
411
412 while (ofputil_parse_key_value(&string, &name, &value)) {
413 const struct protocol *p;
414 const struct mf_field *mf;
415 char *error = NULL;
416
417 if (parse_protocol(name, &p)) {
418 match_set_dl_type(&fm->match, htons(p->dl_type));
419 if (p->nw_proto) {
420 match_set_nw_proto(&fm->match, p->nw_proto);
421 }
422 match_set_default_packet_type(&fm->match);
423 } else if (!strcmp(name, "eth")) {
424 match_set_packet_type(&fm->match, htonl(PT_ETH));
425 } else if (fields & F_FLAGS && !strcmp(name, "send_flow_rem")) {
426 fm->flags |= OFPUTIL_FF_SEND_FLOW_REM;
427 } else if (fields & F_FLAGS && !strcmp(name, "check_overlap")) {
428 fm->flags |= OFPUTIL_FF_CHECK_OVERLAP;
429 } else if (fields & F_FLAGS && !strcmp(name, "reset_counts")) {
430 fm->flags |= OFPUTIL_FF_RESET_COUNTS;
431 *usable_protocols &= OFPUTIL_P_OF12_UP;
432 } else if (fields & F_FLAGS && !strcmp(name, "no_packet_counts")) {
433 fm->flags |= OFPUTIL_FF_NO_PKT_COUNTS;
434 *usable_protocols &= OFPUTIL_P_OF13_UP;
435 } else if (fields & F_FLAGS && !strcmp(name, "no_byte_counts")) {
436 fm->flags |= OFPUTIL_FF_NO_BYT_COUNTS;
437 *usable_protocols &= OFPUTIL_P_OF13_UP;
438 } else if (!strcmp(name, "no_readonly_table")
439 || !strcmp(name, "allow_hidden_fields")) {
440 /* ignore these fields. */
441 } else if ((mf = mf_from_name(name)) != NULL) {
442 error = parse_field(mf, value, port_map,
443 &fm->match, usable_protocols);
444 } else if (strchr(name, '[')) {
445 error = parse_subfield(name, value, &fm->match, usable_protocols);
446 } else {
447 if (!*value) {
448 return xasprintf("field %s missing value", name);
449 }
450
451 if (!strcmp(name, "table")) {
452 error = str_to_u8(value, "table", &fm->table_id);
453 if (fm->table_id != 0xff) {
454 *usable_protocols &= OFPUTIL_P_TID;
455 }
456 } else if (fields & F_OUT_PORT && !strcmp(name, "out_port")) {
457 if (!ofputil_port_from_string(value, port_map,
458 &fm->out_port)) {
459 error = xasprintf("%s is not a valid OpenFlow port",
460 value);
461 }
462 } else if (fields & F_OUT_PORT && !strcmp(name, "out_group")) {
463 *usable_protocols &= OFPUTIL_P_OF11_UP;
464 if (!ofputil_group_from_string(value, &fm->out_group)) {
465 error = xasprintf("%s is not a valid OpenFlow group",
466 value);
467 }
468 } else if (fields & F_PRIORITY && !strcmp(name, "priority")) {
469 uint16_t priority = 0;
470
471 error = str_to_u16(value, name, &priority);
472 fm->priority = priority;
473 } else if (fields & F_TIMEOUT && !strcmp(name, "idle_timeout")) {
474 error = str_to_u16(value, name, &fm->idle_timeout);
475 } else if (fields & F_TIMEOUT && !strcmp(name, "hard_timeout")) {
476 error = str_to_u16(value, name, &fm->hard_timeout);
477 } else if (fields & F_IMPORTANCE && !strcmp(name, "importance")) {
478 error = str_to_u16(value, name, &fm->importance);
479 } else if (!strcmp(name, "cookie")) {
480 char *mask = strchr(value, '/');
481
482 if (mask) {
483 /* A mask means we're searching for a cookie. */
484 if (command == OFPFC_ADD) {
485 return xstrdup("flow additions cannot use "
486 "a cookie mask");
487 }
488 *mask = '\0';
489 error = str_to_be64(value, &fm->cookie);
490 if (error) {
491 return error;
492 }
493 error = str_to_be64(mask + 1, &fm->cookie_mask);
494
495 /* Matching of the cookie is only supported through NXM or
496 * OF1.1+. */
497 if (fm->cookie_mask != htonll(0)) {
498 *usable_protocols &= OFPUTIL_P_NXM_OF11_UP;
499 }
500 } else {
501 /* No mask means that the cookie is being set. */
502 if (command != OFPFC_ADD && command != OFPFC_MODIFY
503 && command != OFPFC_MODIFY_STRICT) {
504 return xstrdup("cannot set cookie");
505 }
506 error = str_to_be64(value, &fm->new_cookie);
507 fm->modify_cookie = true;
508 }
509 } else if (!strcmp(name, "duration")
510 || !strcmp(name, "n_packets")
511 || !strcmp(name, "n_bytes")
512 || !strcmp(name, "idle_age")
513 || !strcmp(name, "hard_age")) {
514 /* Ignore these, so that users can feed the output of
515 * "ovs-ofctl dump-flows" back into commands that parse
516 * flows. */
517 } else {
518 error = xasprintf("unknown keyword %s", name);
519 }
520 }
521
522 if (error) {
523 return error;
524 }
525 }
526 /* Copy ethertype to flow->dl_type for matches on packet_type
527 * (OFPHTN_ETHERTYPE, ethertype). */
528 if (fm->match.wc.masks.packet_type == OVS_BE32_MAX &&
529 pt_ns(fm->match.flow.packet_type) == OFPHTN_ETHERTYPE) {
530 fm->match.flow.dl_type = pt_ns_type_be(fm->match.flow.packet_type);
531 }
532 /* Check for usable protocol interdependencies between match fields. */
533 if (fm->match.flow.dl_type == htons(ETH_TYPE_IPV6)) {
534 const struct flow_wildcards *wc = &fm->match.wc;
535 /* Only NXM and OXM support matching L3 and L4 fields within IPv6.
536 *
537 * (IPv6 specific fields as well as arp_sha, arp_tha, nw_frag, and
538 * nw_ttl are covered elsewhere so they don't need to be included in
539 * this test too.)
540 */
541 if (wc->masks.nw_proto || wc->masks.nw_tos
542 || wc->masks.tp_src || wc->masks.tp_dst) {
543 *usable_protocols &= OFPUTIL_P_NXM_OXM_ANY;
544 }
545 }
546 if (!fm->cookie_mask && fm->new_cookie == OVS_BE64_MAX
547 && (command == OFPFC_MODIFY || command == OFPFC_MODIFY_STRICT)) {
548 /* On modifies without a mask, we are supposed to add a flow if
549 * one does not exist. If a cookie wasn't been specified, use a
550 * default of zero. */
551 fm->new_cookie = htonll(0);
552 }
553 if (fields & F_ACTIONS) {
554 enum ofputil_protocol action_usable_protocols;
555 struct ofpbuf ofpacts;
556 char *error;
557
558 ofpbuf_init(&ofpacts, 32);
559 error = ofpacts_parse_instructions(act_str, port_map, &ofpacts,
560 &action_usable_protocols);
561 *usable_protocols &= action_usable_protocols;
562 if (!error) {
563 enum ofperr err;
564
565 err = ofpacts_check(ofpacts.data, ofpacts.size, &fm->match,
566 OFPP_MAX, fm->table_id, 255, usable_protocols);
567 if (!err && !*usable_protocols) {
568 err = OFPERR_OFPBAC_MATCH_INCONSISTENT;
569 }
570 if (err) {
571 error = xasprintf("actions are invalid with specified match "
572 "(%s)", ofperr_to_string(err));
573 }
574
575 }
576 if (error) {
577 ofpbuf_uninit(&ofpacts);
578 return error;
579 }
580
581 fm->ofpacts_len = ofpacts.size;
582 fm->ofpacts = ofpbuf_steal_data(&ofpacts);
583 } else {
584 fm->ofpacts_len = 0;
585 fm->ofpacts = NULL;
586 }
587
588 return NULL;
589 }
590
591 /* Convert 'str_' (as described in the Flow Syntax section of the ovs-ofctl man
592 * page) into 'fm' for sending the specified flow_mod 'command' to a switch.
593 * Returns the set of usable protocols in '*usable_protocols'.
594 *
595 * To parse syntax for an OFPT_FLOW_MOD (or NXT_FLOW_MOD), use an OFPFC_*
596 * constant for 'command'. To parse syntax for an OFPST_FLOW or
597 * OFPST_AGGREGATE (or NXST_FLOW or NXST_AGGREGATE), use -1 for 'command'.
598 *
599 * If 'command' is given as -2, 'str_' may begin with a command name ("add",
600 * "modify", "delete", "modify_strict", or "delete_strict"). A missing command
601 * name is treated as "add".
602 *
603 * Returns NULL if successful, otherwise a malloc()'d string describing the
604 * error. The caller is responsible for freeing the returned string. */
605 char * OVS_WARN_UNUSED_RESULT
606 parse_ofp_str(struct ofputil_flow_mod *fm, int command, const char *str_,
607 const struct ofputil_port_map *port_map,
608 enum ofputil_protocol *usable_protocols)
609 {
610 char *string = xstrdup(str_);
611 char *error;
612
613 error = parse_ofp_str__(fm, command, string, port_map, usable_protocols);
614 if (error) {
615 fm->ofpacts = NULL;
616 fm->ofpacts_len = 0;
617 }
618
619 free(string);
620 return error;
621 }
622
623 /* Parse a string representation of a OFPT_PACKET_OUT to '*po'. If successful,
624 * both 'po->ofpacts' and 'po->packet' must be free()d by the caller. */
625 static char * OVS_WARN_UNUSED_RESULT
626 parse_ofp_packet_out_str__(struct ofputil_packet_out *po, char *string,
627 const struct ofputil_port_map *port_map,
628 enum ofputil_protocol *usable_protocols)
629 {
630 enum ofputil_protocol action_usable_protocols;
631 uint64_t stub[256 / 8];
632 struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(stub);
633 struct dp_packet *packet = NULL;
634 char *act_str = NULL;
635 char *name, *value;
636 char *error = NULL;
637
638 *usable_protocols = OFPUTIL_P_ANY;
639
640 *po = (struct ofputil_packet_out) {
641 .buffer_id = UINT32_MAX,
642 };
643 match_init_catchall(&po->flow_metadata);
644 match_set_in_port(&po->flow_metadata, OFPP_CONTROLLER);
645
646 act_str = extract_actions(string);
647
648 while (ofputil_parse_key_value(&string, &name, &value)) {
649 if (!*value) {
650 error = xasprintf("field %s missing value", name);
651 goto out;
652 }
653
654 if (!strcmp(name, "in_port")) {
655 ofp_port_t in_port;
656 if (!ofputil_port_from_string(value, port_map, &in_port)) {
657 error = xasprintf("%s is not a valid OpenFlow port", value);
658 goto out;
659 }
660 if (ofp_to_u16(in_port) > ofp_to_u16(OFPP_MAX)
661 && in_port != OFPP_LOCAL
662 && in_port != OFPP_NONE
663 && in_port != OFPP_CONTROLLER) {
664 error = xasprintf(
665 "%s is not a valid OpenFlow port for PACKET_OUT",
666 value);
667 goto out;
668 }
669 match_set_in_port(&po->flow_metadata, in_port);
670 } else if (!strcmp(name, "packet_type")) {
671 char *ns = value;
672 char *ns_type = strstr(value, ",");
673 if (ns_type) {
674 ovs_be32 packet_type;
675 *ns_type = '\0';
676 packet_type = PACKET_TYPE_BE(strtoul(ns, NULL, 0),
677 strtoul(++ns_type, NULL, 0));
678 match_set_packet_type(&po->flow_metadata, packet_type);
679 } else {
680 error = xasprintf("%s(%s) can't be interpreted", name, value);
681 goto out;
682 }
683 } else if (!strcmp(name, "packet")) {
684 const char *error_msg = eth_from_hex(value, &packet);
685 if (error_msg) {
686 error = xasprintf("%s: %s", name, error_msg);
687 goto out;
688 }
689 } else {
690 const struct mf_field *mf = mf_from_name(name);
691 if (!mf) {
692 error = xasprintf("unknown keyword %s", name);
693 goto out;
694 }
695
696 error = parse_field(mf, value, port_map, &po->flow_metadata,
697 usable_protocols);
698 if (error) {
699 goto out;
700 }
701 if (!mf_is_pipeline_field(mf)) {
702 error = xasprintf("%s is not a valid pipeline field "
703 "for PACKET_OUT", name);
704 goto out;
705 }
706 }
707 }
708
709 if (!packet || !dp_packet_size(packet)) {
710 error = xstrdup("must specify packet");
711 goto out;
712 }
713
714 if (act_str) {
715 error = ofpacts_parse_actions(act_str, port_map, &ofpacts,
716 &action_usable_protocols);
717 *usable_protocols &= action_usable_protocols;
718 if (error) {
719 goto out;
720 }
721 }
722 po->ofpacts_len = ofpacts.size;
723 po->ofpacts = ofpbuf_steal_data(&ofpacts);
724
725 po->packet_len = dp_packet_size(packet);
726 po->packet = dp_packet_steal_data(packet);
727 out:
728 ofpbuf_uninit(&ofpacts);
729 dp_packet_delete(packet);
730 return error;
731 }
732
733 /* Convert 'str_' (as described in the Packet-Out Syntax section of the
734 * ovs-ofctl man page) into 'po' for sending a OFPT_PACKET_OUT message to a
735 * switch. Returns the set of usable protocols in '*usable_protocols'.
736 *
737 * Returns NULL if successful, otherwise a malloc()'d string describing the
738 * error. The caller is responsible for freeing the returned string. */
739 char * OVS_WARN_UNUSED_RESULT
740 parse_ofp_packet_out_str(struct ofputil_packet_out *po, const char *str_,
741 const struct ofputil_port_map *port_map,
742 enum ofputil_protocol *usable_protocols)
743 {
744 char *string = xstrdup(str_);
745 char *error;
746
747 error = parse_ofp_packet_out_str__(po, string, port_map, usable_protocols);
748 if (error) {
749 po->ofpacts = NULL;
750 po->ofpacts_len = 0;
751 }
752
753 free(string);
754 return error;
755 }
756
757 /* Parse a string representation of a meter modification message to '*mm'.
758 * If successful, 'mm->meter.bands' must be free()d by the caller. */
759 static char * OVS_WARN_UNUSED_RESULT
760 parse_ofp_meter_mod_str__(struct ofputil_meter_mod *mm, char *string,
761 struct ofpbuf *bands, int command,
762 enum ofputil_protocol *usable_protocols)
763 {
764 enum {
765 F_METER = 1 << 0,
766 F_FLAGS = 1 << 1,
767 F_BANDS = 1 << 2,
768 } fields;
769 char *save_ptr = NULL;
770 char *band_str = NULL;
771 char *name;
772
773 /* Meters require at least OF 1.3. */
774 *usable_protocols = OFPUTIL_P_OF13_UP;
775
776 switch (command) {
777 case -1:
778 fields = F_METER;
779 break;
780
781 case OFPMC13_ADD:
782 fields = F_METER | F_FLAGS | F_BANDS;
783 break;
784
785 case OFPMC13_DELETE:
786 fields = F_METER;
787 break;
788
789 case OFPMC13_MODIFY:
790 fields = F_METER | F_FLAGS | F_BANDS;
791 break;
792
793 default:
794 OVS_NOT_REACHED();
795 }
796
797 mm->command = command;
798 mm->meter.meter_id = 0;
799 mm->meter.flags = 0;
800 mm->meter.n_bands = 0;
801 mm->meter.bands = NULL;
802
803 if (fields & F_BANDS) {
804 band_str = strstr(string, "band");
805 if (!band_str) {
806 return xstrdup("must specify bands");
807 }
808 *band_str = '\0';
809
810 band_str = strchr(band_str + 1, '=');
811 if (!band_str) {
812 return xstrdup("must specify bands");
813 }
814
815 band_str++;
816 }
817 for (name = strtok_r(string, "=, \t\r\n", &save_ptr); name;
818 name = strtok_r(NULL, "=, \t\r\n", &save_ptr)) {
819
820 if (fields & F_FLAGS && !strcmp(name, "kbps")) {
821 mm->meter.flags |= OFPMF13_KBPS;
822 } else if (fields & F_FLAGS && !strcmp(name, "pktps")) {
823 mm->meter.flags |= OFPMF13_PKTPS;
824 } else if (fields & F_FLAGS && !strcmp(name, "burst")) {
825 mm->meter.flags |= OFPMF13_BURST;
826 } else if (fields & F_FLAGS && !strcmp(name, "stats")) {
827 mm->meter.flags |= OFPMF13_STATS;
828 } else {
829 char *value;
830
831 value = strtok_r(NULL, ", \t\r\n", &save_ptr);
832 if (!value) {
833 return xasprintf("field %s missing value", name);
834 }
835
836 if (!strcmp(name, "meter")) {
837 if (!strcmp(value, "all")) {
838 mm->meter.meter_id = OFPM13_ALL;
839 } else if (!strcmp(value, "controller")) {
840 mm->meter.meter_id = OFPM13_CONTROLLER;
841 } else if (!strcmp(value, "slowpath")) {
842 mm->meter.meter_id = OFPM13_SLOWPATH;
843 } else {
844 char *error = str_to_u32(value, &mm->meter.meter_id);
845 if (error) {
846 return error;
847 }
848 if (mm->meter.meter_id > OFPM13_MAX
849 || !mm->meter.meter_id) {
850 return xasprintf("invalid value for %s", name);
851 }
852 }
853 } else {
854 return xasprintf("unknown keyword %s", name);
855 }
856 }
857 }
858 if (fields & F_METER && !mm->meter.meter_id) {
859 return xstrdup("must specify 'meter'");
860 }
861 if (fields & F_FLAGS && !mm->meter.flags) {
862 return xstrdup("meter must specify either 'kbps' or 'pktps'");
863 }
864
865 if (fields & F_BANDS) {
866 uint16_t n_bands = 0;
867 struct ofputil_meter_band *band = NULL;
868 int i;
869
870 for (name = strtok_r(band_str, "=, \t\r\n", &save_ptr); name;
871 name = strtok_r(NULL, "=, \t\r\n", &save_ptr)) {
872
873 char *value;
874
875 value = strtok_r(NULL, ", \t\r\n", &save_ptr);
876 if (!value) {
877 return xasprintf("field %s missing value", name);
878 }
879
880 if (!strcmp(name, "type")) {
881 /* Start a new band */
882 band = ofpbuf_put_zeros(bands, sizeof *band);
883 n_bands++;
884
885 if (!strcmp(value, "drop")) {
886 band->type = OFPMBT13_DROP;
887 } else if (!strcmp(value, "dscp_remark")) {
888 band->type = OFPMBT13_DSCP_REMARK;
889 } else {
890 return xasprintf("field %s unknown value %s", name, value);
891 }
892 } else if (!band || !band->type) {
893 return xstrdup("band must start with the 'type' keyword");
894 } else if (!strcmp(name, "rate")) {
895 char *error = str_to_u32(value, &band->rate);
896 if (error) {
897 return error;
898 }
899 } else if (!strcmp(name, "burst_size")) {
900 char *error = str_to_u32(value, &band->burst_size);
901 if (error) {
902 return error;
903 }
904 } else if (!strcmp(name, "prec_level")) {
905 char *error = str_to_u8(value, name, &band->prec_level);
906 if (error) {
907 return error;
908 }
909 } else {
910 return xasprintf("unknown keyword %s", name);
911 }
912 }
913 /* validate bands */
914 if (!n_bands) {
915 return xstrdup("meter must have bands");
916 }
917
918 mm->meter.n_bands = n_bands;
919 mm->meter.bands = ofpbuf_steal_data(bands);
920
921 for (i = 0; i < n_bands; ++i) {
922 band = &mm->meter.bands[i];
923
924 if (!band->type) {
925 return xstrdup("band must have 'type'");
926 }
927 if (band->type == OFPMBT13_DSCP_REMARK) {
928 if (!band->prec_level) {
929 return xstrdup("'dscp_remark' band must have"
930 " 'prec_level'");
931 }
932 } else {
933 if (band->prec_level) {
934 return xstrdup("Only 'dscp_remark' band may have"
935 " 'prec_level'");
936 }
937 }
938 if (!band->rate) {
939 return xstrdup("band must have 'rate'");
940 }
941 if (mm->meter.flags & OFPMF13_BURST) {
942 if (!band->burst_size) {
943 return xstrdup("band must have 'burst_size' "
944 "when 'burst' flag is set");
945 }
946 } else {
947 if (band->burst_size) {
948 return xstrdup("band may have 'burst_size' only "
949 "when 'burst' flag is set");
950 }
951 }
952 }
953 }
954
955 return NULL;
956 }
957
958 /* Convert 'str_' (as described in the Flow Syntax section of the ovs-ofctl man
959 * page) into 'mm' for sending the specified meter_mod 'command' to a switch.
960 *
961 * Returns NULL if successful, otherwise a malloc()'d string describing the
962 * error. The caller is responsible for freeing the returned string.
963 * If successful, 'mm->meter.bands' must be free()d by the caller. */
964 char * OVS_WARN_UNUSED_RESULT
965 parse_ofp_meter_mod_str(struct ofputil_meter_mod *mm, const char *str_,
966 int command, enum ofputil_protocol *usable_protocols)
967 {
968 struct ofpbuf bands;
969 char *string;
970 char *error;
971
972 ofpbuf_init(&bands, 64);
973 string = xstrdup(str_);
974
975 error = parse_ofp_meter_mod_str__(mm, string, &bands, command,
976 usable_protocols);
977
978 free(string);
979 ofpbuf_uninit(&bands);
980
981 return error;
982 }
983
984 static char * OVS_WARN_UNUSED_RESULT
985 parse_flow_monitor_request__(struct ofputil_flow_monitor_request *fmr,
986 const char *str_,
987 const struct ofputil_port_map *port_map,
988 char *string,
989 enum ofputil_protocol *usable_protocols)
990 {
991 static atomic_count id = ATOMIC_COUNT_INIT(0);
992 char *name, *value;
993
994 fmr->id = atomic_count_inc(&id);
995
996 fmr->flags = (NXFMF_INITIAL | NXFMF_ADD | NXFMF_DELETE | NXFMF_MODIFY
997 | NXFMF_OWN | NXFMF_ACTIONS);
998 fmr->out_port = OFPP_NONE;
999 fmr->table_id = 0xff;
1000 match_init_catchall(&fmr->match);
1001
1002 while (ofputil_parse_key_value(&string, &name, &value)) {
1003 const struct protocol *p;
1004 char *error = NULL;
1005
1006 if (!strcmp(name, "!initial")) {
1007 fmr->flags &= ~NXFMF_INITIAL;
1008 } else if (!strcmp(name, "!add")) {
1009 fmr->flags &= ~NXFMF_ADD;
1010 } else if (!strcmp(name, "!delete")) {
1011 fmr->flags &= ~NXFMF_DELETE;
1012 } else if (!strcmp(name, "!modify")) {
1013 fmr->flags &= ~NXFMF_MODIFY;
1014 } else if (!strcmp(name, "!actions")) {
1015 fmr->flags &= ~NXFMF_ACTIONS;
1016 } else if (!strcmp(name, "!own")) {
1017 fmr->flags &= ~NXFMF_OWN;
1018 } else if (parse_protocol(name, &p)) {
1019 match_set_dl_type(&fmr->match, htons(p->dl_type));
1020 if (p->nw_proto) {
1021 match_set_nw_proto(&fmr->match, p->nw_proto);
1022 }
1023 } else if (mf_from_name(name)) {
1024 error = parse_field(mf_from_name(name), value, port_map,
1025 &fmr->match, usable_protocols);
1026 } else {
1027 if (!*value) {
1028 return xasprintf("%s: field %s missing value", str_, name);
1029 }
1030
1031 if (!strcmp(name, "table")) {
1032 error = str_to_u8(value, "table", &fmr->table_id);
1033 } else if (!strcmp(name, "out_port")) {
1034 fmr->out_port = u16_to_ofp(atoi(value));
1035 } else {
1036 return xasprintf("%s: unknown keyword %s", str_, name);
1037 }
1038 }
1039
1040 if (error) {
1041 return error;
1042 }
1043 }
1044 return NULL;
1045 }
1046
1047 /* Convert 'str_' (as described in the documentation for the "monitor" command
1048 * in the ovs-ofctl man page) into 'fmr'.
1049 *
1050 * Returns NULL if successful, otherwise a malloc()'d string describing the
1051 * error. The caller is responsible for freeing the returned string. */
1052 char * OVS_WARN_UNUSED_RESULT
1053 parse_flow_monitor_request(struct ofputil_flow_monitor_request *fmr,
1054 const char *str_,
1055 const struct ofputil_port_map *port_map,
1056 enum ofputil_protocol *usable_protocols)
1057 {
1058 char *string = xstrdup(str_);
1059 char *error = parse_flow_monitor_request__(fmr, str_, port_map, string,
1060 usable_protocols);
1061 free(string);
1062 return error;
1063 }
1064
1065 /* Parses 'string' as an OFPT_FLOW_MOD or NXT_FLOW_MOD with command 'command'
1066 * (one of OFPFC_*) into 'fm'.
1067 *
1068 * If 'command' is given as -2, 'string' may begin with a command name ("add",
1069 * "modify", "delete", "modify_strict", or "delete_strict"). A missing command
1070 * name is treated as "add".
1071 *
1072 * Returns NULL if successful, otherwise a malloc()'d string describing the
1073 * error. The caller is responsible for freeing the returned string. */
1074 char * OVS_WARN_UNUSED_RESULT
1075 parse_ofp_flow_mod_str(struct ofputil_flow_mod *fm, const char *string,
1076 const struct ofputil_port_map *port_map, int command,
1077 enum ofputil_protocol *usable_protocols)
1078 {
1079 char *error = parse_ofp_str(fm, command, string, port_map,
1080 usable_protocols);
1081
1082 if (!error) {
1083 /* Normalize a copy of the match. This ensures that non-normalized
1084 * flows get logged but doesn't affect what gets sent to the switch, so
1085 * that the switch can do whatever it likes with the flow. */
1086 struct match match_copy = fm->match;
1087 ofputil_normalize_match(&match_copy);
1088 }
1089
1090 return error;
1091 }
1092
1093 /* Convert 'setting' (as described for the "mod-table" command
1094 * in ovs-ofctl man page) into 'tm->table_vacancy->vacancy_up' and
1095 * 'tm->table_vacancy->vacancy_down' threshold values.
1096 * For the two threshold values, value of vacancy_up is always greater
1097 * than value of vacancy_down.
1098 *
1099 * Returns NULL if successful, otherwise a malloc()'d string describing the
1100 * error. The caller is responsible for freeing the returned string. */
1101 char * OVS_WARN_UNUSED_RESULT
1102 parse_ofp_table_vacancy(struct ofputil_table_mod *tm, const char *setting)
1103 {
1104 char *save_ptr = NULL;
1105 char *vac_up, *vac_down;
1106 char *value = xstrdup(setting);
1107 char *ret_msg;
1108 int vacancy_up, vacancy_down;
1109
1110 strtok_r(value, ":", &save_ptr);
1111 vac_down = strtok_r(NULL, ",", &save_ptr);
1112 if (!vac_down) {
1113 ret_msg = xasprintf("Vacancy down value missing");
1114 goto exit;
1115 }
1116 if (!str_to_int(vac_down, 0, &vacancy_down) ||
1117 vacancy_down < 0 || vacancy_down > 100) {
1118 ret_msg = xasprintf("Invalid vacancy down value \"%s\"", vac_down);
1119 goto exit;
1120 }
1121 vac_up = strtok_r(NULL, ",", &save_ptr);
1122 if (!vac_up) {
1123 ret_msg = xasprintf("Vacancy up value missing");
1124 goto exit;
1125 }
1126 if (!str_to_int(vac_up, 0, &vacancy_up) ||
1127 vacancy_up < 0 || vacancy_up > 100) {
1128 ret_msg = xasprintf("Invalid vacancy up value \"%s\"", vac_up);
1129 goto exit;
1130 }
1131 if (vacancy_down > vacancy_up) {
1132 ret_msg = xasprintf("Invalid vacancy range, vacancy up should be "
1133 "greater than vacancy down (%s)",
1134 ofperr_to_string(OFPERR_OFPBPC_BAD_VALUE));
1135 goto exit;
1136 }
1137
1138 free(value);
1139 tm->table_vacancy.vacancy_down = vacancy_down;
1140 tm->table_vacancy.vacancy_up = vacancy_up;
1141 return NULL;
1142
1143 exit:
1144 free(value);
1145 return ret_msg;
1146 }
1147
1148 /* Convert 'table_id' and 'setting' (as described for the "mod-table" command
1149 * in the ovs-ofctl man page) into 'tm' for sending a table_mod command to a
1150 * switch.
1151 *
1152 * Stores a bitmap of the OpenFlow versions that are usable for 'tm' into
1153 * '*usable_versions'.
1154 *
1155 * Returns NULL if successful, otherwise a malloc()'d string describing the
1156 * error. The caller is responsible for freeing the returned string. */
1157 char * OVS_WARN_UNUSED_RESULT
1158 parse_ofp_table_mod(struct ofputil_table_mod *tm, const char *table_id,
1159 const char *setting, uint32_t *usable_versions)
1160 {
1161 *usable_versions = 0;
1162 if (!strcasecmp(table_id, "all")) {
1163 tm->table_id = OFPTT_ALL;
1164 } else {
1165 char *error = str_to_u8(table_id, "table_id", &tm->table_id);
1166 if (error) {
1167 return error;
1168 }
1169 }
1170
1171 tm->miss = OFPUTIL_TABLE_MISS_DEFAULT;
1172 tm->eviction = OFPUTIL_TABLE_EVICTION_DEFAULT;
1173 tm->eviction_flags = UINT32_MAX;
1174 tm->vacancy = OFPUTIL_TABLE_VACANCY_DEFAULT;
1175 tm->table_vacancy.vacancy_down = 0;
1176 tm->table_vacancy.vacancy_up = 0;
1177 tm->table_vacancy.vacancy = 0;
1178 /* Only OpenFlow 1.1 and 1.2 can configure table-miss via table_mod.
1179 * Only OpenFlow 1.4+ can configure eviction and vacancy events
1180 * via table_mod.
1181 */
1182 if (!strcmp(setting, "controller")) {
1183 tm->miss = OFPUTIL_TABLE_MISS_CONTROLLER;
1184 *usable_versions = (1u << OFP11_VERSION) | (1u << OFP12_VERSION);
1185 } else if (!strcmp(setting, "continue")) {
1186 tm->miss = OFPUTIL_TABLE_MISS_CONTINUE;
1187 *usable_versions = (1u << OFP11_VERSION) | (1u << OFP12_VERSION);
1188 } else if (!strcmp(setting, "drop")) {
1189 tm->miss = OFPUTIL_TABLE_MISS_DROP;
1190 *usable_versions = (1u << OFP11_VERSION) | (1u << OFP12_VERSION);
1191 } else if (!strcmp(setting, "evict")) {
1192 tm->eviction = OFPUTIL_TABLE_EVICTION_ON;
1193 *usable_versions = (1 << OFP14_VERSION) | (1u << OFP15_VERSION);
1194 } else if (!strcmp(setting, "noevict")) {
1195 tm->eviction = OFPUTIL_TABLE_EVICTION_OFF;
1196 *usable_versions = (1 << OFP14_VERSION) | (1u << OFP15_VERSION);
1197 } else if (!strncmp(setting, "vacancy", strcspn(setting, ":"))) {
1198 tm->vacancy = OFPUTIL_TABLE_VACANCY_ON;
1199 *usable_versions = (1 << OFP14_VERSION) | (1u << OFP15_VERSION);
1200 char *error = parse_ofp_table_vacancy(tm, setting);
1201 if (error) {
1202 return error;
1203 }
1204 } else if (!strcmp(setting, "novacancy")) {
1205 tm->vacancy = OFPUTIL_TABLE_VACANCY_OFF;
1206 *usable_versions = (1 << OFP14_VERSION) | (1u << OFP15_VERSION);
1207 } else {
1208 return xasprintf("invalid table_mod setting %s", setting);
1209 }
1210
1211 if (tm->table_id == 0xfe
1212 && tm->miss == OFPUTIL_TABLE_MISS_CONTINUE) {
1213 return xstrdup("last table's flow miss handling can not be continue");
1214 }
1215
1216 return NULL;
1217 }
1218
1219
1220 /* Opens file 'file_name' and reads each line as a flow_mod of the specified
1221 * type (one of OFPFC_*). Stores each flow_mod in '*fm', an array allocated
1222 * on the caller's behalf, and the number of flow_mods in '*n_fms'.
1223 *
1224 * If 'command' is given as -2, each line may start with a command name
1225 * ("add", "modify", "delete", "modify_strict", or "delete_strict"). A missing
1226 * command name is treated as "add".
1227 *
1228 * Returns NULL if successful, otherwise a malloc()'d string describing the
1229 * error. The caller is responsible for freeing the returned string. */
1230 char * OVS_WARN_UNUSED_RESULT
1231 parse_ofp_flow_mod_file(const char *file_name,
1232 const struct ofputil_port_map *port_map, int command,
1233 struct ofputil_flow_mod **fms, size_t *n_fms,
1234 enum ofputil_protocol *usable_protocols)
1235 {
1236 size_t allocated_fms;
1237 int line_number;
1238 FILE *stream;
1239 struct ds s;
1240
1241 *usable_protocols = OFPUTIL_P_ANY;
1242
1243 *fms = NULL;
1244 *n_fms = 0;
1245
1246 stream = !strcmp(file_name, "-") ? stdin : fopen(file_name, "r");
1247 if (stream == NULL) {
1248 return xasprintf("%s: open failed (%s)",
1249 file_name, ovs_strerror(errno));
1250 }
1251
1252 allocated_fms = *n_fms;
1253 ds_init(&s);
1254 line_number = 0;
1255 while (!ds_get_preprocessed_line(&s, stream, &line_number)) {
1256 char *error;
1257 enum ofputil_protocol usable;
1258
1259 if (*n_fms >= allocated_fms) {
1260 *fms = x2nrealloc(*fms, &allocated_fms, sizeof **fms);
1261 }
1262 error = parse_ofp_flow_mod_str(&(*fms)[*n_fms], ds_cstr(&s), port_map,
1263 command, &usable);
1264 if (error) {
1265 char *err_msg;
1266 size_t i;
1267
1268 for (i = 0; i < *n_fms; i++) {
1269 free(CONST_CAST(struct ofpact *, (*fms)[i].ofpacts));
1270 }
1271 free(*fms);
1272 *fms = NULL;
1273 *n_fms = 0;
1274
1275 ds_destroy(&s);
1276 if (stream != stdin) {
1277 fclose(stream);
1278 }
1279
1280 err_msg = xasprintf("%s:%d: %s", file_name, line_number, error);
1281 free(error);
1282 return err_msg;
1283 }
1284 *usable_protocols &= usable; /* Each line can narrow the set. */
1285 *n_fms += 1;
1286 }
1287
1288 ds_destroy(&s);
1289 if (stream != stdin) {
1290 fclose(stream);
1291 }
1292 return NULL;
1293 }
1294
1295 char * OVS_WARN_UNUSED_RESULT
1296 parse_ofp_flow_stats_request_str(struct ofputil_flow_stats_request *fsr,
1297 bool aggregate, const char *string,
1298 const struct ofputil_port_map *port_map,
1299 enum ofputil_protocol *usable_protocols)
1300 {
1301 struct ofputil_flow_mod fm;
1302 char *error;
1303
1304 error = parse_ofp_str(&fm, -1, string, port_map, usable_protocols);
1305 if (error) {
1306 return error;
1307 }
1308
1309 /* Special table ID support not required for stats requests. */
1310 if (*usable_protocols & OFPUTIL_P_OF10_STD_TID) {
1311 *usable_protocols |= OFPUTIL_P_OF10_STD;
1312 }
1313 if (*usable_protocols & OFPUTIL_P_OF10_NXM_TID) {
1314 *usable_protocols |= OFPUTIL_P_OF10_NXM;
1315 }
1316
1317 fsr->aggregate = aggregate;
1318 fsr->cookie = fm.cookie;
1319 fsr->cookie_mask = fm.cookie_mask;
1320 fsr->match = fm.match;
1321 fsr->out_port = fm.out_port;
1322 fsr->out_group = fm.out_group;
1323 fsr->table_id = fm.table_id;
1324 return NULL;
1325 }
1326
1327 /* Parses a specification of a flow from 's' into 'flow'. 's' must take the
1328 * form FIELD=VALUE[,FIELD=VALUE]... where each FIELD is the name of a
1329 * mf_field. Fields must be specified in a natural order for satisfying
1330 * prerequisites. If 'wc' is specified, masks the field in 'wc' for each of the
1331 * field specified in flow. If the map, 'names_portno' is specfied, converts
1332 * the in_port name into port no while setting the 'flow'.
1333 *
1334 * Returns NULL on success, otherwise a malloc()'d string that explains the
1335 * problem. */
1336 char *
1337 parse_ofp_exact_flow(struct flow *flow, struct flow_wildcards *wc,
1338 const struct tun_table *tun_table, const char *s,
1339 const struct ofputil_port_map *port_map)
1340 {
1341 char *pos, *key, *value_s;
1342 char *error = NULL;
1343 char *copy;
1344
1345 memset(flow, 0, sizeof *flow);
1346 if (wc) {
1347 memset(wc, 0, sizeof *wc);
1348 }
1349 flow->tunnel.metadata.tab = tun_table;
1350
1351 pos = copy = xstrdup(s);
1352 while (ofputil_parse_key_value(&pos, &key, &value_s)) {
1353 const struct protocol *p;
1354 if (parse_protocol(key, &p)) {
1355 if (flow->dl_type) {
1356 error = xasprintf("%s: Ethernet type set multiple times", s);
1357 goto exit;
1358 }
1359 flow->dl_type = htons(p->dl_type);
1360 if (wc) {
1361 wc->masks.dl_type = OVS_BE16_MAX;
1362 }
1363
1364 if (p->nw_proto) {
1365 if (flow->nw_proto) {
1366 error = xasprintf("%s: network protocol set "
1367 "multiple times", s);
1368 goto exit;
1369 }
1370 flow->nw_proto = p->nw_proto;
1371 if (wc) {
1372 wc->masks.nw_proto = UINT8_MAX;
1373 }
1374 }
1375 } else {
1376 const struct mf_field *mf;
1377 union mf_value value;
1378 char *field_error;
1379
1380 mf = mf_from_name(key);
1381 if (!mf) {
1382 error = xasprintf("%s: unknown field %s", s, key);
1383 goto exit;
1384 }
1385
1386 if (!mf_are_prereqs_ok(mf, flow, NULL)) {
1387 error = xasprintf("%s: prerequisites not met for setting %s",
1388 s, key);
1389 goto exit;
1390 }
1391
1392 if (mf_is_set(mf, flow)) {
1393 error = xasprintf("%s: field %s set multiple times", s, key);
1394 goto exit;
1395 }
1396
1397 field_error = mf_parse_value(mf, value_s, port_map, &value);
1398 if (field_error) {
1399 error = xasprintf("%s: bad value for %s (%s)",
1400 s, key, field_error);
1401 free(field_error);
1402 goto exit;
1403 }
1404
1405 mf_set_flow_value(mf, &value, flow);
1406 if (wc) {
1407 mf_mask_field(mf, wc);
1408 }
1409 }
1410 }
1411
1412 if (!flow->in_port.ofp_port) {
1413 flow->in_port.ofp_port = OFPP_NONE;
1414 }
1415
1416 exit:
1417 free(copy);
1418
1419 if (error) {
1420 memset(flow, 0, sizeof *flow);
1421 if (wc) {
1422 memset(wc, 0, sizeof *wc);
1423 }
1424 }
1425 return error;
1426 }
1427
1428 static char * OVS_WARN_UNUSED_RESULT
1429 parse_bucket_str(struct ofputil_bucket *bucket, char *str_,
1430 const struct ofputil_port_map *port_map, uint8_t group_type,
1431 enum ofputil_protocol *usable_protocols)
1432 {
1433 char *pos, *key, *value;
1434 struct ofpbuf ofpacts;
1435 struct ds actions;
1436 char *error;
1437
1438 bucket->weight = group_type == OFPGT11_SELECT ? 1 : 0;
1439 bucket->bucket_id = OFPG15_BUCKET_ALL;
1440 bucket->watch_port = OFPP_ANY;
1441 bucket->watch_group = OFPG_ANY;
1442
1443 ds_init(&actions);
1444
1445 pos = str_;
1446 error = NULL;
1447 while (ofputil_parse_key_value(&pos, &key, &value)) {
1448 if (!strcasecmp(key, "weight")) {
1449 error = str_to_u16(value, "weight", &bucket->weight);
1450 } else if (!strcasecmp(key, "watch_port")) {
1451 if (!ofputil_port_from_string(value, port_map, &bucket->watch_port)
1452 || (ofp_to_u16(bucket->watch_port) >= ofp_to_u16(OFPP_MAX)
1453 && bucket->watch_port != OFPP_ANY)) {
1454 error = xasprintf("%s: invalid watch_port", value);
1455 }
1456 } else if (!strcasecmp(key, "watch_group")) {
1457 error = str_to_u32(value, &bucket->watch_group);
1458 if (!error && bucket->watch_group > OFPG_MAX) {
1459 error = xasprintf("invalid watch_group id %"PRIu32,
1460 bucket->watch_group);
1461 }
1462 } else if (!strcasecmp(key, "bucket_id")) {
1463 error = str_to_u32(value, &bucket->bucket_id);
1464 if (!error && bucket->bucket_id > OFPG15_BUCKET_MAX) {
1465 error = xasprintf("invalid bucket_id id %"PRIu32,
1466 bucket->bucket_id);
1467 }
1468 *usable_protocols &= OFPUTIL_P_OF15_UP;
1469 } else if (!strcasecmp(key, "action") || !strcasecmp(key, "actions")) {
1470 ds_put_format(&actions, "%s,", value);
1471 } else {
1472 ds_put_format(&actions, "%s(%s),", key, value);
1473 }
1474
1475 if (error) {
1476 ds_destroy(&actions);
1477 return error;
1478 }
1479 }
1480
1481 if (!actions.length) {
1482 return xstrdup("bucket must specify actions");
1483 }
1484 ds_chomp(&actions, ',');
1485
1486 ofpbuf_init(&ofpacts, 0);
1487 error = ofpacts_parse_actions(ds_cstr(&actions), port_map, &ofpacts,
1488 usable_protocols);
1489 ds_destroy(&actions);
1490 if (error) {
1491 ofpbuf_uninit(&ofpacts);
1492 return error;
1493 }
1494 bucket->ofpacts = ofpacts.data;
1495 bucket->ofpacts_len = ofpacts.size;
1496
1497 return NULL;
1498 }
1499
1500 static char * OVS_WARN_UNUSED_RESULT
1501 parse_select_group_field(char *s, const struct ofputil_port_map *port_map,
1502 struct field_array *fa,
1503 enum ofputil_protocol *usable_protocols)
1504 {
1505 char *name, *value_str;
1506
1507 while (ofputil_parse_key_value(&s, &name, &value_str)) {
1508 const struct mf_field *mf = mf_from_name(name);
1509
1510 if (mf) {
1511 char *error;
1512 union mf_value value;
1513
1514 if (bitmap_is_set(fa->used.bm, mf->id)) {
1515 return xasprintf("%s: duplicate field", name);
1516 }
1517
1518 if (*value_str) {
1519 error = mf_parse_value(mf, value_str, port_map, &value);
1520 if (error) {
1521 return error;
1522 }
1523
1524 /* The mask cannot be all-zeros */
1525 if (!mf_is_tun_metadata(mf) &&
1526 is_all_zeros(&value, mf->n_bytes)) {
1527 return xasprintf("%s: values are wildcards here "
1528 "and must not be all-zeros", s);
1529 }
1530
1531 /* The values parsed are masks for fields used
1532 * by the selection method */
1533 if (!mf_is_mask_valid(mf, &value)) {
1534 return xasprintf("%s: invalid mask for field %s",
1535 value_str, mf->name);
1536 }
1537 } else {
1538 memset(&value, 0xff, mf->n_bytes);
1539 }
1540
1541 field_array_set(mf->id, &value, fa);
1542
1543 if (is_all_ones(&value, mf->n_bytes)) {
1544 *usable_protocols &= mf->usable_protocols_exact;
1545 } else if (mf->usable_protocols_bitwise == mf->usable_protocols_cidr
1546 || ip_is_cidr(value.be32)) {
1547 *usable_protocols &= mf->usable_protocols_cidr;
1548 } else {
1549 *usable_protocols &= mf->usable_protocols_bitwise;
1550 }
1551 } else {
1552 return xasprintf("%s: unknown field %s", s, name);
1553 }
1554 }
1555
1556 return NULL;
1557 }
1558
1559 static char * OVS_WARN_UNUSED_RESULT
1560 parse_ofp_group_mod_str__(struct ofputil_group_mod *gm, int command,
1561 char *string,
1562 const struct ofputil_port_map *port_map,
1563 enum ofputil_protocol *usable_protocols)
1564 {
1565 enum {
1566 F_GROUP_TYPE = 1 << 0,
1567 F_BUCKETS = 1 << 1,
1568 F_COMMAND_BUCKET_ID = 1 << 2,
1569 F_COMMAND_BUCKET_ID_ALL = 1 << 3,
1570 } fields;
1571 bool had_type = false;
1572 bool had_command_bucket_id = false;
1573 struct ofputil_bucket *bucket;
1574 char *error = NULL;
1575
1576 *usable_protocols = OFPUTIL_P_OF11_UP;
1577
1578 if (command == -2) {
1579 size_t len;
1580
1581 string += strspn(string, " \t\r\n"); /* Skip white space. */
1582 len = strcspn(string, ", \t\r\n"); /* Get length of the first token. */
1583
1584 if (!strncmp(string, "add", len)) {
1585 command = OFPGC11_ADD;
1586 } else if (!strncmp(string, "delete", len)) {
1587 command = OFPGC11_DELETE;
1588 } else if (!strncmp(string, "modify", len)) {
1589 command = OFPGC11_MODIFY;
1590 } else if (!strncmp(string, "add_or_mod", len)) {
1591 command = OFPGC11_ADD_OR_MOD;
1592 } else if (!strncmp(string, "insert_bucket", len)) {
1593 command = OFPGC15_INSERT_BUCKET;
1594 } else if (!strncmp(string, "remove_bucket", len)) {
1595 command = OFPGC15_REMOVE_BUCKET;
1596 } else {
1597 len = 0;
1598 command = OFPGC11_ADD;
1599 }
1600 string += len;
1601 }
1602
1603 switch (command) {
1604 case OFPGC11_ADD:
1605 fields = F_GROUP_TYPE | F_BUCKETS;
1606 break;
1607
1608 case OFPGC11_DELETE:
1609 fields = 0;
1610 break;
1611
1612 case OFPGC11_MODIFY:
1613 fields = F_GROUP_TYPE | F_BUCKETS;
1614 break;
1615
1616 case OFPGC11_ADD_OR_MOD:
1617 fields = F_GROUP_TYPE | F_BUCKETS;
1618 break;
1619
1620 case OFPGC15_INSERT_BUCKET:
1621 fields = F_BUCKETS | F_COMMAND_BUCKET_ID;
1622 *usable_protocols &= OFPUTIL_P_OF15_UP;
1623 break;
1624
1625 case OFPGC15_REMOVE_BUCKET:
1626 fields = F_COMMAND_BUCKET_ID | F_COMMAND_BUCKET_ID_ALL;
1627 *usable_protocols &= OFPUTIL_P_OF15_UP;
1628 break;
1629
1630 default:
1631 OVS_NOT_REACHED();
1632 }
1633
1634 memset(gm, 0, sizeof *gm);
1635 gm->command = command;
1636 gm->group_id = OFPG_ANY;
1637 gm->command_bucket_id = OFPG15_BUCKET_ALL;
1638 ovs_list_init(&gm->buckets);
1639 if (command == OFPGC11_DELETE && string[0] == '\0') {
1640 gm->group_id = OFPG_ALL;
1641 return NULL;
1642 }
1643
1644 *usable_protocols = OFPUTIL_P_OF11_UP;
1645
1646 /* Strip the buckets off the end of 'string', if there are any, saving a
1647 * pointer for later. We want to parse the buckets last because the bucket
1648 * type influences bucket defaults. */
1649 char *bkt_str = strstr(string, "bucket=");
1650 if (bkt_str) {
1651 if (!(fields & F_BUCKETS)) {
1652 error = xstrdup("bucket is not needed");
1653 goto out;
1654 }
1655 *bkt_str = '\0';
1656 }
1657
1658 /* Parse everything before the buckets. */
1659 char *pos = string;
1660 char *name, *value;
1661 while (ofputil_parse_key_value(&pos, &name, &value)) {
1662 if (!strcmp(name, "command_bucket_id")) {
1663 if (!(fields & F_COMMAND_BUCKET_ID)) {
1664 error = xstrdup("command bucket id is not needed");
1665 goto out;
1666 }
1667 if (!strcmp(value, "all")) {
1668 gm->command_bucket_id = OFPG15_BUCKET_ALL;
1669 } else if (!strcmp(value, "first")) {
1670 gm->command_bucket_id = OFPG15_BUCKET_FIRST;
1671 } else if (!strcmp(value, "last")) {
1672 gm->command_bucket_id = OFPG15_BUCKET_LAST;
1673 } else {
1674 error = str_to_u32(value, &gm->command_bucket_id);
1675 if (error) {
1676 goto out;
1677 }
1678 if (gm->command_bucket_id > OFPG15_BUCKET_MAX
1679 && (gm->command_bucket_id != OFPG15_BUCKET_FIRST
1680 && gm->command_bucket_id != OFPG15_BUCKET_LAST
1681 && gm->command_bucket_id != OFPG15_BUCKET_ALL)) {
1682 error = xasprintf("invalid command bucket id %"PRIu32,
1683 gm->command_bucket_id);
1684 goto out;
1685 }
1686 }
1687 if (gm->command_bucket_id == OFPG15_BUCKET_ALL
1688 && !(fields & F_COMMAND_BUCKET_ID_ALL)) {
1689 error = xstrdup("command_bucket_id=all is not permitted");
1690 goto out;
1691 }
1692 had_command_bucket_id = true;
1693 } else if (!strcmp(name, "group_id")) {
1694 if(!strcmp(value, "all")) {
1695 gm->group_id = OFPG_ALL;
1696 } else {
1697 error = str_to_u32(value, &gm->group_id);
1698 if (error) {
1699 goto out;
1700 }
1701 if (gm->group_id != OFPG_ALL && gm->group_id > OFPG_MAX) {
1702 error = xasprintf("invalid group id %"PRIu32,
1703 gm->group_id);
1704 goto out;
1705 }
1706 }
1707 } else if (!strcmp(name, "type")){
1708 if (!(fields & F_GROUP_TYPE)) {
1709 error = xstrdup("type is not needed");
1710 goto out;
1711 }
1712 if (!strcmp(value, "all")) {
1713 gm->type = OFPGT11_ALL;
1714 } else if (!strcmp(value, "select")) {
1715 gm->type = OFPGT11_SELECT;
1716 } else if (!strcmp(value, "indirect")) {
1717 gm->type = OFPGT11_INDIRECT;
1718 } else if (!strcmp(value, "ff") ||
1719 !strcmp(value, "fast_failover")) {
1720 gm->type = OFPGT11_FF;
1721 } else {
1722 error = xasprintf("invalid group type %s", value);
1723 goto out;
1724 }
1725 had_type = true;
1726 } else if (!strcmp(name, "selection_method")) {
1727 if (!(fields & F_GROUP_TYPE)) {
1728 error = xstrdup("selection method is not needed");
1729 goto out;
1730 }
1731 if (strlen(value) >= NTR_MAX_SELECTION_METHOD_LEN) {
1732 error = xasprintf("selection method is longer than %u"
1733 " bytes long",
1734 NTR_MAX_SELECTION_METHOD_LEN - 1);
1735 goto out;
1736 }
1737 memset(gm->props.selection_method, '\0',
1738 NTR_MAX_SELECTION_METHOD_LEN);
1739 strcpy(gm->props.selection_method, value);
1740 *usable_protocols &= OFPUTIL_P_OF15_UP;
1741 } else if (!strcmp(name, "selection_method_param")) {
1742 if (!(fields & F_GROUP_TYPE)) {
1743 error = xstrdup("selection method param is not needed");
1744 goto out;
1745 }
1746 error = str_to_u64(value, &gm->props.selection_method_param);
1747 if (error) {
1748 goto out;
1749 }
1750 *usable_protocols &= OFPUTIL_P_OF15_UP;
1751 } else if (!strcmp(name, "fields")) {
1752 if (!(fields & F_GROUP_TYPE)) {
1753 error = xstrdup("fields are not needed");
1754 goto out;
1755 }
1756 error = parse_select_group_field(value, port_map,
1757 &gm->props.fields,
1758 usable_protocols);
1759 if (error) {
1760 goto out;
1761 }
1762 *usable_protocols &= OFPUTIL_P_OF15_UP;
1763 } else {
1764 error = xasprintf("unknown keyword %s", name);
1765 goto out;
1766 }
1767 }
1768 if (gm->group_id == OFPG_ANY) {
1769 error = xstrdup("must specify a group_id");
1770 goto out;
1771 }
1772 if (fields & F_GROUP_TYPE && !had_type) {
1773 error = xstrdup("must specify a type");
1774 goto out;
1775 }
1776
1777 /* Exclude fields for non "hash" selection method. */
1778 if (strcmp(gm->props.selection_method, "hash") &&
1779 gm->props.fields.values_size) {
1780 error = xstrdup("fields may only be specified with \"selection_method=hash\"");
1781 goto out;
1782 }
1783 /* Exclude selection_method_param if no selection_method is given. */
1784 if (gm->props.selection_method[0] == 0
1785 && gm->props.selection_method_param != 0) {
1786 error = xstrdup("selection_method_param is only allowed with \"selection_method\"");
1787 goto out;
1788 }
1789 if (fields & F_COMMAND_BUCKET_ID) {
1790 if (!(fields & F_COMMAND_BUCKET_ID_ALL || had_command_bucket_id)) {
1791 error = xstrdup("must specify a command bucket id");
1792 goto out;
1793 }
1794 } else if (had_command_bucket_id) {
1795 error = xstrdup("command bucket id is not needed");
1796 goto out;
1797 }
1798
1799 /* Now parse the buckets, if any. */
1800 while (bkt_str) {
1801 char *next_bkt_str;
1802
1803 bkt_str = strchr(bkt_str + 1, '=');
1804 if (!bkt_str) {
1805 error = xstrdup("must specify bucket content");
1806 goto out;
1807 }
1808 bkt_str++;
1809
1810 next_bkt_str = strstr(bkt_str, "bucket=");
1811 if (next_bkt_str) {
1812 *next_bkt_str = '\0';
1813 }
1814
1815 bucket = xzalloc(sizeof(struct ofputil_bucket));
1816 error = parse_bucket_str(bucket, bkt_str, port_map,
1817 gm->type, usable_protocols);
1818 if (error) {
1819 free(bucket);
1820 goto out;
1821 }
1822 ovs_list_push_back(&gm->buckets, &bucket->list_node);
1823
1824 if (gm->type != OFPGT11_SELECT && bucket->weight) {
1825 error = xstrdup("Only select groups can have bucket weights.");
1826 goto out;
1827 }
1828
1829 bkt_str = next_bkt_str;
1830 }
1831 if (gm->type == OFPGT11_INDIRECT && !ovs_list_is_short(&gm->buckets)) {
1832 error = xstrdup("Indirect groups can have at most one bucket.");
1833 goto out;
1834 }
1835
1836 return NULL;
1837 out:
1838 ofputil_uninit_group_mod(gm);
1839 return error;
1840 }
1841
1842 /* If 'command' is given as -2, each line may start with a command name ("add",
1843 * "modify", "add_or_mod", "delete", "insert_bucket", or "remove_bucket"). A
1844 * missing command name is treated as "add".
1845 */
1846 char * OVS_WARN_UNUSED_RESULT
1847 parse_ofp_group_mod_str(struct ofputil_group_mod *gm, int command,
1848 const char *str_,
1849 const struct ofputil_port_map *port_map,
1850 enum ofputil_protocol *usable_protocols)
1851 {
1852 char *string = xstrdup(str_);
1853 char *error = parse_ofp_group_mod_str__(gm, command, string,
1854 port_map, usable_protocols);
1855 free(string);
1856 return error;
1857 }
1858
1859 /* If 'command' is given as -2, each line may start with a command name ("add",
1860 * "modify", "add_or_mod", "delete", "insert_bucket", or "remove_bucket"). A
1861 * missing command name is treated as "add".
1862 */
1863 char * OVS_WARN_UNUSED_RESULT
1864 parse_ofp_group_mod_file(const char *file_name,
1865 const struct ofputil_port_map *port_map,
1866 int command,
1867 struct ofputil_group_mod **gms, size_t *n_gms,
1868 enum ofputil_protocol *usable_protocols)
1869 {
1870 size_t allocated_gms;
1871 int line_number;
1872 FILE *stream;
1873 struct ds s;
1874
1875 *gms = NULL;
1876 *n_gms = 0;
1877
1878 stream = !strcmp(file_name, "-") ? stdin : fopen(file_name, "r");
1879 if (stream == NULL) {
1880 return xasprintf("%s: open failed (%s)",
1881 file_name, ovs_strerror(errno));
1882 }
1883
1884 allocated_gms = *n_gms;
1885 ds_init(&s);
1886 line_number = 0;
1887 *usable_protocols = OFPUTIL_P_OF11_UP;
1888 while (!ds_get_preprocessed_line(&s, stream, &line_number)) {
1889 enum ofputil_protocol usable;
1890 char *error;
1891
1892 if (*n_gms >= allocated_gms) {
1893 struct ofputil_group_mod *new_gms;
1894 size_t i;
1895
1896 new_gms = x2nrealloc(*gms, &allocated_gms, sizeof **gms);
1897 for (i = 0; i < *n_gms; i++) {
1898 ovs_list_moved(&new_gms[i].buckets, &(*gms)[i].buckets);
1899 }
1900 *gms = new_gms;
1901 }
1902 error = parse_ofp_group_mod_str(&(*gms)[*n_gms], command, ds_cstr(&s),
1903 port_map, &usable);
1904 if (error) {
1905 size_t i;
1906
1907 for (i = 0; i < *n_gms; i++) {
1908 ofputil_uninit_group_mod(&(*gms)[i]);
1909 }
1910 free(*gms);
1911 *gms = NULL;
1912 *n_gms = 0;
1913
1914 ds_destroy(&s);
1915 if (stream != stdin) {
1916 fclose(stream);
1917 }
1918
1919 char *ret = xasprintf("%s:%d: %s", file_name, line_number, error);
1920 free(error);
1921 return ret;
1922 }
1923 *usable_protocols &= usable;
1924 *n_gms += 1;
1925 }
1926
1927 ds_destroy(&s);
1928 if (stream != stdin) {
1929 fclose(stream);
1930 }
1931 return NULL;
1932 }
1933
1934 /* Opens file 'file_name' and reads each line as a flow_mod or a group_mod,
1935 * depending on the first keyword on each line. Stores each flow and group
1936 * mods in '*bms', an array allocated on the caller's behalf, and the number of
1937 * messages in '*n_bms'.
1938 *
1939 * Returns NULL if successful, otherwise a malloc()'d string describing the
1940 * error. The caller is responsible for freeing the returned string. */
1941 char * OVS_WARN_UNUSED_RESULT
1942 parse_ofp_bundle_file(const char *file_name,
1943 const struct ofputil_port_map *port_map,
1944 struct ofputil_bundle_msg **bms, size_t *n_bms,
1945 enum ofputil_protocol *usable_protocols)
1946 {
1947 size_t allocated_bms;
1948 char *error = NULL;
1949 int line_number;
1950 FILE *stream;
1951 struct ds ds;
1952
1953 *usable_protocols = OFPUTIL_P_ANY;
1954
1955 *bms = NULL;
1956 *n_bms = 0;
1957
1958 stream = !strcmp(file_name, "-") ? stdin : fopen(file_name, "r");
1959 if (stream == NULL) {
1960 return xasprintf("%s: open failed (%s)",
1961 file_name, ovs_strerror(errno));
1962 }
1963
1964 allocated_bms = *n_bms;
1965 ds_init(&ds);
1966 line_number = 0;
1967 while (!ds_get_preprocessed_line(&ds, stream, &line_number)) {
1968 enum ofputil_protocol usable;
1969 char *s = ds_cstr(&ds);
1970 size_t len;
1971
1972 if (*n_bms >= allocated_bms) {
1973 struct ofputil_bundle_msg *new_bms;
1974
1975 new_bms = x2nrealloc(*bms, &allocated_bms, sizeof **bms);
1976 for (size_t i = 0; i < *n_bms; i++) {
1977 if (new_bms[i].type == OFPTYPE_GROUP_MOD) {
1978 ovs_list_moved(&new_bms[i].gm.buckets,
1979 &(*bms)[i].gm.buckets);
1980 }
1981 }
1982 *bms = new_bms;
1983 }
1984
1985 s += strspn(s, " \t\r\n"); /* Skip white space. */
1986 len = strcspn(s, ", \t\r\n"); /* Get length of the first token. */
1987
1988 if (!strncmp(s, "flow", len)) {
1989 s += len;
1990 error = parse_ofp_flow_mod_str(&(*bms)[*n_bms].fm, s, port_map,
1991 -2, &usable);
1992 if (error) {
1993 break;
1994 }
1995 (*bms)[*n_bms].type = OFPTYPE_FLOW_MOD;
1996 } else if (!strncmp(s, "group", len)) {
1997 s += len;
1998 error = parse_ofp_group_mod_str(&(*bms)[*n_bms].gm, -2, s,
1999 port_map, &usable);
2000 if (error) {
2001 break;
2002 }
2003 (*bms)[*n_bms].type = OFPTYPE_GROUP_MOD;
2004 } else if (!strncmp(s, "packet-out", len)) {
2005 s += len;
2006 error = parse_ofp_packet_out_str(&(*bms)[*n_bms].po, s, port_map,
2007 &usable);
2008 if (error) {
2009 break;
2010 }
2011 (*bms)[*n_bms].type = OFPTYPE_PACKET_OUT;
2012 } else {
2013 error = xasprintf("Unsupported bundle message type: %.*s",
2014 (int)len, s);
2015 break;
2016 }
2017
2018 *usable_protocols &= usable; /* Each line can narrow the set. */
2019 *n_bms += 1;
2020 }
2021
2022 ds_destroy(&ds);
2023 if (stream != stdin) {
2024 fclose(stream);
2025 }
2026
2027 if (error) {
2028 char *err_msg = xasprintf("%s:%d: %s", file_name, line_number, error);
2029 free(error);
2030
2031 ofputil_free_bundle_msgs(*bms, *n_bms);
2032 *bms = NULL;
2033 *n_bms = 0;
2034 return err_msg;
2035 }
2036 return NULL;
2037 }
2038
2039 char * OVS_WARN_UNUSED_RESULT
2040 parse_ofp_tlv_table_mod_str(struct ofputil_tlv_table_mod *ttm,
2041 uint16_t command, const char *s,
2042 enum ofputil_protocol *usable_protocols)
2043 {
2044 *usable_protocols = OFPUTIL_P_NXM_OXM_ANY;
2045
2046 ttm->command = command;
2047 ovs_list_init(&ttm->mappings);
2048
2049 while (*s) {
2050 struct ofputil_tlv_map *map = xmalloc(sizeof *map);
2051 int n;
2052
2053 if (*s == ',') {
2054 s++;
2055 }
2056
2057 ovs_list_push_back(&ttm->mappings, &map->list_node);
2058
2059 if (!ovs_scan(s, "{class=%"SCNi16",type=%"SCNi8",len=%"SCNi8"}->tun_metadata%"SCNi16"%n",
2060 &map->option_class, &map->option_type, &map->option_len,
2061 &map->index, &n)) {
2062 ofputil_uninit_tlv_table(&ttm->mappings);
2063 return xstrdup("invalid tlv mapping");
2064 }
2065
2066 s += n;
2067 }
2068
2069 return NULL;
2070 }