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