]> git.proxmox.com Git - mirror_ovs.git/blob - lib/ofp-parse.c
Implement OpenFlow 1.4+ OFPTC_EVICTION.
[mirror_ovs.git] / lib / ofp-parse.c
1 /*
2 * Copyright (c) 2010, 2011, 2012, 2013, 2014, 2015 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 "ofp-parse.h"
20
21 #include <ctype.h>
22 #include <errno.h>
23 #include <stdlib.h>
24
25 #include "byte-order.h"
26 #include "dynamic-string.h"
27 #include "learn.h"
28 #include "meta-flow.h"
29 #include "multipath.h"
30 #include "netdev.h"
31 #include "nx-match.h"
32 #include "ofp-actions.h"
33 #include "ofp-util.h"
34 #include "ofpbuf.h"
35 #include "openflow/openflow.h"
36 #include "ovs-thread.h"
37 #include "packets.h"
38 #include "simap.h"
39 #include "socket-util.h"
40 #include "openvswitch/vconn.h"
41
42 /* Parses 'str' as an 8-bit unsigned integer into '*valuep'.
43 *
44 * 'name' describes the value parsed in an error message, if any.
45 *
46 * Returns NULL if successful, otherwise a malloc()'d string describing the
47 * error. The caller is responsible for freeing the returned string. */
48 char * OVS_WARN_UNUSED_RESULT
49 str_to_u8(const char *str, const char *name, uint8_t *valuep)
50 {
51 int value;
52
53 if (!str_to_int(str, 0, &value) || value < 0 || value > 255) {
54 return xasprintf("invalid %s \"%s\"", name, str);
55 }
56 *valuep = value;
57 return NULL;
58 }
59
60 /* Parses 'str' as a 16-bit unsigned integer into '*valuep'.
61 *
62 * 'name' describes the value parsed in an error message, if any.
63 *
64 * Returns NULL if successful, otherwise a malloc()'d string describing the
65 * error. The caller is responsible for freeing the returned string. */
66 char * OVS_WARN_UNUSED_RESULT
67 str_to_u16(const char *str, const char *name, uint16_t *valuep)
68 {
69 int value;
70
71 if (!str_to_int(str, 0, &value) || value < 0 || value > 65535) {
72 return xasprintf("invalid %s \"%s\"", name, str);
73 }
74 *valuep = value;
75 return NULL;
76 }
77
78 /* Parses 'str' as a 32-bit unsigned integer into '*valuep'.
79 *
80 * Returns NULL if successful, otherwise a malloc()'d string describing the
81 * error. The caller is responsible for freeing the returned string. */
82 char * OVS_WARN_UNUSED_RESULT
83 str_to_u32(const char *str, uint32_t *valuep)
84 {
85 char *tail;
86 uint32_t value;
87
88 if (!str[0]) {
89 return xstrdup("missing required numeric argument");
90 }
91
92 errno = 0;
93 value = strtoul(str, &tail, 0);
94 if (errno == EINVAL || errno == ERANGE || *tail) {
95 return xasprintf("invalid numeric format %s", str);
96 }
97 *valuep = value;
98 return NULL;
99 }
100
101 /* Parses 'str' as an 64-bit unsigned integer into '*valuep'.
102 *
103 * Returns NULL if successful, otherwise a malloc()'d string describing the
104 * error. The caller is responsible for freeing the returned string. */
105 char * OVS_WARN_UNUSED_RESULT
106 str_to_u64(const char *str, uint64_t *valuep)
107 {
108 char *tail;
109 uint64_t value;
110
111 if (!str[0]) {
112 return xstrdup("missing required numeric argument");
113 }
114
115 errno = 0;
116 value = strtoull(str, &tail, 0);
117 if (errno == EINVAL || errno == ERANGE || *tail) {
118 return xasprintf("invalid numeric format %s", str);
119 }
120 *valuep = value;
121 return NULL;
122 }
123
124 /* Parses 'str' as an 64-bit unsigned integer in network byte order into
125 * '*valuep'.
126 *
127 * Returns NULL if successful, otherwise a malloc()'d string describing the
128 * error. The caller is responsible for freeing the returned string. */
129 char * OVS_WARN_UNUSED_RESULT
130 str_to_be64(const char *str, ovs_be64 *valuep)
131 {
132 uint64_t value = 0;
133 char *error;
134
135 error = str_to_u64(str, &value);
136 if (!error) {
137 *valuep = htonll(value);
138 }
139 return error;
140 }
141
142 /* Parses 'str' as an Ethernet address into 'mac'.
143 *
144 * Returns NULL if successful, otherwise a malloc()'d string describing the
145 * error. The caller is responsible for freeing the returned string. */
146 char * OVS_WARN_UNUSED_RESULT
147 str_to_mac(const char *str, uint8_t mac[ETH_ADDR_LEN])
148 {
149 if (!ovs_scan(str, ETH_ADDR_SCAN_FMT, ETH_ADDR_SCAN_ARGS(mac))) {
150 return xasprintf("invalid mac address %s", str);
151 }
152 return NULL;
153 }
154
155 /* Parses 'str' as an IP address into '*ip'.
156 *
157 * Returns NULL if successful, otherwise a malloc()'d string describing the
158 * error. The caller is responsible for freeing the returned string. */
159 char * OVS_WARN_UNUSED_RESULT
160 str_to_ip(const char *str, ovs_be32 *ip)
161 {
162 struct in_addr in_addr;
163
164 if (lookup_ip(str, &in_addr)) {
165 return xasprintf("%s: could not convert to IP address", str);
166 }
167 *ip = in_addr.s_addr;
168 return NULL;
169 }
170
171 struct protocol {
172 const char *name;
173 uint16_t dl_type;
174 uint8_t nw_proto;
175 };
176
177 static bool
178 parse_protocol(const char *name, const struct protocol **p_out)
179 {
180 static const struct protocol protocols[] = {
181 { "ip", ETH_TYPE_IP, 0 },
182 { "arp", ETH_TYPE_ARP, 0 },
183 { "icmp", ETH_TYPE_IP, IPPROTO_ICMP },
184 { "tcp", ETH_TYPE_IP, IPPROTO_TCP },
185 { "udp", ETH_TYPE_IP, IPPROTO_UDP },
186 { "sctp", ETH_TYPE_IP, IPPROTO_SCTP },
187 { "ipv6", ETH_TYPE_IPV6, 0 },
188 { "ip6", ETH_TYPE_IPV6, 0 },
189 { "icmp6", ETH_TYPE_IPV6, IPPROTO_ICMPV6 },
190 { "tcp6", ETH_TYPE_IPV6, IPPROTO_TCP },
191 { "udp6", ETH_TYPE_IPV6, IPPROTO_UDP },
192 { "sctp6", ETH_TYPE_IPV6, IPPROTO_SCTP },
193 { "rarp", ETH_TYPE_RARP, 0},
194 { "mpls", ETH_TYPE_MPLS, 0 },
195 { "mplsm", ETH_TYPE_MPLS_MCAST, 0 },
196 };
197 const struct protocol *p;
198
199 for (p = protocols; p < &protocols[ARRAY_SIZE(protocols)]; p++) {
200 if (!strcmp(p->name, name)) {
201 *p_out = p;
202 return true;
203 }
204 }
205 *p_out = NULL;
206 return false;
207 }
208
209 /* Parses 's' as the (possibly masked) value of field 'mf', and updates
210 * 'match' appropriately. Restricts the set of usable protocols to ones
211 * supporting the parsed field.
212 *
213 * Returns NULL if successful, otherwise a malloc()'d string describing the
214 * error. The caller is responsible for freeing the returned string. */
215 static char * OVS_WARN_UNUSED_RESULT
216 parse_field(const struct mf_field *mf, const char *s, struct match *match,
217 enum ofputil_protocol *usable_protocols)
218 {
219 union mf_value value, mask;
220 char *error;
221
222 error = mf_parse(mf, s, &value, &mask);
223 if (!error) {
224 *usable_protocols &= mf_set(mf, &value, &mask, match);
225 }
226 return error;
227 }
228
229 static char *
230 extract_actions(char *s)
231 {
232 s = strstr(s, "action");
233 if (s) {
234 *s = '\0';
235 s = strchr(s + 1, '=');
236 return s ? s + 1 : NULL;
237 } else {
238 return NULL;
239 }
240 }
241
242
243 static char * OVS_WARN_UNUSED_RESULT
244 parse_ofp_str__(struct ofputil_flow_mod *fm, int command, char *string,
245 enum ofputil_protocol *usable_protocols)
246 {
247 enum {
248 F_OUT_PORT = 1 << 0,
249 F_ACTIONS = 1 << 1,
250 F_IMPORTANCE = 1 << 2,
251 F_TIMEOUT = 1 << 3,
252 F_PRIORITY = 1 << 4,
253 F_FLAGS = 1 << 5,
254 } fields;
255 char *save_ptr = NULL;
256 char *act_str = NULL;
257 char *name;
258
259 *usable_protocols = OFPUTIL_P_ANY;
260
261 if (command == -2) {
262 size_t len;
263
264 string += strspn(string, " \t\r\n"); /* Skip white space. */
265 len = strcspn(string, ", \t\r\n"); /* Get length of the first token. */
266
267 if (!strncmp(string, "add", len)) {
268 command = OFPFC_ADD;
269 } else if (!strncmp(string, "delete", len)) {
270 command = OFPFC_DELETE;
271 } else if (!strncmp(string, "delete_strict", len)) {
272 command = OFPFC_DELETE_STRICT;
273 } else if (!strncmp(string, "modify", len)) {
274 command = OFPFC_MODIFY;
275 } else if (!strncmp(string, "modify_strict", len)) {
276 command = OFPFC_MODIFY_STRICT;
277 } else {
278 len = 0;
279 command = OFPFC_ADD;
280 }
281 string += len;
282 }
283
284 switch (command) {
285 case -1:
286 fields = F_OUT_PORT;
287 break;
288
289 case OFPFC_ADD:
290 fields = F_ACTIONS | F_TIMEOUT | F_PRIORITY | F_FLAGS | F_IMPORTANCE;
291 break;
292
293 case OFPFC_DELETE:
294 fields = F_OUT_PORT;
295 break;
296
297 case OFPFC_DELETE_STRICT:
298 fields = F_OUT_PORT | F_PRIORITY;
299 break;
300
301 case OFPFC_MODIFY:
302 fields = F_ACTIONS | F_TIMEOUT | F_PRIORITY | F_FLAGS;
303 break;
304
305 case OFPFC_MODIFY_STRICT:
306 fields = F_ACTIONS | F_TIMEOUT | F_PRIORITY | F_FLAGS;
307 break;
308
309 default:
310 OVS_NOT_REACHED();
311 }
312
313 match_init_catchall(&fm->match);
314 fm->priority = OFP_DEFAULT_PRIORITY;
315 fm->cookie = htonll(0);
316 fm->cookie_mask = htonll(0);
317 if (command == OFPFC_MODIFY || command == OFPFC_MODIFY_STRICT) {
318 /* For modify, by default, don't update the cookie. */
319 fm->new_cookie = OVS_BE64_MAX;
320 } else{
321 fm->new_cookie = htonll(0);
322 }
323 fm->modify_cookie = false;
324 fm->table_id = 0xff;
325 fm->command = command;
326 fm->idle_timeout = OFP_FLOW_PERMANENT;
327 fm->hard_timeout = OFP_FLOW_PERMANENT;
328 fm->buffer_id = UINT32_MAX;
329 fm->out_port = OFPP_ANY;
330 fm->flags = 0;
331 fm->importance = 0;
332 fm->out_group = OFPG11_ANY;
333 fm->delete_reason = OFPRR_DELETE;
334 if (fields & F_ACTIONS) {
335 act_str = extract_actions(string);
336 if (!act_str) {
337 return xstrdup("must specify an action");
338 }
339 }
340 for (name = strtok_r(string, "=, \t\r\n", &save_ptr); name;
341 name = strtok_r(NULL, "=, \t\r\n", &save_ptr)) {
342 const struct protocol *p;
343 char *error = NULL;
344
345 if (parse_protocol(name, &p)) {
346 match_set_dl_type(&fm->match, htons(p->dl_type));
347 if (p->nw_proto) {
348 match_set_nw_proto(&fm->match, p->nw_proto);
349 }
350 } else if (fields & F_FLAGS && !strcmp(name, "send_flow_rem")) {
351 fm->flags |= OFPUTIL_FF_SEND_FLOW_REM;
352 } else if (fields & F_FLAGS && !strcmp(name, "check_overlap")) {
353 fm->flags |= OFPUTIL_FF_CHECK_OVERLAP;
354 } else if (fields & F_FLAGS && !strcmp(name, "reset_counts")) {
355 fm->flags |= OFPUTIL_FF_RESET_COUNTS;
356 *usable_protocols &= OFPUTIL_P_OF12_UP;
357 } else if (fields & F_FLAGS && !strcmp(name, "no_packet_counts")) {
358 fm->flags |= OFPUTIL_FF_NO_PKT_COUNTS;
359 *usable_protocols &= OFPUTIL_P_OF13_UP;
360 } else if (fields & F_FLAGS && !strcmp(name, "no_byte_counts")) {
361 fm->flags |= OFPUTIL_FF_NO_BYT_COUNTS;
362 *usable_protocols &= OFPUTIL_P_OF13_UP;
363 } else if (!strcmp(name, "no_readonly_table")
364 || !strcmp(name, "allow_hidden_fields")) {
365 /* ignore these fields. */
366 } else {
367 char *value;
368
369 value = strtok_r(NULL, ", \t\r\n", &save_ptr);
370 if (!value) {
371 return xasprintf("field %s missing value", name);
372 }
373
374 if (!strcmp(name, "table")) {
375 error = str_to_u8(value, "table", &fm->table_id);
376 if (fm->table_id != 0xff) {
377 *usable_protocols &= OFPUTIL_P_TID;
378 }
379 } else if (fields & F_OUT_PORT && !strcmp(name, "out_port")) {
380 if (!ofputil_port_from_string(value, &fm->out_port)) {
381 error = xasprintf("%s is not a valid OpenFlow port",
382 value);
383 }
384 } else if (fields & F_PRIORITY && !strcmp(name, "priority")) {
385 uint16_t priority = 0;
386
387 error = str_to_u16(value, name, &priority);
388 fm->priority = priority;
389 } else if (fields & F_TIMEOUT && !strcmp(name, "idle_timeout")) {
390 error = str_to_u16(value, name, &fm->idle_timeout);
391 } else if (fields & F_TIMEOUT && !strcmp(name, "hard_timeout")) {
392 error = str_to_u16(value, name, &fm->hard_timeout);
393 } else if (fields & F_IMPORTANCE && !strcmp(name, "importance")) {
394 error = str_to_u16(value, name, &fm->importance);
395 } else if (!strcmp(name, "cookie")) {
396 char *mask = strchr(value, '/');
397
398 if (mask) {
399 /* A mask means we're searching for a cookie. */
400 if (command == OFPFC_ADD) {
401 return xstrdup("flow additions cannot use "
402 "a cookie mask");
403 }
404 *mask = '\0';
405 error = str_to_be64(value, &fm->cookie);
406 if (error) {
407 return error;
408 }
409 error = str_to_be64(mask + 1, &fm->cookie_mask);
410
411 /* Matching of the cookie is only supported through NXM or
412 * OF1.1+. */
413 if (fm->cookie_mask != htonll(0)) {
414 *usable_protocols &= OFPUTIL_P_NXM_OF11_UP;
415 }
416 } else {
417 /* No mask means that the cookie is being set. */
418 if (command != OFPFC_ADD && command != OFPFC_MODIFY
419 && command != OFPFC_MODIFY_STRICT) {
420 return xstrdup("cannot set cookie");
421 }
422 error = str_to_be64(value, &fm->new_cookie);
423 fm->modify_cookie = true;
424 }
425 } else if (mf_from_name(name)) {
426 error = parse_field(mf_from_name(name), value, &fm->match,
427 usable_protocols);
428 } else if (!strcmp(name, "duration")
429 || !strcmp(name, "n_packets")
430 || !strcmp(name, "n_bytes")
431 || !strcmp(name, "idle_age")
432 || !strcmp(name, "hard_age")) {
433 /* Ignore these, so that users can feed the output of
434 * "ovs-ofctl dump-flows" back into commands that parse
435 * flows. */
436 } else {
437 error = xasprintf("unknown keyword %s", name);
438 }
439
440 if (error) {
441 return error;
442 }
443 }
444 }
445 /* Check for usable protocol interdependencies between match fields. */
446 if (fm->match.flow.dl_type == htons(ETH_TYPE_IPV6)) {
447 const struct flow_wildcards *wc = &fm->match.wc;
448 /* Only NXM and OXM support matching L3 and L4 fields within IPv6.
449 *
450 * (IPv6 specific fields as well as arp_sha, arp_tha, nw_frag, and
451 * nw_ttl are covered elsewhere so they don't need to be included in
452 * this test too.)
453 */
454 if (wc->masks.nw_proto || wc->masks.nw_tos
455 || wc->masks.tp_src || wc->masks.tp_dst) {
456 *usable_protocols &= OFPUTIL_P_NXM_OXM_ANY;
457 }
458 }
459 if (!fm->cookie_mask && fm->new_cookie == OVS_BE64_MAX
460 && (command == OFPFC_MODIFY || command == OFPFC_MODIFY_STRICT)) {
461 /* On modifies without a mask, we are supposed to add a flow if
462 * one does not exist. If a cookie wasn't been specified, use a
463 * default of zero. */
464 fm->new_cookie = htonll(0);
465 }
466 if (fields & F_ACTIONS) {
467 enum ofputil_protocol action_usable_protocols;
468 struct ofpbuf ofpacts;
469 char *error;
470
471 ofpbuf_init(&ofpacts, 32);
472 error = ofpacts_parse_instructions(act_str, &ofpacts,
473 &action_usable_protocols);
474 *usable_protocols &= action_usable_protocols;
475 if (!error) {
476 enum ofperr err;
477
478 err = ofpacts_check(ofpacts.data, ofpacts.size, &fm->match.flow,
479 OFPP_MAX, fm->table_id, 255, usable_protocols);
480 if (!err && !usable_protocols) {
481 err = OFPERR_OFPBAC_MATCH_INCONSISTENT;
482 }
483 if (err) {
484 error = xasprintf("actions are invalid with specified match "
485 "(%s)", ofperr_to_string(err));
486 }
487
488 }
489 if (error) {
490 ofpbuf_uninit(&ofpacts);
491 return error;
492 }
493
494 fm->ofpacts_len = ofpacts.size;
495 fm->ofpacts = ofpbuf_steal_data(&ofpacts);
496 } else {
497 fm->ofpacts_len = 0;
498 fm->ofpacts = NULL;
499 }
500
501 return NULL;
502 }
503
504 /* Convert 'str_' (as described in the Flow Syntax section of the ovs-ofctl man
505 * page) into 'fm' for sending the specified flow_mod 'command' to a switch.
506 * Returns the set of usable protocols in '*usable_protocols'.
507 *
508 * To parse syntax for an OFPT_FLOW_MOD (or NXT_FLOW_MOD), use an OFPFC_*
509 * constant for 'command'. To parse syntax for an OFPST_FLOW or
510 * OFPST_AGGREGATE (or NXST_FLOW or NXST_AGGREGATE), use -1 for 'command'.
511 *
512 * If 'command' is given as -2, 'str_' may begin with a command name ("add",
513 * "modify", "delete", "modify_strict", or "delete_strict"). A missing command
514 * name is treated as "add".
515 *
516 * Returns NULL if successful, otherwise a malloc()'d string describing the
517 * error. The caller is responsible for freeing the returned string. */
518 char * OVS_WARN_UNUSED_RESULT
519 parse_ofp_str(struct ofputil_flow_mod *fm, int command, const char *str_,
520 enum ofputil_protocol *usable_protocols)
521 {
522 char *string = xstrdup(str_);
523 char *error;
524
525 error = parse_ofp_str__(fm, command, string, usable_protocols);
526 if (error) {
527 fm->ofpacts = NULL;
528 fm->ofpacts_len = 0;
529 }
530
531 free(string);
532 return error;
533 }
534
535 static char * OVS_WARN_UNUSED_RESULT
536 parse_ofp_meter_mod_str__(struct ofputil_meter_mod *mm, char *string,
537 struct ofpbuf *bands, int command,
538 enum ofputil_protocol *usable_protocols)
539 {
540 enum {
541 F_METER = 1 << 0,
542 F_FLAGS = 1 << 1,
543 F_BANDS = 1 << 2,
544 } fields;
545 char *save_ptr = NULL;
546 char *band_str = NULL;
547 char *name;
548
549 /* Meters require at least OF 1.3. */
550 *usable_protocols = OFPUTIL_P_OF13_UP;
551
552 switch (command) {
553 case -1:
554 fields = F_METER;
555 break;
556
557 case OFPMC13_ADD:
558 fields = F_METER | F_FLAGS | F_BANDS;
559 break;
560
561 case OFPMC13_DELETE:
562 fields = F_METER;
563 break;
564
565 case OFPMC13_MODIFY:
566 fields = F_METER | F_FLAGS | F_BANDS;
567 break;
568
569 default:
570 OVS_NOT_REACHED();
571 }
572
573 mm->command = command;
574 mm->meter.meter_id = 0;
575 mm->meter.flags = 0;
576 if (fields & F_BANDS) {
577 band_str = strstr(string, "band");
578 if (!band_str) {
579 return xstrdup("must specify bands");
580 }
581 *band_str = '\0';
582
583 band_str = strchr(band_str + 1, '=');
584 if (!band_str) {
585 return xstrdup("must specify bands");
586 }
587
588 band_str++;
589 }
590 for (name = strtok_r(string, "=, \t\r\n", &save_ptr); name;
591 name = strtok_r(NULL, "=, \t\r\n", &save_ptr)) {
592
593 if (fields & F_FLAGS && !strcmp(name, "kbps")) {
594 mm->meter.flags |= OFPMF13_KBPS;
595 } else if (fields & F_FLAGS && !strcmp(name, "pktps")) {
596 mm->meter.flags |= OFPMF13_PKTPS;
597 } else if (fields & F_FLAGS && !strcmp(name, "burst")) {
598 mm->meter.flags |= OFPMF13_BURST;
599 } else if (fields & F_FLAGS && !strcmp(name, "stats")) {
600 mm->meter.flags |= OFPMF13_STATS;
601 } else {
602 char *value;
603
604 value = strtok_r(NULL, ", \t\r\n", &save_ptr);
605 if (!value) {
606 return xasprintf("field %s missing value", name);
607 }
608
609 if (!strcmp(name, "meter")) {
610 if (!strcmp(value, "all")) {
611 mm->meter.meter_id = OFPM13_ALL;
612 } else if (!strcmp(value, "controller")) {
613 mm->meter.meter_id = OFPM13_CONTROLLER;
614 } else if (!strcmp(value, "slowpath")) {
615 mm->meter.meter_id = OFPM13_SLOWPATH;
616 } else {
617 char *error = str_to_u32(value, &mm->meter.meter_id);
618 if (error) {
619 return error;
620 }
621 if (mm->meter.meter_id > OFPM13_MAX
622 || !mm->meter.meter_id) {
623 return xasprintf("invalid value for %s", name);
624 }
625 }
626 } else {
627 return xasprintf("unknown keyword %s", name);
628 }
629 }
630 }
631 if (fields & F_METER && !mm->meter.meter_id) {
632 return xstrdup("must specify 'meter'");
633 }
634 if (fields & F_FLAGS && !mm->meter.flags) {
635 return xstrdup("meter must specify either 'kbps' or 'pktps'");
636 }
637
638 if (fields & F_BANDS) {
639 uint16_t n_bands = 0;
640 struct ofputil_meter_band *band = NULL;
641 int i;
642
643 for (name = strtok_r(band_str, "=, \t\r\n", &save_ptr); name;
644 name = strtok_r(NULL, "=, \t\r\n", &save_ptr)) {
645
646 char *value;
647
648 value = strtok_r(NULL, ", \t\r\n", &save_ptr);
649 if (!value) {
650 return xasprintf("field %s missing value", name);
651 }
652
653 if (!strcmp(name, "type")) {
654 /* Start a new band */
655 band = ofpbuf_put_zeros(bands, sizeof *band);
656 n_bands++;
657
658 if (!strcmp(value, "drop")) {
659 band->type = OFPMBT13_DROP;
660 } else if (!strcmp(value, "dscp_remark")) {
661 band->type = OFPMBT13_DSCP_REMARK;
662 } else {
663 return xasprintf("field %s unknown value %s", name, value);
664 }
665 } else if (!band || !band->type) {
666 return xstrdup("band must start with the 'type' keyword");
667 } else if (!strcmp(name, "rate")) {
668 char *error = str_to_u32(value, &band->rate);
669 if (error) {
670 return error;
671 }
672 } else if (!strcmp(name, "burst_size")) {
673 char *error = str_to_u32(value, &band->burst_size);
674 if (error) {
675 return error;
676 }
677 } else if (!strcmp(name, "prec_level")) {
678 char *error = str_to_u8(value, name, &band->prec_level);
679 if (error) {
680 return error;
681 }
682 } else {
683 return xasprintf("unknown keyword %s", name);
684 }
685 }
686 /* validate bands */
687 if (!n_bands) {
688 return xstrdup("meter must have bands");
689 }
690
691 mm->meter.n_bands = n_bands;
692 mm->meter.bands = ofpbuf_steal_data(bands);
693
694 for (i = 0; i < n_bands; ++i) {
695 band = &mm->meter.bands[i];
696
697 if (!band->type) {
698 return xstrdup("band must have 'type'");
699 }
700 if (band->type == OFPMBT13_DSCP_REMARK) {
701 if (!band->prec_level) {
702 return xstrdup("'dscp_remark' band must have"
703 " 'prec_level'");
704 }
705 } else {
706 if (band->prec_level) {
707 return xstrdup("Only 'dscp_remark' band may have"
708 " 'prec_level'");
709 }
710 }
711 if (!band->rate) {
712 return xstrdup("band must have 'rate'");
713 }
714 if (mm->meter.flags & OFPMF13_BURST) {
715 if (!band->burst_size) {
716 return xstrdup("band must have 'burst_size' "
717 "when 'burst' flag is set");
718 }
719 } else {
720 if (band->burst_size) {
721 return xstrdup("band may have 'burst_size' only "
722 "when 'burst' flag is set");
723 }
724 }
725 }
726 } else {
727 mm->meter.n_bands = 0;
728 mm->meter.bands = NULL;
729 }
730
731 return NULL;
732 }
733
734 /* Convert 'str_' (as described in the Flow Syntax section of the ovs-ofctl man
735 * page) into 'mm' for sending the specified meter_mod 'command' to a switch.
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_meter_mod_str(struct ofputil_meter_mod *mm, const char *str_,
741 int command, enum ofputil_protocol *usable_protocols)
742 {
743 struct ofpbuf bands;
744 char *string;
745 char *error;
746
747 ofpbuf_init(&bands, 64);
748 string = xstrdup(str_);
749
750 error = parse_ofp_meter_mod_str__(mm, string, &bands, command,
751 usable_protocols);
752
753 free(string);
754 ofpbuf_uninit(&bands);
755
756 return error;
757 }
758
759 static char * OVS_WARN_UNUSED_RESULT
760 parse_flow_monitor_request__(struct ofputil_flow_monitor_request *fmr,
761 const char *str_, char *string,
762 enum ofputil_protocol *usable_protocols)
763 {
764 static atomic_count id = ATOMIC_COUNT_INIT(0);
765 char *save_ptr = NULL;
766 char *name;
767
768 fmr->id = atomic_count_inc(&id);
769
770 fmr->flags = (NXFMF_INITIAL | NXFMF_ADD | NXFMF_DELETE | NXFMF_MODIFY
771 | NXFMF_OWN | NXFMF_ACTIONS);
772 fmr->out_port = OFPP_NONE;
773 fmr->table_id = 0xff;
774 match_init_catchall(&fmr->match);
775
776 for (name = strtok_r(string, "=, \t\r\n", &save_ptr); name;
777 name = strtok_r(NULL, "=, \t\r\n", &save_ptr)) {
778 const struct protocol *p;
779
780 if (!strcmp(name, "!initial")) {
781 fmr->flags &= ~NXFMF_INITIAL;
782 } else if (!strcmp(name, "!add")) {
783 fmr->flags &= ~NXFMF_ADD;
784 } else if (!strcmp(name, "!delete")) {
785 fmr->flags &= ~NXFMF_DELETE;
786 } else if (!strcmp(name, "!modify")) {
787 fmr->flags &= ~NXFMF_MODIFY;
788 } else if (!strcmp(name, "!actions")) {
789 fmr->flags &= ~NXFMF_ACTIONS;
790 } else if (!strcmp(name, "!own")) {
791 fmr->flags &= ~NXFMF_OWN;
792 } else if (parse_protocol(name, &p)) {
793 match_set_dl_type(&fmr->match, htons(p->dl_type));
794 if (p->nw_proto) {
795 match_set_nw_proto(&fmr->match, p->nw_proto);
796 }
797 } else {
798 char *value;
799
800 value = strtok_r(NULL, ", \t\r\n", &save_ptr);
801 if (!value) {
802 return xasprintf("%s: field %s missing value", str_, name);
803 }
804
805 if (!strcmp(name, "table")) {
806 char *error = str_to_u8(value, "table", &fmr->table_id);
807 if (error) {
808 return error;
809 }
810 } else if (!strcmp(name, "out_port")) {
811 fmr->out_port = u16_to_ofp(atoi(value));
812 } else if (mf_from_name(name)) {
813 char *error;
814
815 error = parse_field(mf_from_name(name), value, &fmr->match,
816 usable_protocols);
817 if (error) {
818 return error;
819 }
820 } else {
821 return xasprintf("%s: unknown keyword %s", str_, name);
822 }
823 }
824 }
825 return NULL;
826 }
827
828 /* Convert 'str_' (as described in the documentation for the "monitor" command
829 * in the ovs-ofctl man page) into 'fmr'.
830 *
831 * Returns NULL if successful, otherwise a malloc()'d string describing the
832 * error. The caller is responsible for freeing the returned string. */
833 char * OVS_WARN_UNUSED_RESULT
834 parse_flow_monitor_request(struct ofputil_flow_monitor_request *fmr,
835 const char *str_,
836 enum ofputil_protocol *usable_protocols)
837 {
838 char *string = xstrdup(str_);
839 char *error = parse_flow_monitor_request__(fmr, str_, string,
840 usable_protocols);
841 free(string);
842 return error;
843 }
844
845 /* Parses 'string' as an OFPT_FLOW_MOD or NXT_FLOW_MOD with command 'command'
846 * (one of OFPFC_*) into 'fm'.
847 *
848 * If 'command' is given as -2, 'string' may begin with a command name ("add",
849 * "modify", "delete", "modify_strict", or "delete_strict"). A missing command
850 * name is treated as "add".
851 *
852 * Returns NULL if successful, otherwise a malloc()'d string describing the
853 * error. The caller is responsible for freeing the returned string. */
854 char * OVS_WARN_UNUSED_RESULT
855 parse_ofp_flow_mod_str(struct ofputil_flow_mod *fm, const char *string,
856 int command,
857 enum ofputil_protocol *usable_protocols)
858 {
859 char *error = parse_ofp_str(fm, command, string, usable_protocols);
860
861 if (!error) {
862 /* Normalize a copy of the match. This ensures that non-normalized
863 * flows get logged but doesn't affect what gets sent to the switch, so
864 * that the switch can do whatever it likes with the flow. */
865 struct match match_copy = fm->match;
866 ofputil_normalize_match(&match_copy);
867 }
868
869 return error;
870 }
871
872 /* Convert 'table_id' and 'setting' (as described for the "mod-table" command
873 * in the ovs-ofctl man page) into 'tm' for sending a table_mod command to a
874 * switch.
875 *
876 * Stores a bitmap of the OpenFlow versions that are usable for 'tm' into
877 * '*usable_versions'.
878 *
879 * Returns NULL if successful, otherwise a malloc()'d string describing the
880 * error. The caller is responsible for freeing the returned string. */
881 char * OVS_WARN_UNUSED_RESULT
882 parse_ofp_table_mod(struct ofputil_table_mod *tm, const char *table_id,
883 const char *setting, uint32_t *usable_versions)
884 {
885 *usable_versions = 0;
886 if (!strcasecmp(table_id, "all")) {
887 tm->table_id = OFPTT_ALL;
888 } else {
889 char *error = str_to_u8(table_id, "table_id", &tm->table_id);
890 if (error) {
891 return error;
892 }
893 }
894
895 tm->miss = OFPUTIL_TABLE_MISS_DEFAULT;
896 tm->eviction = OFPUTIL_TABLE_EVICTION_DEFAULT;
897 tm->eviction_flags = UINT32_MAX;
898
899 /* Only OpenFlow 1.1 and 1.2 can configure table-miss via table_mod.
900 * Only OpenFlow 1.4+ can configure eviction via table_mod.
901 *
902 * (OpenFlow 1.4+ can also configure vacancy events via table_mod, but OVS
903 * doesn't support those yet and they're also logically a per-OpenFlow
904 * session setting so it wouldn't make sense to support them here anyway.)
905 */
906 if (!strcmp(setting, "controller")) {
907 tm->miss = OFPUTIL_TABLE_MISS_CONTROLLER;
908 *usable_versions = (1u << OFP11_VERSION) | (1u << OFP12_VERSION);
909 } else if (!strcmp(setting, "continue")) {
910 tm->miss = OFPUTIL_TABLE_MISS_CONTINUE;
911 *usable_versions = (1u << OFP11_VERSION) | (1u << OFP12_VERSION);
912 } else if (!strcmp(setting, "drop")) {
913 tm->miss = OFPUTIL_TABLE_MISS_DROP;
914 *usable_versions = (1u << OFP11_VERSION) | (1u << OFP12_VERSION);
915 } else if (!strcmp(setting, "evict")) {
916 tm->eviction = OFPUTIL_TABLE_EVICTION_ON;
917 *usable_versions = (1 << OFP14_VERSION) | (1u << OFP15_VERSION);
918 } else if (!strcmp(setting, "noevict")) {
919 tm->eviction = OFPUTIL_TABLE_EVICTION_OFF;
920 *usable_versions = (1 << OFP14_VERSION) | (1u << OFP15_VERSION);
921 } else {
922 return xasprintf("invalid table_mod setting %s", setting);
923 }
924
925 if (tm->table_id == 0xfe
926 && tm->miss == OFPUTIL_TABLE_MISS_CONTINUE) {
927 return xstrdup("last table's flow miss handling can not be continue");
928 }
929
930 return NULL;
931 }
932
933
934 /* Opens file 'file_name' and reads each line as a flow_mod of the specified
935 * type (one of OFPFC_*). Stores each flow_mod in '*fm', an array allocated
936 * on the caller's behalf, and the number of flow_mods in '*n_fms'.
937 *
938 * If 'command' is given as -2, each line may start with a command name
939 * ("add", "modify", "delete", "modify_strict", or "delete_strict"). A missing
940 * command name is treated as "add".
941 *
942 * Returns NULL if successful, otherwise a malloc()'d string describing the
943 * error. The caller is responsible for freeing the returned string. */
944 char * OVS_WARN_UNUSED_RESULT
945 parse_ofp_flow_mod_file(const char *file_name, int command,
946 struct ofputil_flow_mod **fms, size_t *n_fms,
947 enum ofputil_protocol *usable_protocols)
948 {
949 size_t allocated_fms;
950 int line_number;
951 FILE *stream;
952 struct ds s;
953
954 *usable_protocols = OFPUTIL_P_ANY;
955
956 *fms = NULL;
957 *n_fms = 0;
958
959 stream = !strcmp(file_name, "-") ? stdin : fopen(file_name, "r");
960 if (stream == NULL) {
961 return xasprintf("%s: open failed (%s)",
962 file_name, ovs_strerror(errno));
963 }
964
965 allocated_fms = *n_fms;
966 ds_init(&s);
967 line_number = 0;
968 while (!ds_get_preprocessed_line(&s, stream, &line_number)) {
969 char *error;
970 enum ofputil_protocol usable;
971
972 if (*n_fms >= allocated_fms) {
973 *fms = x2nrealloc(*fms, &allocated_fms, sizeof **fms);
974 }
975 error = parse_ofp_flow_mod_str(&(*fms)[*n_fms], ds_cstr(&s), command,
976 &usable);
977 if (error) {
978 size_t i;
979
980 for (i = 0; i < *n_fms; i++) {
981 free(CONST_CAST(struct ofpact *, (*fms)[i].ofpacts));
982 }
983 free(*fms);
984 *fms = NULL;
985 *n_fms = 0;
986
987 ds_destroy(&s);
988 if (stream != stdin) {
989 fclose(stream);
990 }
991
992 return xasprintf("%s:%d: %s", file_name, line_number, error);
993 }
994 *usable_protocols &= usable; /* Each line can narrow the set. */
995 *n_fms += 1;
996 }
997
998 ds_destroy(&s);
999 if (stream != stdin) {
1000 fclose(stream);
1001 }
1002 return NULL;
1003 }
1004
1005 char * OVS_WARN_UNUSED_RESULT
1006 parse_ofp_flow_stats_request_str(struct ofputil_flow_stats_request *fsr,
1007 bool aggregate, const char *string,
1008 enum ofputil_protocol *usable_protocols)
1009 {
1010 struct ofputil_flow_mod fm;
1011 char *error;
1012
1013 error = parse_ofp_str(&fm, -1, string, usable_protocols);
1014 if (error) {
1015 return error;
1016 }
1017
1018 /* Special table ID support not required for stats requests. */
1019 if (*usable_protocols & OFPUTIL_P_OF10_STD_TID) {
1020 *usable_protocols |= OFPUTIL_P_OF10_STD;
1021 }
1022 if (*usable_protocols & OFPUTIL_P_OF10_NXM_TID) {
1023 *usable_protocols |= OFPUTIL_P_OF10_NXM;
1024 }
1025
1026 fsr->aggregate = aggregate;
1027 fsr->cookie = fm.cookie;
1028 fsr->cookie_mask = fm.cookie_mask;
1029 fsr->match = fm.match;
1030 fsr->out_port = fm.out_port;
1031 fsr->out_group = fm.out_group;
1032 fsr->table_id = fm.table_id;
1033 return NULL;
1034 }
1035
1036 /* Parses a specification of a flow from 's' into 'flow'. 's' must take the
1037 * form FIELD=VALUE[,FIELD=VALUE]... where each FIELD is the name of a
1038 * mf_field. Fields must be specified in a natural order for satisfying
1039 * prerequisites. If 'mask' is specified, fills the mask field for each of the
1040 * field specified in flow. If the map, 'names_portno' is specfied, converts
1041 * the in_port name into port no while setting the 'flow'.
1042 *
1043 * Returns NULL on success, otherwise a malloc()'d string that explains the
1044 * problem. */
1045 char *
1046 parse_ofp_exact_flow(struct flow *flow, struct flow *mask, const char *s,
1047 const struct simap *portno_names)
1048 {
1049 char *pos, *key, *value_s;
1050 char *error = NULL;
1051 char *copy;
1052
1053 memset(flow, 0, sizeof *flow);
1054 if (mask) {
1055 memset(mask, 0, sizeof *mask);
1056 }
1057
1058 pos = copy = xstrdup(s);
1059 while (ofputil_parse_key_value(&pos, &key, &value_s)) {
1060 const struct protocol *p;
1061 if (parse_protocol(key, &p)) {
1062 if (flow->dl_type) {
1063 error = xasprintf("%s: Ethernet type set multiple times", s);
1064 goto exit;
1065 }
1066 flow->dl_type = htons(p->dl_type);
1067 if (mask) {
1068 mask->dl_type = OVS_BE16_MAX;
1069 }
1070
1071 if (p->nw_proto) {
1072 if (flow->nw_proto) {
1073 error = xasprintf("%s: network protocol set "
1074 "multiple times", s);
1075 goto exit;
1076 }
1077 flow->nw_proto = p->nw_proto;
1078 if (mask) {
1079 mask->nw_proto = UINT8_MAX;
1080 }
1081 }
1082 } else {
1083 const struct mf_field *mf;
1084 union mf_value value;
1085 char *field_error;
1086
1087 mf = mf_from_name(key);
1088 if (!mf) {
1089 error = xasprintf("%s: unknown field %s", s, key);
1090 goto exit;
1091 }
1092
1093 if (!mf_are_prereqs_ok(mf, flow)) {
1094 error = xasprintf("%s: prerequisites not met for setting %s",
1095 s, key);
1096 goto exit;
1097 }
1098
1099 if (!mf_is_zero(mf, flow)) {
1100 error = xasprintf("%s: field %s set multiple times", s, key);
1101 goto exit;
1102 }
1103
1104 if (!strcmp(key, "in_port")
1105 && portno_names
1106 && simap_contains(portno_names, value_s)) {
1107 flow->in_port.ofp_port = u16_to_ofp(
1108 simap_get(portno_names, value_s));
1109 if (mask) {
1110 mask->in_port.ofp_port = u16_to_ofp(ntohs(OVS_BE16_MAX));
1111 }
1112 } else {
1113 field_error = mf_parse_value(mf, value_s, &value);
1114 if (field_error) {
1115 error = xasprintf("%s: bad value for %s (%s)",
1116 s, key, field_error);
1117 free(field_error);
1118 goto exit;
1119 }
1120
1121 mf_set_flow_value(mf, &value, flow);
1122 if (mask) {
1123 mf_mask_field(mf, mask);
1124 }
1125 }
1126 }
1127 }
1128
1129 if (!flow->in_port.ofp_port) {
1130 flow->in_port.ofp_port = OFPP_NONE;
1131 }
1132
1133 exit:
1134 free(copy);
1135
1136 if (error) {
1137 memset(flow, 0, sizeof *flow);
1138 if (mask) {
1139 memset(mask, 0, sizeof *mask);
1140 }
1141 }
1142 return error;
1143 }
1144
1145 static char * OVS_WARN_UNUSED_RESULT
1146 parse_bucket_str(struct ofputil_bucket *bucket, char *str_,
1147 enum ofputil_protocol *usable_protocols)
1148 {
1149 char *pos, *key, *value;
1150 struct ofpbuf ofpacts;
1151 struct ds actions;
1152 char *error;
1153
1154 bucket->weight = 1;
1155 bucket->bucket_id = OFPG15_BUCKET_ALL;
1156 bucket->watch_port = OFPP_ANY;
1157 bucket->watch_group = OFPG11_ANY;
1158
1159 ds_init(&actions);
1160
1161 pos = str_;
1162 error = NULL;
1163 while (ofputil_parse_key_value(&pos, &key, &value)) {
1164 if (!strcasecmp(key, "weight")) {
1165 error = str_to_u16(value, "weight", &bucket->weight);
1166 } else if (!strcasecmp(key, "watch_port")) {
1167 if (!ofputil_port_from_string(value, &bucket->watch_port)
1168 || (ofp_to_u16(bucket->watch_port) >= ofp_to_u16(OFPP_MAX)
1169 && bucket->watch_port != OFPP_ANY)) {
1170 error = xasprintf("%s: invalid watch_port", value);
1171 }
1172 } else if (!strcasecmp(key, "watch_group")) {
1173 error = str_to_u32(value, &bucket->watch_group);
1174 if (!error && bucket->watch_group > OFPG_MAX) {
1175 error = xasprintf("invalid watch_group id %"PRIu32,
1176 bucket->watch_group);
1177 }
1178 } else if (!strcasecmp(key, "bucket_id")) {
1179 error = str_to_u32(value, &bucket->bucket_id);
1180 if (!error && bucket->bucket_id > OFPG15_BUCKET_MAX) {
1181 error = xasprintf("invalid bucket_id id %"PRIu32,
1182 bucket->bucket_id);
1183 }
1184 *usable_protocols &= OFPUTIL_P_OF15_UP;
1185 } else if (!strcasecmp(key, "action") || !strcasecmp(key, "actions")) {
1186 ds_put_format(&actions, "%s,", value);
1187 } else {
1188 ds_put_format(&actions, "%s(%s),", key, value);
1189 }
1190
1191 if (error) {
1192 ds_destroy(&actions);
1193 return error;
1194 }
1195 }
1196
1197 if (!actions.length) {
1198 return xstrdup("bucket must specify actions");
1199 }
1200 ds_chomp(&actions, ',');
1201
1202 ofpbuf_init(&ofpacts, 0);
1203 error = ofpacts_parse_actions(ds_cstr(&actions), &ofpacts,
1204 usable_protocols);
1205 ds_destroy(&actions);
1206 if (error) {
1207 ofpbuf_uninit(&ofpacts);
1208 return error;
1209 }
1210 bucket->ofpacts = ofpacts.data;
1211 bucket->ofpacts_len = ofpacts.size;
1212
1213 return NULL;
1214 }
1215
1216 static char * OVS_WARN_UNUSED_RESULT
1217 parse_select_group_field(char *s, struct field_array *fa,
1218 enum ofputil_protocol *usable_protocols)
1219 {
1220 char *save_ptr = NULL;
1221 char *name;
1222
1223 for (name = strtok_r(s, "=, \t\r\n", &save_ptr); name;
1224 name = strtok_r(NULL, "=, \t\r\n", &save_ptr)) {
1225 const struct mf_field *mf = mf_from_name(name);
1226
1227 if (mf) {
1228 char *error;
1229 const char *value_str;
1230 union mf_value value;
1231
1232 if (bitmap_is_set(fa->used.bm, mf->id)) {
1233 return xasprintf("%s: duplicate field", name);
1234 }
1235
1236 value_str = strtok_r(NULL, ", \t\r\n", &save_ptr);
1237 if (value_str) {
1238 error = mf_parse_value(mf, value_str, &value);
1239 if (error) {
1240 return error;
1241 }
1242
1243 /* The mask cannot be all-zeros */
1244 if (is_all_zeros(&value, mf->n_bytes)) {
1245 return xasprintf("%s: values are wildcards here "
1246 "and must not be all-zeros", s);
1247 }
1248
1249 /* The values parsed are masks for fields used
1250 * by the selection method */
1251 if (!mf_is_mask_valid(mf, &value)) {
1252 return xasprintf("%s: invalid mask for field %s",
1253 value_str, mf->name);
1254 }
1255 } else {
1256 memset(&value, 0xff, mf->n_bytes);
1257 }
1258
1259 field_array_set(mf->id, &value, fa);
1260
1261 if (is_all_ones(&value, mf->n_bytes)) {
1262 *usable_protocols &= mf->usable_protocols_exact;
1263 } else if (mf->usable_protocols_bitwise == mf->usable_protocols_cidr
1264 || ip_is_cidr(value.be32)) {
1265 *usable_protocols &= mf->usable_protocols_cidr;
1266 } else {
1267 *usable_protocols &= mf->usable_protocols_bitwise;
1268 }
1269 } else {
1270 return xasprintf("%s: unknown field %s", s, name);
1271 }
1272 }
1273
1274 return NULL;
1275 }
1276
1277 static char * OVS_WARN_UNUSED_RESULT
1278 parse_ofp_group_mod_str__(struct ofputil_group_mod *gm, uint16_t command,
1279 char *string,
1280 enum ofputil_protocol *usable_protocols)
1281 {
1282 enum {
1283 F_GROUP_TYPE = 1 << 0,
1284 F_BUCKETS = 1 << 1,
1285 F_COMMAND_BUCKET_ID = 1 << 2,
1286 F_COMMAND_BUCKET_ID_ALL = 1 << 3,
1287 } fields;
1288 char *save_ptr = NULL;
1289 bool had_type = false;
1290 bool had_command_bucket_id = false;
1291 char *name;
1292 struct ofputil_bucket *bucket;
1293 char *error = NULL;
1294
1295 *usable_protocols = OFPUTIL_P_OF11_UP;
1296
1297 switch (command) {
1298 case OFPGC11_ADD:
1299 fields = F_GROUP_TYPE | F_BUCKETS;
1300 break;
1301
1302 case OFPGC11_DELETE:
1303 fields = 0;
1304 break;
1305
1306 case OFPGC11_MODIFY:
1307 fields = F_GROUP_TYPE | F_BUCKETS;
1308 break;
1309
1310 case OFPGC15_INSERT_BUCKET:
1311 fields = F_BUCKETS | F_COMMAND_BUCKET_ID;
1312 *usable_protocols &= OFPUTIL_P_OF15_UP;
1313 break;
1314
1315 case OFPGC15_REMOVE_BUCKET:
1316 fields = F_COMMAND_BUCKET_ID | F_COMMAND_BUCKET_ID_ALL;
1317 *usable_protocols &= OFPUTIL_P_OF15_UP;
1318 break;
1319
1320 default:
1321 OVS_NOT_REACHED();
1322 }
1323
1324 memset(gm, 0, sizeof *gm);
1325 gm->command = command;
1326 gm->group_id = OFPG_ANY;
1327 gm->command_bucket_id = OFPG15_BUCKET_ALL;
1328 list_init(&gm->buckets);
1329 if (command == OFPGC11_DELETE && string[0] == '\0') {
1330 gm->group_id = OFPG_ALL;
1331 return NULL;
1332 }
1333
1334 *usable_protocols = OFPUTIL_P_OF11_UP;
1335
1336 if (fields & F_BUCKETS) {
1337 char *bkt_str = strstr(string, "bucket=");
1338
1339 if (bkt_str) {
1340 *bkt_str = '\0';
1341 }
1342
1343 while (bkt_str) {
1344 char *next_bkt_str;
1345
1346 bkt_str = strchr(bkt_str + 1, '=');
1347 if (!bkt_str) {
1348 error = xstrdup("must specify bucket content");
1349 goto out;
1350 }
1351 bkt_str++;
1352
1353 next_bkt_str = strstr(bkt_str, "bucket=");
1354 if (next_bkt_str) {
1355 *next_bkt_str = '\0';
1356 }
1357
1358 bucket = xzalloc(sizeof(struct ofputil_bucket));
1359 error = parse_bucket_str(bucket, bkt_str, usable_protocols);
1360 if (error) {
1361 free(bucket);
1362 goto out;
1363 }
1364 list_push_back(&gm->buckets, &bucket->list_node);
1365
1366 bkt_str = next_bkt_str;
1367 }
1368 }
1369
1370 for (name = strtok_r(string, "=, \t\r\n", &save_ptr); name;
1371 name = strtok_r(NULL, "=, \t\r\n", &save_ptr)) {
1372 char *value;
1373
1374 value = strtok_r(NULL, ", \t\r\n", &save_ptr);
1375 if (!value) {
1376 error = xasprintf("field %s missing value", name);
1377 goto out;
1378 }
1379
1380 if (!strcmp(name, "command_bucket_id")) {
1381 if (!(fields & F_COMMAND_BUCKET_ID)) {
1382 error = xstrdup("command bucket id is not needed");
1383 goto out;
1384 }
1385 if (!strcmp(value, "all")) {
1386 gm->command_bucket_id = OFPG15_BUCKET_ALL;
1387 } else if (!strcmp(value, "first")) {
1388 gm->command_bucket_id = OFPG15_BUCKET_FIRST;
1389 } else if (!strcmp(value, "last")) {
1390 gm->command_bucket_id = OFPG15_BUCKET_LAST;
1391 } else {
1392 error = str_to_u32(value, &gm->command_bucket_id);
1393 if (error) {
1394 goto out;
1395 }
1396 if (gm->command_bucket_id > OFPG15_BUCKET_MAX
1397 && (gm->command_bucket_id != OFPG15_BUCKET_FIRST
1398 && gm->command_bucket_id != OFPG15_BUCKET_LAST
1399 && gm->command_bucket_id != OFPG15_BUCKET_ALL)) {
1400 error = xasprintf("invalid command bucket id %"PRIu32,
1401 gm->command_bucket_id);
1402 goto out;
1403 }
1404 }
1405 if (gm->command_bucket_id == OFPG15_BUCKET_ALL
1406 && !(fields & F_COMMAND_BUCKET_ID_ALL)) {
1407 error = xstrdup("command_bucket_id=all is not permitted");
1408 goto out;
1409 }
1410 had_command_bucket_id = true;
1411 } else if (!strcmp(name, "group_id")) {
1412 if(!strcmp(value, "all")) {
1413 gm->group_id = OFPG_ALL;
1414 } else {
1415 error = str_to_u32(value, &gm->group_id);
1416 if (error) {
1417 goto out;
1418 }
1419 if (gm->group_id != OFPG_ALL && gm->group_id > OFPG_MAX) {
1420 error = xasprintf("invalid group id %"PRIu32,
1421 gm->group_id);
1422 goto out;
1423 }
1424 }
1425 } else if (!strcmp(name, "type")){
1426 if (!(fields & F_GROUP_TYPE)) {
1427 error = xstrdup("type is not needed");
1428 goto out;
1429 }
1430 if (!strcmp(value, "all")) {
1431 gm->type = OFPGT11_ALL;
1432 } else if (!strcmp(value, "select")) {
1433 gm->type = OFPGT11_SELECT;
1434 } else if (!strcmp(value, "indirect")) {
1435 gm->type = OFPGT11_INDIRECT;
1436 } else if (!strcmp(value, "ff") ||
1437 !strcmp(value, "fast_failover")) {
1438 gm->type = OFPGT11_FF;
1439 } else {
1440 error = xasprintf("invalid group type %s", value);
1441 goto out;
1442 }
1443 had_type = true;
1444 } else if (!strcmp(name, "bucket")) {
1445 error = xstrdup("bucket is not needed");
1446 goto out;
1447 } else if (!strcmp(name, "selection_method")) {
1448 if (!(fields & F_GROUP_TYPE)) {
1449 error = xstrdup("selection method is not needed");
1450 goto out;
1451 }
1452 if (strlen(value) >= NTR_MAX_SELECTION_METHOD_LEN) {
1453 error = xasprintf("selection method is longer than %u"
1454 " bytes long",
1455 NTR_MAX_SELECTION_METHOD_LEN - 1);
1456 goto out;
1457 }
1458 memset(gm->props.selection_method, '\0',
1459 NTR_MAX_SELECTION_METHOD_LEN);
1460 strcpy(gm->props.selection_method, value);
1461 *usable_protocols &= OFPUTIL_P_OF15_UP;
1462 } else if (!strcmp(name, "selection_method_param")) {
1463 if (!(fields & F_GROUP_TYPE)) {
1464 error = xstrdup("selection method param is not needed");
1465 goto out;
1466 }
1467 error = str_to_u64(value, &gm->props.selection_method_param);
1468 if (error) {
1469 goto out;
1470 }
1471 *usable_protocols &= OFPUTIL_P_OF15_UP;
1472 } else if (!strcmp(name, "fields")) {
1473 if (!(fields & F_GROUP_TYPE)) {
1474 error = xstrdup("fields are not needed");
1475 goto out;
1476 }
1477 error = parse_select_group_field(value, &gm->props.fields,
1478 usable_protocols);
1479 if (error) {
1480 goto out;
1481 }
1482 *usable_protocols &= OFPUTIL_P_OF15_UP;
1483 } else {
1484 error = xasprintf("unknown keyword %s", name);
1485 goto out;
1486 }
1487 }
1488 if (gm->group_id == OFPG_ANY) {
1489 error = xstrdup("must specify a group_id");
1490 goto out;
1491 }
1492 if (fields & F_GROUP_TYPE && !had_type) {
1493 error = xstrdup("must specify a type");
1494 goto out;
1495 }
1496
1497 if (fields & F_COMMAND_BUCKET_ID) {
1498 if (!(fields & F_COMMAND_BUCKET_ID_ALL || had_command_bucket_id)) {
1499 error = xstrdup("must specify a command bucket id");
1500 goto out;
1501 }
1502 } else if (had_command_bucket_id) {
1503 error = xstrdup("command bucket id is not needed");
1504 goto out;
1505 }
1506
1507 /* Validate buckets. */
1508 LIST_FOR_EACH (bucket, list_node, &gm->buckets) {
1509 if (bucket->weight != 1 && gm->type != OFPGT11_SELECT) {
1510 error = xstrdup("Only select groups can have bucket weights.");
1511 goto out;
1512 }
1513 }
1514 if (gm->type == OFPGT11_INDIRECT && !list_is_short(&gm->buckets)) {
1515 error = xstrdup("Indirect groups can have at most one bucket.");
1516 goto out;
1517 }
1518
1519 return NULL;
1520 out:
1521 ofputil_bucket_list_destroy(&gm->buckets);
1522 return error;
1523 }
1524
1525 char * OVS_WARN_UNUSED_RESULT
1526 parse_ofp_group_mod_str(struct ofputil_group_mod *gm, uint16_t command,
1527 const char *str_,
1528 enum ofputil_protocol *usable_protocols)
1529 {
1530 char *string = xstrdup(str_);
1531 char *error = parse_ofp_group_mod_str__(gm, command, string,
1532 usable_protocols);
1533 free(string);
1534
1535 if (error) {
1536 ofputil_bucket_list_destroy(&gm->buckets);
1537 }
1538 return error;
1539 }
1540
1541 char * OVS_WARN_UNUSED_RESULT
1542 parse_ofp_group_mod_file(const char *file_name, uint16_t command,
1543 struct ofputil_group_mod **gms, size_t *n_gms,
1544 enum ofputil_protocol *usable_protocols)
1545 {
1546 size_t allocated_gms;
1547 int line_number;
1548 FILE *stream;
1549 struct ds s;
1550
1551 *gms = NULL;
1552 *n_gms = 0;
1553
1554 stream = !strcmp(file_name, "-") ? stdin : fopen(file_name, "r");
1555 if (stream == NULL) {
1556 return xasprintf("%s: open failed (%s)",
1557 file_name, ovs_strerror(errno));
1558 }
1559
1560 allocated_gms = *n_gms;
1561 ds_init(&s);
1562 line_number = 0;
1563 *usable_protocols = OFPUTIL_P_OF11_UP;
1564 while (!ds_get_preprocessed_line(&s, stream, &line_number)) {
1565 enum ofputil_protocol usable;
1566 char *error;
1567
1568 if (*n_gms >= allocated_gms) {
1569 struct ofputil_group_mod *new_gms;
1570 size_t i;
1571
1572 new_gms = x2nrealloc(*gms, &allocated_gms, sizeof **gms);
1573 for (i = 0; i < *n_gms; i++) {
1574 list_moved(&new_gms[i].buckets, &(*gms)[i].buckets);
1575 }
1576 *gms = new_gms;
1577 }
1578 error = parse_ofp_group_mod_str(&(*gms)[*n_gms], command, ds_cstr(&s),
1579 &usable);
1580 if (error) {
1581 size_t i;
1582
1583 for (i = 0; i < *n_gms; i++) {
1584 ofputil_bucket_list_destroy(&(*gms)[i].buckets);
1585 }
1586 free(*gms);
1587 *gms = NULL;
1588 *n_gms = 0;
1589
1590 ds_destroy(&s);
1591 if (stream != stdin) {
1592 fclose(stream);
1593 }
1594
1595 return xasprintf("%s:%d: %s", file_name, line_number, error);
1596 }
1597 *usable_protocols &= usable;
1598 *n_gms += 1;
1599 }
1600
1601 ds_destroy(&s);
1602 if (stream != stdin) {
1603 fclose(stream);
1604 }
1605 return NULL;
1606 }
1607
1608 char * OVS_WARN_UNUSED_RESULT
1609 parse_ofp_geneve_table_mod_str(struct ofputil_geneve_table_mod *gtm,
1610 uint16_t command, const char *s,
1611 enum ofputil_protocol *usable_protocols)
1612 {
1613 *usable_protocols = OFPUTIL_P_NXM_OXM_ANY;
1614
1615 gtm->command = command;
1616 list_init(&gtm->mappings);
1617
1618 while (*s) {
1619 struct ofputil_geneve_map *map = xmalloc(sizeof *map);
1620 int n;
1621
1622 if (*s == ',') {
1623 s++;
1624 }
1625
1626 list_push_back(&gtm->mappings, &map->list_node);
1627
1628 if (!ovs_scan(s, "{class=%"SCNi16",type=%"SCNi8",len=%"SCNi8"}->tun_metadata%"SCNi16"%n",
1629 &map->option_class, &map->option_type, &map->option_len,
1630 &map->index, &n)) {
1631 ofputil_uninit_geneve_table(&gtm->mappings);
1632 return xstrdup("invalid geneve mapping");
1633 }
1634
1635 s += n;
1636 }
1637
1638 return NULL;
1639 }