]> git.proxmox.com Git - mirror_ovs.git/blob - utilities/ovs-ofctl.c
ofp-flow: Reduce memory consumption for ofputil_flow_mod, using minimatch.
[mirror_ovs.git] / utilities / ovs-ofctl.c
1 /*
2 * Copyright (c) 2008-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 #include <ctype.h>
19 #include <errno.h>
20 #include <getopt.h>
21 #include <inttypes.h>
22 #include <sys/socket.h>
23 #include <net/if.h>
24 #include <signal.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29 #include <sys/stat.h>
30 #include <sys/time.h>
31
32 #include "byte-order.h"
33 #include "classifier.h"
34 #include "command-line.h"
35 #include "daemon.h"
36 #include "colors.h"
37 #include "compiler.h"
38 #include "dirs.h"
39 #include "dp-packet.h"
40 #include "fatal-signal.h"
41 #include "nx-match.h"
42 #include "odp-util.h"
43 #include "ofp-version-opt.h"
44 #include "ofproto/ofproto.h"
45 #include "openflow/nicira-ext.h"
46 #include "openflow/openflow.h"
47 #include "openvswitch/dynamic-string.h"
48 #include "openvswitch/meta-flow.h"
49 #include "openvswitch/ofp-actions.h"
50 #include "openvswitch/ofp-bundle.h"
51 #include "openvswitch/ofp-errors.h"
52 #include "openvswitch/ofp-group.h"
53 #include "openvswitch/ofp-match.h"
54 #include "openvswitch/ofp-meter.h"
55 #include "openvswitch/ofp-msgs.h"
56 #include "openvswitch/ofp-monitor.h"
57 #include "openvswitch/ofp-port.h"
58 #include "openvswitch/ofp-print.h"
59 #include "openvswitch/ofp-util.h"
60 #include "openvswitch/ofp-parse.h"
61 #include "openvswitch/ofp-queue.h"
62 #include "openvswitch/ofp-switch.h"
63 #include "openvswitch/ofp-table.h"
64 #include "openvswitch/ofpbuf.h"
65 #include "openvswitch/shash.h"
66 #include "openvswitch/vconn.h"
67 #include "openvswitch/vlog.h"
68 #include "packets.h"
69 #include "pcap-file.h"
70 #include "openvswitch/poll-loop.h"
71 #include "random.h"
72 #include "sort.h"
73 #include "stream-ssl.h"
74 #include "socket-util.h"
75 #include "timeval.h"
76 #include "unixctl.h"
77 #include "util.h"
78
79 VLOG_DEFINE_THIS_MODULE(ofctl);
80
81 /* --bundle: Use OpenFlow 1.3+ bundle for making the flow table change atomic.
82 * NOTE: If OpenFlow 1.3 or higher is not selected with the '-O' option,
83 * OpenFlow 1.4 will be implicitly selected. Also the flow mod will use
84 * OpenFlow 1.4, so the semantics may be different (see the comment in
85 * parse_options() for details).
86 */
87 static bool bundle = false;
88
89 /* --color: Use color markers. */
90 static bool enable_color;
91
92 /* --read-only: Do not execute read only commands. */
93 static bool read_only;
94
95 /* --strict: Use strict matching for flow mod commands? Additionally governs
96 * use of nx_pull_match() instead of nx_pull_match_loose() in parse-nx-match.
97 */
98 static bool strict;
99
100 /* --may-create: If true, the mod-group command creates a group that does not
101 * yet exist; otherwise, such a command has no effect. */
102 static bool may_create;
103
104 /* --readd: If true, on replace-flows, re-add even flows that have not changed
105 * (to reset flow counters). */
106 static bool readd;
107
108 /* -F, --flow-format: Allowed protocols. By default, any protocol is
109 * allowed. */
110 static enum ofputil_protocol allowed_protocols = OFPUTIL_P_ANY;
111
112 /* -P, --packet-in-format: Packet IN format to use in monitor and snoop
113 * commands. Either one of NXPIF_* to force a particular packet_in format, or
114 * -1 to let ovs-ofctl choose the default. */
115 static int preferred_packet_in_format = -1;
116
117 /* -m, --more: Additional verbosity for ofp-print functions. */
118 static int verbosity;
119
120 /* --timestamp: Print a timestamp before each received packet on "monitor" and
121 * "snoop" command? */
122 static bool timestamp;
123
124 /* --unixctl-path: Path to use for unixctl server, for "monitor" and "snoop"
125 commands. */
126 static char *unixctl_path;
127
128 /* --sort, --rsort: Sort order. */
129 enum sort_order { SORT_ASC, SORT_DESC };
130 struct sort_criterion {
131 const struct mf_field *field; /* NULL means to sort by priority. */
132 enum sort_order order;
133 };
134 static struct sort_criterion *criteria;
135 static size_t n_criteria, allocated_criteria;
136
137 /* --names, --no-names: Show port and table names in output and accept them in
138 * input. (When neither is specified, the default is to accept port names but,
139 * for backward compatibility, not to show them unless this is an interactive
140 * console session.) */
141 static int use_names = -1;
142 static const struct ofputil_port_map *ports_to_accept(const char *vconn_name);
143 static const struct ofputil_port_map *ports_to_show(const char *vconn_name);
144 static const struct ofputil_table_map *tables_to_accept(
145 const char *vconn_name);
146 static const struct ofputil_table_map *tables_to_show(const char *vconn_name);
147 static bool should_accept_names(void);
148 static bool should_show_names(void);
149
150 /* --stats, --no-stats: Show statistics in flow dumps? */
151 static int show_stats = 1;
152
153 /* --pcap: Makes "compose-packet" print a pcap on stdout. */
154 static int print_pcap = 0;
155
156 /* --raw: Makes "ofp-print" read binary data from stdin. */
157 static int raw = 0;
158
159 static const struct ovs_cmdl_command *get_all_commands(void);
160
161 OVS_NO_RETURN static void usage(void);
162 static void parse_options(int argc, char *argv[]);
163
164 int
165 main(int argc, char *argv[])
166 {
167 struct ovs_cmdl_context ctx = { .argc = 0, };
168 set_program_name(argv[0]);
169 service_start(&argc, &argv);
170 parse_options(argc, argv);
171 fatal_ignore_sigpipe();
172 ctx.argc = argc - optind;
173 ctx.argv = argv + optind;
174
175 daemon_become_new_user(false);
176 if (read_only) {
177 ovs_cmdl_run_command_read_only(&ctx, get_all_commands());
178 } else {
179 ovs_cmdl_run_command(&ctx, get_all_commands());
180 }
181 return 0;
182 }
183
184 static void
185 add_sort_criterion(enum sort_order order, const char *field)
186 {
187 struct sort_criterion *sc;
188
189 if (n_criteria >= allocated_criteria) {
190 criteria = x2nrealloc(criteria, &allocated_criteria, sizeof *criteria);
191 }
192
193 sc = &criteria[n_criteria++];
194 if (!field || !strcasecmp(field, "priority")) {
195 sc->field = NULL;
196 } else {
197 sc->field = mf_from_name(field);
198 if (!sc->field) {
199 ovs_fatal(0, "%s: unknown field name", field);
200 }
201 }
202 sc->order = order;
203 }
204
205 static void
206 parse_options(int argc, char *argv[])
207 {
208 enum {
209 OPT_STRICT = UCHAR_MAX + 1,
210 OPT_READD,
211 OPT_TIMESTAMP,
212 OPT_SORT,
213 OPT_RSORT,
214 OPT_UNIXCTL,
215 OPT_BUNDLE,
216 OPT_COLOR,
217 OPT_MAY_CREATE,
218 OPT_READ_ONLY,
219 DAEMON_OPTION_ENUMS,
220 OFP_VERSION_OPTION_ENUMS,
221 VLOG_OPTION_ENUMS,
222 SSL_OPTION_ENUMS,
223 };
224 static const struct option long_options[] = {
225 {"timeout", required_argument, NULL, 't'},
226 {"strict", no_argument, NULL, OPT_STRICT},
227 {"readd", no_argument, NULL, OPT_READD},
228 {"flow-format", required_argument, NULL, 'F'},
229 {"packet-in-format", required_argument, NULL, 'P'},
230 {"more", no_argument, NULL, 'm'},
231 {"timestamp", no_argument, NULL, OPT_TIMESTAMP},
232 {"sort", optional_argument, NULL, OPT_SORT},
233 {"rsort", optional_argument, NULL, OPT_RSORT},
234 {"names", no_argument, &use_names, 1},
235 {"no-names", no_argument, &use_names, 0},
236 {"stats", no_argument, &show_stats, 1},
237 {"no-stats", no_argument, &show_stats, 0},
238 {"unixctl", required_argument, NULL, OPT_UNIXCTL},
239 {"help", no_argument, NULL, 'h'},
240 {"option", no_argument, NULL, 'o'},
241 {"bundle", no_argument, NULL, OPT_BUNDLE},
242 {"color", optional_argument, NULL, OPT_COLOR},
243 {"may-create", no_argument, NULL, OPT_MAY_CREATE},
244 {"pcap", no_argument, &print_pcap, 1},
245 {"raw", no_argument, &raw, 1},
246 {"read-only", no_argument, NULL, OPT_READ_ONLY},
247 DAEMON_LONG_OPTIONS,
248 OFP_VERSION_LONG_OPTIONS,
249 VLOG_LONG_OPTIONS,
250 STREAM_SSL_LONG_OPTIONS,
251 {NULL, 0, NULL, 0},
252 };
253 char *short_options = ovs_cmdl_long_options_to_short_options(long_options);
254 uint32_t versions;
255 enum ofputil_protocol version_protocols;
256
257 /* For now, ovs-ofctl only enables OpenFlow 1.0 by default. This is
258 * because ovs-ofctl implements command such as "add-flow" as raw OpenFlow
259 * requests, but those requests have subtly different semantics in
260 * different OpenFlow versions. For example:
261 *
262 * - In OpenFlow 1.0, a "mod-flow" operation that does not find any
263 * existing flow to modify adds a new flow.
264 *
265 * - In OpenFlow 1.1, a "mod-flow" operation that does not find any
266 * existing flow to modify adds a new flow, but only if the mod-flow
267 * did not match on the flow cookie.
268 *
269 * - In OpenFlow 1.2 and a later, a "mod-flow" operation never adds a
270 * new flow.
271 */
272 set_allowed_ofp_versions("OpenFlow10");
273
274 for (;;) {
275 unsigned long int timeout;
276 int c;
277
278 c = getopt_long(argc, argv, short_options, long_options, NULL);
279 if (c == -1) {
280 break;
281 }
282
283 switch (c) {
284 case 't':
285 timeout = strtoul(optarg, NULL, 10);
286 if (timeout <= 0) {
287 ovs_fatal(0, "value %s on -t or --timeout is not at least 1",
288 optarg);
289 } else {
290 time_alarm(timeout);
291 }
292 break;
293
294 case 'F':
295 allowed_protocols = ofputil_protocols_from_string(optarg);
296 if (!allowed_protocols) {
297 ovs_fatal(0, "%s: invalid flow format(s)", optarg);
298 }
299 break;
300
301 case 'P':
302 preferred_packet_in_format =
303 ofputil_packet_in_format_from_string(optarg);
304 if (preferred_packet_in_format < 0) {
305 ovs_fatal(0, "unknown packet-in format `%s'", optarg);
306 }
307 break;
308
309 case 'm':
310 verbosity++;
311 break;
312
313 case 'h':
314 usage();
315
316 case 'o':
317 ovs_cmdl_print_options(long_options);
318 exit(EXIT_SUCCESS);
319
320 case OPT_BUNDLE:
321 bundle = true;
322 break;
323
324 case OPT_STRICT:
325 strict = true;
326 break;
327
328 case OPT_READ_ONLY:
329 read_only = true;
330 break;
331
332 case OPT_READD:
333 readd = true;
334 break;
335
336 case OPT_TIMESTAMP:
337 timestamp = true;
338 break;
339
340 case OPT_SORT:
341 add_sort_criterion(SORT_ASC, optarg);
342 break;
343
344 case OPT_RSORT:
345 add_sort_criterion(SORT_DESC, optarg);
346 break;
347
348 case OPT_UNIXCTL:
349 unixctl_path = optarg;
350 break;
351
352 case OPT_COLOR:
353 if (optarg) {
354 if (!strcasecmp(optarg, "always")
355 || !strcasecmp(optarg, "yes")
356 || !strcasecmp(optarg, "force")) {
357 enable_color = true;
358 } else if (!strcasecmp(optarg, "never")
359 || !strcasecmp(optarg, "no")
360 || !strcasecmp(optarg, "none")) {
361 enable_color = false;
362 } else if (!strcasecmp(optarg, "auto")
363 || !strcasecmp(optarg, "tty")
364 || !strcasecmp(optarg, "if-tty")) {
365 /* Determine whether we need colors, i.e. whether standard
366 * output is a tty. */
367 enable_color = is_stdout_a_tty();
368 } else {
369 ovs_fatal(0, "incorrect value `%s' for --color", optarg);
370 }
371 } else {
372 enable_color = is_stdout_a_tty();
373 }
374 break;
375
376 case OPT_MAY_CREATE:
377 may_create = true;
378 break;
379
380 DAEMON_OPTION_HANDLERS
381 OFP_VERSION_OPTION_HANDLERS
382 VLOG_OPTION_HANDLERS
383 STREAM_SSL_OPTION_HANDLERS
384
385 case '?':
386 exit(EXIT_FAILURE);
387
388 case 0:
389 break;
390
391 default:
392 abort();
393 }
394 }
395
396 if (n_criteria) {
397 /* Always do a final sort pass based on priority. */
398 add_sort_criterion(SORT_DESC, "priority");
399 }
400
401 free(short_options);
402
403 /* Implicit OpenFlow 1.4 with the '--bundle' option. */
404 if (bundle && !(get_allowed_ofp_versions() &
405 ofputil_protocols_to_version_bitmap(OFPUTIL_P_OF13_UP))) {
406 /* Add implicit allowance for OpenFlow 1.4. */
407 add_allowed_ofp_versions(ofputil_protocols_to_version_bitmap(
408 OFPUTIL_P_OF14_OXM));
409 /* Remove all versions that do not support bundles. */
410 mask_allowed_ofp_versions(ofputil_protocols_to_version_bitmap(
411 OFPUTIL_P_OF13_UP));
412 }
413 versions = get_allowed_ofp_versions();
414 version_protocols = ofputil_protocols_from_version_bitmap(versions);
415 if (!(allowed_protocols & version_protocols)) {
416 char *protocols = ofputil_protocols_to_string(allowed_protocols);
417 struct ds version_s = DS_EMPTY_INITIALIZER;
418
419 ofputil_format_version_bitmap_names(&version_s, versions);
420 ovs_fatal(0, "None of the enabled OpenFlow versions (%s) supports "
421 "any of the enabled flow formats (%s). (Use -O to enable "
422 "additional OpenFlow versions or -F to enable additional "
423 "flow formats.)", ds_cstr(&version_s), protocols);
424 }
425 allowed_protocols &= version_protocols;
426 mask_allowed_ofp_versions(ofputil_protocols_to_version_bitmap(
427 allowed_protocols));
428
429 colors_init(enable_color);
430 }
431
432 static void
433 usage(void)
434 {
435 printf("%s: OpenFlow switch management utility\n"
436 "usage: %s [OPTIONS] COMMAND [ARG...]\n"
437 "\nFor OpenFlow switches:\n"
438 " show SWITCH show OpenFlow information\n"
439 " dump-desc SWITCH print switch description\n"
440 " dump-tables SWITCH print table stats\n"
441 " dump-table-features SWITCH print table features\n"
442 " dump-table-desc SWITCH print table description (OF1.4+)\n"
443 " mod-port SWITCH IFACE ACT modify port behavior\n"
444 " mod-table SWITCH MOD modify flow table behavior\n"
445 " OF1.1/1.2 MOD: controller, continue, drop\n"
446 " OF1.4+ MOD: evict, noevict, vacancy:low,high, novacancy\n"
447 " get-frags SWITCH print fragment handling behavior\n"
448 " set-frags SWITCH FRAG_MODE set fragment handling behavior\n"
449 " FRAG_MODE: normal, drop, reassemble, nx-match\n"
450 " dump-ports SWITCH [PORT] print port statistics\n"
451 " dump-ports-desc SWITCH [PORT] print port descriptions\n"
452 " dump-flows SWITCH print all flow entries\n"
453 " dump-flows SWITCH FLOW print matching FLOWs\n"
454 " dump-aggregate SWITCH print aggregate flow statistics\n"
455 " dump-aggregate SWITCH FLOW print aggregate stats for FLOWs\n"
456 " queue-stats SWITCH [PORT [QUEUE]] dump queue stats\n"
457 " add-flow SWITCH FLOW add flow described by FLOW\n"
458 " add-flows SWITCH FILE add flows from FILE\n"
459 " mod-flows SWITCH FLOW modify actions of matching FLOWs\n"
460 " del-flows SWITCH [FLOW] delete matching FLOWs\n"
461 " replace-flows SWITCH FILE replace flows with those in FILE\n"
462 " diff-flows SOURCE1 SOURCE2 compare flows from two sources\n"
463 " packet-out SWITCH IN_PORT ACTIONS PACKET...\n"
464 " execute ACTIONS on PACKET\n"
465 " monitor SWITCH [MISSLEN] [invalid_ttl] [watch:[...]]\n"
466 " print packets received from SWITCH\n"
467 " snoop SWITCH snoop on SWITCH and its controller\n"
468 " add-group SWITCH GROUP add group described by GROUP\n"
469 " add-groups SWITCH FILE add group from FILE\n"
470 " [--may-create] mod-group SWITCH GROUP modify specific group\n"
471 " del-groups SWITCH [GROUP] delete matching GROUPs\n"
472 " insert-buckets SWITCH [GROUP] add buckets to GROUP\n"
473 " remove-buckets SWITCH [GROUP] remove buckets from GROUP\n"
474 " dump-group-features SWITCH print group features\n"
475 " dump-groups SWITCH [GROUP] print group description\n"
476 " dump-group-stats SWITCH [GROUP] print group statistics\n"
477 " queue-get-config SWITCH [PORT] print queue config for PORT\n"
478 " add-meter SWITCH METER add meter described by METER\n"
479 " mod-meter SWITCH METER modify specific METER\n"
480 " del-meter SWITCH METER delete METER\n"
481 " del-meters SWITCH delete all meters\n"
482 " dump-meter SWITCH METER print METER configuration\n"
483 " dump-meters SWITCH print all meter configuration\n"
484 " meter-stats SWITCH [METER] print meter statistics\n"
485 " meter-features SWITCH print meter features\n"
486 " add-tlv-map SWITCH MAP add TLV option MAPpings\n"
487 " del-tlv-map SWITCH [MAP] delete TLV option MAPpings\n"
488 " dump-tlv-map SWITCH print TLV option mappings\n"
489 " dump-ipfix-bridge SWITCH print ipfix stats of bridge\n"
490 " dump-ipfix-flow SWITCH print flow ipfix of a bridge\n"
491 " ct-flush-zone SWITCH ZONE flush conntrack entries in ZONE\n"
492 "\nFor OpenFlow switches and controllers:\n"
493 " probe TARGET probe whether TARGET is up\n"
494 " ping TARGET [N] latency of N-byte echos\n"
495 " benchmark TARGET N COUNT bandwidth of COUNT N-byte echos\n"
496 "SWITCH or TARGET is an active OpenFlow connection method.\n"
497 "\nOther commands:\n"
498 " ofp-parse FILE print messages read from FILE\n"
499 " ofp-parse-pcap PCAP print OpenFlow read from PCAP\n",
500 program_name, program_name);
501 vconn_usage(true, false, false);
502 daemon_usage();
503 ofp_version_usage();
504 vlog_usage();
505 printf("\nOther options:\n"
506 " --strict use strict match for flow commands\n"
507 " --read-only do not execute read/write commands\n"
508 " --readd replace flows that haven't changed\n"
509 " -F, --flow-format=FORMAT force particular flow format\n"
510 " -P, --packet-in-format=FRMT force particular packet in format\n"
511 " -m, --more be more verbose printing OpenFlow\n"
512 " --timestamp (monitor, snoop) print timestamps\n"
513 " -t, --timeout=SECS give up after SECS seconds\n"
514 " --sort[=field] sort in ascending order\n"
515 " --rsort[=field] sort in descending order\n"
516 " --names show port names instead of numbers\n"
517 " --unixctl=SOCKET set control socket name\n"
518 " --color[=always|never|auto] control use of color in output\n"
519 " -h, --help display this help message\n"
520 " -V, --version display version information\n");
521 exit(EXIT_SUCCESS);
522 }
523
524 static void
525 ofctl_exit(struct unixctl_conn *conn, int argc OVS_UNUSED,
526 const char *argv[] OVS_UNUSED, void *exiting_)
527 {
528 bool *exiting = exiting_;
529 *exiting = true;
530 unixctl_command_reply(conn, NULL);
531 }
532
533 static void run(int retval, const char *message, ...)
534 OVS_PRINTF_FORMAT(2, 3);
535
536 static void
537 run(int retval, const char *message, ...)
538 {
539 if (retval) {
540 va_list args;
541
542 va_start(args, message);
543 ovs_fatal_valist(retval, message, args);
544 }
545 }
546 \f
547 /* Generic commands. */
548
549 static int
550 open_vconn_socket(const char *name, struct vconn **vconnp)
551 {
552 char *vconn_name = xasprintf("unix:%s", name);
553 int error;
554
555 error = vconn_open(vconn_name, get_allowed_ofp_versions(), DSCP_DEFAULT,
556 vconnp);
557 if (error && error != ENOENT) {
558 ovs_fatal(0, "%s: failed to open socket (%s)", name,
559 ovs_strerror(error));
560 }
561 free(vconn_name);
562
563 return error;
564 }
565
566 enum open_target { MGMT, SNOOP };
567
568 static enum ofputil_protocol
569 open_vconn__(const char *name, enum open_target target,
570 struct vconn **vconnp)
571 {
572 const char *suffix = target == MGMT ? "mgmt" : "snoop";
573 char *datapath_name, *datapath_type, *socket_name;
574 enum ofputil_protocol protocol;
575 char *bridge_path;
576 int ofp_version;
577 int error;
578
579 bridge_path = xasprintf("%s/%s.%s", ovs_rundir(), name, suffix);
580
581 ofproto_parse_name(name, &datapath_name, &datapath_type);
582 socket_name = xasprintf("%s/%s.%s", ovs_rundir(), datapath_name, suffix);
583 free(datapath_name);
584 free(datapath_type);
585
586 if (strchr(name, ':')) {
587 run(vconn_open(name, get_allowed_ofp_versions(), DSCP_DEFAULT, vconnp),
588 "connecting to %s", name);
589 } else if (!open_vconn_socket(name, vconnp)) {
590 /* Fall Through. */
591 } else if (!open_vconn_socket(bridge_path, vconnp)) {
592 /* Fall Through. */
593 } else if (!open_vconn_socket(socket_name, vconnp)) {
594 /* Fall Through. */
595 } else {
596 ovs_fatal(0, "%s is not a bridge or a socket", name);
597 }
598
599 if (target == SNOOP) {
600 vconn_set_recv_any_version(*vconnp);
601 }
602
603 free(bridge_path);
604 free(socket_name);
605
606 VLOG_DBG("connecting to %s", vconn_get_name(*vconnp));
607 error = vconn_connect_block(*vconnp);
608 if (error) {
609 ovs_fatal(0, "%s: failed to connect to socket (%s)", name,
610 ovs_strerror(error));
611 }
612
613 ofp_version = vconn_get_version(*vconnp);
614 protocol = ofputil_protocol_from_ofp_version(ofp_version);
615 if (!protocol) {
616 ovs_fatal(0, "%s: unsupported OpenFlow version 0x%02x",
617 name, ofp_version);
618 }
619 return protocol;
620 }
621
622 static enum ofputil_protocol
623 open_vconn(const char *name, struct vconn **vconnp)
624 {
625 return open_vconn__(name, MGMT, vconnp);
626 }
627
628 static void
629 send_openflow_buffer(struct vconn *vconn, struct ofpbuf *buffer)
630 {
631 run(vconn_send_block(vconn, buffer), "failed to send packet to switch");
632 }
633
634 static void
635 dump_transaction(struct vconn *vconn, struct ofpbuf *request)
636 {
637 const struct ofp_header *oh = request->data;
638 if (ofpmsg_is_stat_request(oh)) {
639 ovs_be32 send_xid = oh->xid;
640 enum ofpraw request_raw;
641 enum ofpraw reply_raw;
642 bool done = false;
643
644 ofpraw_decode_partial(&request_raw, request->data, request->size);
645 reply_raw = ofpraw_stats_request_to_reply(request_raw, oh->version);
646
647 send_openflow_buffer(vconn, request);
648 while (!done) {
649 ovs_be32 recv_xid;
650 struct ofpbuf *reply;
651
652 run(vconn_recv_block(vconn, &reply),
653 "OpenFlow packet receive failed");
654 recv_xid = ((struct ofp_header *) reply->data)->xid;
655 if (send_xid == recv_xid) {
656 enum ofpraw ofpraw;
657
658 ofp_print(stdout, reply->data, reply->size,
659 ports_to_show(vconn_get_name(vconn)),
660 tables_to_show(vconn_get_name(vconn)),
661 verbosity + 1);
662
663 ofpraw_decode(&ofpraw, reply->data);
664 if (ofptype_from_ofpraw(ofpraw) == OFPTYPE_ERROR) {
665 done = true;
666 } else if (ofpraw == reply_raw) {
667 done = !ofpmp_more(reply->data);
668 } else {
669 ovs_fatal(0, "received bad reply: %s",
670 ofp_to_string(
671 reply->data, reply->size,
672 ports_to_show(vconn_get_name(vconn)),
673 tables_to_show(vconn_get_name(vconn)),
674 verbosity + 1));
675 }
676 } else {
677 VLOG_DBG("received reply with xid %08"PRIx32" "
678 "!= expected %08"PRIx32, recv_xid, send_xid);
679 }
680 ofpbuf_delete(reply);
681 }
682 } else {
683 struct ofpbuf *reply;
684
685 run(vconn_transact(vconn, request, &reply), "talking to %s",
686 vconn_get_name(vconn));
687 ofp_print(stdout, reply->data, reply->size,
688 ports_to_show(vconn_get_name(vconn)),
689 tables_to_show(vconn_get_name(vconn)),
690 verbosity + 1);
691 ofpbuf_delete(reply);
692 }
693 }
694
695 static void
696 dump_trivial_transaction(const char *vconn_name, enum ofpraw ofpraw)
697 {
698 struct ofpbuf *request;
699 struct vconn *vconn;
700
701 open_vconn(vconn_name, &vconn);
702 request = ofpraw_alloc(ofpraw, vconn_get_version(vconn), 0);
703 dump_transaction(vconn, request);
704 vconn_close(vconn);
705 }
706
707 /* Sends all of the 'requests', which should be requests that only have replies
708 * if an error occurs, and waits for them to succeed or fail. If an error does
709 * occur, prints it and exits with an error.
710 *
711 * Destroys all of the 'requests'. */
712 static void
713 transact_multiple_noreply(struct vconn *vconn, struct ovs_list *requests)
714 {
715 struct ofpbuf *reply;
716
717 run(vconn_transact_multiple_noreply(vconn, requests, &reply),
718 "talking to %s", vconn_get_name(vconn));
719 if (reply) {
720 ofp_print(stderr, reply->data, reply->size,
721 ports_to_show(vconn_get_name(vconn)),
722 tables_to_show(vconn_get_name(vconn)),
723 verbosity + 2);
724 exit(1);
725 }
726 ofpbuf_delete(reply);
727 }
728
729 /* Frees the error messages as they are printed. */
730 static void
731 bundle_print_errors(struct ovs_list *errors, struct ovs_list *requests,
732 const char *vconn_name)
733 {
734 struct ofpbuf *error, *next;
735 struct ofpbuf *bmsg;
736
737 INIT_CONTAINER(bmsg, requests, list_node);
738
739 LIST_FOR_EACH_SAFE (error, next, list_node, errors) {
740 const struct ofp_header *error_oh = error->data;
741 ovs_be32 error_xid = error_oh->xid;
742 enum ofperr ofperr;
743 struct ofpbuf payload;
744
745 ofperr = ofperr_decode_msg(error_oh, &payload);
746 if (!ofperr) {
747 fprintf(stderr, "***decode error***");
748 } else {
749 /* Default to the likely truncated message. */
750 const struct ofp_header *ofp_msg = payload.data;
751 size_t msg_len = payload.size;
752
753 /* Find the failing message from the requests list to be able to
754 * dump the whole message. We assume the errors are returned in
755 * the same order as in which the messages are sent to get O(n)
756 * rather than O(n^2) processing here. If this heuristics fails we
757 * may print the truncated hexdumps instead. */
758 LIST_FOR_EACH_CONTINUE (bmsg, list_node, requests) {
759 const struct ofp_header *oh = bmsg->data;
760
761 if (oh->xid == error_xid) {
762 ofp_msg = oh;
763 msg_len = bmsg->size;
764 break;
765 }
766 }
767 fprintf(stderr, "Error %s for: ", ofperr_get_name(ofperr));
768 ofp_print(stderr, ofp_msg, msg_len, ports_to_show(vconn_name),
769 tables_to_show(vconn_name), verbosity + 1);
770 }
771 ofpbuf_uninit(&payload);
772 ofpbuf_delete(error);
773 }
774 fflush(stderr);
775 }
776
777 static void
778 bundle_transact(struct vconn *vconn, struct ovs_list *requests, uint16_t flags)
779 {
780 struct ovs_list errors;
781 int retval = vconn_bundle_transact(vconn, requests, flags, &errors);
782
783 bundle_print_errors(&errors, requests, vconn_get_name(vconn));
784
785 if (retval) {
786 ovs_fatal(retval, "talking to %s", vconn_get_name(vconn));
787 }
788 }
789
790 /* Sends 'request', which should be a request that only has a reply if an error
791 * occurs, and waits for it to succeed or fail. If an error does occur, prints
792 * it and exits with an error.
793 *
794 * Destroys 'request'. */
795 static void
796 transact_noreply(struct vconn *vconn, struct ofpbuf *request)
797 {
798 struct ovs_list requests;
799
800 ovs_list_init(&requests);
801 ovs_list_push_back(&requests, &request->list_node);
802 transact_multiple_noreply(vconn, &requests);
803 }
804
805 static void
806 fetch_switch_config(struct vconn *vconn, struct ofputil_switch_config *config)
807 {
808 struct ofpbuf *request;
809 struct ofpbuf *reply;
810 enum ofptype type;
811
812 request = ofpraw_alloc(OFPRAW_OFPT_GET_CONFIG_REQUEST,
813 vconn_get_version(vconn), 0);
814 run(vconn_transact(vconn, request, &reply),
815 "talking to %s", vconn_get_name(vconn));
816
817 if (ofptype_decode(&type, reply->data)
818 || type != OFPTYPE_GET_CONFIG_REPLY) {
819 ovs_fatal(0, "%s: bad reply to config request", vconn_get_name(vconn));
820 }
821 ofputil_decode_get_config_reply(reply->data, config);
822 ofpbuf_delete(reply);
823 }
824
825 static void
826 set_switch_config(struct vconn *vconn,
827 const struct ofputil_switch_config *config)
828 {
829 enum ofp_version version = vconn_get_version(vconn);
830 transact_noreply(vconn, ofputil_encode_set_config(config, version));
831 }
832
833 static void
834 ofctl_show(struct ovs_cmdl_context *ctx)
835 {
836 const char *vconn_name = ctx->argv[1];
837 enum ofp_version version;
838 struct vconn *vconn;
839 struct ofpbuf *request;
840 struct ofpbuf *reply;
841 bool has_ports;
842
843 open_vconn(vconn_name, &vconn);
844 version = vconn_get_version(vconn);
845 request = ofpraw_alloc(OFPRAW_OFPT_FEATURES_REQUEST, version, 0);
846 run(vconn_transact(vconn, request, &reply), "talking to %s", vconn_name);
847
848 has_ports = ofputil_switch_features_has_ports(reply);
849 ofp_print(stdout, reply->data, reply->size, NULL, NULL, verbosity + 1);
850 ofpbuf_delete(reply);
851
852 if (!has_ports) {
853 request = ofputil_encode_port_desc_stats_request(version, OFPP_ANY);
854 dump_transaction(vconn, request);
855 }
856 dump_trivial_transaction(vconn_name, OFPRAW_OFPT_GET_CONFIG_REQUEST);
857 vconn_close(vconn);
858 }
859
860 static void
861 ofctl_dump_desc(struct ovs_cmdl_context *ctx)
862 {
863 dump_trivial_transaction(ctx->argv[1], OFPRAW_OFPST_DESC_REQUEST);
864 }
865
866 static void
867 ofctl_dump_tables(struct ovs_cmdl_context *ctx)
868 {
869 dump_trivial_transaction(ctx->argv[1], OFPRAW_OFPST_TABLE_REQUEST);
870 }
871
872 static void
873 ofctl_dump_table_features(struct ovs_cmdl_context *ctx)
874 {
875 struct ofpbuf *request;
876 struct vconn *vconn;
877
878 open_vconn(ctx->argv[1], &vconn);
879 request = ofputil_encode_table_features_request(vconn_get_version(vconn));
880
881 /* The following is similar to dump_trivial_transaction(), but it
882 * maintains the previous 'ofputil_table_features' from one stats reply
883 * message to the next, which allows duplication to be eliminated in the
884 * output across messages. Otherwise the output is much larger and harder
885 * to read, because only 17 or so ofputil_table_features elements fit in a
886 * single 64 kB OpenFlow message and therefore you get a ton of repetition
887 * (every 17th element is printed in full instead of abbreviated). */
888
889 const struct ofp_header *request_oh = request->data;
890 ovs_be32 send_xid = request_oh->xid;
891 bool done = false;
892
893 struct ofputil_table_features prev;
894 int n = 0;
895
896 send_openflow_buffer(vconn, request);
897 while (!done) {
898 ovs_be32 recv_xid;
899 struct ofpbuf *reply;
900
901 run(vconn_recv_block(vconn, &reply), "OpenFlow packet receive failed");
902 recv_xid = ((struct ofp_header *) reply->data)->xid;
903 if (send_xid == recv_xid) {
904 enum ofptype type;
905 enum ofperr error;
906 error = ofptype_decode(&type, reply->data);
907 if (error) {
908 ovs_fatal(0, "decode error: %s", ofperr_get_name(error));
909 } else if (type == OFPTYPE_ERROR) {
910 ofp_print(stdout, reply->data, reply->size, NULL, NULL,
911 verbosity + 1);
912 done = true;
913 } else if (type == OFPTYPE_TABLE_FEATURES_STATS_REPLY) {
914 done = !ofpmp_more(reply->data);
915 for (;;) {
916 struct ofputil_table_features tf;
917 int retval;
918
919 retval = ofputil_decode_table_features(reply, &tf, true);
920 if (retval) {
921 if (retval != EOF) {
922 ovs_fatal(0, "decode error: %s",
923 ofperr_get_name(retval));
924 }
925 break;
926 }
927
928 struct ds s = DS_EMPTY_INITIALIZER;
929 ofputil_table_features_format(
930 &s, &tf, n ? &prev : NULL, NULL, NULL,
931 tables_to_show(ctx->argv[1]));
932 puts(ds_cstr(&s));
933 ds_destroy(&s);
934
935 prev = tf;
936 n++;
937 }
938 } else {
939 ovs_fatal(0, "received bad reply: %s",
940 ofp_to_string(reply->data, reply->size,
941 ports_to_show(ctx->argv[1]),
942 tables_to_show(ctx->argv[1]),
943 verbosity + 1));
944 }
945 } else {
946 VLOG_DBG("received reply with xid %08"PRIx32" "
947 "!= expected %08"PRIx32, recv_xid, send_xid);
948 }
949 ofpbuf_delete(reply);
950 }
951
952 vconn_close(vconn);
953 }
954
955 static void
956 ofctl_dump_table_desc(struct ovs_cmdl_context *ctx)
957 {
958 struct ofpbuf *request;
959 struct vconn *vconn;
960
961 open_vconn(ctx->argv[1], &vconn);
962 request = ofputil_encode_table_desc_request(vconn_get_version(vconn));
963 if (request) {
964 dump_transaction(vconn, request);
965 }
966
967 vconn_close(vconn);
968 }
969
970
971 static bool
972 str_to_ofp(const char *s, ofp_port_t *ofp_port)
973 {
974 bool ret;
975 uint32_t port_;
976
977 ret = str_to_uint(s, 10, &port_);
978 *ofp_port = u16_to_ofp(port_);
979 return ret;
980 }
981
982 struct port_iterator {
983 struct vconn *vconn;
984
985 enum { PI_FEATURES, PI_PORT_DESC } variant;
986 struct ofpbuf *reply;
987 ovs_be32 send_xid;
988 bool more;
989 };
990
991 static void
992 port_iterator_fetch_port_desc(struct port_iterator *pi)
993 {
994 pi->variant = PI_PORT_DESC;
995 pi->more = true;
996
997 struct ofpbuf *rq = ofputil_encode_port_desc_stats_request(
998 vconn_get_version(pi->vconn), OFPP_ANY);
999 pi->send_xid = ((struct ofp_header *) rq->data)->xid;
1000 send_openflow_buffer(pi->vconn, rq);
1001 }
1002
1003 static void
1004 port_iterator_fetch_features(struct port_iterator *pi)
1005 {
1006 pi->variant = PI_FEATURES;
1007
1008 /* Fetch the switch's ofp_switch_features. */
1009 enum ofp_version version = vconn_get_version(pi->vconn);
1010 struct ofpbuf *rq = ofpraw_alloc(OFPRAW_OFPT_FEATURES_REQUEST, version, 0);
1011 run(vconn_transact(pi->vconn, rq, &pi->reply),
1012 "talking to %s", vconn_get_name(pi->vconn));
1013
1014 enum ofptype type;
1015 if (ofptype_decode(&type, pi->reply->data)
1016 || type != OFPTYPE_FEATURES_REPLY) {
1017 ovs_fatal(0, "%s: received bad features reply",
1018 vconn_get_name(pi->vconn));
1019 }
1020 if (!ofputil_switch_features_has_ports(pi->reply)) {
1021 /* The switch features reply does not contain a complete list of ports.
1022 * Probably, there are more ports than will fit into a single 64 kB
1023 * OpenFlow message. Use OFPST_PORT_DESC to get a complete list of
1024 * ports. */
1025 ofpbuf_delete(pi->reply);
1026 pi->reply = NULL;
1027 port_iterator_fetch_port_desc(pi);
1028 return;
1029 }
1030
1031 struct ofputil_switch_features features;
1032 enum ofperr error = ofputil_pull_switch_features(pi->reply, &features);
1033 if (error) {
1034 ovs_fatal(0, "%s: failed to decode features reply (%s)",
1035 vconn_get_name(pi->vconn), ofperr_to_string(error));
1036 }
1037 }
1038
1039 /* Initializes 'pi' to prepare for iterating through all of the ports on the
1040 * OpenFlow switch to which 'vconn' is connected.
1041 *
1042 * During iteration, the client should not make other use of 'vconn', because
1043 * that can cause other messages to be interleaved with the replies used by the
1044 * iterator and thus some ports may be missed or a hang can occur. */
1045 static void
1046 port_iterator_init(struct port_iterator *pi, struct vconn *vconn)
1047 {
1048 memset(pi, 0, sizeof *pi);
1049 pi->vconn = vconn;
1050 if (vconn_get_version(vconn) < OFP13_VERSION) {
1051 port_iterator_fetch_features(pi);
1052 } else {
1053 port_iterator_fetch_port_desc(pi);
1054 }
1055 }
1056
1057 /* Obtains the next port from 'pi'. On success, initializes '*pp' with the
1058 * port's details and returns true, otherwise (if all the ports have already
1059 * been seen), returns false. */
1060 static bool
1061 port_iterator_next(struct port_iterator *pi, struct ofputil_phy_port *pp)
1062 {
1063 for (;;) {
1064 if (pi->reply) {
1065 int retval = ofputil_pull_phy_port(vconn_get_version(pi->vconn),
1066 pi->reply, pp);
1067 if (!retval) {
1068 return true;
1069 } else if (retval != EOF) {
1070 ovs_fatal(0, "received bad reply: %s",
1071 ofp_to_string(pi->reply->data, pi->reply->size,
1072 NULL, NULL, verbosity + 1));
1073 }
1074 }
1075
1076 if (pi->variant == PI_FEATURES || !pi->more) {
1077 return false;
1078 }
1079
1080 ovs_be32 recv_xid;
1081 do {
1082 ofpbuf_delete(pi->reply);
1083 run(vconn_recv_block(pi->vconn, &pi->reply),
1084 "OpenFlow receive failed");
1085 recv_xid = ((struct ofp_header *) pi->reply->data)->xid;
1086 } while (pi->send_xid != recv_xid);
1087
1088 struct ofp_header *oh = pi->reply->data;
1089 enum ofptype type;
1090 if (ofptype_pull(&type, pi->reply)
1091 || type != OFPTYPE_PORT_DESC_STATS_REPLY) {
1092 ovs_fatal(0, "received bad reply: %s",
1093 ofp_to_string(pi->reply->data, pi->reply->size, NULL,
1094 NULL, verbosity + 1));
1095 }
1096
1097 pi->more = (ofpmp_flags(oh) & OFPSF_REPLY_MORE) != 0;
1098 }
1099 }
1100
1101 /* Destroys iterator 'pi'. */
1102 static void
1103 port_iterator_destroy(struct port_iterator *pi)
1104 {
1105 if (pi) {
1106 while (pi->variant == PI_PORT_DESC && pi->more) {
1107 /* Drain vconn's queue of any other replies for this request. */
1108 struct ofputil_phy_port pp;
1109 port_iterator_next(pi, &pp);
1110 }
1111
1112 ofpbuf_delete(pi->reply);
1113 }
1114 }
1115
1116 /* Opens a connection to 'vconn_name', fetches the port structure for
1117 * 'port_name' (which may be a port name or number), and copies it into
1118 * '*pp'. */
1119 static void
1120 fetch_ofputil_phy_port(const char *vconn_name, const char *port_name,
1121 struct ofputil_phy_port *pp)
1122 {
1123 struct vconn *vconn;
1124 ofp_port_t port_no;
1125 bool found = false;
1126
1127 /* Try to interpret the argument as a port number. */
1128 if (!str_to_ofp(port_name, &port_no)) {
1129 port_no = OFPP_NONE;
1130 }
1131
1132 /* OpenFlow 1.0, 1.1, and 1.2 put the list of ports in the
1133 * OFPT_FEATURES_REPLY message. OpenFlow 1.3 and later versions put it
1134 * into the OFPST_PORT_DESC reply. Try it the correct way. */
1135 open_vconn(vconn_name, &vconn);
1136 struct port_iterator pi;
1137 for (port_iterator_init(&pi, vconn); port_iterator_next(&pi, pp); ) {
1138 if (port_no != OFPP_NONE
1139 ? port_no == pp->port_no
1140 : !strcmp(pp->name, port_name)) {
1141 found = true;
1142 break;
1143 }
1144 }
1145 port_iterator_destroy(&pi);
1146 vconn_close(vconn);
1147
1148 if (!found) {
1149 ovs_fatal(0, "%s: couldn't find port `%s'", vconn_name, port_name);
1150 }
1151 }
1152
1153 static const struct ofputil_port_map *
1154 get_port_map(const char *vconn_name)
1155 {
1156 static struct shash port_maps = SHASH_INITIALIZER(&port_maps);
1157 struct ofputil_port_map *map = shash_find_data(&port_maps, vconn_name);
1158 if (!map) {
1159 map = xmalloc(sizeof *map);
1160 ofputil_port_map_init(map);
1161 shash_add(&port_maps, vconn_name, map);
1162
1163 if (!strchr(vconn_name, ':') || !vconn_verify_name(vconn_name)) {
1164 /* For an active vconn (which includes a vconn constructed from a
1165 * bridge name), connect to it and pull down the port name-number
1166 * mapping. */
1167 struct vconn *vconn;
1168 open_vconn(vconn_name, &vconn);
1169
1170 struct port_iterator pi;
1171 struct ofputil_phy_port pp;
1172 for (port_iterator_init(&pi, vconn);
1173 port_iterator_next(&pi, &pp); ) {
1174 ofputil_port_map_put(map, pp.port_no, pp.name);
1175 }
1176 port_iterator_destroy(&pi);
1177
1178 vconn_close(vconn);
1179 } else {
1180 /* Don't bother with passive vconns, since it could take a long
1181 * time for the remote to try to connect to us. Don't bother with
1182 * invalid vconn names either. */
1183 }
1184 }
1185 return map;
1186 }
1187
1188 static const struct ofputil_port_map *
1189 ports_to_accept(const char *vconn_name)
1190 {
1191 return should_accept_names() ? get_port_map(vconn_name) : NULL;
1192 }
1193
1194 static const struct ofputil_port_map *
1195 ports_to_show(const char *vconn_name)
1196 {
1197 return should_show_names() ? get_port_map(vconn_name) : NULL;
1198 }
1199
1200 struct table_iterator {
1201 struct vconn *vconn;
1202
1203 enum { TI_STATS, TI_FEATURES } variant;
1204 struct ofpbuf *reply;
1205 ovs_be32 send_xid;
1206 bool more;
1207
1208 struct ofputil_table_features features;
1209 };
1210
1211 /* Initializes 'ti' to prepare for iterating through all of the tables on the
1212 * OpenFlow switch to which 'vconn' is connected.
1213 *
1214 * During iteration, the client should not make other use of 'vconn', because
1215 * that can cause other messages to be interleaved with the replies used by the
1216 * iterator and thus some tables may be missed or a hang can occur. */
1217 static void
1218 table_iterator_init(struct table_iterator *ti, struct vconn *vconn)
1219 {
1220 memset(ti, 0, sizeof *ti);
1221 ti->vconn = vconn;
1222 ti->variant = (vconn_get_version(vconn) < OFP13_VERSION
1223 ? TI_STATS : TI_FEATURES);
1224 ti->more = true;
1225
1226 enum ofpraw ofpraw = (ti->variant == TI_STATS
1227 ? OFPRAW_OFPST_TABLE_REQUEST
1228 : OFPRAW_OFPST13_TABLE_FEATURES_REQUEST);
1229 struct ofpbuf *rq = ofpraw_alloc(ofpraw, vconn_get_version(vconn), 0);
1230 ti->send_xid = ((struct ofp_header *) rq->data)->xid;
1231 send_openflow_buffer(ti->vconn, rq);
1232 }
1233
1234 /* Obtains the next table from 'ti'. On success, returns the next table's
1235 * features; on failure, returns NULL. */
1236 static const struct ofputil_table_features *
1237 table_iterator_next(struct table_iterator *ti)
1238 {
1239 for (;;) {
1240 if (ti->reply) {
1241 int retval;
1242 if (ti->variant == TI_STATS) {
1243 struct ofputil_table_stats ts;
1244 retval = ofputil_decode_table_stats_reply(ti->reply,
1245 &ts, &ti->features);
1246 } else {
1247 ovs_assert(ti->variant == TI_FEATURES);
1248 retval = ofputil_decode_table_features(ti->reply,
1249 &ti->features,
1250 true);
1251 }
1252 if (!retval) {
1253 return &ti->features;
1254 } else if (retval != EOF) {
1255 ovs_fatal(0, "received bad reply: %s",
1256 ofp_to_string(ti->reply->data, ti->reply->size,
1257 NULL, NULL, verbosity + 1));
1258 }
1259 }
1260
1261 if (!ti->more) {
1262 return NULL;
1263 }
1264
1265 ovs_be32 recv_xid;
1266 do {
1267 ofpbuf_delete(ti->reply);
1268 run(vconn_recv_block(ti->vconn, &ti->reply),
1269 "OpenFlow receive failed");
1270 recv_xid = ((struct ofp_header *) ti->reply->data)->xid;
1271 } while (ti->send_xid != recv_xid);
1272
1273 struct ofp_header *oh = ti->reply->data;
1274 enum ofptype type;
1275 if (ofptype_pull(&type, ti->reply)
1276 || type != (ti->variant == TI_STATS
1277 ? OFPTYPE_TABLE_STATS_REPLY
1278 : OFPTYPE_TABLE_FEATURES_STATS_REPLY)) {
1279 ovs_fatal(0, "received bad reply: %s",
1280 ofp_to_string(ti->reply->data, ti->reply->size, NULL,
1281 NULL, verbosity + 1));
1282 }
1283
1284 ti->more = (ofpmp_flags(oh) & OFPSF_REPLY_MORE) != 0;
1285 }
1286 }
1287
1288 /* Destroys iterator 'ti'. */
1289 static void
1290 table_iterator_destroy(struct table_iterator *ti)
1291 {
1292 if (ti) {
1293 while (ti->more) {
1294 /* Drain vconn's queue of any other replies for this request. */
1295 table_iterator_next(ti);
1296 }
1297
1298 ofpbuf_delete(ti->reply);
1299 }
1300 }
1301
1302 static const struct ofputil_table_map *
1303 get_table_map(const char *vconn_name)
1304 {
1305 static struct shash table_maps = SHASH_INITIALIZER(&table_maps);
1306 struct ofputil_table_map *map = shash_find_data(&table_maps, vconn_name);
1307 if (!map) {
1308 map = xmalloc(sizeof *map);
1309 ofputil_table_map_init(map);
1310 shash_add(&table_maps, vconn_name, map);
1311
1312 if (!strchr(vconn_name, ':') || !vconn_verify_name(vconn_name)) {
1313 /* For an active vconn (which includes a vconn constructed from a
1314 * bridge name), connect to it and pull down the port name-number
1315 * mapping. */
1316 struct vconn *vconn;
1317 open_vconn(vconn_name, &vconn);
1318
1319 struct table_iterator ti;
1320 table_iterator_init(&ti, vconn);
1321 for (;;) {
1322 const struct ofputil_table_features *tf
1323 = table_iterator_next(&ti);
1324 if (!tf) {
1325 break;
1326 }
1327 if (tf->name[0]) {
1328 ofputil_table_map_put(map, tf->table_id, tf->name);
1329 }
1330 }
1331 table_iterator_destroy(&ti);
1332
1333 vconn_close(vconn);
1334 } else {
1335 /* Don't bother with passive vconns, since it could take a long
1336 * time for the remote to try to connect to us. Don't bother with
1337 * invalid vconn names either. */
1338 }
1339 }
1340 return map;
1341 }
1342
1343 static const struct ofputil_table_map *
1344 tables_to_accept(const char *vconn_name)
1345 {
1346 return should_accept_names() ? get_table_map(vconn_name) : NULL;
1347 }
1348
1349 static const struct ofputil_table_map *
1350 tables_to_show(const char *vconn_name)
1351 {
1352 return should_show_names() ? get_table_map(vconn_name) : NULL;
1353 }
1354
1355 /* We accept port and table names unless the feature is turned off
1356 * explicitly. */
1357 static bool
1358 should_accept_names(void)
1359 {
1360 return use_names != 0;
1361 }
1362
1363 /* We show port and table names only if the feature is turned on explicitly, or
1364 * if we're interacting with a user on the console. */
1365 static bool
1366 should_show_names(void)
1367 {
1368 static int interactive = -1;
1369 if (interactive == -1) {
1370 interactive = isatty(STDOUT_FILENO);
1371 }
1372
1373 return use_names > 0 || (use_names == -1 && interactive);
1374 }
1375
1376 /* Returns the port number corresponding to 'port_name' (which may be a port
1377 * name or number) within the switch 'vconn_name'. */
1378 static ofp_port_t
1379 str_to_port_no(const char *vconn_name, const char *port_name)
1380 {
1381 ofp_port_t port_no;
1382 if (ofputil_port_from_string(port_name, NULL, &port_no) ||
1383 ofputil_port_from_string(port_name, ports_to_accept(vconn_name),
1384 &port_no)) {
1385 return port_no;
1386 }
1387 ovs_fatal(0, "%s: unknown port `%s'", vconn_name, port_name);
1388 }
1389
1390 static bool
1391 try_set_protocol(struct vconn *vconn, enum ofputil_protocol want,
1392 enum ofputil_protocol *cur)
1393 {
1394 for (;;) {
1395 struct ofpbuf *request, *reply;
1396 enum ofputil_protocol next;
1397
1398 request = ofputil_encode_set_protocol(*cur, want, &next);
1399 if (!request) {
1400 return *cur == want;
1401 }
1402
1403 run(vconn_transact_noreply(vconn, request, &reply),
1404 "talking to %s", vconn_get_name(vconn));
1405 if (reply) {
1406 char *s = ofp_to_string(reply->data, reply->size, NULL, NULL, 2);
1407 VLOG_DBG("%s: failed to set protocol, switch replied: %s",
1408 vconn_get_name(vconn), s);
1409 free(s);
1410 ofpbuf_delete(reply);
1411 return false;
1412 }
1413
1414 *cur = next;
1415 }
1416 }
1417
1418 static enum ofputil_protocol
1419 set_protocol_for_flow_dump(struct vconn *vconn,
1420 enum ofputil_protocol cur_protocol,
1421 enum ofputil_protocol usable_protocols)
1422 {
1423 char *usable_s;
1424 int i;
1425
1426 for (i = 0; i < ofputil_n_flow_dump_protocols; i++) {
1427 enum ofputil_protocol f = ofputil_flow_dump_protocols[i];
1428 if (f & usable_protocols & allowed_protocols
1429 && try_set_protocol(vconn, f, &cur_protocol)) {
1430 return f;
1431 }
1432 }
1433
1434 usable_s = ofputil_protocols_to_string(usable_protocols);
1435 if (usable_protocols & allowed_protocols) {
1436 ovs_fatal(0, "switch does not support any of the usable flow "
1437 "formats (%s)", usable_s);
1438 } else {
1439 char *allowed_s = ofputil_protocols_to_string(allowed_protocols);
1440 ovs_fatal(0, "none of the usable flow formats (%s) is among the "
1441 "allowed flow formats (%s)", usable_s, allowed_s);
1442 }
1443 }
1444
1445 static struct vconn *
1446 prepare_dump_flows(int argc, char *argv[], bool aggregate,
1447 struct ofputil_flow_stats_request *fsr,
1448 enum ofputil_protocol *protocolp)
1449 {
1450 const char *vconn_name = argv[1];
1451 enum ofputil_protocol usable_protocols, protocol;
1452 struct vconn *vconn;
1453 char *error;
1454
1455 const char *match = argc > 2 ? argv[2] : "";
1456 const struct ofputil_port_map *port_map
1457 = *match ? ports_to_accept(vconn_name) : NULL;
1458 const struct ofputil_table_map *table_map
1459 = *match ? tables_to_accept(vconn_name) : NULL;
1460 error = parse_ofp_flow_stats_request_str(fsr, aggregate, match,
1461 port_map, table_map,
1462 &usable_protocols);
1463 if (error) {
1464 ovs_fatal(0, "%s", error);
1465 }
1466
1467 protocol = open_vconn(vconn_name, &vconn);
1468 *protocolp = set_protocol_for_flow_dump(vconn, protocol, usable_protocols);
1469 return vconn;
1470 }
1471
1472 static void
1473 ofctl_dump_flows__(int argc, char *argv[], bool aggregate)
1474 {
1475 struct ofputil_flow_stats_request fsr;
1476 enum ofputil_protocol protocol;
1477 struct vconn *vconn;
1478
1479 vconn = prepare_dump_flows(argc, argv, aggregate, &fsr, &protocol);
1480 dump_transaction(vconn, ofputil_encode_flow_stats_request(&fsr, protocol));
1481 vconn_close(vconn);
1482 }
1483
1484 static void
1485 get_match_field(const struct mf_field *field, const struct match *match,
1486 union mf_value *value)
1487 {
1488 if (!match->tun_md.valid || (field->id < MFF_TUN_METADATA0 ||
1489 field->id >= MFF_TUN_METADATA0 +
1490 TUN_METADATA_NUM_OPTS)) {
1491 mf_get_value(field, &match->flow, value);
1492 } else {
1493 const struct tun_metadata_loc *loc = &match->tun_md.entry[field->id -
1494 MFF_TUN_METADATA0].loc;
1495
1496 /* Since we don't have a tunnel mapping table, extract the value
1497 * from the locally allocated location in the match. */
1498 memset(value, 0, field->n_bytes - loc->len);
1499 memcpy(value->tun_metadata + field->n_bytes - loc->len,
1500 match->flow.tunnel.metadata.opts.u8 + loc->c.offset, loc->len);
1501 }
1502 }
1503
1504 static int
1505 compare_flows(const void *afs_, const void *bfs_)
1506 {
1507 const struct ofputil_flow_stats *afs = afs_;
1508 const struct ofputil_flow_stats *bfs = bfs_;
1509 const struct match *a = &afs->match;
1510 const struct match *b = &bfs->match;
1511 const struct sort_criterion *sc;
1512
1513 for (sc = criteria; sc < &criteria[n_criteria]; sc++) {
1514 const struct mf_field *f = sc->field;
1515 int ret;
1516
1517 if (!f) {
1518 int a_pri = afs->priority;
1519 int b_pri = bfs->priority;
1520 ret = a_pri < b_pri ? -1 : a_pri > b_pri;
1521 } else {
1522 bool ina, inb;
1523
1524 ina = mf_are_prereqs_ok(f, &a->flow, NULL)
1525 && !mf_is_all_wild(f, &a->wc);
1526 inb = mf_are_prereqs_ok(f, &b->flow, NULL)
1527 && !mf_is_all_wild(f, &b->wc);
1528 if (ina != inb) {
1529 /* Skip the test for sc->order, so that missing fields always
1530 * sort to the end whether we're sorting in ascending or
1531 * descending order. */
1532 return ina ? -1 : 1;
1533 } else {
1534 union mf_value aval, bval;
1535
1536 get_match_field(f, a, &aval);
1537 get_match_field(f, b, &bval);
1538 ret = memcmp(&aval, &bval, f->n_bytes);
1539 }
1540 }
1541
1542 if (ret) {
1543 return sc->order == SORT_ASC ? ret : -ret;
1544 }
1545 }
1546
1547 return 0;
1548 }
1549
1550 static void
1551 ofctl_dump_flows(struct ovs_cmdl_context *ctx)
1552 {
1553 if (!n_criteria && !should_show_names() && show_stats) {
1554 ofctl_dump_flows__(ctx->argc, ctx->argv, false);
1555 return;
1556 } else {
1557 struct ofputil_flow_stats_request fsr;
1558 enum ofputil_protocol protocol;
1559 struct vconn *vconn;
1560
1561 vconn = prepare_dump_flows(ctx->argc, ctx->argv, false,
1562 &fsr, &protocol);
1563
1564 struct ofputil_flow_stats *fses;
1565 size_t n_fses;
1566 run(vconn_dump_flows(vconn, &fsr, protocol, &fses, &n_fses),
1567 "dump flows");
1568
1569 qsort(fses, n_fses, sizeof *fses, compare_flows);
1570
1571 struct ds s = DS_EMPTY_INITIALIZER;
1572 for (size_t i = 0; i < n_fses; i++) {
1573 ds_clear(&s);
1574 ofputil_flow_stats_format(&s, &fses[i],
1575 ports_to_show(ctx->argv[1]),
1576 tables_to_show(ctx->argv[1]),
1577 show_stats);
1578 printf(" %s\n", ds_cstr(&s));
1579 }
1580 ds_destroy(&s);
1581
1582 for (size_t i = 0; i < n_fses; i++) {
1583 free(CONST_CAST(struct ofpact *, fses[i].ofpacts));
1584 }
1585 free(fses);
1586
1587 vconn_close(vconn);
1588 }
1589 }
1590
1591 static void
1592 ofctl_dump_aggregate(struct ovs_cmdl_context *ctx)
1593 {
1594 ofctl_dump_flows__(ctx->argc, ctx->argv, true);
1595 }
1596
1597 static void
1598 ofctl_queue_stats(struct ovs_cmdl_context *ctx)
1599 {
1600 struct ofpbuf *request;
1601 struct vconn *vconn;
1602 struct ofputil_queue_stats_request oqs;
1603
1604 open_vconn(ctx->argv[1], &vconn);
1605
1606 if (ctx->argc > 2 && ctx->argv[2][0] && strcasecmp(ctx->argv[2], "all")) {
1607 oqs.port_no = str_to_port_no(ctx->argv[1], ctx->argv[2]);
1608 } else {
1609 oqs.port_no = OFPP_ANY;
1610 }
1611 if (ctx->argc > 3 && ctx->argv[3][0] && strcasecmp(ctx->argv[3], "all")) {
1612 oqs.queue_id = atoi(ctx->argv[3]);
1613 } else {
1614 oqs.queue_id = OFPQ_ALL;
1615 }
1616
1617 request = ofputil_encode_queue_stats_request(vconn_get_version(vconn), &oqs);
1618 dump_transaction(vconn, request);
1619 vconn_close(vconn);
1620 }
1621
1622 static void
1623 ofctl_queue_get_config(struct ovs_cmdl_context *ctx)
1624 {
1625 const char *vconn_name = ctx->argv[1];
1626 const char *port_name = ctx->argc > 2 ? ctx->argv[2] : "any";
1627 ofp_port_t port = str_to_port_no(vconn_name, port_name);
1628 const char *queue_name = ctx->argc > 3 ? ctx->argv[3] : "all";
1629 uint32_t queue = (!strcasecmp(queue_name, "all")
1630 ? OFPQ_ALL
1631 : atoi(queue_name));
1632 struct vconn *vconn;
1633
1634 enum ofputil_protocol protocol = open_vconn(vconn_name, &vconn);
1635 enum ofp_version version = ofputil_protocol_to_ofp_version(protocol);
1636 if (port == OFPP_ANY && version == OFP10_VERSION) {
1637 /* The user requested all queues on all ports. OpenFlow 1.0 only
1638 * supports getting queues for an individual port, so to implement the
1639 * user's request we have to get a list of all the ports.
1640 *
1641 * We use a second vconn to avoid having to accumulate a list of all of
1642 * the ports. */
1643 struct vconn *vconn2;
1644 enum ofputil_protocol protocol2 = open_vconn(vconn_name, &vconn2);
1645 enum ofp_version version2 = ofputil_protocol_to_ofp_version(protocol2);
1646
1647 struct port_iterator pi;
1648 struct ofputil_phy_port pp;
1649 for (port_iterator_init(&pi, vconn); port_iterator_next(&pi, &pp); ) {
1650 if (ofp_to_u16(pp.port_no) < ofp_to_u16(OFPP_MAX)) {
1651 dump_transaction(vconn2,
1652 ofputil_encode_queue_get_config_request(
1653 version2, pp.port_no, queue));
1654 }
1655 }
1656 port_iterator_destroy(&pi);
1657 vconn_close(vconn2);
1658 } else {
1659 dump_transaction(vconn, ofputil_encode_queue_get_config_request(
1660 version, port, queue));
1661 }
1662 vconn_close(vconn);
1663 }
1664
1665 static enum ofputil_protocol
1666 open_vconn_for_flow_mod(const char *remote, struct vconn **vconnp,
1667 enum ofputil_protocol usable_protocols)
1668 {
1669 enum ofputil_protocol cur_protocol;
1670 char *usable_s;
1671 int i;
1672
1673 if (!(usable_protocols & allowed_protocols)) {
1674 char *allowed_s = ofputil_protocols_to_string(allowed_protocols);
1675 usable_s = ofputil_protocols_to_string(usable_protocols);
1676 ovs_fatal(0, "none of the usable flow formats (%s) is among the "
1677 "allowed flow formats (%s)", usable_s, allowed_s);
1678 }
1679
1680 /* If the initial flow format is allowed and usable, keep it. */
1681 cur_protocol = open_vconn(remote, vconnp);
1682 if (usable_protocols & allowed_protocols & cur_protocol) {
1683 return cur_protocol;
1684 }
1685
1686 /* Otherwise try each flow format in turn. */
1687 for (i = 0; i < sizeof(enum ofputil_protocol) * CHAR_BIT; i++) {
1688 enum ofputil_protocol f = 1 << i;
1689
1690 if (f != cur_protocol
1691 && f & usable_protocols & allowed_protocols
1692 && try_set_protocol(*vconnp, f, &cur_protocol)) {
1693 return f;
1694 }
1695 }
1696
1697 usable_s = ofputil_protocols_to_string(usable_protocols);
1698 ovs_fatal(0, "switch does not support any of the usable flow "
1699 "formats (%s)", usable_s);
1700 }
1701
1702 static void
1703 bundle_flow_mod__(const char *remote, struct ofputil_flow_mod *fms,
1704 size_t n_fms, enum ofputil_protocol usable_protocols)
1705 {
1706 enum ofputil_protocol protocol;
1707 struct vconn *vconn;
1708 struct ovs_list requests;
1709 size_t i;
1710
1711 ovs_list_init(&requests);
1712
1713 /* Bundles need OpenFlow 1.3+. */
1714 usable_protocols &= OFPUTIL_P_OF13_UP;
1715 protocol = open_vconn_for_flow_mod(remote, &vconn, usable_protocols);
1716
1717 for (i = 0; i < n_fms; i++) {
1718 struct ofputil_flow_mod *fm = &fms[i];
1719 struct ofpbuf *request = ofputil_encode_flow_mod(fm, protocol);
1720
1721 ovs_list_push_back(&requests, &request->list_node);
1722 free(CONST_CAST(struct ofpact *, fm->ofpacts));
1723 }
1724
1725 bundle_transact(vconn, &requests, OFPBF_ORDERED | OFPBF_ATOMIC);
1726 ofpbuf_list_delete(&requests);
1727 vconn_close(vconn);
1728 }
1729
1730 static void
1731 ofctl_flow_mod__(const char *remote, struct ofputil_flow_mod *fms,
1732 size_t n_fms, enum ofputil_protocol usable_protocols)
1733 {
1734 enum ofputil_protocol protocol;
1735 struct vconn *vconn;
1736 size_t i;
1737
1738 if (bundle) {
1739 bundle_flow_mod__(remote, fms, n_fms, usable_protocols);
1740 return;
1741 }
1742
1743 protocol = open_vconn_for_flow_mod(remote, &vconn, usable_protocols);
1744
1745 for (i = 0; i < n_fms; i++) {
1746 struct ofputil_flow_mod *fm = &fms[i];
1747
1748 transact_noreply(vconn, ofputil_encode_flow_mod(fm, protocol));
1749 free(CONST_CAST(struct ofpact *, fm->ofpacts));
1750 minimatch_destroy(&fm->match);
1751 }
1752 vconn_close(vconn);
1753 }
1754
1755 static void
1756 ofctl_flow_mod_file(int argc OVS_UNUSED, char *argv[], int command)
1757 {
1758 enum ofputil_protocol usable_protocols;
1759 struct ofputil_flow_mod *fms = NULL;
1760 size_t n_fms = 0;
1761 char *error;
1762
1763 if (command == OFPFC_ADD) {
1764 /* Allow the file to specify a mix of commands. If none specified at
1765 * the beginning of any given line, then the default is OFPFC_ADD, so
1766 * this is backwards compatible. */
1767 command = -2;
1768 }
1769 error = parse_ofp_flow_mod_file(argv[2], ports_to_accept(argv[1]),
1770 tables_to_accept(argv[1]), command,
1771 &fms, &n_fms, &usable_protocols);
1772 if (error) {
1773 ovs_fatal(0, "%s", error);
1774 }
1775 ofctl_flow_mod__(argv[1], fms, n_fms, usable_protocols);
1776 free(fms);
1777 }
1778
1779 static void
1780 ofctl_flow_mod(int argc, char *argv[], uint16_t command)
1781 {
1782 if (argc > 2 && !strcmp(argv[2], "-")) {
1783 ofctl_flow_mod_file(argc, argv, command);
1784 } else {
1785 struct ofputil_flow_mod fm;
1786 char *error;
1787 enum ofputil_protocol usable_protocols;
1788
1789 error = parse_ofp_flow_mod_str(&fm, argc > 2 ? argv[2] : "",
1790 ports_to_accept(argv[1]),
1791 tables_to_accept(argv[1]), command,
1792 &usable_protocols);
1793 if (error) {
1794 ovs_fatal(0, "%s", error);
1795 }
1796 ofctl_flow_mod__(argv[1], &fm, 1, usable_protocols);
1797 }
1798 }
1799
1800 static void
1801 ofctl_add_flow(struct ovs_cmdl_context *ctx)
1802 {
1803 ofctl_flow_mod(ctx->argc, ctx->argv, OFPFC_ADD);
1804 }
1805
1806 static void
1807 ofctl_add_flows(struct ovs_cmdl_context *ctx)
1808 {
1809 ofctl_flow_mod_file(ctx->argc, ctx->argv, OFPFC_ADD);
1810 }
1811
1812 static void
1813 ofctl_mod_flows(struct ovs_cmdl_context *ctx)
1814 {
1815 ofctl_flow_mod(ctx->argc, ctx->argv, strict ? OFPFC_MODIFY_STRICT : OFPFC_MODIFY);
1816 }
1817
1818 static void
1819 ofctl_del_flows(struct ovs_cmdl_context *ctx)
1820 {
1821 ofctl_flow_mod(ctx->argc, ctx->argv, strict ? OFPFC_DELETE_STRICT : OFPFC_DELETE);
1822 }
1823
1824 static bool
1825 set_packet_in_format(struct vconn *vconn,
1826 enum ofputil_packet_in_format packet_in_format,
1827 bool must_succeed)
1828 {
1829 struct ofpbuf *spif;
1830
1831 spif = ofputil_encode_set_packet_in_format(vconn_get_version(vconn),
1832 packet_in_format);
1833 if (must_succeed) {
1834 transact_noreply(vconn, spif);
1835 } else {
1836 struct ofpbuf *reply;
1837
1838 run(vconn_transact_noreply(vconn, spif, &reply),
1839 "talking to %s", vconn_get_name(vconn));
1840 if (reply) {
1841 char *s = ofp_to_string(reply->data, reply->size, NULL, NULL, 2);
1842 VLOG_DBG("%s: failed to set packet in format to nx_packet_in, "
1843 "controller replied: %s.",
1844 vconn_get_name(vconn), s);
1845 free(s);
1846 ofpbuf_delete(reply);
1847
1848 return false;
1849 } else {
1850 VLOG_DBG("%s: using user-specified packet in format %s",
1851 vconn_get_name(vconn),
1852 ofputil_packet_in_format_to_string(packet_in_format));
1853 }
1854 }
1855 return true;
1856 }
1857
1858 static int
1859 monitor_set_invalid_ttl_to_controller(struct vconn *vconn)
1860 {
1861 struct ofputil_switch_config config;
1862
1863 fetch_switch_config(vconn, &config);
1864 if (!config.invalid_ttl_to_controller) {
1865 config.invalid_ttl_to_controller = 1;
1866 set_switch_config(vconn, &config);
1867
1868 /* Then retrieve the configuration to see if it really took. OpenFlow
1869 * has ill-defined error reporting for bad flags, so this is about the
1870 * best we can do. */
1871 fetch_switch_config(vconn, &config);
1872 if (!config.invalid_ttl_to_controller) {
1873 ovs_fatal(0, "setting invalid_ttl_to_controller failed (this "
1874 "switch probably doesn't support this flag)");
1875 }
1876 }
1877 return 0;
1878 }
1879
1880 /* Converts hex digits in 'hex' to an OpenFlow message in '*msgp'. The
1881 * caller must free '*msgp'. On success, returns NULL. On failure, returns
1882 * an error message and stores NULL in '*msgp'. */
1883 static const char *
1884 openflow_from_hex(const char *hex, struct ofpbuf **msgp)
1885 {
1886 struct ofp_header *oh;
1887 struct ofpbuf *msg;
1888
1889 msg = ofpbuf_new(strlen(hex) / 2);
1890 *msgp = NULL;
1891
1892 if (ofpbuf_put_hex(msg, hex, NULL)[0] != '\0') {
1893 ofpbuf_delete(msg);
1894 return "Trailing garbage in hex data";
1895 }
1896
1897 if (msg->size < sizeof(struct ofp_header)) {
1898 ofpbuf_delete(msg);
1899 return "Message too short for OpenFlow";
1900 }
1901
1902 oh = msg->data;
1903 if (msg->size != ntohs(oh->length)) {
1904 ofpbuf_delete(msg);
1905 return "Message size does not match length in OpenFlow header";
1906 }
1907
1908 *msgp = msg;
1909 return NULL;
1910 }
1911
1912 static void
1913 ofctl_send(struct unixctl_conn *conn, int argc,
1914 const char *argv[], void *vconn_)
1915 {
1916 struct vconn *vconn = vconn_;
1917 struct ds reply;
1918 bool ok;
1919 int i;
1920
1921 ok = true;
1922 ds_init(&reply);
1923 for (i = 1; i < argc; i++) {
1924 const char *error_msg;
1925 struct ofpbuf *msg;
1926 int error;
1927
1928 error_msg = openflow_from_hex(argv[i], &msg);
1929 if (error_msg) {
1930 ds_put_format(&reply, "%s\n", error_msg);
1931 ok = false;
1932 continue;
1933 }
1934
1935 fprintf(stderr, "send: ");
1936 ofp_print(stderr, msg->data, msg->size,
1937 ports_to_show(vconn_get_name(vconn)),
1938 tables_to_show(vconn_get_name(vconn)), verbosity);
1939
1940 error = vconn_send_block(vconn, msg);
1941 if (error) {
1942 ofpbuf_delete(msg);
1943 ds_put_format(&reply, "%s\n", ovs_strerror(error));
1944 ok = false;
1945 } else {
1946 ds_put_cstr(&reply, "sent\n");
1947 }
1948 }
1949
1950 if (ok) {
1951 unixctl_command_reply(conn, ds_cstr(&reply));
1952 } else {
1953 unixctl_command_reply_error(conn, ds_cstr(&reply));
1954 }
1955 ds_destroy(&reply);
1956 }
1957
1958 static void
1959 unixctl_packet_out(struct unixctl_conn *conn, int OVS_UNUSED argc,
1960 const char *argv[], void *vconn_)
1961 {
1962 struct vconn *vconn = vconn_;
1963 enum ofputil_protocol protocol
1964 = ofputil_protocol_from_ofp_version(vconn_get_version(vconn));
1965 struct ds reply = DS_EMPTY_INITIALIZER;
1966 bool ok = true;
1967
1968 enum ofputil_protocol usable_protocols;
1969 struct ofputil_packet_out po;
1970 char *error_msg;
1971
1972 error_msg = parse_ofp_packet_out_str(
1973 &po, argv[1], ports_to_accept(vconn_get_name(vconn)),
1974 tables_to_accept(vconn_get_name(vconn)), &usable_protocols);
1975 if (error_msg) {
1976 ds_put_format(&reply, "%s\n", error_msg);
1977 free(error_msg);
1978 ok = false;
1979 }
1980
1981 if (ok && !(usable_protocols & protocol)) {
1982 ds_put_format(&reply, "PACKET_OUT actions are incompatible with the OpenFlow connection.\n");
1983 ok = false;
1984 }
1985
1986 if (ok) {
1987 struct ofpbuf *msg = ofputil_encode_packet_out(&po, protocol);
1988
1989 ofp_print(stderr, msg->data, msg->size,
1990 ports_to_show(vconn_get_name(vconn)),
1991 tables_to_show(vconn_get_name(vconn)), verbosity);
1992
1993 int error = vconn_send_block(vconn, msg);
1994 if (error) {
1995 ofpbuf_delete(msg);
1996 ds_put_format(&reply, "%s\n", ovs_strerror(error));
1997 ok = false;
1998 }
1999 }
2000
2001 if (ok) {
2002 unixctl_command_reply(conn, ds_cstr(&reply));
2003 } else {
2004 unixctl_command_reply_error(conn, ds_cstr(&reply));
2005 }
2006 ds_destroy(&reply);
2007
2008 if (!error_msg) {
2009 free(CONST_CAST(void *, po.packet));
2010 free(po.ofpacts);
2011 }
2012 }
2013
2014 struct barrier_aux {
2015 struct vconn *vconn; /* OpenFlow connection for sending barrier. */
2016 struct unixctl_conn *conn; /* Connection waiting for barrier response. */
2017 };
2018
2019 static void
2020 ofctl_barrier(struct unixctl_conn *conn, int argc OVS_UNUSED,
2021 const char *argv[] OVS_UNUSED, void *aux_)
2022 {
2023 struct barrier_aux *aux = aux_;
2024 struct ofpbuf *msg;
2025 int error;
2026
2027 if (aux->conn) {
2028 unixctl_command_reply_error(conn, "already waiting for barrier reply");
2029 return;
2030 }
2031
2032 msg = ofputil_encode_barrier_request(vconn_get_version(aux->vconn));
2033 error = vconn_send_block(aux->vconn, msg);
2034 if (error) {
2035 ofpbuf_delete(msg);
2036 unixctl_command_reply_error(conn, ovs_strerror(error));
2037 } else {
2038 aux->conn = conn;
2039 }
2040 }
2041
2042 static void
2043 ofctl_set_output_file(struct unixctl_conn *conn, int argc OVS_UNUSED,
2044 const char *argv[], void *aux OVS_UNUSED)
2045 {
2046 int fd;
2047
2048 fd = open(argv[1], O_CREAT | O_TRUNC | O_WRONLY, 0666);
2049 if (fd < 0) {
2050 unixctl_command_reply_error(conn, ovs_strerror(errno));
2051 return;
2052 }
2053
2054 fflush(stderr);
2055 dup2(fd, STDERR_FILENO);
2056 close(fd);
2057 unixctl_command_reply(conn, NULL);
2058 }
2059
2060 static void
2061 ofctl_block(struct unixctl_conn *conn, int argc OVS_UNUSED,
2062 const char *argv[] OVS_UNUSED, void *blocked_)
2063 {
2064 bool *blocked = blocked_;
2065
2066 if (!*blocked) {
2067 *blocked = true;
2068 unixctl_command_reply(conn, NULL);
2069 } else {
2070 unixctl_command_reply(conn, "already blocking");
2071 }
2072 }
2073
2074 static void
2075 ofctl_unblock(struct unixctl_conn *conn, int argc OVS_UNUSED,
2076 const char *argv[] OVS_UNUSED, void *blocked_)
2077 {
2078 bool *blocked = blocked_;
2079
2080 if (*blocked) {
2081 *blocked = false;
2082 unixctl_command_reply(conn, NULL);
2083 } else {
2084 unixctl_command_reply(conn, "already unblocked");
2085 }
2086 }
2087
2088 /* Prints to stderr all of the messages received on 'vconn'.
2089 *
2090 * Iff 'reply_to_echo_requests' is true, sends a reply to any echo request
2091 * received on 'vconn'.
2092 *
2093 * If 'resume_continuations' is true, sends an NXT_RESUME in reply to any
2094 * NXT_PACKET_IN2 that includes a continuation. */
2095 static void
2096 monitor_vconn(struct vconn *vconn, bool reply_to_echo_requests,
2097 bool resume_continuations)
2098 {
2099 struct barrier_aux barrier_aux = { vconn, NULL };
2100 struct unixctl_server *server;
2101 bool exiting = false;
2102 bool blocked = false;
2103 int error;
2104
2105 daemon_save_fd(STDERR_FILENO);
2106 daemonize_start(false);
2107 error = unixctl_server_create(unixctl_path, &server);
2108 if (error) {
2109 ovs_fatal(error, "failed to create unixctl server");
2110 }
2111 unixctl_command_register("exit", "", 0, 0, ofctl_exit, &exiting);
2112 unixctl_command_register("ofctl/send", "OFMSG...", 1, INT_MAX,
2113 ofctl_send, vconn);
2114 unixctl_command_register("ofctl/packet-out", "\"in_port=<port> packet=<hex data> actions=...\"", 1, 1,
2115 unixctl_packet_out, vconn);
2116 unixctl_command_register("ofctl/barrier", "", 0, 0,
2117 ofctl_barrier, &barrier_aux);
2118 unixctl_command_register("ofctl/set-output-file", "FILE", 1, 1,
2119 ofctl_set_output_file, NULL);
2120
2121 unixctl_command_register("ofctl/block", "", 0, 0, ofctl_block, &blocked);
2122 unixctl_command_register("ofctl/unblock", "", 0, 0, ofctl_unblock,
2123 &blocked);
2124
2125 daemonize_complete();
2126
2127 enum ofp_version version = vconn_get_version(vconn);
2128 enum ofputil_protocol protocol
2129 = ofputil_protocol_from_ofp_version(version);
2130
2131 for (;;) {
2132 struct ofpbuf *b;
2133 int retval;
2134
2135 unixctl_server_run(server);
2136
2137 while (!blocked) {
2138 enum ofptype type;
2139
2140 retval = vconn_recv(vconn, &b);
2141 if (retval == EAGAIN) {
2142 break;
2143 }
2144 run(retval, "vconn_recv");
2145
2146 if (timestamp) {
2147 char *s = xastrftime_msec("%Y-%m-%d %H:%M:%S.###: ",
2148 time_wall_msec(), true);
2149 fputs(s, stderr);
2150 free(s);
2151 }
2152
2153 ofptype_decode(&type, b->data);
2154 ofp_print(stderr, b->data, b->size,
2155 ports_to_show(vconn_get_name(vconn)),
2156 tables_to_show(vconn_get_name(vconn)), verbosity + 2);
2157 fflush(stderr);
2158
2159 switch ((int) type) {
2160 case OFPTYPE_BARRIER_REPLY:
2161 if (barrier_aux.conn) {
2162 unixctl_command_reply(barrier_aux.conn, NULL);
2163 barrier_aux.conn = NULL;
2164 }
2165 break;
2166
2167 case OFPTYPE_ECHO_REQUEST:
2168 if (reply_to_echo_requests) {
2169 struct ofpbuf *reply;
2170
2171 reply = ofputil_encode_echo_reply(b->data);
2172 retval = vconn_send_block(vconn, reply);
2173 if (retval) {
2174 ovs_fatal(retval, "failed to send echo reply");
2175 }
2176 }
2177 break;
2178
2179 case OFPTYPE_PACKET_IN:
2180 if (resume_continuations) {
2181 struct ofputil_packet_in pin;
2182 struct ofpbuf continuation;
2183
2184 error = ofputil_decode_packet_in(b->data, true, NULL, NULL,
2185 &pin, NULL, NULL,
2186 &continuation);
2187 if (error) {
2188 fprintf(stderr, "decoding packet-in failed: %s",
2189 ofperr_to_string(error));
2190 } else if (continuation.size) {
2191 struct ofpbuf *reply;
2192
2193 reply = ofputil_encode_resume(&pin, &continuation,
2194 protocol);
2195
2196 fprintf(stderr, "send: ");
2197 ofp_print(stderr, reply->data, reply->size,
2198 ports_to_show(vconn_get_name(vconn)),
2199 tables_to_show(vconn_get_name(vconn)),
2200 verbosity + 2);
2201 fflush(stderr);
2202
2203 retval = vconn_send_block(vconn, reply);
2204 if (retval) {
2205 ovs_fatal(retval, "failed to send NXT_RESUME");
2206 }
2207 }
2208 }
2209 break;
2210 }
2211 ofpbuf_delete(b);
2212 }
2213
2214 if (exiting) {
2215 break;
2216 }
2217
2218 vconn_run(vconn);
2219 vconn_run_wait(vconn);
2220 if (!blocked) {
2221 vconn_recv_wait(vconn);
2222 }
2223 unixctl_server_wait(server);
2224 poll_block();
2225 }
2226 vconn_close(vconn);
2227 unixctl_server_destroy(server);
2228 }
2229
2230 static void
2231 ofctl_monitor(struct ovs_cmdl_context *ctx)
2232 {
2233 struct vconn *vconn;
2234 int i;
2235 enum ofputil_protocol usable_protocols;
2236
2237 /* If the user wants the invalid_ttl_to_controller feature, limit the
2238 * OpenFlow versions to those that support that feature. (Support in
2239 * OpenFlow 1.0 is an Open vSwitch extension.) */
2240 for (i = 2; i < ctx->argc; i++) {
2241 if (!strcmp(ctx->argv[i], "invalid_ttl")) {
2242 uint32_t usable_versions = ((1u << OFP10_VERSION) |
2243 (1u << OFP11_VERSION) |
2244 (1u << OFP12_VERSION));
2245 uint32_t allowed_versions = get_allowed_ofp_versions();
2246 if (!(allowed_versions & usable_versions)) {
2247 struct ds versions = DS_EMPTY_INITIALIZER;
2248 ofputil_format_version_bitmap_names(&versions,
2249 usable_versions);
2250 ovs_fatal(0, "invalid_ttl requires one of the OpenFlow "
2251 "versions %s but none is enabled (use -O)",
2252 ds_cstr(&versions));
2253 }
2254 mask_allowed_ofp_versions(usable_versions);
2255 break;
2256 }
2257 }
2258
2259 open_vconn(ctx->argv[1], &vconn);
2260 bool resume_continuations = false;
2261 for (i = 2; i < ctx->argc; i++) {
2262 const char *arg = ctx->argv[i];
2263
2264 if (isdigit((unsigned char) *arg)) {
2265 struct ofputil_switch_config config;
2266
2267 fetch_switch_config(vconn, &config);
2268 config.miss_send_len = atoi(arg);
2269 set_switch_config(vconn, &config);
2270 } else if (!strcmp(arg, "invalid_ttl")) {
2271 monitor_set_invalid_ttl_to_controller(vconn);
2272 } else if (!strncmp(arg, "watch:", 6)) {
2273 struct ofputil_flow_monitor_request fmr;
2274 struct ofpbuf *msg;
2275 char *error;
2276
2277 error = parse_flow_monitor_request(&fmr, arg + 6,
2278 ports_to_accept(ctx->argv[1]),
2279 tables_to_accept(ctx->argv[1]),
2280 &usable_protocols);
2281 if (error) {
2282 ovs_fatal(0, "%s", error);
2283 }
2284
2285 msg = ofpbuf_new(0);
2286 ofputil_append_flow_monitor_request(&fmr, msg);
2287 dump_transaction(vconn, msg);
2288 fflush(stdout);
2289 } else if (!strcmp(arg, "resume")) {
2290 /* This option is intentionally undocumented because it is meant
2291 * only for testing. */
2292 resume_continuations = true;
2293
2294 /* Set miss_send_len to ensure that we get packet-ins. */
2295 struct ofputil_switch_config config;
2296 fetch_switch_config(vconn, &config);
2297 config.miss_send_len = UINT16_MAX;
2298 set_switch_config(vconn, &config);
2299 } else {
2300 ovs_fatal(0, "%s: unsupported \"monitor\" argument", arg);
2301 }
2302 }
2303
2304 if (preferred_packet_in_format >= 0) {
2305 /* A particular packet-in format was requested, so we must set it. */
2306 set_packet_in_format(vconn, preferred_packet_in_format, true);
2307 } else {
2308 /* Otherwise, we always prefer NXT_PACKET_IN2. */
2309 if (!set_packet_in_format(vconn, OFPUTIL_PACKET_IN_NXT2, false)) {
2310 /* We can't get NXT_PACKET_IN2. For OpenFlow 1.0 only, request
2311 * NXT_PACKET_IN. (Before 2.6, Open vSwitch will accept a request
2312 * for NXT_PACKET_IN with OF1.1+, but even after that it still
2313 * sends packet-ins in the OpenFlow native format.) */
2314 if (vconn_get_version(vconn) == OFP10_VERSION) {
2315 set_packet_in_format(vconn, OFPUTIL_PACKET_IN_NXT, false);
2316 }
2317 }
2318 }
2319
2320 monitor_vconn(vconn, true, resume_continuations);
2321 }
2322
2323 static void
2324 ofctl_snoop(struct ovs_cmdl_context *ctx)
2325 {
2326 struct vconn *vconn;
2327
2328 open_vconn__(ctx->argv[1], SNOOP, &vconn);
2329 monitor_vconn(vconn, false, false);
2330 }
2331
2332 static void
2333 ofctl_dump_ports(struct ovs_cmdl_context *ctx)
2334 {
2335 struct ofpbuf *request;
2336 struct vconn *vconn;
2337 ofp_port_t port;
2338
2339 open_vconn(ctx->argv[1], &vconn);
2340 port = ctx->argc > 2 ? str_to_port_no(ctx->argv[1], ctx->argv[2]) : OFPP_ANY;
2341 request = ofputil_encode_dump_ports_request(vconn_get_version(vconn), port);
2342 dump_transaction(vconn, request);
2343 vconn_close(vconn);
2344 }
2345
2346 static void
2347 ofctl_dump_ports_desc(struct ovs_cmdl_context *ctx)
2348 {
2349 struct ofpbuf *request;
2350 struct vconn *vconn;
2351 ofp_port_t port;
2352
2353 open_vconn(ctx->argv[1], &vconn);
2354 port = ctx->argc > 2 ? str_to_port_no(ctx->argv[1], ctx->argv[2]) : OFPP_ANY;
2355 request = ofputil_encode_port_desc_stats_request(vconn_get_version(vconn),
2356 port);
2357 dump_transaction(vconn, request);
2358 vconn_close(vconn);
2359 }
2360
2361 static void
2362 ofctl_probe(struct ovs_cmdl_context *ctx)
2363 {
2364 struct ofpbuf *request;
2365 struct vconn *vconn;
2366 struct ofpbuf *reply;
2367
2368 open_vconn(ctx->argv[1], &vconn);
2369 request = ofputil_encode_echo_request(vconn_get_version(vconn));
2370 run(vconn_transact(vconn, request, &reply), "talking to %s", ctx->argv[1]);
2371 if (reply->size != sizeof(struct ofp_header)) {
2372 ovs_fatal(0, "reply does not match request");
2373 }
2374 ofpbuf_delete(reply);
2375 vconn_close(vconn);
2376 }
2377
2378 static void
2379 ofctl_packet_out(struct ovs_cmdl_context *ctx)
2380 {
2381 enum ofputil_protocol usable_protocols;
2382 enum ofputil_protocol protocol;
2383 struct ofputil_packet_out po;
2384 struct vconn *vconn;
2385 struct ofpbuf *opo;
2386 char *error;
2387
2388 match_init_catchall(&po.flow_metadata);
2389 /* Use the old syntax when more than 4 arguments are given. */
2390 if (ctx->argc > 4) {
2391 struct ofpbuf ofpacts;
2392 int i;
2393
2394 ofpbuf_init(&ofpacts, 64);
2395 struct ofpact_parse_params pp = {
2396 .port_map = ports_to_accept(ctx->argv[1]),
2397 .table_map = tables_to_accept(ctx->argv[1]),
2398 .ofpacts = &ofpacts,
2399 .usable_protocols = &usable_protocols
2400 };
2401 error = ofpacts_parse_actions(ctx->argv[3], &pp);
2402 if (error) {
2403 ovs_fatal(0, "%s", error);
2404 }
2405
2406 po.buffer_id = UINT32_MAX;
2407 match_set_in_port(&po.flow_metadata,
2408 str_to_port_no(ctx->argv[1], ctx->argv[2]));
2409 po.ofpacts = ofpacts.data;
2410 po.ofpacts_len = ofpacts.size;
2411 po.flow_metadata.flow.packet_type = htonl(PT_ETH);
2412
2413 protocol = open_vconn_for_flow_mod(ctx->argv[1], &vconn,
2414 usable_protocols);
2415 for (i = 4; i < ctx->argc; i++) {
2416 struct dp_packet *packet;
2417 const char *error_msg;
2418
2419 error_msg = eth_from_hex(ctx->argv[i], &packet);
2420 if (error_msg) {
2421 ovs_fatal(0, "%s", error_msg);
2422 }
2423
2424 po.packet = dp_packet_data(packet);
2425 po.packet_len = dp_packet_size(packet);
2426 opo = ofputil_encode_packet_out(&po, protocol);
2427 transact_noreply(vconn, opo);
2428 dp_packet_delete(packet);
2429 }
2430 vconn_close(vconn);
2431 ofpbuf_uninit(&ofpacts);
2432 } else if (ctx->argc == 3) {
2433 error = parse_ofp_packet_out_str(&po, ctx->argv[2],
2434 ports_to_accept(ctx->argv[1]),
2435 tables_to_accept(ctx->argv[1]),
2436 &usable_protocols);
2437 if (error) {
2438 ovs_fatal(0, "%s", error);
2439 }
2440 protocol = open_vconn_for_flow_mod(ctx->argv[1], &vconn,
2441 usable_protocols);
2442 opo = ofputil_encode_packet_out(&po, protocol);
2443 transact_noreply(vconn, opo);
2444 vconn_close(vconn);
2445 free(CONST_CAST(void *, po.packet));
2446 free(po.ofpacts);
2447 } else {
2448 ovs_fatal(0, "Too many arguments (%d)", ctx->argc);
2449 }
2450 }
2451
2452 static void
2453 ofctl_mod_port(struct ovs_cmdl_context *ctx)
2454 {
2455 struct ofp_config_flag {
2456 const char *name; /* The flag's name. */
2457 enum ofputil_port_config bit; /* Bit to turn on or off. */
2458 bool on; /* Value to set the bit to. */
2459 };
2460 static const struct ofp_config_flag flags[] = {
2461 { "up", OFPUTIL_PC_PORT_DOWN, false },
2462 { "down", OFPUTIL_PC_PORT_DOWN, true },
2463 { "stp", OFPUTIL_PC_NO_STP, false },
2464 { "receive", OFPUTIL_PC_NO_RECV, false },
2465 { "receive-stp", OFPUTIL_PC_NO_RECV_STP, false },
2466 { "flood", OFPUTIL_PC_NO_FLOOD, false },
2467 { "forward", OFPUTIL_PC_NO_FWD, false },
2468 { "packet-in", OFPUTIL_PC_NO_PACKET_IN, false },
2469 };
2470
2471 const struct ofp_config_flag *flag;
2472 enum ofputil_protocol protocol;
2473 struct ofputil_port_mod pm;
2474 struct ofputil_phy_port pp;
2475 struct vconn *vconn;
2476 const char *command;
2477 bool not;
2478
2479 fetch_ofputil_phy_port(ctx->argv[1], ctx->argv[2], &pp);
2480
2481 pm.port_no = pp.port_no;
2482 pm.hw_addr = pp.hw_addr;
2483 pm.hw_addr64 = pp.hw_addr64;
2484 pm.config = 0;
2485 pm.mask = 0;
2486 pm.advertise = 0;
2487
2488 if (!strncasecmp(ctx->argv[3], "no-", 3)) {
2489 command = ctx->argv[3] + 3;
2490 not = true;
2491 } else if (!strncasecmp(ctx->argv[3], "no", 2)) {
2492 command = ctx->argv[3] + 2;
2493 not = true;
2494 } else {
2495 command = ctx->argv[3];
2496 not = false;
2497 }
2498 for (flag = flags; flag < &flags[ARRAY_SIZE(flags)]; flag++) {
2499 if (!strcasecmp(command, flag->name)) {
2500 pm.mask = flag->bit;
2501 pm.config = flag->on ^ not ? flag->bit : 0;
2502 goto found;
2503 }
2504 }
2505 ovs_fatal(0, "unknown mod-port command '%s'", ctx->argv[3]);
2506
2507 found:
2508 protocol = open_vconn(ctx->argv[1], &vconn);
2509 transact_noreply(vconn, ofputil_encode_port_mod(&pm, protocol));
2510 vconn_close(vconn);
2511 }
2512
2513 /* This function uses OFPMP14_TABLE_DESC request to get the current
2514 * table configuration from switch. The function then modifies
2515 * only that table-config property, which has been requested. */
2516 static void
2517 fetch_table_desc(struct vconn *vconn, struct ofputil_table_mod *tm,
2518 struct ofputil_table_desc *td)
2519 {
2520 struct ofpbuf *request;
2521 ovs_be32 send_xid;
2522 bool done = false;
2523 bool found = false;
2524
2525 request = ofputil_encode_table_desc_request(vconn_get_version(vconn));
2526 send_xid = ((struct ofp_header *) request->data)->xid;
2527 send_openflow_buffer(vconn, request);
2528 while (!done) {
2529 ovs_be32 recv_xid;
2530 struct ofpbuf *reply;
2531
2532 run(vconn_recv_block(vconn, &reply), "OpenFlow packet receive failed");
2533 recv_xid = ((struct ofp_header *) reply->data)->xid;
2534 if (send_xid == recv_xid) {
2535 struct ofp_header *oh = reply->data;
2536 struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
2537
2538 enum ofptype type;
2539 if (ofptype_pull(&type, &b)
2540 || type != OFPTYPE_TABLE_DESC_REPLY) {
2541 ovs_fatal(0, "received bad reply: %s",
2542 ofp_to_string(reply->data, reply->size, NULL, NULL,
2543 verbosity + 1));
2544 }
2545 uint16_t flags = ofpmp_flags(oh);
2546 done = !(flags & OFPSF_REPLY_MORE);
2547 if (found) {
2548 /* We've already found the table desc consisting of current
2549 * table configuration, but we need to drain the queue of
2550 * any other replies for this request. */
2551 continue;
2552 }
2553 while (!ofputil_decode_table_desc(&b, td, oh->version)) {
2554 if (td->table_id == tm->table_id) {
2555 found = true;
2556 break;
2557 }
2558 }
2559 } else {
2560 VLOG_DBG("received reply with xid %08"PRIx32" "
2561 "!= expected %08"PRIx32, recv_xid, send_xid);
2562 }
2563 ofpbuf_delete(reply);
2564 }
2565 if (tm->eviction != OFPUTIL_TABLE_EVICTION_DEFAULT) {
2566 tm->vacancy = td->vacancy;
2567 tm->table_vacancy.vacancy_down = td->table_vacancy.vacancy_down;
2568 tm->table_vacancy.vacancy_up = td->table_vacancy.vacancy_up;
2569 } else if (tm->vacancy != OFPUTIL_TABLE_VACANCY_DEFAULT) {
2570 tm->eviction = td->eviction;
2571 tm->eviction_flags = td->eviction_flags;
2572 }
2573 }
2574
2575 static void
2576 ofctl_mod_table(struct ovs_cmdl_context *ctx)
2577 {
2578 uint32_t usable_versions;
2579 struct ofputil_table_mod tm;
2580 struct vconn *vconn;
2581 char *error;
2582 int i;
2583
2584 error = parse_ofp_table_mod(&tm, ctx->argv[2], ctx->argv[3],
2585 tables_to_accept(ctx->argv[1]),
2586 &usable_versions);
2587 if (error) {
2588 ovs_fatal(0, "%s", error);
2589 }
2590
2591 uint32_t allowed_versions = get_allowed_ofp_versions();
2592 if (!(allowed_versions & usable_versions)) {
2593 struct ds versions = DS_EMPTY_INITIALIZER;
2594 ofputil_format_version_bitmap_names(&versions, usable_versions);
2595 ovs_fatal(0, "table_mod '%s' requires one of the OpenFlow "
2596 "versions %s",
2597 ctx->argv[3], ds_cstr(&versions));
2598 }
2599 mask_allowed_ofp_versions(usable_versions);
2600 enum ofputil_protocol protocol = open_vconn(ctx->argv[1], &vconn);
2601
2602 /* For OpenFlow 1.4+, ovs-ofctl mod-table should not affect table-config
2603 * properties that the user didn't ask to change, so it is necessary to
2604 * restore the current configuration of table-config parameters using
2605 * OFPMP14_TABLE_DESC request. */
2606 if ((allowed_versions & (1u << OFP14_VERSION)) ||
2607 (allowed_versions & (1u << OFP15_VERSION))) {
2608 struct ofputil_table_desc td;
2609
2610 if (tm.table_id == OFPTT_ALL) {
2611 for (i = 0; i < OFPTT_MAX; i++) {
2612 tm.table_id = i;
2613 fetch_table_desc(vconn, &tm, &td);
2614 transact_noreply(vconn,
2615 ofputil_encode_table_mod(&tm, protocol));
2616 }
2617 } else {
2618 fetch_table_desc(vconn, &tm, &td);
2619 transact_noreply(vconn, ofputil_encode_table_mod(&tm, protocol));
2620 }
2621 } else {
2622 transact_noreply(vconn, ofputil_encode_table_mod(&tm, protocol));
2623 }
2624 vconn_close(vconn);
2625 }
2626
2627 static void
2628 ofctl_get_frags(struct ovs_cmdl_context *ctx)
2629 {
2630 struct ofputil_switch_config config;
2631 struct vconn *vconn;
2632
2633 open_vconn(ctx->argv[1], &vconn);
2634 fetch_switch_config(vconn, &config);
2635 puts(ofputil_frag_handling_to_string(config.frag));
2636 vconn_close(vconn);
2637 }
2638
2639 static void
2640 ofctl_set_frags(struct ovs_cmdl_context *ctx)
2641 {
2642 struct ofputil_switch_config config;
2643 enum ofputil_frag_handling frag;
2644 struct vconn *vconn;
2645
2646 if (!ofputil_frag_handling_from_string(ctx->argv[2], &frag)) {
2647 ovs_fatal(0, "%s: unknown fragment handling mode", ctx->argv[2]);
2648 }
2649
2650 open_vconn(ctx->argv[1], &vconn);
2651 fetch_switch_config(vconn, &config);
2652 if (frag != config.frag) {
2653 /* Set the configuration. */
2654 config.frag = frag;
2655 set_switch_config(vconn, &config);
2656
2657 /* Then retrieve the configuration to see if it really took. OpenFlow
2658 * has ill-defined error reporting for bad flags, so this is about the
2659 * best we can do. */
2660 fetch_switch_config(vconn, &config);
2661 if (frag != config.frag) {
2662 ovs_fatal(0, "%s: setting fragment handling mode failed (this "
2663 "switch probably doesn't support mode \"%s\")",
2664 ctx->argv[1], ofputil_frag_handling_to_string(frag));
2665 }
2666 }
2667 vconn_close(vconn);
2668 }
2669
2670 static void
2671 ofctl_ofp_parse(struct ovs_cmdl_context *ctx)
2672 {
2673 const char *filename = ctx->argv[1];
2674 struct ofpbuf b;
2675 FILE *file;
2676
2677 file = !strcmp(filename, "-") ? stdin : fopen(filename, "r");
2678 if (file == NULL) {
2679 ovs_fatal(errno, "%s: open", filename);
2680 }
2681
2682 ofpbuf_init(&b, 65536);
2683 for (;;) {
2684 struct ofp_header *oh;
2685 size_t length, tail_len;
2686 void *tail;
2687 size_t n;
2688
2689 ofpbuf_clear(&b);
2690 oh = ofpbuf_put_uninit(&b, sizeof *oh);
2691 n = fread(oh, 1, sizeof *oh, file);
2692 if (n == 0) {
2693 break;
2694 } else if (n < sizeof *oh) {
2695 ovs_fatal(0, "%s: unexpected end of file mid-message", filename);
2696 }
2697
2698 length = ntohs(oh->length);
2699 if (length < sizeof *oh) {
2700 ovs_fatal(0, "%s: %"PRIuSIZE"-byte message is too short for OpenFlow",
2701 filename, length);
2702 }
2703
2704 tail_len = length - sizeof *oh;
2705 tail = ofpbuf_put_uninit(&b, tail_len);
2706 n = fread(tail, 1, tail_len, file);
2707 if (n < tail_len) {
2708 ovs_fatal(0, "%s: unexpected end of file mid-message", filename);
2709 }
2710
2711 ofp_print(stdout, b.data, b.size, NULL, NULL, verbosity + 2);
2712 }
2713 ofpbuf_uninit(&b);
2714
2715 if (file != stdin) {
2716 fclose(file);
2717 }
2718 }
2719
2720 static bool
2721 is_openflow_port(ovs_be16 port_, char *ports[])
2722 {
2723 uint16_t port = ntohs(port_);
2724 if (ports[0]) {
2725 int i;
2726
2727 for (i = 0; ports[i]; i++) {
2728 if (port == atoi(ports[i])) {
2729 return true;
2730 }
2731 }
2732 return false;
2733 } else {
2734 return port == OFP_PORT || port == OFP_OLD_PORT;
2735 }
2736 }
2737
2738 static void
2739 ofctl_ofp_parse_pcap(struct ovs_cmdl_context *ctx)
2740 {
2741 struct tcp_reader *reader;
2742 FILE *file;
2743 int error;
2744 bool first;
2745
2746 file = ovs_pcap_open(ctx->argv[1], "rb");
2747 if (!file) {
2748 ovs_fatal(errno, "%s: open failed", ctx->argv[1]);
2749 }
2750
2751 reader = tcp_reader_open();
2752 first = true;
2753 for (;;) {
2754 struct dp_packet *packet;
2755 long long int when;
2756 struct flow flow;
2757
2758 error = ovs_pcap_read(file, &packet, &when);
2759 if (error) {
2760 break;
2761 }
2762 pkt_metadata_init(&packet->md, ODPP_NONE);
2763 flow_extract(packet, &flow);
2764 if (flow.dl_type == htons(ETH_TYPE_IP)
2765 && flow.nw_proto == IPPROTO_TCP
2766 && (is_openflow_port(flow.tp_src, ctx->argv + 2) ||
2767 is_openflow_port(flow.tp_dst, ctx->argv + 2))) {
2768 struct dp_packet *payload = tcp_reader_run(reader, &flow, packet);
2769 if (payload) {
2770 while (dp_packet_size(payload) >= sizeof(struct ofp_header)) {
2771 const struct ofp_header *oh;
2772 void *data = dp_packet_data(payload);
2773 int length;
2774
2775 /* Align OpenFlow on 8-byte boundary for safe access. */
2776 dp_packet_shift(payload, -((intptr_t) data & 7));
2777
2778 oh = dp_packet_data(payload);
2779 length = ntohs(oh->length);
2780 if (dp_packet_size(payload) < length) {
2781 break;
2782 }
2783
2784 if (!first) {
2785 putchar('\n');
2786 }
2787 first = false;
2788
2789 if (timestamp) {
2790 char *s = xastrftime_msec("%H:%M:%S.### ", when, true);
2791 fputs(s, stdout);
2792 free(s);
2793 }
2794
2795 printf(IP_FMT".%"PRIu16" > "IP_FMT".%"PRIu16":\n",
2796 IP_ARGS(flow.nw_src), ntohs(flow.tp_src),
2797 IP_ARGS(flow.nw_dst), ntohs(flow.tp_dst));
2798 ofp_print(stdout, dp_packet_data(payload), length,
2799 NULL, NULL, verbosity + 1);
2800 dp_packet_pull(payload, length);
2801 }
2802 }
2803 }
2804 dp_packet_delete(packet);
2805 }
2806 tcp_reader_close(reader);
2807 fclose(file);
2808 }
2809
2810 static void
2811 ofctl_ping(struct ovs_cmdl_context *ctx)
2812 {
2813 size_t max_payload = 65535 - sizeof(struct ofp_header);
2814 unsigned int payload;
2815 struct vconn *vconn;
2816 int i;
2817
2818 payload = ctx->argc > 2 ? atoi(ctx->argv[2]) : 64;
2819 if (payload > max_payload) {
2820 ovs_fatal(0, "payload must be between 0 and %"PRIuSIZE" bytes", max_payload);
2821 }
2822
2823 open_vconn(ctx->argv[1], &vconn);
2824 for (i = 0; i < 10; i++) {
2825 struct timeval start, end;
2826 struct ofpbuf *request, *reply;
2827 const struct ofp_header *rpy_hdr;
2828 enum ofptype type;
2829
2830 request = ofpraw_alloc(OFPRAW_OFPT_ECHO_REQUEST,
2831 vconn_get_version(vconn), payload);
2832 random_bytes(ofpbuf_put_uninit(request, payload), payload);
2833
2834 xgettimeofday(&start);
2835 run(vconn_transact(vconn, ofpbuf_clone(request), &reply), "transact");
2836 xgettimeofday(&end);
2837
2838 rpy_hdr = reply->data;
2839 if (ofptype_pull(&type, reply)
2840 || type != OFPTYPE_ECHO_REPLY
2841 || reply->size != payload
2842 || memcmp(request->msg, reply->msg, payload)) {
2843 printf("Reply does not match request. Request:\n");
2844 ofp_print(stdout, request, request->size, NULL, NULL,
2845 verbosity + 2);
2846 printf("Reply:\n");
2847 ofp_print(stdout, reply, reply->size, NULL, NULL, verbosity + 2);
2848 }
2849 printf("%"PRIu32" bytes from %s: xid=%08"PRIx32" time=%.1f ms\n",
2850 reply->size, ctx->argv[1], ntohl(rpy_hdr->xid),
2851 (1000*(double)(end.tv_sec - start.tv_sec))
2852 + (.001*(end.tv_usec - start.tv_usec)));
2853 ofpbuf_delete(request);
2854 ofpbuf_delete(reply);
2855 }
2856 vconn_close(vconn);
2857 }
2858
2859 static void
2860 ofctl_benchmark(struct ovs_cmdl_context *ctx)
2861 {
2862 size_t max_payload = 65535 - sizeof(struct ofp_header);
2863 struct timeval start, end;
2864 unsigned int payload_size, message_size;
2865 struct vconn *vconn;
2866 double duration;
2867 int count;
2868 int i;
2869
2870 payload_size = atoi(ctx->argv[2]);
2871 if (payload_size > max_payload) {
2872 ovs_fatal(0, "payload must be between 0 and %"PRIuSIZE" bytes", max_payload);
2873 }
2874 message_size = sizeof(struct ofp_header) + payload_size;
2875
2876 count = atoi(ctx->argv[3]);
2877
2878 printf("Sending %d packets * %u bytes (with header) = %u bytes total\n",
2879 count, message_size, count * message_size);
2880
2881 open_vconn(ctx->argv[1], &vconn);
2882 xgettimeofday(&start);
2883 for (i = 0; i < count; i++) {
2884 struct ofpbuf *request, *reply;
2885
2886 request = ofpraw_alloc(OFPRAW_OFPT_ECHO_REQUEST,
2887 vconn_get_version(vconn), payload_size);
2888 ofpbuf_put_zeros(request, payload_size);
2889 run(vconn_transact(vconn, request, &reply), "transact");
2890 ofpbuf_delete(reply);
2891 }
2892 xgettimeofday(&end);
2893 vconn_close(vconn);
2894
2895 duration = ((1000*(double)(end.tv_sec - start.tv_sec))
2896 + (.001*(end.tv_usec - start.tv_usec)));
2897 printf("Finished in %.1f ms (%.0f packets/s) (%.0f bytes/s)\n",
2898 duration, count / (duration / 1000.0),
2899 count * message_size / (duration / 1000.0));
2900 }
2901
2902 static void
2903 ofctl_dump_ipfix_bridge(struct ovs_cmdl_context *ctx)
2904 {
2905 dump_trivial_transaction(ctx->argv[1], OFPRAW_NXST_IPFIX_BRIDGE_REQUEST);
2906 }
2907
2908 static void
2909 ofctl_ct_flush_zone(struct ovs_cmdl_context *ctx)
2910 {
2911 uint16_t zone_id;
2912 char *error = str_to_u16(ctx->argv[2], "zone_id", &zone_id);
2913 if (error) {
2914 ovs_fatal(0, "%s", error);
2915 }
2916
2917 struct vconn *vconn;
2918 open_vconn(ctx->argv[1], &vconn);
2919 enum ofp_version version = vconn_get_version(vconn);
2920
2921 struct ofpbuf *msg = ofpraw_alloc(OFPRAW_NXT_CT_FLUSH_ZONE, version, 0);
2922 struct nx_zone_id *nzi = ofpbuf_put_zeros(msg, sizeof *nzi);
2923 nzi->zone_id = htons(zone_id);
2924
2925 transact_noreply(vconn, msg);
2926 vconn_close(vconn);
2927 }
2928
2929 static void
2930 ofctl_dump_ipfix_flow(struct ovs_cmdl_context *ctx)
2931 {
2932 dump_trivial_transaction(ctx->argv[1], OFPRAW_NXST_IPFIX_FLOW_REQUEST);
2933 }
2934
2935 static void
2936 bundle_group_mod__(const char *remote, struct ofputil_group_mod *gms,
2937 size_t n_gms, enum ofputil_protocol usable_protocols)
2938 {
2939 enum ofputil_protocol protocol;
2940 enum ofp_version version;
2941 struct vconn *vconn;
2942 struct ovs_list requests;
2943 size_t i;
2944
2945 ovs_list_init(&requests);
2946
2947 /* Bundles need OpenFlow 1.3+. */
2948 usable_protocols &= OFPUTIL_P_OF13_UP;
2949 protocol = open_vconn_for_flow_mod(remote, &vconn, usable_protocols);
2950 version = ofputil_protocol_to_ofp_version(protocol);
2951
2952 for (i = 0; i < n_gms; i++) {
2953 struct ofputil_group_mod *gm = &gms[i];
2954 struct ofpbuf *request = ofputil_encode_group_mod(version, gm);
2955
2956 ovs_list_push_back(&requests, &request->list_node);
2957 ofputil_uninit_group_mod(gm);
2958 }
2959
2960 bundle_transact(vconn, &requests, OFPBF_ORDERED | OFPBF_ATOMIC);
2961 ofpbuf_list_delete(&requests);
2962 vconn_close(vconn);
2963 }
2964
2965 static void
2966 ofctl_group_mod__(const char *remote, struct ofputil_group_mod *gms,
2967 size_t n_gms, enum ofputil_protocol usable_protocols)
2968 {
2969 enum ofputil_protocol protocol;
2970 struct ofputil_group_mod *gm;
2971 enum ofp_version version;
2972 struct ofpbuf *request;
2973
2974 struct vconn *vconn;
2975 size_t i;
2976
2977 if (bundle) {
2978 bundle_group_mod__(remote, gms, n_gms, usable_protocols);
2979 return;
2980 }
2981
2982 protocol = open_vconn_for_flow_mod(remote, &vconn, usable_protocols);
2983 version = ofputil_protocol_to_ofp_version(protocol);
2984
2985 for (i = 0; i < n_gms; i++) {
2986 gm = &gms[i];
2987 request = ofputil_encode_group_mod(version, gm);
2988 transact_noreply(vconn, request);
2989 ofputil_uninit_group_mod(gm);
2990 }
2991
2992 vconn_close(vconn);
2993 }
2994
2995 static void
2996 ofctl_group_mod_file(int argc OVS_UNUSED, char *argv[], int command)
2997 {
2998 struct ofputil_group_mod *gms = NULL;
2999 enum ofputil_protocol usable_protocols;
3000 size_t n_gms = 0;
3001 char *error;
3002
3003 if (command == OFPGC11_ADD) {
3004 /* Allow the file to specify a mix of commands. If none specified at
3005 * the beginning of any given line, then the default is OFPGC11_ADD, so
3006 * this is backwards compatible. */
3007 command = -2;
3008 }
3009 error = parse_ofp_group_mod_file(argv[2], ports_to_accept(argv[1]),
3010 tables_to_accept(argv[1]),
3011 command, &gms, &n_gms, &usable_protocols);
3012 if (error) {
3013 ovs_fatal(0, "%s", error);
3014 }
3015 ofctl_group_mod__(argv[1], gms, n_gms, usable_protocols);
3016 free(gms);
3017 }
3018
3019 static void
3020 ofctl_group_mod(int argc, char *argv[], uint16_t command)
3021 {
3022 if (argc > 2 && !strcmp(argv[2], "-")) {
3023 ofctl_group_mod_file(argc, argv, command);
3024 } else {
3025 enum ofputil_protocol usable_protocols;
3026 struct ofputil_group_mod gm;
3027 char *error;
3028
3029 error = parse_ofp_group_mod_str(&gm, command, argc > 2 ? argv[2] : "",
3030 ports_to_accept(argv[1]),
3031 tables_to_accept(argv[1]),
3032 &usable_protocols);
3033 if (error) {
3034 ovs_fatal(0, "%s", error);
3035 }
3036 ofctl_group_mod__(argv[1], &gm, 1, usable_protocols);
3037 }
3038 }
3039
3040 static void
3041 ofctl_add_group(struct ovs_cmdl_context *ctx)
3042 {
3043 ofctl_group_mod(ctx->argc, ctx->argv, OFPGC11_ADD);
3044 }
3045
3046 static void
3047 ofctl_add_groups(struct ovs_cmdl_context *ctx)
3048 {
3049 ofctl_group_mod_file(ctx->argc, ctx->argv, OFPGC11_ADD);
3050 }
3051
3052 static void
3053 ofctl_mod_group(struct ovs_cmdl_context *ctx)
3054 {
3055 ofctl_group_mod(ctx->argc, ctx->argv,
3056 may_create ? OFPGC11_ADD_OR_MOD : OFPGC11_MODIFY);
3057 }
3058
3059 static void
3060 ofctl_del_groups(struct ovs_cmdl_context *ctx)
3061 {
3062 ofctl_group_mod(ctx->argc, ctx->argv, OFPGC11_DELETE);
3063 }
3064
3065 static void
3066 ofctl_insert_bucket(struct ovs_cmdl_context *ctx)
3067 {
3068 ofctl_group_mod(ctx->argc, ctx->argv, OFPGC15_INSERT_BUCKET);
3069 }
3070
3071 static void
3072 ofctl_remove_bucket(struct ovs_cmdl_context *ctx)
3073 {
3074 ofctl_group_mod(ctx->argc, ctx->argv, OFPGC15_REMOVE_BUCKET);
3075 }
3076
3077 static void
3078 ofctl_dump_group_stats(struct ovs_cmdl_context *ctx)
3079 {
3080 enum ofputil_protocol usable_protocols;
3081 struct ofputil_group_mod gm;
3082 struct ofpbuf *request;
3083 struct vconn *vconn;
3084 uint32_t group_id;
3085 char *error;
3086
3087 memset(&gm, 0, sizeof gm);
3088
3089 error = parse_ofp_group_mod_str(&gm, OFPGC11_DELETE,
3090 ctx->argc > 2 ? ctx->argv[2] : "",
3091 ports_to_accept(ctx->argv[1]),
3092 tables_to_accept(ctx->argv[1]),
3093 &usable_protocols);
3094 if (error) {
3095 ovs_fatal(0, "%s", error);
3096 }
3097
3098 group_id = gm.group_id;
3099
3100 open_vconn(ctx->argv[1], &vconn);
3101 request = ofputil_encode_group_stats_request(vconn_get_version(vconn),
3102 group_id);
3103 if (request) {
3104 dump_transaction(vconn, request);
3105 }
3106
3107 vconn_close(vconn);
3108 }
3109
3110 static void
3111 ofctl_dump_group_desc(struct ovs_cmdl_context *ctx)
3112 {
3113 struct ofpbuf *request;
3114 struct vconn *vconn;
3115 uint32_t group_id;
3116
3117 open_vconn(ctx->argv[1], &vconn);
3118
3119 if (ctx->argc < 3 || !ofputil_group_from_string(ctx->argv[2], &group_id)) {
3120 group_id = OFPG_ALL;
3121 }
3122
3123 request = ofputil_encode_group_desc_request(vconn_get_version(vconn),
3124 group_id);
3125 if (request) {
3126 dump_transaction(vconn, request);
3127 }
3128
3129 vconn_close(vconn);
3130 }
3131
3132 static void
3133 ofctl_dump_group_features(struct ovs_cmdl_context *ctx)
3134 {
3135 struct ofpbuf *request;
3136 struct vconn *vconn;
3137
3138 open_vconn(ctx->argv[1], &vconn);
3139 request = ofputil_encode_group_features_request(vconn_get_version(vconn));
3140 if (request) {
3141 dump_transaction(vconn, request);
3142 }
3143
3144 vconn_close(vconn);
3145 }
3146
3147 static void
3148 ofctl_bundle(struct ovs_cmdl_context *ctx)
3149 {
3150 enum ofputil_protocol protocol, usable_protocols;
3151 struct ofputil_bundle_msg *bms;
3152 struct ovs_list requests;
3153 struct vconn *vconn;
3154 size_t n_bms;
3155 char *error;
3156
3157 error = parse_ofp_bundle_file(ctx->argv[2], ports_to_accept(ctx->argv[1]),
3158 tables_to_accept(ctx->argv[1]),
3159 &bms, &n_bms, &usable_protocols);
3160 if (error) {
3161 ovs_fatal(0, "%s", error);
3162 }
3163
3164 /* Implicit OpenFlow 1.4. */
3165 if (!(get_allowed_ofp_versions() &
3166 ofputil_protocols_to_version_bitmap(OFPUTIL_P_OF13_UP))) {
3167
3168 /* Add implicit allowance for OpenFlow 1.4. */
3169 add_allowed_ofp_versions(ofputil_protocols_to_version_bitmap(
3170 OFPUTIL_P_OF14_OXM));
3171 /* Remove all versions that do not support bundles. */
3172 mask_allowed_ofp_versions(ofputil_protocols_to_version_bitmap(
3173 OFPUTIL_P_OF13_UP));
3174 allowed_protocols = ofputil_protocols_from_version_bitmap(
3175 get_allowed_ofp_versions());
3176 }
3177
3178 /* Bundles need OpenFlow 1.3+. */
3179 usable_protocols &= OFPUTIL_P_OF13_UP;
3180 protocol = open_vconn_for_flow_mod(ctx->argv[1], &vconn, usable_protocols);
3181
3182 ovs_list_init(&requests);
3183 ofputil_encode_bundle_msgs(bms, n_bms, &requests, protocol);
3184 ofputil_free_bundle_msgs(bms, n_bms);
3185 bundle_transact(vconn, &requests, OFPBF_ORDERED | OFPBF_ATOMIC);
3186 ofpbuf_list_delete(&requests);
3187
3188 vconn_close(vconn);
3189 }
3190
3191 static void
3192 ofctl_tlv_mod(struct ovs_cmdl_context *ctx, uint16_t command)
3193 {
3194 enum ofputil_protocol usable_protocols;
3195 enum ofputil_protocol protocol;
3196 struct ofputil_tlv_table_mod ttm;
3197 char *error;
3198 enum ofp_version version;
3199 struct ofpbuf *request;
3200 struct vconn *vconn;
3201
3202 error = parse_ofp_tlv_table_mod_str(&ttm, command, ctx->argc > 2 ?
3203 ctx->argv[2] : "",
3204 &usable_protocols);
3205 if (error) {
3206 ovs_fatal(0, "%s", error);
3207 }
3208
3209 protocol = open_vconn_for_flow_mod(ctx->argv[1], &vconn, usable_protocols);
3210 version = ofputil_protocol_to_ofp_version(protocol);
3211
3212 request = ofputil_encode_tlv_table_mod(version, &ttm);
3213 if (request) {
3214 transact_noreply(vconn, request);
3215 }
3216
3217 vconn_close(vconn);
3218 ofputil_uninit_tlv_table(&ttm.mappings);
3219 }
3220
3221 static void
3222 ofctl_add_tlv_map(struct ovs_cmdl_context *ctx)
3223 {
3224 ofctl_tlv_mod(ctx, NXTTMC_ADD);
3225 }
3226
3227 static void
3228 ofctl_del_tlv_map(struct ovs_cmdl_context *ctx)
3229 {
3230 ofctl_tlv_mod(ctx, ctx->argc > 2 ? NXTTMC_DELETE : NXTTMC_CLEAR);
3231 }
3232
3233 static void
3234 ofctl_dump_tlv_map(struct ovs_cmdl_context *ctx)
3235 {
3236 dump_trivial_transaction(ctx->argv[1], OFPRAW_NXT_TLV_TABLE_REQUEST);
3237 }
3238
3239 static void
3240 ofctl_help(struct ovs_cmdl_context *ctx OVS_UNUSED)
3241 {
3242 usage();
3243 }
3244
3245 static void
3246 ofctl_list_commands(struct ovs_cmdl_context *ctx OVS_UNUSED)
3247 {
3248 ovs_cmdl_print_commands(get_all_commands());
3249 }
3250 \f
3251 /* replace-flows and diff-flows commands. */
3252
3253 struct flow_tables {
3254 struct classifier tables[OFPTT_MAX + 1];
3255 };
3256
3257 #define FOR_EACH_TABLE(CLS, TABLES) \
3258 for ((CLS) = (TABLES)->tables; \
3259 (CLS) < &(TABLES)->tables[ARRAY_SIZE((TABLES)->tables)]; \
3260 (CLS)++)
3261
3262 static void
3263 flow_tables_init(struct flow_tables *tables)
3264 {
3265 struct classifier *cls;
3266
3267 FOR_EACH_TABLE (cls, tables) {
3268 classifier_init(cls, NULL);
3269 }
3270 }
3271
3272 static void
3273 flow_tables_defer(struct flow_tables *tables)
3274 {
3275 struct classifier *cls;
3276
3277 FOR_EACH_TABLE (cls, tables) {
3278 classifier_defer(cls);
3279 }
3280 }
3281
3282 static void
3283 flow_tables_publish(struct flow_tables *tables)
3284 {
3285 struct classifier *cls;
3286
3287 FOR_EACH_TABLE (cls, tables) {
3288 classifier_publish(cls);
3289 }
3290 }
3291
3292 /* A flow table entry, possibly with two different versions. */
3293 struct fte {
3294 struct cls_rule rule; /* Within a "struct classifier". */
3295 struct fte_version *versions[2];
3296 };
3297
3298 /* One version of a Flow Table Entry. */
3299 struct fte_version {
3300 ovs_be64 cookie;
3301 uint16_t idle_timeout;
3302 uint16_t hard_timeout;
3303 uint16_t importance;
3304 uint16_t flags;
3305 struct ofpact *ofpacts;
3306 size_t ofpacts_len;
3307 uint8_t table_id;
3308 };
3309
3310 /* A FTE entry that has been queued for later insertion after all
3311 * flows have been scanned to correctly allocation tunnel metadata. */
3312 struct fte_pending {
3313 struct minimatch match;
3314 int priority;
3315 struct fte_version *version;
3316 int index;
3317
3318 struct ovs_list list_node;
3319 };
3320
3321 /* Processing state during two stage processing of flow table entries.
3322 * Tracks the maximum size seen for each tunnel metadata entry as well
3323 * as a list of the pending FTE entries. */
3324 struct fte_state {
3325 int tun_metadata_size[TUN_METADATA_NUM_OPTS];
3326 struct ovs_list fte_pending_list;
3327
3328 /* The final metadata table that we have constructed. */
3329 struct tun_table *tun_tab;
3330
3331 /* Port and table map. There is only one of each, not one per source,
3332 * because it only makes sense to display a single name for a given port
3333 * or table number. */
3334 const struct ofputil_port_map *port_map;
3335 const struct ofputil_table_map *table_map;
3336 };
3337
3338 /* Frees 'version' and the data that it owns. */
3339 static void
3340 fte_version_free(struct fte_version *version)
3341 {
3342 if (version) {
3343 free(CONST_CAST(struct ofpact *, version->ofpacts));
3344 free(version);
3345 }
3346 }
3347
3348 /* Returns true if 'a' and 'b' are the same, false if they differ.
3349 *
3350 * Ignores differences in 'flags' because there's no way to retrieve flags from
3351 * an OpenFlow switch. We have to assume that they are the same. */
3352 static bool
3353 fte_version_equals(const struct fte_version *a, const struct fte_version *b)
3354 {
3355 return (a->cookie == b->cookie
3356 && a->idle_timeout == b->idle_timeout
3357 && a->hard_timeout == b->hard_timeout
3358 && a->importance == b->importance
3359 && a->table_id == b->table_id
3360 && ofpacts_equal_stringwise(a->ofpacts, a->ofpacts_len,
3361 b->ofpacts, b->ofpacts_len));
3362 }
3363
3364 /* Clears 's', then if 's' has a version 'index', formats 'fte' and version
3365 * 'index' into 's', followed by a new-line. */
3366 static void
3367 fte_version_format(const struct fte_state *fte_state, const struct fte *fte,
3368 int index, struct ds *s)
3369 {
3370 const struct fte_version *version = fte->versions[index];
3371
3372 ds_clear(s);
3373 if (!version) {
3374 return;
3375 }
3376
3377 if (version->table_id) {
3378 ds_put_format(s, "table=%"PRIu8" ", version->table_id);
3379 }
3380 cls_rule_format(&fte->rule, fte_state->tun_tab, fte_state->port_map, s);
3381 if (version->cookie != htonll(0)) {
3382 ds_put_format(s, " cookie=0x%"PRIx64, ntohll(version->cookie));
3383 }
3384 if (version->idle_timeout != OFP_FLOW_PERMANENT) {
3385 ds_put_format(s, " idle_timeout=%"PRIu16, version->idle_timeout);
3386 }
3387 if (version->hard_timeout != OFP_FLOW_PERMANENT) {
3388 ds_put_format(s, " hard_timeout=%"PRIu16, version->hard_timeout);
3389 }
3390 if (version->importance != 0) {
3391 ds_put_format(s, " importance=%"PRIu16, version->importance);
3392 }
3393
3394 ds_put_cstr(s, " actions=");
3395 struct ofpact_format_params fp = {
3396 .port_map = fte_state->port_map,
3397 .s = s,
3398 };
3399 ofpacts_format(version->ofpacts, version->ofpacts_len, &fp);
3400
3401 ds_put_char(s, '\n');
3402 }
3403
3404 static struct fte *
3405 fte_from_cls_rule(const struct cls_rule *cls_rule)
3406 {
3407 return cls_rule ? CONTAINER_OF(cls_rule, struct fte, rule) : NULL;
3408 }
3409
3410 /* Frees 'fte' and its versions. */
3411 static void
3412 fte_free(struct fte *fte)
3413 {
3414 if (fte) {
3415 fte_version_free(fte->versions[0]);
3416 fte_version_free(fte->versions[1]);
3417 cls_rule_destroy(&fte->rule);
3418 free(fte);
3419 }
3420 }
3421
3422 /* Frees all of the FTEs within 'tables'. */
3423 static void
3424 fte_free_all(struct flow_tables *tables)
3425 {
3426 struct classifier *cls;
3427
3428 FOR_EACH_TABLE (cls, tables) {
3429 struct fte *fte;
3430
3431 classifier_defer(cls);
3432 CLS_FOR_EACH (fte, rule, cls) {
3433 classifier_remove_assert(cls, &fte->rule);
3434 ovsrcu_postpone(fte_free, fte);
3435 }
3436 classifier_destroy(cls);
3437 }
3438 }
3439
3440 /* Searches 'tables' for an FTE matching 'rule', inserting a new one if
3441 * necessary. Sets 'version' as the version of that rule with the given
3442 * 'index', replacing any existing version, if any.
3443 *
3444 * Takes ownership of 'version'. */
3445 static void
3446 fte_insert(struct flow_tables *tables, const struct minimatch *match,
3447 int priority, struct fte_version *version, int index)
3448 {
3449 struct classifier *cls = &tables->tables[version->table_id];
3450 struct fte *old, *fte;
3451
3452 fte = xzalloc(sizeof *fte);
3453 cls_rule_init_from_minimatch(&fte->rule, match, priority);
3454 fte->versions[index] = version;
3455
3456 old = fte_from_cls_rule(classifier_replace(cls, &fte->rule,
3457 OVS_VERSION_MIN, NULL, 0));
3458 if (old) {
3459 fte->versions[!index] = old->versions[!index];
3460 old->versions[!index] = NULL;
3461
3462 ovsrcu_postpone(fte_free, old);
3463 }
3464 }
3465
3466 /* Given a list of the field sizes for each tunnel metadata entry, install
3467 * a mapping table for later operations. */
3468 static void
3469 generate_tun_metadata(struct fte_state *state)
3470 {
3471 struct ofputil_tlv_table_mod ttm;
3472 int i;
3473
3474 ttm.command = NXTTMC_ADD;
3475 ovs_list_init(&ttm.mappings);
3476
3477 for (i = 0; i < TUN_METADATA_NUM_OPTS; i++) {
3478 if (state->tun_metadata_size[i] != -1) {
3479 struct ofputil_tlv_map *map = xmalloc(sizeof *map);
3480
3481 ovs_list_push_back(&ttm.mappings, &map->list_node);
3482
3483 /* We don't care about the actual option class and type since there
3484 * won't be any lookup. We just need to make them unique. */
3485 map->option_class = i / UINT8_MAX;
3486 map->option_type = i;
3487 map->option_len = ROUND_UP(state->tun_metadata_size[i], 4);
3488 map->index = i;
3489 }
3490 }
3491
3492 tun_metadata_table_mod(&ttm, NULL, &state->tun_tab);
3493 ofputil_uninit_tlv_table(&ttm.mappings);
3494 }
3495
3496 /* Once we have created a tunnel mapping table with a consistent overall
3497 * allocation, we need to remap each flow to use this table from its own
3498 * allocation. Since the mapping table has already been installed, we
3499 * can just read the data from the match and rewrite it. On rewrite, it
3500 * will use the new table. */
3501 static void
3502 remap_match(struct fte_state *state, struct minimatch *minimatch)
3503 {
3504 int i;
3505
3506 if (!minimatch->tun_md || !minimatch->tun_md->valid) {
3507 return;
3508 }
3509
3510 struct match match;
3511 minimatch_expand(minimatch, &match);
3512
3513 struct tun_metadata flow = match.flow.tunnel.metadata;
3514 struct tun_metadata flow_mask = match.wc.masks.tunnel.metadata;
3515 memset(&match.flow.tunnel.metadata, 0, sizeof match.flow.tunnel.metadata);
3516 memset(&match.wc.masks.tunnel.metadata, 0,
3517 sizeof match.wc.masks.tunnel.metadata);
3518 match.tun_md.valid = false;
3519
3520 match.flow.tunnel.metadata.tab = state->tun_tab;
3521 match.wc.masks.tunnel.metadata.tab = match.flow.tunnel.metadata.tab;
3522
3523 ULLONG_FOR_EACH_1 (i, flow_mask.present.map) {
3524 const struct mf_field *field = mf_from_id(MFF_TUN_METADATA0 + i);
3525 int offset = match.tun_md.entry[i].loc.c.offset;
3526 int len = match.tun_md.entry[i].loc.len;
3527 union mf_value value, mask;
3528
3529 memset(&value, 0, field->n_bytes - len);
3530 memset(&mask, match.tun_md.entry[i].masked ? 0 : 0xff,
3531 field->n_bytes - len);
3532
3533 memcpy(value.tun_metadata + field->n_bytes - len,
3534 flow.opts.u8 + offset, len);
3535 memcpy(mask.tun_metadata + field->n_bytes - len,
3536 flow_mask.opts.u8 + offset, len);
3537 mf_set(field, &value, &mask, &match, NULL);
3538 }
3539 minimatch_destroy(minimatch);
3540 minimatch_init(minimatch, &match);
3541 }
3542
3543 /* In order to correctly handle tunnel metadata, we need to have
3544 * two passes over the flows. This happens because tunnel metadata
3545 * doesn't have fixed locations in a flow entry but is instead dynamically
3546 * allocated space. In the case of flows coming from a file, we don't
3547 * even know the size of each field when we need to do the allocation.
3548 * When the flows come in, each flow has an individual allocation based
3549 * on its own fields. However, this allocation is not the same across
3550 * different flows and therefore fields are not directly comparable.
3551 *
3552 * In the first pass, we record the maximum size of each tunnel metadata
3553 * field as well as queue FTE entries for later processing.
3554 *
3555 * In the second pass, we use the metadata size information to create a
3556 * tunnel mapping table and set that through the tunnel metadata processing
3557 * code. We then remap all individual flows to use this common allocation
3558 * scheme. Finally, we load the queued entries into the classifier for
3559 * comparison.
3560 *
3561 * fte_state_init() should be called before processing any flows. */
3562 static void
3563 fte_state_init(struct fte_state *state)
3564 {
3565 int i;
3566
3567 for (i = 0; i < TUN_METADATA_NUM_OPTS; i++) {
3568 state->tun_metadata_size[i] = -1;
3569 }
3570
3571 ovs_list_init(&state->fte_pending_list);
3572 state->tun_tab = NULL;
3573 state->port_map = NULL;
3574 state->table_map = NULL;
3575 }
3576
3577 static void
3578 fte_state_destroy(struct fte_state *state)
3579 {
3580 tun_metadata_free(state->tun_tab);
3581 }
3582
3583 /* The first pass of the processing described in the comment about
3584 * fte_state_init(). fte_queue() is the first pass to be called as each
3585 * flow is read from its source. */
3586 static void
3587 fte_queue(struct fte_state *state, const struct minimatch *match,
3588 int priority, struct fte_version *version, int index)
3589 {
3590 struct fte_pending *pending = xmalloc(sizeof *pending);
3591 int i;
3592
3593 minimatch_clone(&pending->match, match);
3594 pending->priority = priority;
3595 pending->version = version;
3596 pending->index = index;
3597 ovs_list_push_back(&state->fte_pending_list, &pending->list_node);
3598
3599 if (!match->tun_md || !match->tun_md->valid) {
3600 return;
3601 }
3602
3603 uint64_t map = miniflow_get_tun_metadata_present_map(&match->mask->masks);
3604 ULLONG_FOR_EACH_1 (i, map) {
3605 if (match->tun_md->entry[i].loc.len > state->tun_metadata_size[i]) {
3606 state->tun_metadata_size[i] = match->tun_md->entry[i].loc.len;
3607 }
3608 }
3609 }
3610
3611 /* The second pass of the processing described in the comment about
3612 * fte_state_init(). This should be called once all flows (from both
3613 * sides of the comparison) have been added through fte_queue(). */
3614 static void
3615 fte_fill(struct fte_state *state, struct flow_tables *tables)
3616 {
3617 struct fte_pending *pending;
3618
3619 generate_tun_metadata(state);
3620
3621 flow_tables_init(tables);
3622 flow_tables_defer(tables);
3623
3624 LIST_FOR_EACH_POP(pending, list_node, &state->fte_pending_list) {
3625 remap_match(state, &pending->match);
3626 fte_insert(tables, &pending->match, pending->priority,
3627 pending->version, pending->index);
3628 minimatch_destroy(&pending->match);
3629 free(pending);
3630 }
3631
3632 flow_tables_publish(tables);
3633 }
3634
3635 /* Reads the flows in 'filename' as flow table entries in 'tables' for the
3636 * version with the specified 'index'. Returns the flow formats able to
3637 * represent the flows that were read. */
3638 static enum ofputil_protocol
3639 read_flows_from_file(const char *filename, struct fte_state *state, int index)
3640 {
3641 enum ofputil_protocol usable_protocols;
3642 int line_number;
3643 struct ds s;
3644 FILE *file;
3645
3646 file = !strcmp(filename, "-") ? stdin : fopen(filename, "r");
3647 if (file == NULL) {
3648 ovs_fatal(errno, "%s: open", filename);
3649 }
3650
3651 ds_init(&s);
3652 usable_protocols = OFPUTIL_P_ANY;
3653 line_number = 0;
3654 while (!ds_get_preprocessed_line(&s, file, &line_number)) {
3655 struct fte_version *version;
3656 struct ofputil_flow_mod fm;
3657 char *error;
3658 enum ofputil_protocol usable;
3659
3660 error = parse_ofp_str(&fm, OFPFC_ADD, ds_cstr(&s), state->port_map,
3661 state->table_map, &usable);
3662 if (error) {
3663 ovs_fatal(0, "%s:%d: %s", filename, line_number, error);
3664 }
3665 usable_protocols &= usable;
3666
3667 version = xmalloc(sizeof *version);
3668 version->cookie = fm.new_cookie;
3669 version->idle_timeout = fm.idle_timeout;
3670 version->hard_timeout = fm.hard_timeout;
3671 version->importance = fm.importance;
3672 version->flags = fm.flags & (OFPUTIL_FF_SEND_FLOW_REM
3673 | OFPUTIL_FF_EMERG);
3674 version->ofpacts = fm.ofpacts;
3675 version->ofpacts_len = fm.ofpacts_len;
3676 version->table_id = fm.table_id != OFPTT_ALL ? fm.table_id : 0;
3677
3678 fte_queue(state, &fm.match, fm.priority, version, index);
3679
3680 minimatch_destroy(&fm.match);
3681 }
3682 ds_destroy(&s);
3683
3684 if (file != stdin) {
3685 fclose(file);
3686 }
3687
3688 return usable_protocols;
3689 }
3690
3691 /* Reads the OpenFlow flow table from 'vconn', which has currently active flow
3692 * format 'protocol', and adds them as flow table entries in 'tables' for the
3693 * version with the specified 'index'. */
3694 static void
3695 read_flows_from_switch(struct vconn *vconn,
3696 enum ofputil_protocol protocol,
3697 struct fte_state *state, int index)
3698 {
3699 struct ofputil_flow_stats_request fsr;
3700
3701 fsr.aggregate = false;
3702 match_init_catchall(&fsr.match);
3703 fsr.out_port = OFPP_ANY;
3704 fsr.out_group = OFPG_ANY;
3705 fsr.table_id = 0xff;
3706 fsr.cookie = fsr.cookie_mask = htonll(0);
3707
3708 struct ofputil_flow_stats *fses;
3709 size_t n_fses;
3710 run(vconn_dump_flows(vconn, &fsr, protocol, &fses, &n_fses),
3711 "dump flows");
3712 for (size_t i = 0; i < n_fses; i++) {
3713 const struct ofputil_flow_stats *fs = &fses[i];
3714 struct fte_version *version;
3715
3716 version = xmalloc(sizeof *version);
3717 version->cookie = fs->cookie;
3718 version->idle_timeout = fs->idle_timeout;
3719 version->hard_timeout = fs->hard_timeout;
3720 version->importance = fs->importance;
3721 version->flags = 0;
3722 version->ofpacts_len = fs->ofpacts_len;
3723 version->ofpacts = xmemdup(fs->ofpacts, fs->ofpacts_len);
3724 version->table_id = fs->table_id;
3725
3726 struct minimatch match;
3727 minimatch_init(&match, &fs->match);
3728 fte_queue(state, &match, fs->priority, version, index);
3729 minimatch_destroy(&match);
3730 }
3731
3732 for (size_t i = 0; i < n_fses; i++) {
3733 free(CONST_CAST(struct ofpact *, fses[i].ofpacts));
3734 }
3735 free(fses);
3736 }
3737
3738 static void
3739 fte_make_flow_mod(const struct fte *fte, int index, uint16_t command,
3740 enum ofputil_protocol protocol, struct ovs_list *packets)
3741 {
3742 const struct fte_version *version = fte->versions[index];
3743 struct ofpbuf *ofm;
3744
3745 struct ofputil_flow_mod fm = {
3746 .priority = fte->rule.priority,
3747 .new_cookie = version->cookie,
3748 .modify_cookie = true,
3749 .table_id = version->table_id,
3750 .command = command,
3751 .idle_timeout = version->idle_timeout,
3752 .hard_timeout = version->hard_timeout,
3753 .importance = version->importance,
3754 .buffer_id = UINT32_MAX,
3755 .out_port = OFPP_ANY,
3756 .out_group = OFPG_ANY,
3757 .flags = version->flags,
3758 };
3759 minimatch_clone(&fm.match, &fte->rule.match);
3760 if (command == OFPFC_ADD || command == OFPFC_MODIFY ||
3761 command == OFPFC_MODIFY_STRICT) {
3762 fm.ofpacts = version->ofpacts;
3763 fm.ofpacts_len = version->ofpacts_len;
3764 } else {
3765 fm.ofpacts = NULL;
3766 fm.ofpacts_len = 0;
3767 }
3768 ofm = ofputil_encode_flow_mod(&fm, protocol);
3769 minimatch_destroy(&fm.match);
3770
3771 ovs_list_push_back(packets, &ofm->list_node);
3772 }
3773
3774 static void
3775 ofctl_replace_flows(struct ovs_cmdl_context *ctx)
3776 {
3777 enum { FILE_IDX = 0, SWITCH_IDX = 1 };
3778 enum ofputil_protocol usable_protocols, protocol;
3779 struct fte_state fte_state;
3780 struct flow_tables tables;
3781 struct classifier *cls;
3782 struct ovs_list requests;
3783 struct vconn *vconn;
3784 struct fte *fte;
3785
3786 fte_state_init(&fte_state);
3787 fte_state.port_map = ports_to_accept(ctx->argv[1]);
3788 fte_state.table_map = tables_to_accept(ctx->argv[1]);
3789 usable_protocols = read_flows_from_file(ctx->argv[2], &fte_state, FILE_IDX);
3790
3791 protocol = open_vconn(ctx->argv[1], &vconn);
3792 protocol = set_protocol_for_flow_dump(vconn, protocol, usable_protocols);
3793
3794 read_flows_from_switch(vconn, protocol, &fte_state, SWITCH_IDX);
3795
3796 fte_fill(&fte_state, &tables);
3797
3798 ovs_list_init(&requests);
3799
3800 FOR_EACH_TABLE (cls, &tables) {
3801 /* Delete flows that exist on the switch but not in the file. */
3802 CLS_FOR_EACH (fte, rule, cls) {
3803 struct fte_version *file_ver = fte->versions[FILE_IDX];
3804 struct fte_version *sw_ver = fte->versions[SWITCH_IDX];
3805
3806 if (sw_ver && !file_ver) {
3807 fte_make_flow_mod(fte, SWITCH_IDX, OFPFC_DELETE_STRICT,
3808 protocol, &requests);
3809 }
3810 }
3811
3812 /* Add flows that exist in the file but not on the switch.
3813 * Update flows that exist in both places but differ. */
3814 CLS_FOR_EACH (fte, rule, cls) {
3815 struct fte_version *file_ver = fte->versions[FILE_IDX];
3816 struct fte_version *sw_ver = fte->versions[SWITCH_IDX];
3817
3818 if (file_ver &&
3819 (readd || !sw_ver || !fte_version_equals(sw_ver, file_ver))) {
3820 fte_make_flow_mod(fte, FILE_IDX, OFPFC_ADD, protocol,
3821 &requests);
3822 }
3823 }
3824 }
3825 if (bundle) {
3826 bundle_transact(vconn, &requests, OFPBF_ORDERED | OFPBF_ATOMIC);
3827 } else {
3828 transact_multiple_noreply(vconn, &requests);
3829 }
3830
3831 ofpbuf_list_delete(&requests);
3832 vconn_close(vconn);
3833
3834 fte_free_all(&tables);
3835 fte_state_destroy(&fte_state);
3836 }
3837
3838 static void
3839 read_flows_from_source(const char *source, struct fte_state *state, int index)
3840 {
3841 struct stat s;
3842
3843 if (source[0] == '/' || source[0] == '.'
3844 || (!strchr(source, ':') && !stat(source, &s))) {
3845 read_flows_from_file(source, state, index);
3846 } else {
3847 enum ofputil_protocol protocol;
3848 struct vconn *vconn;
3849
3850 protocol = open_vconn(source, &vconn);
3851 protocol = set_protocol_for_flow_dump(vconn, protocol, OFPUTIL_P_ANY);
3852 read_flows_from_switch(vconn, protocol, state, index);
3853 vconn_close(vconn);
3854
3855 if (!state->port_map) {
3856 state->port_map = ports_to_show(source);
3857 }
3858 }
3859 }
3860
3861 static void
3862 ofctl_diff_flows(struct ovs_cmdl_context *ctx)
3863 {
3864 bool differences = false;
3865 struct fte_state fte_state;
3866 struct flow_tables tables;
3867 struct classifier *cls;
3868 struct ds a_s, b_s;
3869 struct fte *fte;
3870
3871 fte_state_init(&fte_state);
3872 read_flows_from_source(ctx->argv[1], &fte_state, 0);
3873 read_flows_from_source(ctx->argv[2], &fte_state, 1);
3874 fte_fill(&fte_state, &tables);
3875
3876 ds_init(&a_s);
3877 ds_init(&b_s);
3878
3879 FOR_EACH_TABLE (cls, &tables) {
3880 CLS_FOR_EACH (fte, rule, cls) {
3881 struct fte_version *a = fte->versions[0];
3882 struct fte_version *b = fte->versions[1];
3883
3884 if (!a || !b || !fte_version_equals(a, b)) {
3885 fte_version_format(&fte_state, fte, 0, &a_s);
3886 fte_version_format(&fte_state, fte, 1, &b_s);
3887 if (a_s.length) {
3888 printf("-%s", ds_cstr(&a_s));
3889 }
3890 if (b_s.length) {
3891 printf("+%s", ds_cstr(&b_s));
3892 }
3893 differences = true;
3894 }
3895 }
3896 }
3897
3898 ds_destroy(&a_s);
3899 ds_destroy(&b_s);
3900
3901 fte_free_all(&tables);
3902 fte_state_destroy(&fte_state);
3903
3904 if (differences) {
3905 exit(2);
3906 }
3907 }
3908
3909 static void
3910 ofctl_meter_mod__(const char *bridge, const char *str, int command)
3911 {
3912 struct ofputil_meter_mod mm;
3913 struct vconn *vconn;
3914 enum ofputil_protocol protocol;
3915 enum ofputil_protocol usable_protocols;
3916 enum ofp_version version;
3917
3918 if (str) {
3919 char *error;
3920 error = parse_ofp_meter_mod_str(&mm, str, command, &usable_protocols);
3921 if (error) {
3922 ovs_fatal(0, "%s", error);
3923 }
3924 } else {
3925 usable_protocols = OFPUTIL_P_OF13_UP;
3926 mm.command = command;
3927 mm.meter.meter_id = OFPM13_ALL;
3928 mm.meter.bands = NULL;
3929 }
3930
3931 protocol = open_vconn_for_flow_mod(bridge, &vconn, usable_protocols);
3932 version = ofputil_protocol_to_ofp_version(protocol);
3933 transact_noreply(vconn, ofputil_encode_meter_mod(version, &mm));
3934 free(mm.meter.bands);
3935 vconn_close(vconn);
3936 }
3937
3938 static void
3939 ofctl_meter_request__(const char *bridge, const char *str,
3940 enum ofputil_meter_request_type type)
3941 {
3942 struct ofputil_meter_mod mm;
3943 struct vconn *vconn;
3944 enum ofputil_protocol usable_protocols;
3945 enum ofputil_protocol protocol;
3946 enum ofp_version version;
3947
3948 if (str) {
3949 char *error;
3950 error = parse_ofp_meter_mod_str(&mm, str, -1, &usable_protocols);
3951 if (error) {
3952 ovs_fatal(0, "%s", error);
3953 }
3954 } else {
3955 usable_protocols = OFPUTIL_P_OF13_UP;
3956 mm.meter.meter_id = OFPM13_ALL;
3957 mm.meter.bands = NULL;
3958 }
3959
3960 protocol = open_vconn_for_flow_mod(bridge, &vconn, usable_protocols);
3961 version = ofputil_protocol_to_ofp_version(protocol);
3962 dump_transaction(vconn, ofputil_encode_meter_request(version, type,
3963 mm.meter.meter_id));
3964 free(mm.meter.bands);
3965 vconn_close(vconn);
3966 }
3967
3968
3969 static void
3970 ofctl_add_meter(struct ovs_cmdl_context *ctx)
3971 {
3972 ofctl_meter_mod__(ctx->argv[1], ctx->argv[2], OFPMC13_ADD);
3973 }
3974
3975 static void
3976 ofctl_mod_meter(struct ovs_cmdl_context *ctx)
3977 {
3978 ofctl_meter_mod__(ctx->argv[1], ctx->argv[2], OFPMC13_MODIFY);
3979 }
3980
3981 static void
3982 ofctl_del_meters(struct ovs_cmdl_context *ctx)
3983 {
3984 ofctl_meter_mod__(ctx->argv[1], ctx->argc > 2 ? ctx->argv[2] : NULL, OFPMC13_DELETE);
3985 }
3986
3987 static void
3988 ofctl_dump_meters(struct ovs_cmdl_context *ctx)
3989 {
3990 ofctl_meter_request__(ctx->argv[1], ctx->argc > 2 ? ctx->argv[2] : NULL,
3991 OFPUTIL_METER_CONFIG);
3992 }
3993
3994 static void
3995 ofctl_meter_stats(struct ovs_cmdl_context *ctx)
3996 {
3997 ofctl_meter_request__(ctx->argv[1], ctx->argc > 2 ? ctx->argv[2] : NULL,
3998 OFPUTIL_METER_STATS);
3999 }
4000
4001 static void
4002 ofctl_meter_features(struct ovs_cmdl_context *ctx)
4003 {
4004 ofctl_meter_request__(ctx->argv[1], NULL, OFPUTIL_METER_FEATURES);
4005 }
4006
4007 \f
4008 /* Undocumented commands for unit testing. */
4009
4010 static void
4011 ofctl_parse_flows__(struct ofputil_flow_mod *fms, size_t n_fms,
4012 enum ofputil_protocol usable_protocols)
4013 {
4014 enum ofputil_protocol protocol = 0;
4015 char *usable_s;
4016 size_t i;
4017
4018 usable_s = ofputil_protocols_to_string(usable_protocols);
4019 printf("usable protocols: %s\n", usable_s);
4020 free(usable_s);
4021
4022 if (!(usable_protocols & allowed_protocols)) {
4023 ovs_fatal(0, "no usable protocol");
4024 }
4025 for (i = 0; i < sizeof(enum ofputil_protocol) * CHAR_BIT; i++) {
4026 protocol = 1 << i;
4027 if (protocol & usable_protocols & allowed_protocols) {
4028 break;
4029 }
4030 }
4031 ovs_assert(is_pow2(protocol));
4032
4033 printf("chosen protocol: %s\n", ofputil_protocol_to_string(protocol));
4034
4035 for (i = 0; i < n_fms; i++) {
4036 struct ofputil_flow_mod *fm = &fms[i];
4037 struct ofpbuf *msg;
4038
4039 msg = ofputil_encode_flow_mod(fm, protocol);
4040 ofp_print(stdout, msg->data, msg->size, NULL, NULL, verbosity);
4041 ofpbuf_delete(msg);
4042
4043 free(CONST_CAST(struct ofpact *, fm->ofpacts));
4044 minimatch_destroy(&fm->match);
4045 }
4046 }
4047
4048 /* "parse-flow FLOW": parses the argument as a flow (like add-flow) and prints
4049 * it back to stdout. */
4050 static void
4051 ofctl_parse_flow(struct ovs_cmdl_context *ctx)
4052 {
4053 enum ofputil_protocol usable_protocols;
4054 struct ofputil_flow_mod fm;
4055 char *error;
4056
4057 error = parse_ofp_flow_mod_str(&fm, ctx->argv[1], NULL, NULL,
4058 OFPFC_ADD, &usable_protocols);
4059 if (error) {
4060 ovs_fatal(0, "%s", error);
4061 }
4062 ofctl_parse_flows__(&fm, 1, usable_protocols);
4063 }
4064
4065 /* "parse-flows FILENAME": reads the named file as a sequence of flows (like
4066 * add-flows) and prints each of the flows back to stdout. */
4067 static void
4068 ofctl_parse_flows(struct ovs_cmdl_context *ctx)
4069 {
4070 enum ofputil_protocol usable_protocols;
4071 struct ofputil_flow_mod *fms = NULL;
4072 size_t n_fms = 0;
4073 char *error;
4074
4075 error = parse_ofp_flow_mod_file(ctx->argv[1], NULL, NULL, OFPFC_ADD,
4076 &fms, &n_fms, &usable_protocols);
4077 if (error) {
4078 ovs_fatal(0, "%s", error);
4079 }
4080 ofctl_parse_flows__(fms, n_fms, usable_protocols);
4081 free(fms);
4082 }
4083
4084 static void
4085 ofctl_parse_nxm__(bool oxm, enum ofp_version version)
4086 {
4087 struct ds in;
4088
4089 ds_init(&in);
4090 while (!ds_get_test_line(&in, stdin)) {
4091 struct ofpbuf nx_match;
4092 struct match match;
4093 ovs_be64 cookie, cookie_mask;
4094 enum ofperr error;
4095 int match_len;
4096
4097 /* Convert string to nx_match. */
4098 ofpbuf_init(&nx_match, 0);
4099 if (oxm) {
4100 match_len = oxm_match_from_string(ds_cstr(&in), &nx_match);
4101 } else {
4102 match_len = nx_match_from_string(ds_cstr(&in), &nx_match);
4103 }
4104
4105 /* Convert nx_match to match. */
4106 if (strict) {
4107 if (oxm) {
4108 error = oxm_pull_match(&nx_match, false, NULL, NULL, &match);
4109 } else {
4110 error = nx_pull_match(&nx_match, match_len, &match, &cookie,
4111 &cookie_mask, false, NULL, NULL);
4112 }
4113 } else {
4114 if (oxm) {
4115 error = oxm_pull_match_loose(&nx_match, false, NULL, &match);
4116 } else {
4117 error = nx_pull_match_loose(&nx_match, match_len, &match,
4118 &cookie, &cookie_mask, false,
4119 NULL);
4120 }
4121 }
4122
4123
4124 if (!error) {
4125 char *out;
4126
4127 /* Convert match back to nx_match. */
4128 ofpbuf_uninit(&nx_match);
4129 ofpbuf_init(&nx_match, 0);
4130 if (oxm) {
4131 match_len = oxm_put_match(&nx_match, &match, version);
4132 out = oxm_match_to_string(&nx_match, match_len);
4133 } else {
4134 match_len = nx_put_match(&nx_match, &match,
4135 cookie, cookie_mask);
4136 out = nx_match_to_string(nx_match.data, match_len);
4137 }
4138
4139 puts(out);
4140 free(out);
4141
4142 if (verbosity > 0) {
4143 ovs_hex_dump(stdout, nx_match.data, nx_match.size, 0, false);
4144 }
4145 } else {
4146 printf("nx_pull_match() returned error %s\n",
4147 ofperr_get_name(error));
4148 }
4149
4150 ofpbuf_uninit(&nx_match);
4151 }
4152 ds_destroy(&in);
4153 }
4154
4155 /* "parse-nxm": reads a series of NXM nx_match specifications as strings from
4156 * stdin, does some internal fussing with them, and then prints them back as
4157 * strings on stdout. */
4158 static void
4159 ofctl_parse_nxm(struct ovs_cmdl_context *ctx OVS_UNUSED)
4160 {
4161 ofctl_parse_nxm__(false, 0);
4162 }
4163
4164 /* "parse-oxm VERSION": reads a series of OXM nx_match specifications as
4165 * strings from stdin, does some internal fussing with them, and then prints
4166 * them back as strings on stdout. VERSION must specify an OpenFlow version,
4167 * e.g. "OpenFlow12". */
4168 static void
4169 ofctl_parse_oxm(struct ovs_cmdl_context *ctx)
4170 {
4171 enum ofp_version version = ofputil_version_from_string(ctx->argv[1]);
4172 if (version < OFP12_VERSION) {
4173 ovs_fatal(0, "%s: not a valid version for OXM", ctx->argv[1]);
4174 }
4175
4176 ofctl_parse_nxm__(true, version);
4177 }
4178
4179 static void
4180 print_differences(const char *prefix,
4181 const void *a_, size_t a_len,
4182 const void *b_, size_t b_len)
4183 {
4184 const uint8_t *a = a_;
4185 const uint8_t *b = b_;
4186 size_t i;
4187
4188 for (i = 0; i < MIN(a_len, b_len); i++) {
4189 if (a[i] != b[i]) {
4190 printf("%s%2"PRIuSIZE": %02"PRIx8" -> %02"PRIx8"\n",
4191 prefix, i, a[i], b[i]);
4192 }
4193 }
4194 for (i = a_len; i < b_len; i++) {
4195 printf("%s%2"PRIuSIZE": (none) -> %02"PRIx8"\n", prefix, i, b[i]);
4196 }
4197 for (i = b_len; i < a_len; i++) {
4198 printf("%s%2"PRIuSIZE": %02"PRIx8" -> (none)\n", prefix, i, a[i]);
4199 }
4200 }
4201
4202 static void
4203 ofctl_parse_actions__(const char *version_s, bool instructions)
4204 {
4205 enum ofp_version version;
4206 struct ds in;
4207
4208 version = ofputil_version_from_string(version_s);
4209 if (!version) {
4210 ovs_fatal(0, "%s: not a valid OpenFlow version", version_s);
4211 }
4212
4213 ds_init(&in);
4214 while (!ds_get_preprocessed_line(&in, stdin, NULL)) {
4215 struct ofpbuf of_out;
4216 struct ofpbuf of_in;
4217 struct ofpbuf ofpacts;
4218 const char *table_id;
4219 char *actions;
4220 enum ofperr error;
4221 size_t size;
4222 struct ds s;
4223
4224 /* Parse table_id separated with the follow-up actions by ",", if
4225 * any. */
4226 actions = ds_cstr(&in);
4227 table_id = NULL;
4228 if (strstr(actions, ",")) {
4229 table_id = strsep(&actions, ",");
4230 }
4231
4232 /* Parse hex bytes. */
4233 ofpbuf_init(&of_in, 0);
4234 if (ofpbuf_put_hex(&of_in, actions, NULL)[0] != '\0') {
4235 ovs_fatal(0, "Trailing garbage in hex data");
4236 }
4237
4238 /* Convert to ofpacts. */
4239 ofpbuf_init(&ofpacts, 0);
4240 size = of_in.size;
4241 error = (instructions
4242 ? ofpacts_pull_openflow_instructions
4243 : ofpacts_pull_openflow_actions)(
4244 &of_in, of_in.size, version, NULL, NULL, &ofpacts);
4245 if (!error && instructions) {
4246 /* Verify actions, enforce consistency. */
4247 enum ofputil_protocol protocol;
4248 struct match match;
4249
4250 memset(&match, 0, sizeof match);
4251 protocol = ofputil_protocols_from_ofp_version(version);
4252 error = ofpacts_check_consistency(ofpacts.data, ofpacts.size,
4253 &match, OFPP_MAX,
4254 table_id ? atoi(table_id) : 0,
4255 OFPTT_MAX + 1, protocol);
4256 }
4257 if (error) {
4258 printf("bad %s %s: %s\n\n",
4259 version_s, instructions ? "instructions" : "actions",
4260 ofperr_get_name(error));
4261 ofpbuf_uninit(&ofpacts);
4262 ofpbuf_uninit(&of_in);
4263 continue;
4264 }
4265 ofpbuf_push_uninit(&of_in, size);
4266
4267 /* Print cls_rule. */
4268 ds_init(&s);
4269 ds_put_cstr(&s, "actions=");
4270 struct ofpact_format_params fp = { .s = &s };
4271 ofpacts_format(ofpacts.data, ofpacts.size, &fp);
4272 puts(ds_cstr(&s));
4273 ds_destroy(&s);
4274
4275 /* Convert back to ofp10 actions and print differences from input. */
4276 ofpbuf_init(&of_out, 0);
4277 if (instructions) {
4278 ofpacts_put_openflow_instructions(ofpacts.data, ofpacts.size,
4279 &of_out, version);
4280 } else {
4281 ofpacts_put_openflow_actions(ofpacts.data, ofpacts.size,
4282 &of_out, version);
4283 }
4284
4285 print_differences("", of_in.data, of_in.size,
4286 of_out.data, of_out.size);
4287 putchar('\n');
4288
4289 ofpbuf_uninit(&ofpacts);
4290 ofpbuf_uninit(&of_in);
4291 ofpbuf_uninit(&of_out);
4292 }
4293 ds_destroy(&in);
4294 }
4295
4296 /* "parse-actions VERSION": reads a series of action specifications for the
4297 * given OpenFlow VERSION as hex bytes from stdin, converts them to ofpacts,
4298 * prints them as strings on stdout, and then converts them back to hex bytes
4299 * and prints any differences from the input. */
4300 static void
4301 ofctl_parse_actions(struct ovs_cmdl_context *ctx)
4302 {
4303 ofctl_parse_actions__(ctx->argv[1], false);
4304 }
4305
4306 /* "parse-actions VERSION": reads a series of instruction specifications for
4307 * the given OpenFlow VERSION as hex bytes from stdin, converts them to
4308 * ofpacts, prints them as strings on stdout, and then converts them back to
4309 * hex bytes and prints any differences from the input. */
4310 static void
4311 ofctl_parse_instructions(struct ovs_cmdl_context *ctx)
4312 {
4313 ofctl_parse_actions__(ctx->argv[1], true);
4314 }
4315
4316 /* "parse-ofp10-match": reads a series of ofp10_match specifications as hex
4317 * bytes from stdin, converts them to cls_rules, prints them as strings on
4318 * stdout, and then converts them back to hex bytes and prints any differences
4319 * from the input.
4320 *
4321 * The input hex bytes may contain "x"s to represent "don't-cares", bytes whose
4322 * values are ignored in the input and will be set to zero when OVS converts
4323 * them back to hex bytes. ovs-ofctl actually sets "x"s to random bits when
4324 * it does the conversion to hex, to ensure that in fact they are ignored. */
4325 static void
4326 ofctl_parse_ofp10_match(struct ovs_cmdl_context *ctx OVS_UNUSED)
4327 {
4328 struct ds expout;
4329 struct ds in;
4330
4331 ds_init(&in);
4332 ds_init(&expout);
4333 while (!ds_get_preprocessed_line(&in, stdin, NULL)) {
4334 struct ofpbuf match_in, match_expout;
4335 struct ofp10_match match_out;
4336 struct ofp10_match match_normal;
4337 struct match match;
4338 char *p;
4339
4340 /* Parse hex bytes to use for expected output. */
4341 ds_clear(&expout);
4342 ds_put_cstr(&expout, ds_cstr(&in));
4343 for (p = ds_cstr(&expout); *p; p++) {
4344 if (*p == 'x') {
4345 *p = '0';
4346 }
4347 }
4348 ofpbuf_init(&match_expout, 0);
4349 if (ofpbuf_put_hex(&match_expout, ds_cstr(&expout), NULL)[0] != '\0') {
4350 ovs_fatal(0, "Trailing garbage in hex data");
4351 }
4352 if (match_expout.size != sizeof(struct ofp10_match)) {
4353 ovs_fatal(0, "Input is %"PRIu32" bytes, expected %"PRIuSIZE,
4354 match_expout.size, sizeof(struct ofp10_match));
4355 }
4356
4357 /* Parse hex bytes for input. */
4358 for (p = ds_cstr(&in); *p; p++) {
4359 if (*p == 'x') {
4360 *p = "0123456789abcdef"[random_uint32() & 0xf];
4361 }
4362 }
4363 ofpbuf_init(&match_in, 0);
4364 if (ofpbuf_put_hex(&match_in, ds_cstr(&in), NULL)[0] != '\0') {
4365 ovs_fatal(0, "Trailing garbage in hex data");
4366 }
4367 if (match_in.size != sizeof(struct ofp10_match)) {
4368 ovs_fatal(0, "Input is %"PRIu32" bytes, expected %"PRIuSIZE,
4369 match_in.size, sizeof(struct ofp10_match));
4370 }
4371
4372 /* Convert to cls_rule and print. */
4373 ofputil_match_from_ofp10_match(match_in.data, &match);
4374 match_print(&match, NULL);
4375
4376 /* Convert back to ofp10_match and print differences from input. */
4377 ofputil_match_to_ofp10_match(&match, &match_out);
4378 print_differences("", match_expout.data, match_expout.size,
4379 &match_out, sizeof match_out);
4380
4381 /* Normalize, then convert and compare again. */
4382 ofputil_normalize_match(&match);
4383 ofputil_match_to_ofp10_match(&match, &match_normal);
4384 print_differences("normal: ", &match_out, sizeof match_out,
4385 &match_normal, sizeof match_normal);
4386 putchar('\n');
4387
4388 ofpbuf_uninit(&match_in);
4389 ofpbuf_uninit(&match_expout);
4390 }
4391 ds_destroy(&in);
4392 ds_destroy(&expout);
4393 }
4394
4395 /* "parse-ofp11-match": reads a series of ofp11_match specifications as hex
4396 * bytes from stdin, converts them to "struct match"es, prints them as strings
4397 * on stdout, and then converts them back to hex bytes and prints any
4398 * differences from the input. */
4399 static void
4400 ofctl_parse_ofp11_match(struct ovs_cmdl_context *ctx OVS_UNUSED)
4401 {
4402 struct ds in;
4403
4404 ds_init(&in);
4405 while (!ds_get_preprocessed_line(&in, stdin, NULL)) {
4406 struct ofpbuf match_in;
4407 struct ofp11_match match_out;
4408 struct match match;
4409 enum ofperr error;
4410
4411 /* Parse hex bytes. */
4412 ofpbuf_init(&match_in, 0);
4413 if (ofpbuf_put_hex(&match_in, ds_cstr(&in), NULL)[0] != '\0') {
4414 ovs_fatal(0, "Trailing garbage in hex data");
4415 }
4416 if (match_in.size != sizeof(struct ofp11_match)) {
4417 ovs_fatal(0, "Input is %"PRIu32" bytes, expected %"PRIuSIZE,
4418 match_in.size, sizeof(struct ofp11_match));
4419 }
4420
4421 /* Convert to match. */
4422 error = ofputil_match_from_ofp11_match(match_in.data, &match);
4423 if (error) {
4424 printf("bad ofp11_match: %s\n\n", ofperr_get_name(error));
4425 ofpbuf_uninit(&match_in);
4426 continue;
4427 }
4428
4429 /* Print match. */
4430 match_print(&match, NULL);
4431
4432 /* Convert back to ofp11_match and print differences from input. */
4433 ofputil_match_to_ofp11_match(&match, &match_out);
4434
4435 print_differences("", match_in.data, match_in.size,
4436 &match_out, sizeof match_out);
4437 putchar('\n');
4438
4439 ofpbuf_uninit(&match_in);
4440 }
4441 ds_destroy(&in);
4442 }
4443
4444 /* "parse-pcap PCAP...": read packets from each PCAP file and print their
4445 * flows. */
4446 static void
4447 ofctl_parse_pcap(struct ovs_cmdl_context *ctx)
4448 {
4449 int error = 0;
4450 for (int i = 1; i < ctx->argc; i++) {
4451 const char *filename = ctx->argv[i];
4452 FILE *pcap = ovs_pcap_open(filename, "rb");
4453 if (!pcap) {
4454 error = errno;
4455 ovs_error(error, "%s: open failed", filename);
4456 continue;
4457 }
4458
4459 for (;;) {
4460 struct dp_packet *packet;
4461 struct flow flow;
4462 int retval;
4463
4464 retval = ovs_pcap_read(pcap, &packet, NULL);
4465 if (retval == EOF) {
4466 break;
4467 } else if (retval) {
4468 error = retval;
4469 ovs_error(error, "%s: read failed", filename);
4470 }
4471
4472 pkt_metadata_init(&packet->md, u32_to_odp(ofp_to_u16(OFPP_ANY)));
4473 flow_extract(packet, &flow);
4474 flow_print(stdout, &flow, NULL);
4475 putchar('\n');
4476 dp_packet_delete(packet);
4477 }
4478 fclose(pcap);
4479 }
4480 exit(error);
4481 }
4482
4483 /* "check-vlan VLAN_TCI VLAN_TCI_MASK": converts the specified vlan_tci and
4484 * mask values to and from various formats and prints the results. */
4485 static void
4486 ofctl_check_vlan(struct ovs_cmdl_context *ctx)
4487 {
4488 struct match match;
4489
4490 char *string_s;
4491 struct ofputil_flow_mod fm;
4492
4493 struct ofpbuf nxm;
4494 struct match nxm_match;
4495 int nxm_match_len;
4496 char *nxm_s;
4497
4498 struct ofp10_match of10_raw;
4499 struct match of10_match;
4500
4501 struct ofp11_match of11_raw;
4502 struct match of11_match;
4503
4504 enum ofperr error;
4505 char *error_s;
4506
4507 enum ofputil_protocol usable_protocols; /* Unused for now. */
4508
4509 match_init_catchall(&match);
4510 match.flow.vlans[0].tci = htons(strtoul(ctx->argv[1], NULL, 16));
4511 match.wc.masks.vlans[0].tci = htons(strtoul(ctx->argv[2], NULL, 16));
4512
4513 /* Convert to and from string. */
4514 string_s = match_to_string(&match, NULL, OFP_DEFAULT_PRIORITY);
4515 printf("%s -> ", string_s);
4516 fflush(stdout);
4517 error_s = parse_ofp_str(&fm, -1, string_s, NULL, NULL, &usable_protocols);
4518 if (error_s) {
4519 ovs_fatal(0, "%s", error_s);
4520 }
4521 struct match fm_match;
4522 minimatch_expand(&fm.match, &fm_match);
4523 printf("%04"PRIx16"/%04"PRIx16"\n",
4524 ntohs(fm_match.flow.vlans[0].tci),
4525 ntohs(fm_match.wc.masks.vlans[0].tci));
4526 free(string_s);
4527 minimatch_destroy(&fm.match);
4528
4529 /* Convert to and from NXM. */
4530 ofpbuf_init(&nxm, 0);
4531 nxm_match_len = nx_put_match(&nxm, &match, htonll(0), htonll(0));
4532 nxm_s = nx_match_to_string(nxm.data, nxm_match_len);
4533 error = nx_pull_match(&nxm, nxm_match_len, &nxm_match, NULL, NULL, false,
4534 NULL, NULL);
4535 printf("NXM: %s -> ", nxm_s);
4536 if (error) {
4537 printf("%s\n", ofperr_to_string(error));
4538 } else {
4539 printf("%04"PRIx16"/%04"PRIx16"\n",
4540 ntohs(nxm_match.flow.vlans[0].tci),
4541 ntohs(nxm_match.wc.masks.vlans[0].tci));
4542 }
4543 free(nxm_s);
4544 ofpbuf_uninit(&nxm);
4545
4546 /* Convert to and from OXM. */
4547 ofpbuf_init(&nxm, 0);
4548 nxm_match_len = oxm_put_match(&nxm, &match, OFP12_VERSION);
4549 nxm_s = oxm_match_to_string(&nxm, nxm_match_len);
4550 error = oxm_pull_match(&nxm, false, NULL, NULL, &nxm_match);
4551 printf("OXM: %s -> ", nxm_s);
4552 if (error) {
4553 printf("%s\n", ofperr_to_string(error));
4554 } else {
4555 uint16_t vid = ntohs(nxm_match.flow.vlans[0].tci) &
4556 (VLAN_VID_MASK | VLAN_CFI);
4557 uint16_t mask = ntohs(nxm_match.wc.masks.vlans[0].tci) &
4558 (VLAN_VID_MASK | VLAN_CFI);
4559
4560 printf("%04"PRIx16"/%04"PRIx16",", vid, mask);
4561 if (vid && vlan_tci_to_pcp(nxm_match.wc.masks.vlans[0].tci)) {
4562 printf("%02d\n", vlan_tci_to_pcp(nxm_match.flow.vlans[0].tci));
4563 } else {
4564 printf("--\n");
4565 }
4566 }
4567 free(nxm_s);
4568 ofpbuf_uninit(&nxm);
4569
4570 /* Convert to and from OpenFlow 1.0. */
4571 ofputil_match_to_ofp10_match(&match, &of10_raw);
4572 ofputil_match_from_ofp10_match(&of10_raw, &of10_match);
4573 printf("OF1.0: %04"PRIx16"/%d,%02"PRIx8"/%d -> %04"PRIx16"/%04"PRIx16"\n",
4574 ntohs(of10_raw.dl_vlan),
4575 (of10_raw.wildcards & htonl(OFPFW10_DL_VLAN)) != 0,
4576 of10_raw.dl_vlan_pcp,
4577 (of10_raw.wildcards & htonl(OFPFW10_DL_VLAN_PCP)) != 0,
4578 ntohs(of10_match.flow.vlans[0].tci),
4579 ntohs(of10_match.wc.masks.vlans[0].tci));
4580
4581 /* Convert to and from OpenFlow 1.1. */
4582 ofputil_match_to_ofp11_match(&match, &of11_raw);
4583 ofputil_match_from_ofp11_match(&of11_raw, &of11_match);
4584 printf("OF1.1: %04"PRIx16"/%d,%02"PRIx8"/%d -> %04"PRIx16"/%04"PRIx16"\n",
4585 ntohs(of11_raw.dl_vlan),
4586 (of11_raw.wildcards & htonl(OFPFW11_DL_VLAN)) != 0,
4587 of11_raw.dl_vlan_pcp,
4588 (of11_raw.wildcards & htonl(OFPFW11_DL_VLAN_PCP)) != 0,
4589 ntohs(of11_match.flow.vlans[0].tci),
4590 ntohs(of11_match.wc.masks.vlans[0].tci));
4591 }
4592
4593 /* "print-error ENUM": Prints the type and code of ENUM for every OpenFlow
4594 * version. */
4595 static void
4596 ofctl_print_error(struct ovs_cmdl_context *ctx)
4597 {
4598 enum ofperr error;
4599 int version;
4600
4601 error = ofperr_from_name(ctx->argv[1]);
4602 if (!error) {
4603 ovs_fatal(0, "unknown error \"%s\"", ctx->argv[1]);
4604 }
4605
4606 for (version = 0; version <= UINT8_MAX; version++) {
4607 const char *name = ofperr_domain_get_name(version);
4608 if (name) {
4609 int vendor = ofperr_get_vendor(error, version);
4610 int type = ofperr_get_type(error, version);
4611 int code = ofperr_get_code(error, version);
4612
4613 if (vendor != -1 || type != -1 || code != -1) {
4614 printf("%s: vendor %#x, type %d, code %d\n",
4615 name, vendor, type, code);
4616 }
4617 }
4618 }
4619 }
4620
4621 /* "encode-error-reply ENUM REQUEST": Encodes an error reply to REQUEST for the
4622 * error named ENUM and prints the error reply in hex. */
4623 static void
4624 ofctl_encode_error_reply(struct ovs_cmdl_context *ctx)
4625 {
4626 const struct ofp_header *oh;
4627 struct ofpbuf request, *reply;
4628 enum ofperr error;
4629
4630 error = ofperr_from_name(ctx->argv[1]);
4631 if (!error) {
4632 ovs_fatal(0, "unknown error \"%s\"", ctx->argv[1]);
4633 }
4634
4635 ofpbuf_init(&request, 0);
4636 if (ofpbuf_put_hex(&request, ctx->argv[2], NULL)[0] != '\0') {
4637 ovs_fatal(0, "Trailing garbage in hex data");
4638 }
4639 if (request.size < sizeof(struct ofp_header)) {
4640 ovs_fatal(0, "Request too short");
4641 }
4642
4643 oh = request.data;
4644 if (request.size != ntohs(oh->length)) {
4645 ovs_fatal(0, "Request size inconsistent");
4646 }
4647
4648 reply = ofperr_encode_reply(error, request.data);
4649 ofpbuf_uninit(&request);
4650
4651 ovs_hex_dump(stdout, reply->data, reply->size, 0, false);
4652 ofpbuf_delete(reply);
4653 }
4654
4655 /* Usage:
4656 * ofp-print HEXSTRING [VERBOSITY]
4657 * ofp-print - [VERBOSITY] < HEXSTRING_FILE
4658 * ofp-print --raw - [VERBOSITY] < RAW_FILE
4659 *
4660 * Converts the hex digits in HEXSTRING into binary data, interpreting them as
4661 * an OpenFlow message, and prints the OpenFlow message on stdout, at VERBOSITY
4662 * (level 2 by default). With -, hex data is read from HEXSTRING_FILE, and
4663 * with --raw -, raw binary data is read from RAW_FILE. */
4664 static void
4665 ofctl_ofp_print(struct ovs_cmdl_context *ctx)
4666 {
4667 int verbosity_ = ctx->argc > 2 ? atoi(ctx->argv[2]) : 2;
4668
4669 struct ofpbuf packet;
4670 ofpbuf_init(&packet, 0);
4671
4672 char *buffer = NULL;
4673 if (!strcmp(ctx->argv[1], "-")) {
4674 if (raw) {
4675 for (;;) {
4676 int c = getchar();
4677 if (c == EOF) {
4678 break;
4679 }
4680 ofpbuf_put(&packet, &c, 1);
4681 }
4682 } else {
4683 struct ds line = DS_EMPTY_INITIALIZER;
4684 if (ds_get_line(&line, stdin)) {
4685 VLOG_FATAL("Failed to read stdin");
4686 }
4687 buffer = ds_steal_cstr(&line);
4688 }
4689 } else {
4690 buffer = xstrdup(ctx->argv[1]);
4691 }
4692 if (buffer && ofpbuf_put_hex(&packet, buffer, NULL)[0] != '\0') {
4693 ovs_fatal(0, "trailing garbage following hex bytes");
4694 }
4695 free(buffer);
4696 ofp_print(stdout, packet.data, packet.size, NULL, NULL, verbosity_);
4697 ofpbuf_uninit(&packet);
4698 }
4699
4700 /* "encode-hello BITMAP...": Encodes each BITMAP as an OpenFlow hello message
4701 * and dumps each message in hex. */
4702 static void
4703 ofctl_encode_hello(struct ovs_cmdl_context *ctx)
4704 {
4705 uint32_t bitmap = strtol(ctx->argv[1], NULL, 0);
4706 struct ofpbuf *hello;
4707
4708 hello = ofputil_encode_hello(bitmap);
4709 ovs_hex_dump(stdout, hello->data, hello->size, 0, false);
4710 ofp_print(stdout, hello->data, hello->size, NULL, NULL, verbosity);
4711 ofpbuf_delete(hello);
4712 }
4713
4714 static void
4715 ofctl_parse_key_value(struct ovs_cmdl_context *ctx)
4716 {
4717 for (size_t i = 1; i < ctx->argc; i++) {
4718 char *s = ctx->argv[i];
4719 char *key, *value;
4720 int j = 0;
4721 while (ofputil_parse_key_value(&s, &key, &value)) {
4722 if (j++) {
4723 fputs(", ", stdout);
4724 }
4725 fputs(key, stdout);
4726 if (value[0]) {
4727 printf("=%s", value);
4728 }
4729 }
4730 putchar('\n');
4731 }
4732 }
4733
4734 /* "compose-packet [--pcap] FLOW [L7]": Converts the OpenFlow flow
4735 * specification FLOW to a packet with flow_compose() and prints the hex bytes
4736 * in the packet on stdout. Also verifies that the flow extracted from that
4737 * packet matches the original FLOW.
4738 *
4739 * With --pcap, prints the packet to stdout instead as a pcap file, so that you
4740 * can do something like "ovs-ofctl --pcap compose-packet udp | tcpdump -vvvv
4741 * -r-" to use another tool to dump the packet contents.
4742 *
4743 * If L7 is specified, draws the L7 payload data from it, otherwise defaults to
4744 * 64 bytes of payload. */
4745 static void
4746 ofctl_compose_packet(struct ovs_cmdl_context *ctx)
4747 {
4748 if (print_pcap && isatty(STDOUT_FILENO)) {
4749 ovs_fatal(1, "not writing pcap data to stdout; redirect to a file "
4750 "or pipe to tcpdump instead");
4751 }
4752
4753 struct flow flow1;
4754 char *error = parse_ofp_exact_flow(&flow1, NULL, NULL, ctx->argv[1], NULL);
4755 if (error) {
4756 ovs_fatal(0, "%s", error);
4757 }
4758
4759 struct dp_packet p;
4760 memset(&p, 0, sizeof p);
4761 dp_packet_init(&p, 0);
4762
4763 void *l7 = NULL;
4764 size_t l7_len = 64;
4765 if (ctx->argc > 2) {
4766 struct dp_packet payload;
4767 memset(&payload, 0, sizeof payload);
4768 dp_packet_init(&payload, 0);
4769 if (dp_packet_put_hex(&payload, ctx->argv[2], NULL)[0] != '\0') {
4770 ovs_fatal(0, "%s: trailing garbage in packet data", ctx->argv[2]);
4771 }
4772 l7_len = dp_packet_size(&payload);
4773 l7 = dp_packet_steal_data(&payload);
4774 }
4775 flow_compose(&p, &flow1, l7, l7_len);
4776 free(l7);
4777
4778 if (print_pcap) {
4779 ovs_pcap_write_header(stdout);
4780 ovs_pcap_write(stdout, &p);
4781 } else {
4782 ovs_hex_dump(stdout, dp_packet_data(&p), dp_packet_size(&p), 0, false);
4783 }
4784
4785 struct flow flow2;
4786 flow_extract(&p, &flow2);
4787 flow2.in_port.ofp_port = OFPP_ANY;
4788
4789 dp_packet_uninit(&p);
4790
4791 if (!flow_equal(&flow1, &flow2)) {
4792 fprintf(stderr, "specified and extracted flows differ:\n");
4793 fputs("specified: ", stderr);
4794 flow_print(stderr, &flow1, NULL);
4795 fputs("\nextracted: ", stderr);
4796 flow_print(stderr, &flow2, NULL);
4797 exit(1);
4798 }
4799 }
4800
4801 static const struct ovs_cmdl_command all_commands[] = {
4802 { "show", "switch",
4803 1, 1, ofctl_show, OVS_RO },
4804 { "monitor", "switch [misslen] [invalid_ttl] [watch:[...]]",
4805 1, 3, ofctl_monitor, OVS_RO },
4806 { "snoop", "switch",
4807 1, 1, ofctl_snoop, OVS_RO },
4808 { "dump-desc", "switch",
4809 1, 1, ofctl_dump_desc, OVS_RO },
4810 { "dump-tables", "switch",
4811 1, 1, ofctl_dump_tables, OVS_RO },
4812 { "dump-table-features", "switch",
4813 1, 1, ofctl_dump_table_features, OVS_RO },
4814 { "dump-table-desc", "switch",
4815 1, 1, ofctl_dump_table_desc, OVS_RO },
4816 { "dump-flows", "switch",
4817 1, 2, ofctl_dump_flows, OVS_RO },
4818 { "dump-aggregate", "switch",
4819 1, 2, ofctl_dump_aggregate, OVS_RO },
4820 { "queue-stats", "switch [port [queue]]",
4821 1, 3, ofctl_queue_stats, OVS_RO },
4822 { "queue-get-config", "switch [port [queue]]",
4823 1, 3, ofctl_queue_get_config, OVS_RO },
4824 { "add-flow", "switch flow",
4825 2, 2, ofctl_add_flow, OVS_RW },
4826 { "add-flows", "switch file",
4827 2, 2, ofctl_add_flows, OVS_RW },
4828 { "mod-flows", "switch flow",
4829 2, 2, ofctl_mod_flows, OVS_RW },
4830 { "del-flows", "switch [flow]",
4831 1, 2, ofctl_del_flows, OVS_RW },
4832 { "replace-flows", "switch file",
4833 2, 2, ofctl_replace_flows, OVS_RW },
4834 { "diff-flows", "source1 source2",
4835 2, 2, ofctl_diff_flows, OVS_RW },
4836 { "add-meter", "switch meter",
4837 2, 2, ofctl_add_meter, OVS_RW },
4838 { "mod-meter", "switch meter",
4839 2, 2, ofctl_mod_meter, OVS_RW },
4840 { "del-meter", "switch meter",
4841 2, 2, ofctl_del_meters, OVS_RW },
4842 { "del-meters", "switch",
4843 1, 1, ofctl_del_meters, OVS_RW },
4844 { "dump-meter", "switch meter",
4845 2, 2, ofctl_dump_meters, OVS_RO },
4846 { "dump-meters", "switch",
4847 1, 1, ofctl_dump_meters, OVS_RO },
4848 { "meter-stats", "switch [meter]",
4849 1, 2, ofctl_meter_stats, OVS_RO },
4850 { "meter-features", "switch",
4851 1, 1, ofctl_meter_features, OVS_RO },
4852 { "packet-out", "switch \"in_port=<port> packet=<hex data> actions=...\"",
4853 2, INT_MAX, ofctl_packet_out, OVS_RW },
4854 { "dump-ports", "switch [port]",
4855 1, 2, ofctl_dump_ports, OVS_RO },
4856 { "dump-ports-desc", "switch [port]",
4857 1, 2, ofctl_dump_ports_desc, OVS_RO },
4858 { "mod-port", "switch iface act",
4859 3, 3, ofctl_mod_port, OVS_RW },
4860 { "mod-table", "switch mod",
4861 3, 3, ofctl_mod_table, OVS_RW },
4862 { "get-frags", "switch",
4863 1, 1, ofctl_get_frags, OVS_RO },
4864 { "set-frags", "switch frag_mode",
4865 2, 2, ofctl_set_frags, OVS_RW },
4866 { "probe", "target",
4867 1, 1, ofctl_probe, OVS_RO },
4868 { "ping", "target [n]",
4869 1, 2, ofctl_ping, OVS_RO },
4870 { "benchmark", "target n count",
4871 3, 3, ofctl_benchmark, OVS_RO },
4872
4873 { "dump-ipfix-bridge", "switch",
4874 1, 1, ofctl_dump_ipfix_bridge, OVS_RO },
4875 { "dump-ipfix-flow", "switch",
4876 1, 1, ofctl_dump_ipfix_flow, OVS_RO },
4877
4878 { "ct-flush-zone", "switch zone",
4879 2, 2, ofctl_ct_flush_zone, OVS_RO },
4880
4881 { "ofp-parse", "file",
4882 1, 1, ofctl_ofp_parse, OVS_RW },
4883 { "ofp-parse-pcap", "pcap",
4884 1, INT_MAX, ofctl_ofp_parse_pcap, OVS_RW },
4885
4886 { "add-group", "switch group",
4887 1, 2, ofctl_add_group, OVS_RW },
4888 { "add-groups", "switch file",
4889 1, 2, ofctl_add_groups, OVS_RW },
4890 { "mod-group", "switch group",
4891 1, 2, ofctl_mod_group, OVS_RW },
4892 { "del-groups", "switch [group]",
4893 1, 2, ofctl_del_groups, OVS_RW },
4894 { "insert-buckets", "switch [group]",
4895 1, 2, ofctl_insert_bucket, OVS_RW },
4896 { "remove-buckets", "switch [group]",
4897 1, 2, ofctl_remove_bucket, OVS_RW },
4898 { "dump-groups", "switch [group]",
4899 1, 2, ofctl_dump_group_desc, OVS_RO },
4900 { "dump-group-stats", "switch [group]",
4901 1, 2, ofctl_dump_group_stats, OVS_RO },
4902 { "dump-group-features", "switch",
4903 1, 1, ofctl_dump_group_features, OVS_RO },
4904
4905 { "bundle", "switch file",
4906 2, 2, ofctl_bundle, OVS_RW },
4907
4908 { "add-tlv-map", "switch map",
4909 2, 2, ofctl_add_tlv_map, OVS_RO },
4910 { "del-tlv-map", "switch [map]",
4911 1, 2, ofctl_del_tlv_map, OVS_RO },
4912 { "dump-tlv-map", "switch",
4913 1, 1, ofctl_dump_tlv_map, OVS_RO },
4914 { "help", NULL, 0, INT_MAX, ofctl_help, OVS_RO },
4915 { "list-commands", NULL, 0, INT_MAX, ofctl_list_commands, OVS_RO },
4916
4917 /* Undocumented commands for testing. */
4918 { "parse-flow", NULL, 1, 1, ofctl_parse_flow, OVS_RW },
4919 { "parse-flows", NULL, 1, 1, ofctl_parse_flows, OVS_RW },
4920 { "parse-nx-match", NULL, 0, 0, ofctl_parse_nxm, OVS_RW },
4921 { "parse-nxm", NULL, 0, 0, ofctl_parse_nxm, OVS_RW },
4922 { "parse-oxm", NULL, 1, 1, ofctl_parse_oxm, OVS_RW },
4923 { "parse-actions", NULL, 1, 1, ofctl_parse_actions, OVS_RW },
4924 { "parse-instructions", NULL, 1, 1, ofctl_parse_instructions, OVS_RW },
4925 { "parse-ofp10-match", NULL, 0, 0, ofctl_parse_ofp10_match, OVS_RW },
4926 { "parse-ofp11-match", NULL, 0, 0, ofctl_parse_ofp11_match, OVS_RW },
4927 { "parse-pcap", NULL, 1, INT_MAX, ofctl_parse_pcap, OVS_RW },
4928 { "check-vlan", NULL, 2, 2, ofctl_check_vlan, OVS_RW },
4929 { "print-error", NULL, 1, 1, ofctl_print_error, OVS_RW },
4930 { "encode-error-reply", NULL, 2, 2, ofctl_encode_error_reply, OVS_RW },
4931 { "ofp-print", NULL, 1, 2, ofctl_ofp_print, OVS_RW },
4932 { "encode-hello", NULL, 1, 1, ofctl_encode_hello, OVS_RW },
4933 { "parse-key-value", NULL, 1, INT_MAX, ofctl_parse_key_value, OVS_RW },
4934 { "compose-packet", NULL, 1, 2, ofctl_compose_packet, OVS_RO },
4935
4936 { NULL, NULL, 0, 0, NULL, OVS_RO },
4937 };
4938
4939 static const struct ovs_cmdl_command *get_all_commands(void)
4940 {
4941 return all_commands;
4942 }