]> git.proxmox.com Git - ovs.git/blame - utilities/ovs-ofctl.c
ofp-util: Fix xid in ofputil_encode_bundle_add().
[ovs.git] / utilities / ovs-ofctl.c
CommitLineData
064af421 1/*
18080541 2 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc.
064af421 3 *
a14bc59f
BP
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:
064af421 7 *
a14bc59f
BP
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.
064af421
BP
15 */
16
17#include <config.h>
2b07c8b1 18#include <ctype.h>
064af421
BP
19#include <errno.h>
20#include <getopt.h>
21#include <inttypes.h>
bd6b7545 22#include <sys/socket.h>
064af421 23#include <net/if.h>
064af421 24#include <signal.h>
064af421
BP
25#include <stdlib.h>
26#include <string.h>
27#include <unistd.h>
71d1b763 28#include <fcntl.h>
064af421
BP
29#include <sys/stat.h>
30#include <sys/time.h>
31
10a24935 32#include "byte-order.h"
09246b99 33#include "classifier.h"
064af421 34#include "command-line.h"
1eb85ef5 35#include "daemon.h"
064af421
BP
36#include "compiler.h"
37#include "dirs.h"
09246b99 38#include "dynamic-string.h"
8a777cf6 39#include "fatal-signal.h"
09246b99 40#include "nx-match.h"
064af421 41#include "odp-util.h"
f25d0cf3 42#include "ofp-actions.h"
90bf1e07 43#include "ofp-errors.h"
982697a4 44#include "ofp-msgs.h"
f22716dc 45#include "ofp-parse.h"
064af421 46#include "ofp-print.h"
fa37b408 47#include "ofp-util.h"
a53a8efa 48#include "ofp-version-opt.h"
064af421 49#include "ofpbuf.h"
63d347ce 50#include "ofproto/ofproto.h"
064af421
BP
51#include "openflow/nicira-ext.h"
52#include "openflow/openflow.h"
cf62fa4c 53#include "dp-packet.h"
0c3d5fc8 54#include "packets.h"
14249c02 55#include "pcap-file.h"
1eb85ef5 56#include "poll-loop.h"
064af421 57#include "random.h"
fe55ad15 58#include "stream-ssl.h"
c3f25389 59#include "socket-util.h"
064af421 60#include "timeval.h"
1eb85ef5 61#include "unixctl.h"
064af421 62#include "util.h"
4a1f523f 63#include "openvswitch/vconn.h"
e6211adc 64#include "openvswitch/vlog.h"
bdcc5925
BP
65#include "meta-flow.h"
66#include "sort.h"
064af421 67
d98e6007 68VLOG_DEFINE_THIS_MODULE(ofctl);
064af421 69
102ce766
EJ
70/* --strict: Use strict matching for flow mod commands? Additionally governs
71 * use of nx_pull_match() instead of nx_pull_match_loose() in parse-nx-match.
72 */
675febfa 73static bool strict;
064af421 74
96989efc 75/* --readd: If true, on replace-flows, re-add even flows that have not changed
c4ea79bf
BP
76 * (to reset flow counters). */
77static bool readd;
78
27527aa0
BP
79/* -F, --flow-format: Allowed protocols. By default, any protocol is
80 * allowed. */
81static enum ofputil_protocol allowed_protocols = OFPUTIL_P_ANY;
88ca35ee 82
54834960
EJ
83/* -P, --packet-in-format: Packet IN format to use in monitor and snoop
84 * commands. Either one of NXPIF_* to force a particular packet_in format, or
85 * -1 to let ovs-ofctl choose the default. */
86static int preferred_packet_in_format = -1;
87
4f564f8d
BP
88/* -m, --more: Additional verbosity for ofp-print functions. */
89static int verbosity;
90
0c9560b7
BP
91/* --timestamp: Print a timestamp before each received packet on "monitor" and
92 * "snoop" command? */
93static bool timestamp;
94
19945013
BP
95/* --unixctl-path: Path to use for unixctl server, for "monitor" and "snoop"
96 commands. */
97static char *unixctl_path;
98
bdcc5925
BP
99/* --sort, --rsort: Sort order. */
100enum sort_order { SORT_ASC, SORT_DESC };
101struct sort_criterion {
102 const struct mf_field *field; /* NULL means to sort by priority. */
103 enum sort_order order;
104};
105static struct sort_criterion *criteria;
106static size_t n_criteria, allocated_criteria;
107
5f383751 108static const struct ovs_cmdl_command *get_all_commands(void);
064af421 109
cab50449 110OVS_NO_RETURN static void usage(void);
675febfa 111static void parse_options(int argc, char *argv[]);
064af421 112
bdcc5925
BP
113static bool recv_flow_stats_reply(struct vconn *, ovs_be32 send_xid,
114 struct ofpbuf **replyp,
115 struct ofputil_flow_stats *,
116 struct ofpbuf *ofpacts);
675febfa
BP
117int
118main(int argc, char *argv[])
064af421 119{
1636c761 120 struct ovs_cmdl_context ctx = { .argc = 0, };
064af421 121 set_program_name(argv[0]);
5e3ee29d 122 service_start(&argc, &argv);
675febfa 123 parse_options(argc, argv);
8a777cf6 124 fatal_ignore_sigpipe();
1636c761
RB
125 ctx.argc = argc - optind;
126 ctx.argv = argv + optind;
127 ovs_cmdl_run_command(&ctx, get_all_commands());
064af421
BP
128 return 0;
129}
130
bdcc5925
BP
131static void
132add_sort_criterion(enum sort_order order, const char *field)
133{
134 struct sort_criterion *sc;
135
136 if (n_criteria >= allocated_criteria) {
137 criteria = x2nrealloc(criteria, &allocated_criteria, sizeof *criteria);
138 }
139
140 sc = &criteria[n_criteria++];
141 if (!field || !strcasecmp(field, "priority")) {
142 sc->field = NULL;
143 } else {
144 sc->field = mf_from_name(field);
145 if (!sc->field) {
146 ovs_fatal(0, "%s: unknown field name", field);
147 }
148 }
149 sc->order = order;
150}
151
064af421 152static void
675febfa 153parse_options(int argc, char *argv[])
064af421
BP
154{
155 enum {
87c84891 156 OPT_STRICT = UCHAR_MAX + 1,
c4ea79bf 157 OPT_READD,
0c9560b7 158 OPT_TIMESTAMP,
bdcc5925
BP
159 OPT_SORT,
160 OPT_RSORT,
19945013 161 OPT_UNIXCTL,
1eb85ef5 162 DAEMON_OPTION_ENUMS,
a53a8efa 163 OFP_VERSION_OPTION_ENUMS,
87c84891 164 VLOG_OPTION_ENUMS
064af421 165 };
07fc4ed3 166 static const struct option long_options[] = {
e3c17733
BP
167 {"timeout", required_argument, NULL, 't'},
168 {"strict", no_argument, NULL, OPT_STRICT},
c4ea79bf 169 {"readd", no_argument, NULL, OPT_READD},
e3c17733 170 {"flow-format", required_argument, NULL, 'F'},
54834960 171 {"packet-in-format", required_argument, NULL, 'P'},
e3c17733 172 {"more", no_argument, NULL, 'm'},
0c9560b7 173 {"timestamp", no_argument, NULL, OPT_TIMESTAMP},
bdcc5925
BP
174 {"sort", optional_argument, NULL, OPT_SORT},
175 {"rsort", optional_argument, NULL, OPT_RSORT},
19945013 176 {"unixctl", required_argument, NULL, OPT_UNIXCTL},
e3c17733 177 {"help", no_argument, NULL, 'h'},
66fa2c88 178 {"option", no_argument, NULL, 'o'},
1eb85ef5 179 DAEMON_LONG_OPTIONS,
a53a8efa 180 OFP_VERSION_LONG_OPTIONS,
87c84891 181 VLOG_LONG_OPTIONS,
bf8f2167 182 STREAM_SSL_LONG_OPTIONS,
e3c17733 183 {NULL, 0, NULL, 0},
064af421 184 };
5f383751 185 char *short_options = ovs_cmdl_long_options_to_short_options(long_options);
37923ac7
BP
186 uint32_t versions;
187 enum ofputil_protocol version_protocols;
064af421 188
6dc53744
BP
189 /* For now, ovs-ofctl only enables OpenFlow 1.0 by default. This is
190 * because ovs-ofctl implements command such as "add-flow" as raw OpenFlow
191 * requests, but those requests have subtly different semantics in
192 * different OpenFlow versions. For example:
193 *
194 * - In OpenFlow 1.0, a "mod-flow" operation that does not find any
195 * existing flow to modify adds a new flow.
196 *
197 * - In OpenFlow 1.1, a "mod-flow" operation that does not find any
198 * existing flow to modify adds a new flow, but only if the mod-flow
199 * did not match on the flow cookie.
200 *
201 * - In OpenFlow 1.2 and a later, a "mod-flow" operation never adds a
202 * new flow.
203 */
204 set_allowed_ofp_versions("OpenFlow10");
205
064af421
BP
206 for (;;) {
207 unsigned long int timeout;
208 int c;
209
210 c = getopt_long(argc, argv, short_options, long_options, NULL);
211 if (c == -1) {
212 break;
213 }
214
215 switch (c) {
216 case 't':
217 timeout = strtoul(optarg, NULL, 10);
218 if (timeout <= 0) {
219 ovs_fatal(0, "value %s on -t or --timeout is not at least 1",
220 optarg);
221 } else {
222 time_alarm(timeout);
223 }
224 break;
225
88ca35ee 226 case 'F':
27527aa0
BP
227 allowed_protocols = ofputil_protocols_from_string(optarg);
228 if (!allowed_protocols) {
229 ovs_fatal(0, "%s: invalid flow format(s)", optarg);
88ca35ee
BP
230 }
231 break;
232
54834960
EJ
233 case 'P':
234 preferred_packet_in_format =
235 ofputil_packet_in_format_from_string(optarg);
236 if (preferred_packet_in_format < 0) {
237 ovs_fatal(0, "unknown packet-in format `%s'", optarg);
238 }
239 break;
240
4f564f8d
BP
241 case 'm':
242 verbosity++;
243 break;
244
064af421
BP
245 case 'h':
246 usage();
247
66fa2c88 248 case 'o':
5f383751 249 ovs_cmdl_print_options(long_options);
66fa2c88
AW
250 exit(EXIT_SUCCESS);
251
064af421 252 case OPT_STRICT:
675febfa 253 strict = true;
064af421
BP
254 break;
255
c4ea79bf
BP
256 case OPT_READD:
257 readd = true;
258 break;
259
0c9560b7
BP
260 case OPT_TIMESTAMP:
261 timestamp = true;
262 break;
263
bdcc5925
BP
264 case OPT_SORT:
265 add_sort_criterion(SORT_ASC, optarg);
266 break;
267
268 case OPT_RSORT:
269 add_sort_criterion(SORT_DESC, optarg);
270 break;
271
19945013
BP
272 case OPT_UNIXCTL:
273 unixctl_path = optarg;
274 break;
275
1eb85ef5 276 DAEMON_OPTION_HANDLERS
a53a8efa 277 OFP_VERSION_OPTION_HANDLERS
87c84891 278 VLOG_OPTION_HANDLERS
fe55ad15 279 STREAM_SSL_OPTION_HANDLERS
064af421
BP
280
281 case '?':
282 exit(EXIT_FAILURE);
283
284 default:
285 abort();
286 }
287 }
bdcc5925
BP
288
289 if (n_criteria) {
290 /* Always do a final sort pass based on priority. */
291 add_sort_criterion(SORT_DESC, "priority");
292 }
293
064af421 294 free(short_options);
37923ac7
BP
295
296 versions = get_allowed_ofp_versions();
297 version_protocols = ofputil_protocols_from_version_bitmap(versions);
298 if (!(allowed_protocols & version_protocols)) {
299 char *protocols = ofputil_protocols_to_string(allowed_protocols);
300 struct ds version_s = DS_EMPTY_INITIALIZER;
301
302 ofputil_format_version_bitmap_names(&version_s, versions);
303 ovs_fatal(0, "None of the enabled OpenFlow versions (%s) supports "
304 "any of the enabled flow formats (%s). (Use -O to enable "
305 "additional OpenFlow versions or -F to enable additional "
306 "flow formats.)", ds_cstr(&version_s), protocols);
307 }
308 allowed_protocols &= version_protocols;
309 mask_allowed_ofp_versions(ofputil_protocols_to_version_bitmap(
310 allowed_protocols));
064af421
BP
311}
312
313static void
314usage(void)
315{
316 printf("%s: OpenFlow switch management utility\n"
317 "usage: %s [OPTIONS] COMMAND [ARG...]\n"
318 "\nFor OpenFlow switches:\n"
319 " show SWITCH show OpenFlow information\n"
064af421
BP
320 " dump-desc SWITCH print switch description\n"
321 " dump-tables SWITCH print table stats\n"
5deff5aa 322 " dump-table-features SWITCH print table features\n"
064af421 323 " mod-port SWITCH IFACE ACT modify port behavior\n"
918f2b82 324 " mod-table SWITCH MOD modify flow table behavior\n"
7257b535
BP
325 " get-frags SWITCH print fragment handling behavior\n"
326 " set-frags SWITCH FRAG_MODE set fragment handling behavior\n"
abaad8cf 327 " dump-ports SWITCH [PORT] print port statistics\n"
70ae4f93 328 " dump-ports-desc SWITCH [PORT] print port descriptions\n"
064af421
BP
329 " dump-flows SWITCH print all flow entries\n"
330 " dump-flows SWITCH FLOW print matching FLOWs\n"
331 " dump-aggregate SWITCH print aggregate flow statistics\n"
332 " dump-aggregate SWITCH FLOW print aggregate stats for FLOWs\n"
d2805da2 333 " queue-stats SWITCH [PORT [QUEUE]] dump queue stats\n"
064af421
BP
334 " add-flow SWITCH FLOW add flow described by FLOW\n"
335 " add-flows SWITCH FILE add flows from FILE\n"
336 " mod-flows SWITCH FLOW modify actions of matching FLOWs\n"
337 " del-flows SWITCH [FLOW] delete matching FLOWs\n"
5ff660c6 338 " replace-flows SWITCH FILE replace flows with those in FILE\n"
1dac118c 339 " diff-flows SOURCE1 SOURCE2 compare flows from two sources\n"
0c3d5fc8
BP
340 " packet-out SWITCH IN_PORT ACTIONS PACKET...\n"
341 " execute ACTIONS on PACKET\n"
2b07c8b1 342 " monitor SWITCH [MISSLEN] [invalid_ttl] [watch:[...]]\n"
1dac118c
BP
343 " print packets received from SWITCH\n"
344 " snoop SWITCH snoop on SWITCH and its controller\n"
7395c052 345 " add-group SWITCH GROUP add group described by GROUP\n"
bdcca615 346 " add-groups SWITCH FILE add group from FILE\n"
7395c052
NZ
347 " mod-group SWITCH GROUP modify specific group\n"
348 " del-groups SWITCH [GROUP] delete matching GROUPs\n"
bdbb8426
SH
349 " insert-buckets SWITCH [GROUP] add buckets to GROUP\n"
350 " remove-buckets SWITCH [GROUP] remove buckets from GROUP\n"
7395c052 351 " dump-group-features SWITCH print group features\n"
19187a71 352 " dump-groups SWITCH [GROUP] print group description\n"
7395c052 353 " dump-group-stats SWITCH [GROUP] print group statistics\n"
e8f9a7bb 354 " queue-get-config SWITCH PORT print queue information for port\n"
3200ed58
JR
355 " add-meter SWITCH METER add meter described by METER\n"
356 " mod-meter SWITCH METER modify specific METER\n"
357 " del-meter SWITCH METER delete METER\n"
358 " del-meters SWITCH delete all meters\n"
359 " dump-meter SWITCH METER print METER configuration\n"
360 " dump-meters SWITCH print all meter configuration\n"
361 " meter-stats SWITCH [METER] print meter statistics\n"
362 " meter-features SWITCH print meter features\n"
064af421 363 "\nFor OpenFlow switches and controllers:\n"
2daadadd
BP
364 " probe TARGET probe whether TARGET is up\n"
365 " ping TARGET [N] latency of N-byte echos\n"
366 " benchmark TARGET N COUNT bandwidth of COUNT N-byte echos\n"
1ac0e975
BP
367 "SWITCH or TARGET is an active OpenFlow connection method.\n"
368 "\nOther commands:\n"
f3dd1419
BP
369 " ofp-parse FILE print messages read from FILE\n"
370 " ofp-parse-pcap PCAP print OpenFlow read from PCAP\n",
064af421
BP
371 program_name, program_name);
372 vconn_usage(true, false, false);
1eb85ef5 373 daemon_usage();
a53a8efa 374 ofp_version_usage();
064af421
BP
375 vlog_usage();
376 printf("\nOther options:\n"
377 " --strict use strict match for flow commands\n"
c4ea79bf 378 " --readd replace flows that haven't changed\n"
88ca35ee 379 " -F, --flow-format=FORMAT force particular flow format\n"
54834960 380 " -P, --packet-in-format=FRMT force particular packet in format\n"
4f564f8d 381 " -m, --more be more verbose printing OpenFlow\n"
0c9560b7 382 " --timestamp (monitor, snoop) print timestamps\n"
064af421 383 " -t, --timeout=SECS give up after SECS seconds\n"
bdcc5925
BP
384 " --sort[=field] sort in ascending order\n"
385 " --rsort[=field] sort in descending order\n"
19945013 386 " --unixctl=SOCKET set control socket name\n"
064af421
BP
387 " -h, --help display this help message\n"
388 " -V, --version display version information\n");
389 exit(EXIT_SUCCESS);
390}
391
1eb85ef5
EJ
392static void
393ofctl_exit(struct unixctl_conn *conn, int argc OVS_UNUSED,
394 const char *argv[] OVS_UNUSED, void *exiting_)
395{
396 bool *exiting = exiting_;
397 *exiting = true;
bde9f75d 398 unixctl_command_reply(conn, NULL);
1eb85ef5
EJ
399}
400
064af421 401static void run(int retval, const char *message, ...)
cab50449 402 OVS_PRINTF_FORMAT(2, 3);
064af421 403
473f65a2
BP
404static void
405run(int retval, const char *message, ...)
064af421
BP
406{
407 if (retval) {
408 va_list args;
409
064af421 410 va_start(args, message);
fcaddd4d 411 ovs_fatal_valist(retval, message, args);
064af421
BP
412 }
413}
414\f
415/* Generic commands. */
416
c3f25389 417static int
1a6f1e2a
JG
418open_vconn_socket(const char *name, struct vconn **vconnp)
419{
420 char *vconn_name = xasprintf("unix:%s", name);
c3f25389
EJ
421 int error;
422
82c8c53c
BP
423 error = vconn_open(vconn_name, get_allowed_ofp_versions(), DSCP_DEFAULT,
424 vconnp);
c3f25389
EJ
425 if (error && error != ENOENT) {
426 ovs_fatal(0, "%s: failed to open socket (%s)", name,
10a89ef0 427 ovs_strerror(error));
c3f25389 428 }
1a6f1e2a 429 free(vconn_name);
c3f25389
EJ
430
431 return error;
1a6f1e2a
JG
432}
433
4766ce7a
BP
434enum open_target { MGMT, SNOOP };
435
27527aa0 436static enum ofputil_protocol
4766ce7a 437open_vconn__(const char *name, enum open_target target,
0caf6bde 438 struct vconn **vconnp)
064af421 439{
4766ce7a 440 const char *suffix = target == MGMT ? "mgmt" : "snoop";
63d347ce 441 char *datapath_name, *datapath_type, *socket_name;
27527aa0 442 enum ofputil_protocol protocol;
63d347ce 443 char *bridge_path;
27527aa0 444 int ofp_version;
c3f25389 445 int error;
1a6f1e2a 446
4766ce7a 447 bridge_path = xasprintf("%s/%s.%s", ovs_rundir(), name, suffix);
63d347ce
BP
448
449 ofproto_parse_name(name, &datapath_name, &datapath_type);
4766ce7a 450 socket_name = xasprintf("%s/%s.%s", ovs_rundir(), datapath_name, suffix);
63d347ce
BP
451 free(datapath_name);
452 free(datapath_type);
064af421 453
3a27375e 454 if (strchr(name, ':')) {
539b741f 455 run(vconn_open(name, get_allowed_ofp_versions(), DSCP_DEFAULT, vconnp),
a53a8efa 456 "connecting to %s", name);
c3f25389
EJ
457 } else if (!open_vconn_socket(name, vconnp)) {
458 /* Fall Through. */
459 } else if (!open_vconn_socket(bridge_path, vconnp)) {
460 /* Fall Through. */
461 } else if (!open_vconn_socket(socket_name, vconnp)) {
462 /* Fall Through. */
064af421 463 } else {
2c0e6eb4 464 ovs_fatal(0, "%s is not a bridge or a socket", name);
064af421 465 }
1a6f1e2a 466
4766ce7a
BP
467 if (target == SNOOP) {
468 vconn_set_recv_any_version(*vconnp);
469 }
470
1a6f1e2a 471 free(bridge_path);
63d347ce 472 free(socket_name);
27527aa0 473
c3f25389
EJ
474 VLOG_DBG("connecting to %s", vconn_get_name(*vconnp));
475 error = vconn_connect_block(*vconnp);
476 if (error) {
477 ovs_fatal(0, "%s: failed to connect to socket (%s)", name,
10a89ef0 478 ovs_strerror(error));
c3f25389
EJ
479 }
480
27527aa0
BP
481 ofp_version = vconn_get_version(*vconnp);
482 protocol = ofputil_protocol_from_ofp_version(ofp_version);
483 if (!protocol) {
484 ovs_fatal(0, "%s: unsupported OpenFlow version 0x%02x",
485 name, ofp_version);
486 }
487 return protocol;
064af421
BP
488}
489
27527aa0 490static enum ofputil_protocol
0caf6bde
BP
491open_vconn(const char *name, struct vconn **vconnp)
492{
4766ce7a 493 return open_vconn__(name, MGMT, vconnp);
0caf6bde
BP
494}
495
064af421
BP
496static void
497send_openflow_buffer(struct vconn *vconn, struct ofpbuf *buffer)
498{
982697a4 499 ofpmsg_update_length(buffer);
064af421
BP
500 run(vconn_send_block(vconn, buffer), "failed to send packet to switch");
501}
502
503static void
a53a8efa 504dump_transaction(struct vconn *vconn, struct ofpbuf *request)
064af421 505{
064af421
BP
506 struct ofpbuf *reply;
507
982697a4 508 ofpmsg_update_length(request);
a53a8efa
SH
509 run(vconn_transact(vconn, request, &reply), "talking to %s",
510 vconn_get_name(vconn));
6fd6ed71 511 ofp_print(stdout, reply->data, reply->size, verbosity + 1);
e49190c4 512 ofpbuf_delete(reply);
064af421
BP
513}
514
515static void
982697a4 516dump_trivial_transaction(const char *vconn_name, enum ofpraw raw)
064af421
BP
517{
518 struct ofpbuf *request;
a53a8efa
SH
519 struct vconn *vconn;
520
521 open_vconn(vconn_name, &vconn);
522 request = ofpraw_alloc(raw, vconn_get_version(vconn), 0);
523 dump_transaction(vconn, request);
524 vconn_close(vconn);
064af421
BP
525}
526
527static void
53514387 528dump_stats_transaction(struct vconn *vconn, struct ofpbuf *request)
064af421 529{
6fd6ed71 530 const struct ofp_header *request_oh = request->data;
982697a4
BP
531 ovs_be32 send_xid = request_oh->xid;
532 enum ofpraw request_raw;
533 enum ofpraw reply_raw;
064af421
BP
534 bool done = false;
535
6fd6ed71 536 ofpraw_decode_partial(&request_raw, request->data, request->size);
982697a4
BP
537 reply_raw = ofpraw_stats_request_to_reply(request_raw,
538 request_oh->version);
539
064af421
BP
540 send_openflow_buffer(vconn, request);
541 while (!done) {
02833365 542 ovs_be32 recv_xid;
064af421
BP
543 struct ofpbuf *reply;
544
545 run(vconn_recv_block(vconn, &reply), "OpenFlow packet receive failed");
6fd6ed71 546 recv_xid = ((struct ofp_header *) reply->data)->xid;
064af421 547 if (send_xid == recv_xid) {
982697a4 548 enum ofpraw raw;
064af421 549
6fd6ed71 550 ofp_print(stdout, reply->data, reply->size, verbosity + 1);
064af421 551
6fd6ed71 552 ofpraw_decode(&raw, reply->data);
982697a4 553 if (ofptype_from_ofpraw(raw) == OFPTYPE_ERROR) {
a76150b1 554 done = true;
982697a4 555 } else if (raw == reply_raw) {
6fd6ed71 556 done = !ofpmp_more(reply->data);
a76150b1
BP
557 } else {
558 ovs_fatal(0, "received bad reply: %s",
6fd6ed71 559 ofp_to_string(reply->data, reply->size,
a76150b1
BP
560 verbosity + 1));
561 }
064af421
BP
562 } else {
563 VLOG_DBG("received reply with xid %08"PRIx32" "
564 "!= expected %08"PRIx32, recv_xid, send_xid);
565 }
566 ofpbuf_delete(reply);
567 }
9abfe557
BP
568}
569
570static void
53514387 571dump_trivial_stats_transaction(const char *vconn_name, enum ofpraw raw)
9abfe557 572{
53514387 573 struct ofpbuf *request;
9abfe557
BP
574 struct vconn *vconn;
575
576 open_vconn(vconn_name, &vconn);
53514387
SH
577 request = ofpraw_alloc(raw, vconn_get_version(vconn), 0);
578 dump_stats_transaction(vconn, request);
064af421
BP
579 vconn_close(vconn);
580}
581
a8eebd48
BP
582/* Sends all of the 'requests', which should be requests that only have replies
583 * if an error occurs, and waits for them to succeed or fail. If an error does
584 * occur, prints it and exits with an error.
7257b535
BP
585 *
586 * Destroys all of the 'requests'. */
d12513f7 587static void
ca6ba700 588transact_multiple_noreply(struct vconn *vconn, struct ovs_list *requests)
d12513f7 589{
88ca35ee 590 struct ofpbuf *request, *reply;
d12513f7 591
88ca35ee 592 LIST_FOR_EACH (request, list_node, requests) {
982697a4 593 ofpmsg_update_length(request);
88ca35ee
BP
594 }
595
596 run(vconn_transact_multiple_noreply(vconn, requests, &reply),
d12513f7
BP
597 "talking to %s", vconn_get_name(vconn));
598 if (reply) {
6fd6ed71 599 ofp_print(stderr, reply->data, reply->size, verbosity + 2);
d12513f7
BP
600 exit(1);
601 }
602 ofpbuf_delete(reply);
603}
604
88ca35ee
BP
605/* Sends 'request', which should be a request that only has a reply if an error
606 * occurs, and waits for it to succeed or fail. If an error does occur, prints
7257b535
BP
607 * it and exits with an error.
608 *
609 * Destroys 'request'. */
88ca35ee
BP
610static void
611transact_noreply(struct vconn *vconn, struct ofpbuf *request)
612{
ca6ba700 613 struct ovs_list requests;
88ca35ee
BP
614
615 list_init(&requests);
616 list_push_back(&requests, &request->list_node);
617 transact_multiple_noreply(vconn, &requests);
618}
619
7257b535
BP
620static void
621fetch_switch_config(struct vconn *vconn, struct ofp_switch_config *config_)
622{
623 struct ofp_switch_config *config;
7257b535
BP
624 struct ofpbuf *request;
625 struct ofpbuf *reply;
982697a4 626 enum ofptype type;
7257b535 627
a53a8efa
SH
628 request = ofpraw_alloc(OFPRAW_OFPT_GET_CONFIG_REQUEST,
629 vconn_get_version(vconn), 0);
7257b535
BP
630 run(vconn_transact(vconn, request, &reply),
631 "talking to %s", vconn_get_name(vconn));
632
982697a4 633 if (ofptype_pull(&type, reply) || type != OFPTYPE_GET_CONFIG_REPLY) {
7257b535
BP
634 ovs_fatal(0, "%s: bad reply to config request", vconn_get_name(vconn));
635 }
636
982697a4 637 config = ofpbuf_pull(reply, sizeof *config);
7257b535 638 *config_ = *config;
828c72d0
BP
639
640 ofpbuf_delete(reply);
7257b535
BP
641}
642
643static void
982697a4 644set_switch_config(struct vconn *vconn, const struct ofp_switch_config *config)
7257b535 645{
7257b535
BP
646 struct ofpbuf *request;
647
a53a8efa 648 request = ofpraw_alloc(OFPRAW_OFPT_SET_CONFIG, vconn_get_version(vconn), 0);
982697a4 649 ofpbuf_put(request, config, sizeof *config);
7257b535
BP
650
651 transact_noreply(vconn, request);
652}
653
064af421 654static void
1636c761 655ofctl_show(struct ovs_cmdl_context *ctx)
064af421 656{
1636c761 657 const char *vconn_name = ctx->argv[1];
fca6d553 658 enum ofp_version version;
ae0e7009
JP
659 struct vconn *vconn;
660 struct ofpbuf *request;
661 struct ofpbuf *reply;
fca6d553 662 bool has_ports;
ae0e7009 663
ae0e7009 664 open_vconn(vconn_name, &vconn);
fca6d553
BP
665 version = vconn_get_version(vconn);
666 request = ofpraw_alloc(OFPRAW_OFPT_FEATURES_REQUEST, version, 0);
ae0e7009
JP
667 run(vconn_transact(vconn, request, &reply), "talking to %s", vconn_name);
668
fca6d553 669 has_ports = ofputil_switch_features_has_ports(reply);
6fd6ed71 670 ofp_print(stdout, reply->data, reply->size, verbosity + 1);
ae0e7009 671 ofpbuf_delete(reply);
ae0e7009 672
fca6d553 673 if (!has_ports) {
70ae4f93 674 request = ofputil_encode_port_desc_stats_request(version, OFPP_ANY);
fca6d553 675 dump_stats_transaction(vconn, request);
ae0e7009 676 }
982697a4 677 dump_trivial_transaction(vconn_name, OFPRAW_OFPT_GET_CONFIG_REQUEST);
a53a8efa 678 vconn_close(vconn);
064af421
BP
679}
680
064af421 681static void
1636c761 682ofctl_dump_desc(struct ovs_cmdl_context *ctx)
064af421 683{
1636c761 684 dump_trivial_stats_transaction(ctx->argv[1], OFPRAW_OFPST_DESC_REQUEST);
064af421
BP
685}
686
687static void
1636c761 688ofctl_dump_tables(struct ovs_cmdl_context *ctx)
064af421 689{
1636c761 690 dump_trivial_stats_transaction(ctx->argv[1], OFPRAW_OFPST_TABLE_REQUEST);
064af421
BP
691}
692
5deff5aa 693static void
1636c761 694ofctl_dump_table_features(struct ovs_cmdl_context *ctx)
5deff5aa
AW
695{
696 struct ofpbuf *request;
697 struct vconn *vconn;
698
1636c761 699 open_vconn(ctx->argv[1], &vconn);
5deff5aa
AW
700 request = ofputil_encode_table_features_request(vconn_get_version(vconn));
701 if (request) {
702 dump_stats_transaction(vconn, request);
703 }
704
705 vconn_close(vconn);
706}
707
fca6d553
BP
708static bool fetch_port_by_stats(struct vconn *,
709 const char *port_name, ofp_port_t port_no,
710 struct ofputil_phy_port *);
711
712/* Uses OFPT_FEATURES_REQUEST to attempt to fetch information about the port
713 * named 'port_name' or numbered 'port_no' into '*pp'. Returns true if
714 * successful, false on failure.
715 *
716 * This is only appropriate for OpenFlow 1.0, 1.1, and 1.2, which include a
717 * list of ports in OFPT_FEATURES_REPLY. */
da91750f 718static bool
fca6d553 719fetch_port_by_features(struct vconn *vconn,
4e022ec0 720 const char *port_name, ofp_port_t port_no,
fca6d553 721 struct ofputil_phy_port *pp)
abaad8cf 722{
9e1fd49b 723 struct ofputil_switch_features features;
982697a4 724 const struct ofp_header *oh;
abaad8cf 725 struct ofpbuf *request, *reply;
9e1fd49b 726 enum ofperr error;
982697a4 727 enum ofptype type;
9e1fd49b 728 struct ofpbuf b;
da91750f 729 bool found = false;
abaad8cf 730
0df0e81d 731 /* Fetch the switch's ofp_switch_features. */
a53a8efa
SH
732 request = ofpraw_alloc(OFPRAW_OFPT_FEATURES_REQUEST,
733 vconn_get_version(vconn), 0);
fca6d553
BP
734 run(vconn_transact(vconn, request, &reply),
735 "talking to %s", vconn_get_name(vconn));
abaad8cf 736
6fd6ed71
PS
737 oh = reply->data;
738 if (ofptype_decode(&type, reply->data)
982697a4 739 || type != OFPTYPE_FEATURES_REPLY) {
fca6d553 740 ovs_fatal(0, "%s: received bad features reply", vconn_get_name(vconn));
0df0e81d 741 }
fca6d553
BP
742 if (!ofputil_switch_features_has_ports(reply)) {
743 /* The switch features reply does not contain a complete list of ports.
744 * Probably, there are more ports than will fit into a single 64 kB
745 * OpenFlow message. Use OFPST_PORT_DESC to get a complete list of
746 * ports. */
747 ofpbuf_delete(reply);
748 return fetch_port_by_stats(vconn, port_name, port_no, pp);
da91750f
JP
749 }
750
982697a4 751 error = ofputil_decode_switch_features(oh, &features, &b);
9e1fd49b
BP
752 if (error) {
753 ovs_fatal(0, "%s: failed to decode features reply (%s)",
fca6d553 754 vconn_get_name(vconn), ofperr_to_string(error));
9e1fd49b 755 }
0df0e81d 756
982697a4 757 while (!ofputil_pull_phy_port(oh->version, &b, pp)) {
4e022ec0 758 if (port_no != OFPP_NONE
9e1fd49b
BP
759 ? port_no == pp->port_no
760 : !strcmp(pp->name, port_name)) {
da91750f 761 found = true;
fca6d553 762 break;
abaad8cf
JP
763 }
764 }
da91750f
JP
765 ofpbuf_delete(reply);
766 return found;
767}
768
fca6d553
BP
769/* Uses a OFPST_PORT_DESC request to attempt to fetch information about the
770 * port named 'port_name' or numbered 'port_no' into '*pp'. Returns true if
771 * successful, false on failure.
772 *
773 * This is most appropriate for OpenFlow 1.3 and later. Open vSwitch 1.7 and
774 * later also implements OFPST_PORT_DESC, as an extension, for OpenFlow 1.0,
775 * 1.1, and 1.2, so this can be used as a fallback in those versions when there
776 * are too many ports than fit in an OFPT_FEATURES_REPLY. */
da91750f 777static bool
fca6d553 778fetch_port_by_stats(struct vconn *vconn,
4e022ec0 779 const char *port_name, ofp_port_t port_no,
da91750f
JP
780 struct ofputil_phy_port *pp)
781{
782 struct ofpbuf *request;
da91750f 783 ovs_be32 send_xid;
da91750f
JP
784 bool done = false;
785 bool found = false;
786
70ae4f93
BP
787 request = ofputil_encode_port_desc_stats_request(vconn_get_version(vconn),
788 port_no);
6fd6ed71 789 send_xid = ((struct ofp_header *) request->data)->xid;
da91750f 790
da91750f
JP
791 send_openflow_buffer(vconn, request);
792 while (!done) {
793 ovs_be32 recv_xid;
794 struct ofpbuf *reply;
795
796 run(vconn_recv_block(vconn, &reply), "OpenFlow packet receive failed");
6fd6ed71 797 recv_xid = ((struct ofp_header *) reply->data)->xid;
da91750f 798 if (send_xid == recv_xid) {
6fd6ed71 799 struct ofp_header *oh = reply->data;
982697a4
BP
800 enum ofptype type;
801 struct ofpbuf b;
802 uint16_t flags;
803
804 ofpbuf_use_const(&b, oh, ntohs(oh->length));
805 if (ofptype_pull(&type, &b)
806 || type != OFPTYPE_PORT_DESC_STATS_REPLY) {
da91750f 807 ovs_fatal(0, "received bad reply: %s",
6fd6ed71 808 ofp_to_string(reply->data, reply->size,
da91750f
JP
809 verbosity + 1));
810 }
811
982697a4
BP
812 flags = ofpmp_flags(oh);
813 done = !(flags & OFPSF_REPLY_MORE);
da91750f
JP
814
815 if (found) {
816 /* We've already found the port, but we need to drain
817 * the queue of any other replies for this request. */
818 continue;
819 }
820
982697a4 821 while (!ofputil_pull_phy_port(oh->version, &b, pp)) {
4e022ec0
AW
822 if (port_no != OFPP_NONE ? port_no == pp->port_no
823 : !strcmp(pp->name, port_name)) {
da91750f
JP
824 found = true;
825 break;
826 }
827 }
828 } else {
829 VLOG_DBG("received reply with xid %08"PRIx32" "
830 "!= expected %08"PRIx32, recv_xid, send_xid);
831 }
832 ofpbuf_delete(reply);
833 }
da91750f
JP
834
835 return found;
836}
837
4e022ec0
AW
838static bool
839str_to_ofp(const char *s, ofp_port_t *ofp_port)
840{
841 bool ret;
842 uint32_t port_;
843
844 ret = str_to_uint(s, 10, &port_);
845 *ofp_port = u16_to_ofp(port_);
846 return ret;
847}
da91750f
JP
848
849/* Opens a connection to 'vconn_name', fetches the port structure for
850 * 'port_name' (which may be a port name or number), and copies it into
851 * '*pp'. */
852static void
853fetch_ofputil_phy_port(const char *vconn_name, const char *port_name,
854 struct ofputil_phy_port *pp)
855{
fca6d553 856 struct vconn *vconn;
4e022ec0 857 ofp_port_t port_no;
da91750f 858 bool found;
da91750f
JP
859
860 /* Try to interpret the argument as a port number. */
4e022ec0
AW
861 if (!str_to_ofp(port_name, &port_no)) {
862 port_no = OFPP_NONE;
da91750f
JP
863 }
864
fca6d553
BP
865 /* OpenFlow 1.0, 1.1, and 1.2 put the list of ports in the
866 * OFPT_FEATURES_REPLY message. OpenFlow 1.3 and later versions put it
867 * into the OFPST_PORT_DESC reply. Try it the correct way. */
868 open_vconn(vconn_name, &vconn);
869 found = (vconn_get_version(vconn) < OFP13_VERSION
870 ? fetch_port_by_features(vconn, port_name, port_no, pp)
871 : fetch_port_by_stats(vconn, port_name, port_no, pp));
872 vconn_close(vconn);
da91750f
JP
873
874 if (!found) {
875 ovs_fatal(0, "%s: couldn't find port `%s'", vconn_name, port_name);
876 }
0df0e81d 877}
abaad8cf 878
0df0e81d
BP
879/* Returns the port number corresponding to 'port_name' (which may be a port
880 * name or number) within the switch 'vconn_name'. */
4e022ec0 881static ofp_port_t
0df0e81d
BP
882str_to_port_no(const char *vconn_name, const char *port_name)
883{
4e022ec0 884 ofp_port_t port_no;
8010100b
BP
885
886 if (ofputil_port_from_string(port_name, &port_no)) {
0df0e81d
BP
887 return port_no;
888 } else {
9e1fd49b 889 struct ofputil_phy_port pp;
abaad8cf 890
9e1fd49b
BP
891 fetch_ofputil_phy_port(vconn_name, port_name, &pp);
892 return pp.port_no;
0df0e81d 893 }
abaad8cf
JP
894}
895
88ca35ee 896static bool
27527aa0
BP
897try_set_protocol(struct vconn *vconn, enum ofputil_protocol want,
898 enum ofputil_protocol *cur)
88ca35ee 899{
27527aa0
BP
900 for (;;) {
901 struct ofpbuf *request, *reply;
902 enum ofputil_protocol next;
88ca35ee 903
27527aa0
BP
904 request = ofputil_encode_set_protocol(*cur, want, &next);
905 if (!request) {
e43928f2 906 return *cur == want;
27527aa0
BP
907 }
908
909 run(vconn_transact_noreply(vconn, request, &reply),
910 "talking to %s", vconn_get_name(vconn));
911 if (reply) {
6fd6ed71 912 char *s = ofp_to_string(reply->data, reply->size, 2);
27527aa0
BP
913 VLOG_DBG("%s: failed to set protocol, switch replied: %s",
914 vconn_get_name(vconn), s);
915 free(s);
916 ofpbuf_delete(reply);
917 return false;
918 }
919
920 *cur = next;
88ca35ee 921 }
88ca35ee
BP
922}
923
27527aa0
BP
924static enum ofputil_protocol
925set_protocol_for_flow_dump(struct vconn *vconn,
926 enum ofputil_protocol cur_protocol,
927 enum ofputil_protocol usable_protocols)
064af421 928{
27527aa0
BP
929 char *usable_s;
930 int i;
064af421 931
27527aa0
BP
932 for (i = 0; i < ofputil_n_flow_dump_protocols; i++) {
933 enum ofputil_protocol f = ofputil_flow_dump_protocols[i];
934 if (f & usable_protocols & allowed_protocols
935 && try_set_protocol(vconn, f, &cur_protocol)) {
936 return f;
f9cbfbe4 937 }
27527aa0 938 }
f9cbfbe4 939
27527aa0
BP
940 usable_s = ofputil_protocols_to_string(usable_protocols);
941 if (usable_protocols & allowed_protocols) {
942 ovs_fatal(0, "switch does not support any of the usable flow "
943 "formats (%s)", usable_s);
f9cbfbe4 944 } else {
27527aa0
BP
945 char *allowed_s = ofputil_protocols_to_string(allowed_protocols);
946 ovs_fatal(0, "none of the usable flow formats (%s) is among the "
947 "allowed flow formats (%s)", usable_s, allowed_s);
88ca35ee 948 }
064af421
BP
949}
950
bdcc5925
BP
951static struct vconn *
952prepare_dump_flows(int argc, char *argv[], bool aggregate,
953 struct ofpbuf **requestp)
064af421 954{
27527aa0 955 enum ofputil_protocol usable_protocols, protocol;
81d1ea94 956 struct ofputil_flow_stats_request fsr;
88ca35ee 957 struct vconn *vconn;
bdda5aca
BP
958 char *error;
959
960 error = parse_ofp_flow_stats_request_str(&fsr, aggregate,
db0b6c29 961 argc > 2 ? argv[2] : "",
ba2fe8e9 962 &usable_protocols);
bdda5aca
BP
963 if (error) {
964 ovs_fatal(0, "%s", error);
965 }
064af421 966
27527aa0
BP
967 protocol = open_vconn(argv[1], &vconn);
968 protocol = set_protocol_for_flow_dump(vconn, protocol, usable_protocols);
bdcc5925
BP
969 *requestp = ofputil_encode_flow_stats_request(&fsr, protocol);
970 return vconn;
971}
972
973static void
974ofctl_dump_flows__(int argc, char *argv[], bool aggregate)
975{
976 struct ofpbuf *request;
977 struct vconn *vconn;
978
979 vconn = prepare_dump_flows(argc, argv, aggregate, &request);
53514387 980 dump_stats_transaction(vconn, request);
88ca35ee
BP
981 vconn_close(vconn);
982}
983
bdcc5925
BP
984static int
985compare_flows(const void *afs_, const void *bfs_)
986{
987 const struct ofputil_flow_stats *afs = afs_;
988 const struct ofputil_flow_stats *bfs = bfs_;
81a76618
BP
989 const struct match *a = &afs->match;
990 const struct match *b = &bfs->match;
bdcc5925
BP
991 const struct sort_criterion *sc;
992
993 for (sc = criteria; sc < &criteria[n_criteria]; sc++) {
994 const struct mf_field *f = sc->field;
995 int ret;
996
997 if (!f) {
eb391b76
BP
998 int a_pri = afs->priority;
999 int b_pri = bfs->priority;
81a76618 1000 ret = a_pri < b_pri ? -1 : a_pri > b_pri;
bdcc5925
BP
1001 } else {
1002 bool ina, inb;
1003
1004 ina = mf_are_prereqs_ok(f, &a->flow) && !mf_is_all_wild(f, &a->wc);
1005 inb = mf_are_prereqs_ok(f, &b->flow) && !mf_is_all_wild(f, &b->wc);
1006 if (ina != inb) {
1007 /* Skip the test for sc->order, so that missing fields always
1008 * sort to the end whether we're sorting in ascending or
1009 * descending order. */
1010 return ina ? -1 : 1;
1011 } else {
1012 union mf_value aval, bval;
1013
1014 mf_get_value(f, &a->flow, &aval);
1015 mf_get_value(f, &b->flow, &bval);
1016 ret = memcmp(&aval, &bval, f->n_bytes);
1017 }
1018 }
1019
1020 if (ret) {
1021 return sc->order == SORT_ASC ? ret : -ret;
1022 }
1023 }
1024
1025 return 0;
1026}
1027
88ca35ee 1028static void
1636c761 1029ofctl_dump_flows(struct ovs_cmdl_context *ctx)
88ca35ee 1030{
bdcc5925 1031 if (!n_criteria) {
1636c761 1032 ofctl_dump_flows__(ctx->argc, ctx->argv, false);
2f4aba0b 1033 return;
bdcc5925
BP
1034 } else {
1035 struct ofputil_flow_stats *fses;
1036 size_t n_fses, allocated_fses;
1037 struct ofpbuf *request;
1038 struct ofpbuf ofpacts;
1039 struct ofpbuf *reply;
1040 struct vconn *vconn;
1041 ovs_be32 send_xid;
1042 struct ds s;
1043 size_t i;
1044
1636c761 1045 vconn = prepare_dump_flows(ctx->argc, ctx->argv, false, &request);
6fd6ed71 1046 send_xid = ((struct ofp_header *) request->data)->xid;
bdcc5925
BP
1047 send_openflow_buffer(vconn, request);
1048
1049 fses = NULL;
1050 n_fses = allocated_fses = 0;
1051 reply = NULL;
1052 ofpbuf_init(&ofpacts, 0);
1053 for (;;) {
1054 struct ofputil_flow_stats *fs;
1055
1056 if (n_fses >= allocated_fses) {
1057 fses = x2nrealloc(fses, &allocated_fses, sizeof *fses);
1058 }
1059
1060 fs = &fses[n_fses];
1061 if (!recv_flow_stats_reply(vconn, send_xid, &reply, fs,
1062 &ofpacts)) {
1063 break;
1064 }
1065 fs->ofpacts = xmemdup(fs->ofpacts, fs->ofpacts_len);
1066 n_fses++;
1067 }
1068 ofpbuf_uninit(&ofpacts);
1069
1070 qsort(fses, n_fses, sizeof *fses, compare_flows);
1071
1072 ds_init(&s);
1073 for (i = 0; i < n_fses; i++) {
1074 ds_clear(&s);
1075 ofp_print_flow_stats(&s, &fses[i]);
1076 puts(ds_cstr(&s));
1077 }
1078 ds_destroy(&s);
1079
1080 for (i = 0; i < n_fses; i++) {
dc723c44 1081 free(CONST_CAST(struct ofpact *, fses[i].ofpacts));
bdcc5925
BP
1082 }
1083 free(fses);
1084
1085 vconn_close(vconn);
1086 }
88ca35ee
BP
1087}
1088
1089static void
1636c761 1090ofctl_dump_aggregate(struct ovs_cmdl_context *ctx)
88ca35ee 1091{
1636c761 1092 ofctl_dump_flows__(ctx->argc, ctx->argv, true);
064af421
BP
1093}
1094
d2805da2 1095static void
1636c761 1096ofctl_queue_stats(struct ovs_cmdl_context *ctx)
d2805da2 1097{
d2805da2 1098 struct ofpbuf *request;
53514387 1099 struct vconn *vconn;
64626975 1100 struct ofputil_queue_stats_request oqs;
d2805da2 1101
1636c761 1102 open_vconn(ctx->argv[1], &vconn);
d2805da2 1103
1636c761
RB
1104 if (ctx->argc > 2 && ctx->argv[2][0] && strcasecmp(ctx->argv[2], "all")) {
1105 oqs.port_no = str_to_port_no(ctx->argv[1], ctx->argv[2]);
d2805da2 1106 } else {
7f05e7ab 1107 oqs.port_no = OFPP_ANY;
d2805da2 1108 }
1636c761
RB
1109 if (ctx->argc > 3 && ctx->argv[3][0] && strcasecmp(ctx->argv[3], "all")) {
1110 oqs.queue_id = atoi(ctx->argv[3]);
d2805da2 1111 } else {
64626975 1112 oqs.queue_id = OFPQ_ALL;
d2805da2
BP
1113 }
1114
64626975 1115 request = ofputil_encode_queue_stats_request(vconn_get_version(vconn), &oqs);
53514387
SH
1116 dump_stats_transaction(vconn, request);
1117 vconn_close(vconn);
d2805da2
BP
1118}
1119
e8f9a7bb 1120static void
1636c761 1121ofctl_queue_get_config(struct ovs_cmdl_context *ctx)
e8f9a7bb 1122{
1636c761
RB
1123 const char *vconn_name = ctx->argv[1];
1124 const char *port_name = ctx->argv[2];
e8f9a7bb
VG
1125 enum ofputil_protocol protocol;
1126 enum ofp_version version;
1127 struct ofpbuf *request;
1128 struct vconn *vconn;
1129 ofp_port_t port;
1130
1131 port = str_to_port_no(vconn_name, port_name);
1132
1133 protocol = open_vconn(vconn_name, &vconn);
1134 version = ofputil_protocol_to_ofp_version(protocol);
1135 request = ofputil_encode_queue_get_config_request(version, port);
1136 dump_transaction(vconn, request);
1137 vconn_close(vconn);
1138}
1139
27527aa0 1140static enum ofputil_protocol
db0b6c29
JR
1141open_vconn_for_flow_mod(const char *remote, struct vconn **vconnp,
1142 enum ofputil_protocol usable_protocols)
0fbc9f11 1143{
27527aa0
BP
1144 enum ofputil_protocol cur_protocol;
1145 char *usable_s;
1146 int i;
0fbc9f11 1147
27527aa0
BP
1148 if (!(usable_protocols & allowed_protocols)) {
1149 char *allowed_s = ofputil_protocols_to_string(allowed_protocols);
1150 usable_s = ofputil_protocols_to_string(usable_protocols);
1151 ovs_fatal(0, "none of the usable flow formats (%s) is among the "
1152 "allowed flow formats (%s)", usable_s, allowed_s);
0fbc9f11 1153 }
0fbc9f11 1154
27527aa0
BP
1155 /* If the initial flow format is allowed and usable, keep it. */
1156 cur_protocol = open_vconn(remote, vconnp);
1157 if (usable_protocols & allowed_protocols & cur_protocol) {
1158 return cur_protocol;
1159 }
1160
1161 /* Otherwise try each flow format in turn. */
1162 for (i = 0; i < sizeof(enum ofputil_protocol) * CHAR_BIT; i++) {
1163 enum ofputil_protocol f = 1 << i;
1164
1165 if (f != cur_protocol
1166 && f & usable_protocols & allowed_protocols
1167 && try_set_protocol(*vconnp, f, &cur_protocol)) {
1168 return f;
1169 }
0fbc9f11 1170 }
27527aa0
BP
1171
1172 usable_s = ofputil_protocols_to_string(usable_protocols);
1173 ovs_fatal(0, "switch does not support any of the usable flow "
1174 "formats (%s)", usable_s);
0fbc9f11
BP
1175}
1176
064af421 1177static void
e1fef0f9 1178ofctl_flow_mod__(const char *remote, struct ofputil_flow_mod *fms,
db0b6c29 1179 size_t n_fms, enum ofputil_protocol usable_protocols)
064af421 1180{
27527aa0 1181 enum ofputil_protocol protocol;
064af421 1182 struct vconn *vconn;
27527aa0 1183 size_t i;
4989c59f 1184
db0b6c29 1185 protocol = open_vconn_for_flow_mod(remote, &vconn, usable_protocols);
049c8dc2 1186
27527aa0
BP
1187 for (i = 0; i < n_fms; i++) {
1188 struct ofputil_flow_mod *fm = &fms[i];
0fbc9f11 1189
27527aa0 1190 transact_noreply(vconn, ofputil_encode_flow_mod(fm, protocol));
dc723c44 1191 free(CONST_CAST(struct ofpact *, fm->ofpacts));
4989c59f 1192 }
064af421 1193 vconn_close(vconn);
88ca35ee
BP
1194}
1195
064af421 1196static void
e1fef0f9 1197ofctl_flow_mod_file(int argc OVS_UNUSED, char *argv[], uint16_t command)
064af421 1198{
db0b6c29 1199 enum ofputil_protocol usable_protocols;
27527aa0
BP
1200 struct ofputil_flow_mod *fms = NULL;
1201 size_t n_fms = 0;
bdda5aca 1202 char *error;
064af421 1203
db0b6c29 1204 error = parse_ofp_flow_mod_file(argv[2], command, &fms, &n_fms,
ba2fe8e9 1205 &usable_protocols);
bdda5aca
BP
1206 if (error) {
1207 ovs_fatal(0, "%s", error);
1208 }
db0b6c29 1209 ofctl_flow_mod__(argv[1], fms, n_fms, usable_protocols);
27527aa0
BP
1210 free(fms);
1211}
1212
1213static void
e1fef0f9 1214ofctl_flow_mod(int argc, char *argv[], uint16_t command)
27527aa0 1215{
4989c59f 1216 if (argc > 2 && !strcmp(argv[2], "-")) {
e1fef0f9 1217 ofctl_flow_mod_file(argc, argv, command);
27527aa0
BP
1218 } else {
1219 struct ofputil_flow_mod fm;
bdda5aca 1220 char *error;
3200ed58 1221 enum ofputil_protocol usable_protocols;
bdda5aca 1222
db0b6c29 1223 error = parse_ofp_flow_mod_str(&fm, argc > 2 ? argv[2] : "", command,
ba2fe8e9 1224 &usable_protocols);
bdda5aca
BP
1225 if (error) {
1226 ovs_fatal(0, "%s", error);
1227 }
db0b6c29 1228 ofctl_flow_mod__(argv[1], &fm, 1, usable_protocols);
064af421 1229 }
4989c59f 1230}
88ca35ee 1231
4989c59f 1232static void
1636c761 1233ofctl_add_flow(struct ovs_cmdl_context *ctx)
4989c59f 1234{
1636c761 1235 ofctl_flow_mod(ctx->argc, ctx->argv, OFPFC_ADD);
4989c59f
BP
1236}
1237
1238static void
1636c761 1239ofctl_add_flows(struct ovs_cmdl_context *ctx)
4989c59f 1240{
1636c761 1241 ofctl_flow_mod_file(ctx->argc, ctx->argv, OFPFC_ADD);
064af421
BP
1242}
1243
1244static void
1636c761 1245ofctl_mod_flows(struct ovs_cmdl_context *ctx)
064af421 1246{
1636c761 1247 ofctl_flow_mod(ctx->argc, ctx->argv, strict ? OFPFC_MODIFY_STRICT : OFPFC_MODIFY);
064af421
BP
1248}
1249
88ca35ee 1250static void
1636c761 1251ofctl_del_flows(struct ovs_cmdl_context *ctx)
064af421 1252{
1636c761 1253 ofctl_flow_mod(ctx->argc, ctx->argv, strict ? OFPFC_DELETE_STRICT : OFPFC_DELETE);
064af421
BP
1254}
1255
54834960
EJ
1256static void
1257set_packet_in_format(struct vconn *vconn,
1258 enum nx_packet_in_format packet_in_format)
1259{
3f4a1939
SH
1260 struct ofpbuf *spif;
1261
1262 spif = ofputil_make_set_packet_in_format(vconn_get_version(vconn),
1263 packet_in_format);
54834960
EJ
1264 transact_noreply(vconn, spif);
1265 VLOG_DBG("%s: using user-specified packet in format %s",
1266 vconn_get_name(vconn),
1267 ofputil_packet_in_format_to_string(packet_in_format));
1268}
1269
f0fd1a17
PS
1270static int
1271monitor_set_invalid_ttl_to_controller(struct vconn *vconn)
1272{
1273 struct ofp_switch_config config;
1274 enum ofp_config_flags flags;
1275
1276 fetch_switch_config(vconn, &config);
1277 flags = ntohs(config.flags);
1278 if (!(flags & OFPC_INVALID_TTL_TO_CONTROLLER)) {
1279 /* Set the invalid ttl config. */
1280 flags |= OFPC_INVALID_TTL_TO_CONTROLLER;
1281
1282 config.flags = htons(flags);
1283 set_switch_config(vconn, &config);
1284
1285 /* Then retrieve the configuration to see if it really took. OpenFlow
1286 * doesn't define error reporting for bad modes, so this is all we can
1287 * do. */
1288 fetch_switch_config(vconn, &config);
1289 flags = ntohs(config.flags);
1290 if (!(flags & OFPC_INVALID_TTL_TO_CONTROLLER)) {
1291 ovs_fatal(0, "setting invalid_ttl_to_controller failed (this "
1292 "switch probably doesn't support mode)");
1293 return -EOPNOTSUPP;
1294 }
1295 }
1296 return 0;
1297}
1298
96761f58
BP
1299/* Converts hex digits in 'hex' to an OpenFlow message in '*msgp'. The
1300 * caller must free '*msgp'. On success, returns NULL. On failure, returns
1301 * an error message and stores NULL in '*msgp'. */
1302static const char *
1303openflow_from_hex(const char *hex, struct ofpbuf **msgp)
1304{
1305 struct ofp_header *oh;
1306 struct ofpbuf *msg;
1307
1308 msg = ofpbuf_new(strlen(hex) / 2);
1309 *msgp = NULL;
1310
1311 if (ofpbuf_put_hex(msg, hex, NULL)[0] != '\0') {
1312 ofpbuf_delete(msg);
1313 return "Trailing garbage in hex data";
1314 }
1315
6fd6ed71 1316 if (msg->size < sizeof(struct ofp_header)) {
96761f58
BP
1317 ofpbuf_delete(msg);
1318 return "Message too short for OpenFlow";
1319 }
1320
6fd6ed71
PS
1321 oh = msg->data;
1322 if (msg->size != ntohs(oh->length)) {
96761f58
BP
1323 ofpbuf_delete(msg);
1324 return "Message size does not match length in OpenFlow header";
1325 }
1326
1327 *msgp = msg;
1328 return NULL;
1329}
1330
1331static void
1332ofctl_send(struct unixctl_conn *conn, int argc,
1333 const char *argv[], void *vconn_)
1334{
1335 struct vconn *vconn = vconn_;
1336 struct ds reply;
1337 bool ok;
1338 int i;
1339
1340 ok = true;
1341 ds_init(&reply);
1342 for (i = 1; i < argc; i++) {
1343 const char *error_msg;
1344 struct ofpbuf *msg;
1345 int error;
1346
1347 error_msg = openflow_from_hex(argv[i], &msg);
1348 if (error_msg) {
1349 ds_put_format(&reply, "%s\n", error_msg);
1350 ok = false;
1351 continue;
1352 }
1353
1354 fprintf(stderr, "send: ");
6fd6ed71 1355 ofp_print(stderr, msg->data, msg->size, verbosity);
96761f58
BP
1356
1357 error = vconn_send_block(vconn, msg);
1358 if (error) {
1359 ofpbuf_delete(msg);
10a89ef0 1360 ds_put_format(&reply, "%s\n", ovs_strerror(error));
96761f58
BP
1361 ok = false;
1362 } else {
1363 ds_put_cstr(&reply, "sent\n");
1364 }
1365 }
bde9f75d
EJ
1366
1367 if (ok) {
1368 unixctl_command_reply(conn, ds_cstr(&reply));
1369 } else {
1370 unixctl_command_reply_error(conn, ds_cstr(&reply));
1371 }
96761f58
BP
1372 ds_destroy(&reply);
1373}
1374
bb638b9a
BP
1375struct barrier_aux {
1376 struct vconn *vconn; /* OpenFlow connection for sending barrier. */
1377 struct unixctl_conn *conn; /* Connection waiting for barrier response. */
1378};
1379
1380static void
1381ofctl_barrier(struct unixctl_conn *conn, int argc OVS_UNUSED,
1382 const char *argv[] OVS_UNUSED, void *aux_)
1383{
1384 struct barrier_aux *aux = aux_;
1385 struct ofpbuf *msg;
1386 int error;
1387
1388 if (aux->conn) {
bde9f75d 1389 unixctl_command_reply_error(conn, "already waiting for barrier reply");
bb638b9a
BP
1390 return;
1391 }
1392
a0ae0b6e 1393 msg = ofputil_encode_barrier_request(vconn_get_version(aux->vconn));
bb638b9a
BP
1394 error = vconn_send_block(aux->vconn, msg);
1395 if (error) {
1396 ofpbuf_delete(msg);
10a89ef0 1397 unixctl_command_reply_error(conn, ovs_strerror(error));
bb638b9a
BP
1398 } else {
1399 aux->conn = conn;
1400 }
1401}
1402
1e1d00a5
BP
1403static void
1404ofctl_set_output_file(struct unixctl_conn *conn, int argc OVS_UNUSED,
1405 const char *argv[], void *aux OVS_UNUSED)
1406{
1407 int fd;
1408
1409 fd = open(argv[1], O_CREAT | O_TRUNC | O_WRONLY, 0666);
1410 if (fd < 0) {
10a89ef0 1411 unixctl_command_reply_error(conn, ovs_strerror(errno));
1e1d00a5
BP
1412 return;
1413 }
1414
1415 fflush(stderr);
1416 dup2(fd, STDERR_FILENO);
1417 close(fd);
bde9f75d 1418 unixctl_command_reply(conn, NULL);
1e1d00a5
BP
1419}
1420
2b07c8b1
BP
1421static void
1422ofctl_block(struct unixctl_conn *conn, int argc OVS_UNUSED,
4f8f2439 1423 const char *argv[] OVS_UNUSED, void *blocked_)
2b07c8b1 1424{
4f8f2439 1425 bool *blocked = blocked_;
2b07c8b1 1426
4f8f2439
BP
1427 if (!*blocked) {
1428 *blocked = true;
1429 unixctl_command_reply(conn, NULL);
1430 } else {
2b07c8b1 1431 unixctl_command_reply(conn, "already blocking");
2b07c8b1
BP
1432 }
1433}
1434
1435static void
1436ofctl_unblock(struct unixctl_conn *conn, int argc OVS_UNUSED,
4f8f2439 1437 const char *argv[] OVS_UNUSED, void *blocked_)
2b07c8b1 1438{
4f8f2439 1439 bool *blocked = blocked_;
2b07c8b1 1440
4f8f2439
BP
1441 if (*blocked) {
1442 *blocked = false;
2b07c8b1 1443 unixctl_command_reply(conn, NULL);
4f8f2439
BP
1444 } else {
1445 unixctl_command_reply(conn, "already unblocked");
2b07c8b1
BP
1446 }
1447}
1448
05f453a8
BP
1449/* Prints to stdout all of the messages received on 'vconn'.
1450 *
1451 * Iff 'reply_to_echo_requests' is true, sends a reply to any echo request
1452 * received on 'vconn'. */
064af421 1453static void
05f453a8 1454monitor_vconn(struct vconn *vconn, bool reply_to_echo_requests)
0caf6bde 1455{
bb638b9a 1456 struct barrier_aux barrier_aux = { vconn, NULL };
1eb85ef5
EJ
1457 struct unixctl_server *server;
1458 bool exiting = false;
4f8f2439 1459 bool blocked = false;
7d0c5973 1460 int error;
1eb85ef5 1461
7d0c5973 1462 daemon_save_fd(STDERR_FILENO);
1eb85ef5 1463 daemonize_start();
19945013 1464 error = unixctl_server_create(unixctl_path, &server);
1eb85ef5
EJ
1465 if (error) {
1466 ovs_fatal(error, "failed to create unixctl server");
1467 }
1468 unixctl_command_register("exit", "", 0, 0, ofctl_exit, &exiting);
96761f58
BP
1469 unixctl_command_register("ofctl/send", "OFMSG...", 1, INT_MAX,
1470 ofctl_send, vconn);
bb638b9a
BP
1471 unixctl_command_register("ofctl/barrier", "", 0, 0,
1472 ofctl_barrier, &barrier_aux);
1e1d00a5
BP
1473 unixctl_command_register("ofctl/set-output-file", "FILE", 1, 1,
1474 ofctl_set_output_file, NULL);
2b07c8b1 1475
4f8f2439
BP
1476 unixctl_command_register("ofctl/block", "", 0, 0, ofctl_block, &blocked);
1477 unixctl_command_register("ofctl/unblock", "", 0, 0, ofctl_unblock,
1478 &blocked);
2b07c8b1 1479
1eb85ef5
EJ
1480 daemonize_complete();
1481
0caf6bde
BP
1482 for (;;) {
1483 struct ofpbuf *b;
1eb85ef5
EJ
1484 int retval;
1485
1486 unixctl_server_run(server);
982697a4 1487
4f8f2439 1488 while (!blocked) {
982697a4 1489 enum ofptype type;
bb638b9a 1490
1eb85ef5
EJ
1491 retval = vconn_recv(vconn, &b);
1492 if (retval == EAGAIN) {
1493 break;
1494 }
1eb85ef5 1495 run(retval, "vconn_recv");
31c6fcd7 1496
0c9560b7 1497 if (timestamp) {
2b31d8e7
PI
1498 char *s = xastrftime_msec("%Y-%m-%d %H:%M:%S.###: ",
1499 time_wall_msec(), true);
0c9560b7 1500 fputs(s, stderr);
3e78870d 1501 free(s);
0c9560b7 1502 }
31c6fcd7 1503
6fd6ed71
PS
1504 ofptype_decode(&type, b->data);
1505 ofp_print(stderr, b->data, b->size, verbosity + 2);
eafa7af8 1506 fflush(stderr);
bb638b9a 1507
05f453a8
BP
1508 switch ((int) type) {
1509 case OFPTYPE_BARRIER_REPLY:
1510 if (barrier_aux.conn) {
1511 unixctl_command_reply(barrier_aux.conn, NULL);
1512 barrier_aux.conn = NULL;
1513 }
1514 break;
1515
1516 case OFPTYPE_ECHO_REQUEST:
1517 if (reply_to_echo_requests) {
1518 struct ofpbuf *reply;
1519
6fd6ed71 1520 reply = make_echo_reply(b->data);
05f453a8
BP
1521 retval = vconn_send_block(vconn, reply);
1522 if (retval) {
1523 ovs_fatal(retval, "failed to send echo reply");
1524 }
1525 }
1526 break;
bb638b9a 1527 }
05f453a8 1528 ofpbuf_delete(b);
1eb85ef5
EJ
1529 }
1530
1531 if (exiting) {
1532 break;
1533 }
1534
1535 vconn_run(vconn);
1536 vconn_run_wait(vconn);
4f8f2439
BP
1537 if (!blocked) {
1538 vconn_recv_wait(vconn);
1539 }
1eb85ef5
EJ
1540 unixctl_server_wait(server);
1541 poll_block();
0caf6bde 1542 }
828c72d0
BP
1543 vconn_close(vconn);
1544 unixctl_server_destroy(server);
0caf6bde
BP
1545}
1546
1547static void
1636c761 1548ofctl_monitor(struct ovs_cmdl_context *ctx)
064af421
BP
1549{
1550 struct vconn *vconn;
2b07c8b1 1551 int i;
db0b6c29 1552 enum ofputil_protocol usable_protocols;
064af421 1553
1636c761
RB
1554 open_vconn(ctx->argv[1], &vconn);
1555 for (i = 2; i < ctx->argc; i++) {
1556 const char *arg = ctx->argv[i];
064af421 1557
2b07c8b1
BP
1558 if (isdigit((unsigned char) *arg)) {
1559 struct ofp_switch_config config;
1560
1561 fetch_switch_config(vconn, &config);
1562 config.miss_send_len = htons(atoi(arg));
1563 set_switch_config(vconn, &config);
1564 } else if (!strcmp(arg, "invalid_ttl")) {
f0fd1a17 1565 monitor_set_invalid_ttl_to_controller(vconn);
2b07c8b1
BP
1566 } else if (!strncmp(arg, "watch:", 6)) {
1567 struct ofputil_flow_monitor_request fmr;
1568 struct ofpbuf *msg;
bdda5aca 1569 char *error;
2b07c8b1 1570
db0b6c29
JR
1571 error = parse_flow_monitor_request(&fmr, arg + 6,
1572 &usable_protocols);
bdda5aca
BP
1573 if (error) {
1574 ovs_fatal(0, "%s", error);
1575 }
2b07c8b1
BP
1576
1577 msg = ofpbuf_new(0);
1578 ofputil_append_flow_monitor_request(&fmr, msg);
53514387 1579 dump_stats_transaction(vconn, msg);
eafa7af8 1580 fflush(stdout);
2b07c8b1
BP
1581 } else {
1582 ovs_fatal(0, "%s: unsupported \"monitor\" argument", arg);
f0fd1a17
PS
1583 }
1584 }
2b07c8b1 1585
ca8526e0
BP
1586 if (preferred_packet_in_format >= 0) {
1587 set_packet_in_format(vconn, preferred_packet_in_format);
1588 } else {
f02b12c4
SH
1589 enum ofp_version version = vconn_get_version(vconn);
1590
1591 switch (version) {
1592 case OFP10_VERSION: {
1593 struct ofpbuf *spif, *reply;
1594
1595 spif = ofputil_make_set_packet_in_format(vconn_get_version(vconn),
1596 NXPIF_NXM);
1597 run(vconn_transact_noreply(vconn, spif, &reply),
1598 "talking to %s", vconn_get_name(vconn));
1599 if (reply) {
6fd6ed71 1600 char *s = ofp_to_string(reply->data, reply->size, 2);
f02b12c4
SH
1601 VLOG_DBG("%s: failed to set packet in format to nxm, controller"
1602 " replied: %s. Falling back to the switch default.",
1603 vconn_get_name(vconn), s);
1604 free(s);
1605 ofpbuf_delete(reply);
1606 }
1607 break;
1608 }
1609 case OFP11_VERSION:
1610 case OFP12_VERSION:
1611 case OFP13_VERSION:
c37c0382 1612 case OFP14_VERSION:
42dccab5 1613 case OFP15_VERSION:
f02b12c4
SH
1614 break;
1615 default:
428b2edd 1616 OVS_NOT_REACHED();
ca8526e0
BP
1617 }
1618 }
1619
05f453a8 1620 monitor_vconn(vconn, true);
0caf6bde
BP
1621}
1622
1623static void
1636c761 1624ofctl_snoop(struct ovs_cmdl_context *ctx)
0caf6bde
BP
1625{
1626 struct vconn *vconn;
1627
1636c761 1628 open_vconn__(ctx->argv[1], SNOOP, &vconn);
05f453a8 1629 monitor_vconn(vconn, false);
064af421
BP
1630}
1631
1632static void
1636c761 1633ofctl_dump_ports(struct ovs_cmdl_context *ctx)
064af421 1634{
abaad8cf 1635 struct ofpbuf *request;
53514387 1636 struct vconn *vconn;
4e022ec0 1637 ofp_port_t port;
abaad8cf 1638
1636c761
RB
1639 open_vconn(ctx->argv[1], &vconn);
1640 port = ctx->argc > 2 ? str_to_port_no(ctx->argv[1], ctx->argv[2]) : OFPP_ANY;
f8e4867e 1641 request = ofputil_encode_dump_ports_request(vconn_get_version(vconn), port);
53514387
SH
1642 dump_stats_transaction(vconn, request);
1643 vconn_close(vconn);
064af421
BP
1644}
1645
2be393ed 1646static void
1636c761 1647ofctl_dump_ports_desc(struct ovs_cmdl_context *ctx)
2be393ed 1648{
70ae4f93
BP
1649 struct ofpbuf *request;
1650 struct vconn *vconn;
1651 ofp_port_t port;
1652
1636c761
RB
1653 open_vconn(ctx->argv[1], &vconn);
1654 port = ctx->argc > 2 ? str_to_port_no(ctx->argv[1], ctx->argv[2]) : OFPP_ANY;
70ae4f93
BP
1655 request = ofputil_encode_port_desc_stats_request(vconn_get_version(vconn),
1656 port);
1657 dump_stats_transaction(vconn, request);
1658 vconn_close(vconn);
2be393ed
JP
1659}
1660
064af421 1661static void
1636c761 1662ofctl_probe(struct ovs_cmdl_context *ctx)
064af421
BP
1663{
1664 struct ofpbuf *request;
1665 struct vconn *vconn;
1666 struct ofpbuf *reply;
1667
1636c761 1668 open_vconn(ctx->argv[1], &vconn);
1a126c0c 1669 request = make_echo_request(vconn_get_version(vconn));
1636c761 1670 run(vconn_transact(vconn, request, &reply), "talking to %s", ctx->argv[1]);
6fd6ed71 1671 if (reply->size != sizeof(struct ofp_header)) {
064af421
BP
1672 ovs_fatal(0, "reply does not match request");
1673 }
1674 ofpbuf_delete(reply);
1675 vconn_close(vconn);
1676}
1677
0c3d5fc8 1678static void
1636c761 1679ofctl_packet_out(struct ovs_cmdl_context *ctx)
0c3d5fc8 1680{
de0f3156 1681 enum ofputil_protocol protocol;
0c3d5fc8 1682 struct ofputil_packet_out po;
f25d0cf3 1683 struct ofpbuf ofpacts;
0c3d5fc8 1684 struct vconn *vconn;
bdda5aca 1685 char *error;
0c3d5fc8 1686 int i;
b420c0cf 1687 enum ofputil_protocol usable_protocols; /* XXX: Use in proto selection */
0c3d5fc8 1688
f25d0cf3 1689 ofpbuf_init(&ofpacts, 64);
1636c761 1690 error = ofpacts_parse_actions(ctx->argv[3], &ofpacts, &usable_protocols);
bdda5aca
BP
1691 if (error) {
1692 ovs_fatal(0, "%s", error);
1693 }
0c3d5fc8
BP
1694
1695 po.buffer_id = UINT32_MAX;
1636c761 1696 po.in_port = str_to_port_no(ctx->argv[1], ctx->argv[2]);
6fd6ed71
PS
1697 po.ofpacts = ofpacts.data;
1698 po.ofpacts_len = ofpacts.size;
0c3d5fc8 1699
1636c761
RB
1700 protocol = open_vconn(ctx->argv[1], &vconn);
1701 for (i = 4; i < ctx->argc; i++) {
cf62fa4c
PS
1702 struct dp_packet *packet;
1703 struct ofpbuf *opo;
0c3d5fc8
BP
1704 const char *error_msg;
1705
1636c761 1706 error_msg = eth_from_hex(ctx->argv[i], &packet);
0c3d5fc8
BP
1707 if (error_msg) {
1708 ovs_fatal(0, "%s", error_msg);
1709 }
1710
cf62fa4c
PS
1711 po.packet = dp_packet_data(packet);
1712 po.packet_len = dp_packet_size(packet);
de0f3156 1713 opo = ofputil_encode_packet_out(&po, protocol);
0c3d5fc8 1714 transact_noreply(vconn, opo);
cf62fa4c 1715 dp_packet_delete(packet);
0c3d5fc8
BP
1716 }
1717 vconn_close(vconn);
f25d0cf3 1718 ofpbuf_uninit(&ofpacts);
0c3d5fc8
BP
1719}
1720
064af421 1721static void
1636c761 1722ofctl_mod_port(struct ovs_cmdl_context *ctx)
064af421 1723{
28124950
BP
1724 struct ofp_config_flag {
1725 const char *name; /* The flag's name. */
1726 enum ofputil_port_config bit; /* Bit to turn on or off. */
1727 bool on; /* Value to set the bit to. */
1728 };
1729 static const struct ofp_config_flag flags[] = {
1730 { "up", OFPUTIL_PC_PORT_DOWN, false },
1731 { "down", OFPUTIL_PC_PORT_DOWN, true },
1732 { "stp", OFPUTIL_PC_NO_STP, false },
1733 { "receive", OFPUTIL_PC_NO_RECV, false },
1734 { "receive-stp", OFPUTIL_PC_NO_RECV_STP, false },
1735 { "flood", OFPUTIL_PC_NO_FLOOD, false },
1736 { "forward", OFPUTIL_PC_NO_FWD, false },
1737 { "packet-in", OFPUTIL_PC_NO_PACKET_IN, false },
1738 };
1739
1740 const struct ofp_config_flag *flag;
9e1fd49b
BP
1741 enum ofputil_protocol protocol;
1742 struct ofputil_port_mod pm;
1743 struct ofputil_phy_port pp;
064af421 1744 struct vconn *vconn;
28124950
BP
1745 const char *command;
1746 bool not;
064af421 1747
1636c761 1748 fetch_ofputil_phy_port(ctx->argv[1], ctx->argv[2], &pp);
064af421 1749
9e1fd49b
BP
1750 pm.port_no = pp.port_no;
1751 memcpy(pm.hw_addr, pp.hw_addr, ETH_ADDR_LEN);
1752 pm.config = 0;
1753 pm.mask = 0;
1754 pm.advertise = 0;
064af421 1755
1636c761
RB
1756 if (!strncasecmp(ctx->argv[3], "no-", 3)) {
1757 command = ctx->argv[3] + 3;
28124950 1758 not = true;
1636c761
RB
1759 } else if (!strncasecmp(ctx->argv[3], "no", 2)) {
1760 command = ctx->argv[3] + 2;
28124950 1761 not = true;
064af421 1762 } else {
1636c761 1763 command = ctx->argv[3];
28124950
BP
1764 not = false;
1765 }
1766 for (flag = flags; flag < &flags[ARRAY_SIZE(flags)]; flag++) {
1767 if (!strcasecmp(command, flag->name)) {
1768 pm.mask = flag->bit;
1769 pm.config = flag->on ^ not ? flag->bit : 0;
1770 goto found;
1771 }
064af421 1772 }
1636c761 1773 ovs_fatal(0, "unknown mod-port command '%s'", ctx->argv[3]);
064af421 1774
28124950 1775found:
1636c761 1776 protocol = open_vconn(ctx->argv[1], &vconn);
9e1fd49b 1777 transact_noreply(vconn, ofputil_encode_port_mod(&pm, protocol));
064af421
BP
1778 vconn_close(vconn);
1779}
1780
918f2b82 1781static void
1636c761 1782ofctl_mod_table(struct ovs_cmdl_context *ctx)
918f2b82
AZ
1783{
1784 enum ofputil_protocol protocol, usable_protocols;
1785 struct ofputil_table_mod tm;
1786 struct vconn *vconn;
1787 char *error;
1788 int i;
1789
1636c761 1790 error = parse_ofp_table_mod(&tm, ctx->argv[2], ctx->argv[3], &usable_protocols);
918f2b82
AZ
1791 if (error) {
1792 ovs_fatal(0, "%s", error);
1793 }
1794
1636c761 1795 protocol = open_vconn(ctx->argv[1], &vconn);
918f2b82
AZ
1796 if (!(protocol & usable_protocols)) {
1797 for (i = 0; i < sizeof(enum ofputil_protocol) * CHAR_BIT; i++) {
1798 enum ofputil_protocol f = 1 << i;
1799 if (f != protocol
1800 && f & usable_protocols
1801 && try_set_protocol(vconn, f, &protocol)) {
1802 protocol = f;
1803 break;
1804 }
1805 }
1806 }
1807
1808 if (!(protocol & usable_protocols)) {
1809 char *usable_s = ofputil_protocols_to_string(usable_protocols);
1810 ovs_fatal(0, "Switch does not support table mod message(%s)", usable_s);
1811 }
1812
1813 transact_noreply(vconn, ofputil_encode_table_mod(&tm, protocol));
1814 vconn_close(vconn);
1815}
1816
7257b535 1817static void
1636c761 1818ofctl_get_frags(struct ovs_cmdl_context *ctx)
7257b535
BP
1819{
1820 struct ofp_switch_config config;
1821 struct vconn *vconn;
1822
1636c761 1823 open_vconn(ctx->argv[1], &vconn);
7257b535
BP
1824 fetch_switch_config(vconn, &config);
1825 puts(ofputil_frag_handling_to_string(ntohs(config.flags)));
1826 vconn_close(vconn);
1827}
1828
1829static void
1636c761 1830ofctl_set_frags(struct ovs_cmdl_context *ctx)
7257b535
BP
1831{
1832 struct ofp_switch_config config;
1833 enum ofp_config_flags mode;
1834 struct vconn *vconn;
1835 ovs_be16 flags;
1836
1636c761
RB
1837 if (!ofputil_frag_handling_from_string(ctx->argv[2], &mode)) {
1838 ovs_fatal(0, "%s: unknown fragment handling mode", ctx->argv[2]);
7257b535
BP
1839 }
1840
1636c761 1841 open_vconn(ctx->argv[1], &vconn);
7257b535
BP
1842 fetch_switch_config(vconn, &config);
1843 flags = htons(mode) | (config.flags & htons(~OFPC_FRAG_MASK));
1844 if (flags != config.flags) {
1845 /* Set the configuration. */
1846 config.flags = flags;
1847 set_switch_config(vconn, &config);
1848
1849 /* Then retrieve the configuration to see if it really took. OpenFlow
1850 * doesn't define error reporting for bad modes, so this is all we can
1851 * do. */
1852 fetch_switch_config(vconn, &config);
1853 if (flags != config.flags) {
1854 ovs_fatal(0, "%s: setting fragment handling mode failed (this "
1855 "switch probably doesn't support mode \"%s\")",
1636c761 1856 ctx->argv[1], ofputil_frag_handling_to_string(mode));
7257b535
BP
1857 }
1858 }
1859 vconn_close(vconn);
1860}
1861
1ac0e975 1862static void
1636c761 1863ofctl_ofp_parse(struct ovs_cmdl_context *ctx)
1ac0e975 1864{
1636c761 1865 const char *filename = ctx->argv[1];
1ac0e975
BP
1866 struct ofpbuf b;
1867 FILE *file;
1868
1869 file = !strcmp(filename, "-") ? stdin : fopen(filename, "r");
1870 if (file == NULL) {
1871 ovs_fatal(errno, "%s: open", filename);
1872 }
1873
1874 ofpbuf_init(&b, 65536);
1875 for (;;) {
1876 struct ofp_header *oh;
1877 size_t length, tail_len;
1878 void *tail;
1879 size_t n;
1880
1881 ofpbuf_clear(&b);
1882 oh = ofpbuf_put_uninit(&b, sizeof *oh);
1883 n = fread(oh, 1, sizeof *oh, file);
1884 if (n == 0) {
1885 break;
1886 } else if (n < sizeof *oh) {
1887 ovs_fatal(0, "%s: unexpected end of file mid-message", filename);
1888 }
1889
1890 length = ntohs(oh->length);
1891 if (length < sizeof *oh) {
34582733 1892 ovs_fatal(0, "%s: %"PRIuSIZE"-byte message is too short for OpenFlow",
1ac0e975
BP
1893 filename, length);
1894 }
1895
1896 tail_len = length - sizeof *oh;
1897 tail = ofpbuf_put_uninit(&b, tail_len);
1898 n = fread(tail, 1, tail_len, file);
1899 if (n < tail_len) {
1900 ovs_fatal(0, "%s: unexpected end of file mid-message", filename);
1901 }
1902
6fd6ed71 1903 ofp_print(stdout, b.data, b.size, verbosity + 2);
1ac0e975
BP
1904 }
1905 ofpbuf_uninit(&b);
1906
1907 if (file != stdin) {
1908 fclose(file);
1909 }
1910}
1911
f3dd1419
BP
1912static bool
1913is_openflow_port(ovs_be16 port_, char *ports[])
1914{
1915 uint16_t port = ntohs(port_);
1916 if (ports[0]) {
1917 int i;
1918
1919 for (i = 0; ports[i]; i++) {
1920 if (port == atoi(ports[i])) {
1921 return true;
1922 }
1923 }
1924 return false;
1925 } else {
1926 return port == OFP_PORT || port == OFP_OLD_PORT;
1927 }
1928}
1929
1930static void
1636c761 1931ofctl_ofp_parse_pcap(struct ovs_cmdl_context *ctx)
f3dd1419
BP
1932{
1933 struct tcp_reader *reader;
1934 FILE *file;
1935 int error;
1936 bool first;
1937
1636c761 1938 file = ovs_pcap_open(ctx->argv[1], "rb");
f3dd1419 1939 if (!file) {
1636c761 1940 ovs_fatal(errno, "%s: open failed", ctx->argv[1]);
f3dd1419
BP
1941 }
1942
1943 reader = tcp_reader_open();
1944 first = true;
1945 for (;;) {
cf62fa4c 1946 struct dp_packet *packet;
f3dd1419
BP
1947 long long int when;
1948 struct flow flow;
1949
50aa0364 1950 error = ovs_pcap_read(file, &packet, &when);
f3dd1419
BP
1951 if (error) {
1952 break;
1953 }
cf62fa4c
PS
1954 packet->md = PKT_METADATA_INITIALIZER(ODPP_NONE);
1955 flow_extract(packet, &flow);
f3dd1419
BP
1956 if (flow.dl_type == htons(ETH_TYPE_IP)
1957 && flow.nw_proto == IPPROTO_TCP
1636c761
RB
1958 && (is_openflow_port(flow.tp_src, ctx->argv + 2) ||
1959 is_openflow_port(flow.tp_dst, ctx->argv + 2))) {
cf62fa4c 1960 struct dp_packet *payload = tcp_reader_run(reader, &flow, packet);
f3dd1419 1961 if (payload) {
cf62fa4c 1962 while (dp_packet_size(payload) >= sizeof(struct ofp_header)) {
f3dd1419 1963 const struct ofp_header *oh;
cf62fa4c 1964 void *data = dp_packet_data(payload);
f3dd1419
BP
1965 int length;
1966
1967 /* Align OpenFlow on 8-byte boundary for safe access. */
cf62fa4c 1968 dp_packet_shift(payload, -((intptr_t) data & 7));
f3dd1419 1969
cf62fa4c 1970 oh = dp_packet_data(payload);
f3dd1419 1971 length = ntohs(oh->length);
cf62fa4c 1972 if (dp_packet_size(payload) < length) {
f3dd1419
BP
1973 break;
1974 }
1975
1976 if (!first) {
1977 putchar('\n');
1978 }
1979 first = false;
1980
1981 if (timestamp) {
1982 char *s = xastrftime_msec("%H:%M:%S.### ", when, true);
1983 fputs(s, stdout);
1984 free(s);
1985 }
1986
1987 printf(IP_FMT".%"PRIu16" > "IP_FMT".%"PRIu16":\n",
1988 IP_ARGS(flow.nw_src), ntohs(flow.tp_src),
1989 IP_ARGS(flow.nw_dst), ntohs(flow.tp_dst));
cf62fa4c
PS
1990 ofp_print(stdout, dp_packet_data(payload), length, verbosity + 1);
1991 dp_packet_pull(payload, length);
f3dd1419
BP
1992 }
1993 }
1994 }
cf62fa4c 1995 dp_packet_delete(packet);
f3dd1419
BP
1996 }
1997 tcp_reader_close(reader);
1998}
1999
064af421 2000static void
1636c761 2001ofctl_ping(struct ovs_cmdl_context *ctx)
064af421
BP
2002{
2003 size_t max_payload = 65535 - sizeof(struct ofp_header);
2004 unsigned int payload;
2005 struct vconn *vconn;
2006 int i;
2007
1636c761 2008 payload = ctx->argc > 2 ? atoi(ctx->argv[2]) : 64;
064af421 2009 if (payload > max_payload) {
34582733 2010 ovs_fatal(0, "payload must be between 0 and %"PRIuSIZE" bytes", max_payload);
064af421
BP
2011 }
2012
1636c761 2013 open_vconn(ctx->argv[1], &vconn);
064af421
BP
2014 for (i = 0; i < 10; i++) {
2015 struct timeval start, end;
2016 struct ofpbuf *request, *reply;
982697a4
BP
2017 const struct ofp_header *rpy_hdr;
2018 enum ofptype type;
064af421 2019
a53a8efa
SH
2020 request = ofpraw_alloc(OFPRAW_OFPT_ECHO_REQUEST,
2021 vconn_get_version(vconn), payload);
982697a4 2022 random_bytes(ofpbuf_put_uninit(request, payload), payload);
064af421 2023
279c9e03 2024 xgettimeofday(&start);
064af421 2025 run(vconn_transact(vconn, ofpbuf_clone(request), &reply), "transact");
279c9e03 2026 xgettimeofday(&end);
064af421 2027
6fd6ed71 2028 rpy_hdr = reply->data;
982697a4
BP
2029 if (ofptype_pull(&type, reply)
2030 || type != OFPTYPE_ECHO_REPLY
6fd6ed71
PS
2031 || reply->size != payload
2032 || memcmp(request->msg, reply->msg, payload)) {
064af421 2033 printf("Reply does not match request. Request:\n");
6fd6ed71 2034 ofp_print(stdout, request, request->size, verbosity + 2);
064af421 2035 printf("Reply:\n");
6fd6ed71 2036 ofp_print(stdout, reply, reply->size, verbosity + 2);
064af421 2037 }
437d0d22 2038 printf("%"PRIu32" bytes from %s: xid=%08"PRIx32" time=%.1f ms\n",
1636c761 2039 reply->size, ctx->argv[1], ntohl(rpy_hdr->xid),
064af421
BP
2040 (1000*(double)(end.tv_sec - start.tv_sec))
2041 + (.001*(end.tv_usec - start.tv_usec)));
2042 ofpbuf_delete(request);
2043 ofpbuf_delete(reply);
2044 }
2045 vconn_close(vconn);
2046}
2047
2048static void
1636c761 2049ofctl_benchmark(struct ovs_cmdl_context *ctx)
064af421
BP
2050{
2051 size_t max_payload = 65535 - sizeof(struct ofp_header);
2052 struct timeval start, end;
2053 unsigned int payload_size, message_size;
2054 struct vconn *vconn;
2055 double duration;
2056 int count;
2057 int i;
2058
1636c761 2059 payload_size = atoi(ctx->argv[2]);
064af421 2060 if (payload_size > max_payload) {
34582733 2061 ovs_fatal(0, "payload must be between 0 and %"PRIuSIZE" bytes", max_payload);
064af421
BP
2062 }
2063 message_size = sizeof(struct ofp_header) + payload_size;
2064
1636c761 2065 count = atoi(ctx->argv[3]);
064af421
BP
2066
2067 printf("Sending %d packets * %u bytes (with header) = %u bytes total\n",
2068 count, message_size, count * message_size);
2069
1636c761 2070 open_vconn(ctx->argv[1], &vconn);
279c9e03 2071 xgettimeofday(&start);
064af421
BP
2072 for (i = 0; i < count; i++) {
2073 struct ofpbuf *request, *reply;
064af421 2074
a53a8efa
SH
2075 request = ofpraw_alloc(OFPRAW_OFPT_ECHO_REQUEST,
2076 vconn_get_version(vconn), payload_size);
982697a4 2077 ofpbuf_put_zeros(request, payload_size);
064af421
BP
2078 run(vconn_transact(vconn, request, &reply), "transact");
2079 ofpbuf_delete(reply);
2080 }
279c9e03 2081 xgettimeofday(&end);
064af421
BP
2082 vconn_close(vconn);
2083
2084 duration = ((1000*(double)(end.tv_sec - start.tv_sec))
2085 + (.001*(end.tv_usec - start.tv_usec)));
2086 printf("Finished in %.1f ms (%.0f packets/s) (%.0f bytes/s)\n",
2087 duration, count / (duration / 1000.0),
2088 count * message_size / (duration / 1000.0));
2089}
2090
7395c052
NZ
2091static void
2092ofctl_group_mod__(const char *remote, struct ofputil_group_mod *gms,
69185eb2 2093 size_t n_gms, enum ofputil_protocol usable_protocols)
7395c052 2094{
69185eb2 2095 enum ofputil_protocol protocol;
7395c052 2096 struct ofputil_group_mod *gm;
69185eb2 2097 enum ofp_version version;
7395c052
NZ
2098 struct ofpbuf *request;
2099
2100 struct vconn *vconn;
2101 size_t i;
2102
69185eb2
SH
2103 protocol = open_vconn_for_flow_mod(remote, &vconn, usable_protocols);
2104 version = ofputil_protocol_to_ofp_version(protocol);
7395c052
NZ
2105
2106 for (i = 0; i < n_gms; i++) {
2107 gm = &gms[i];
69185eb2 2108 request = ofputil_encode_group_mod(version, gm);
7395c052
NZ
2109 if (request) {
2110 transact_noreply(vconn, request);
2111 }
2112 }
2113
2114 vconn_close(vconn);
2115
2116}
2117
2118
2119static void
2120ofctl_group_mod_file(int argc OVS_UNUSED, char *argv[], uint16_t command)
2121{
2122 struct ofputil_group_mod *gms = NULL;
2123 enum ofputil_protocol usable_protocols;
2124 size_t n_gms = 0;
2125 char *error;
0da32511 2126 int i;
7395c052
NZ
2127
2128 error = parse_ofp_group_mod_file(argv[2], command, &gms, &n_gms,
2129 &usable_protocols);
2130 if (error) {
2131 ovs_fatal(0, "%s", error);
2132 }
69185eb2 2133 ofctl_group_mod__(argv[1], gms, n_gms, usable_protocols);
0da32511
SH
2134 for (i = 0; i < n_gms; i++) {
2135 ofputil_bucket_list_destroy(&gms[i].buckets);
2136 }
7395c052
NZ
2137 free(gms);
2138}
2139
2140static void
2141ofctl_group_mod(int argc, char *argv[], uint16_t command)
2142{
2143 if (argc > 2 && !strcmp(argv[2], "-")) {
2144 ofctl_group_mod_file(argc, argv, command);
2145 } else {
2146 enum ofputil_protocol usable_protocols;
2147 struct ofputil_group_mod gm;
2148 char *error;
2149
2150 error = parse_ofp_group_mod_str(&gm, command, argc > 2 ? argv[2] : "",
2151 &usable_protocols);
2152 if (error) {
2153 ovs_fatal(0, "%s", error);
2154 }
69185eb2 2155 ofctl_group_mod__(argv[1], &gm, 1, usable_protocols);
0da32511 2156 ofputil_bucket_list_destroy(&gm.buckets);
7395c052
NZ
2157 }
2158}
2159
2160static void
1636c761 2161ofctl_add_group(struct ovs_cmdl_context *ctx)
7395c052 2162{
1636c761 2163 ofctl_group_mod(ctx->argc, ctx->argv, OFPGC11_ADD);
7395c052
NZ
2164}
2165
2166static void
1636c761 2167ofctl_add_groups(struct ovs_cmdl_context *ctx)
7395c052 2168{
1636c761 2169 ofctl_group_mod_file(ctx->argc, ctx->argv, OFPGC11_ADD);
7395c052
NZ
2170}
2171
2172static void
1636c761 2173ofctl_mod_group(struct ovs_cmdl_context *ctx)
7395c052 2174{
1636c761 2175 ofctl_group_mod(ctx->argc, ctx->argv, OFPGC11_MODIFY);
7395c052
NZ
2176}
2177
2178static void
1636c761 2179ofctl_del_groups(struct ovs_cmdl_context *ctx)
7395c052 2180{
1636c761 2181 ofctl_group_mod(ctx->argc, ctx->argv, OFPGC11_DELETE);
7395c052
NZ
2182}
2183
bdbb8426 2184static void
1636c761 2185ofctl_insert_bucket(struct ovs_cmdl_context *ctx)
bdbb8426 2186{
1636c761 2187 ofctl_group_mod(ctx->argc, ctx->argv, OFPGC15_INSERT_BUCKET);
bdbb8426
SH
2188}
2189
2190static void
1636c761 2191ofctl_remove_bucket(struct ovs_cmdl_context *ctx)
bdbb8426 2192{
1636c761 2193 ofctl_group_mod(ctx->argc, ctx->argv, OFPGC15_REMOVE_BUCKET);
bdbb8426
SH
2194}
2195
7395c052 2196static void
1636c761 2197ofctl_dump_group_stats(struct ovs_cmdl_context *ctx)
7395c052
NZ
2198{
2199 enum ofputil_protocol usable_protocols;
2200 struct ofputil_group_mod gm;
2201 struct ofpbuf *request;
2202 struct vconn *vconn;
2203 uint32_t group_id;
2204 char *error;
2205
2206 memset(&gm, 0, sizeof gm);
2207
2208 error = parse_ofp_group_mod_str(&gm, OFPGC11_DELETE,
1636c761 2209 ctx->argc > 2 ? ctx->argv[2] : "",
7395c052
NZ
2210 &usable_protocols);
2211 if (error) {
2212 ovs_fatal(0, "%s", error);
2213 }
2214
2215 group_id = gm.group_id;
2216
1636c761 2217 open_vconn(ctx->argv[1], &vconn);
7395c052
NZ
2218 request = ofputil_encode_group_stats_request(vconn_get_version(vconn),
2219 group_id);
2220 if (request) {
2221 dump_stats_transaction(vconn, request);
2222 }
2223
2224 vconn_close(vconn);
2225}
2226
2227static void
1636c761 2228ofctl_dump_group_desc(struct ovs_cmdl_context *ctx)
7395c052
NZ
2229{
2230 struct ofpbuf *request;
2231 struct vconn *vconn;
19187a71 2232 uint32_t group_id;
7395c052 2233
1636c761 2234 open_vconn(ctx->argv[1], &vconn);
7395c052 2235
1636c761 2236 if (ctx->argc < 3 || !ofputil_group_from_string(ctx->argv[2], &group_id)) {
19187a71
BP
2237 group_id = OFPG11_ALL;
2238 }
2239
2240 request = ofputil_encode_group_desc_request(vconn_get_version(vconn),
2241 group_id);
7395c052
NZ
2242 if (request) {
2243 dump_stats_transaction(vconn, request);
2244 }
2245
2246 vconn_close(vconn);
2247}
2248
2249static void
1636c761 2250ofctl_dump_group_features(struct ovs_cmdl_context *ctx)
7395c052
NZ
2251{
2252 struct ofpbuf *request;
2253 struct vconn *vconn;
2254
1636c761 2255 open_vconn(ctx->argv[1], &vconn);
7395c052
NZ
2256 request = ofputil_encode_group_features_request(vconn_get_version(vconn));
2257 if (request) {
2258 dump_stats_transaction(vconn, request);
2259 }
2260
2261 vconn_close(vconn);
2262}
2263
09246b99 2264static void
1636c761 2265ofctl_help(struct ovs_cmdl_context *ctx OVS_UNUSED)
09246b99
BP
2266{
2267 usage();
2268}
451de37e
AW
2269
2270static void
1636c761 2271ofctl_list_commands(struct ovs_cmdl_context *ctx OVS_UNUSED)
451de37e 2272{
5f383751 2273 ovs_cmdl_print_commands(get_all_commands());
451de37e 2274}
09246b99 2275\f
0199c526
BP
2276/* replace-flows and diff-flows commands. */
2277
2278/* A flow table entry, possibly with two different versions. */
2279struct fte {
2280 struct cls_rule rule; /* Within a "struct classifier". */
2281 struct fte_version *versions[2];
2282};
2283
2284/* One version of a Flow Table Entry. */
2285struct fte_version {
2286 ovs_be64 cookie;
2287 uint16_t idle_timeout;
2288 uint16_t hard_timeout;
ca26eb44 2289 uint16_t importance;
0199c526 2290 uint16_t flags;
f25d0cf3
BP
2291 struct ofpact *ofpacts;
2292 size_t ofpacts_len;
0199c526
BP
2293};
2294
2295/* Frees 'version' and the data that it owns. */
2296static void
2297fte_version_free(struct fte_version *version)
2298{
2299 if (version) {
dc723c44 2300 free(CONST_CAST(struct ofpact *, version->ofpacts));
0199c526
BP
2301 free(version);
2302 }
2303}
2304
2305/* Returns true if 'a' and 'b' are the same, false if they differ.
2306 *
2307 * Ignores differences in 'flags' because there's no way to retrieve flags from
2308 * an OpenFlow switch. We have to assume that they are the same. */
2309static bool
2310fte_version_equals(const struct fte_version *a, const struct fte_version *b)
2311{
2312 return (a->cookie == b->cookie
2313 && a->idle_timeout == b->idle_timeout
2314 && a->hard_timeout == b->hard_timeout
ca26eb44 2315 && a->importance == b->importance
f25d0cf3
BP
2316 && ofpacts_equal(a->ofpacts, a->ofpacts_len,
2317 b->ofpacts, b->ofpacts_len));
0199c526
BP
2318}
2319
98f7f427
BP
2320/* Clears 's', then if 's' has a version 'index', formats 'fte' and version
2321 * 'index' into 's', followed by a new-line. */
0199c526 2322static void
98f7f427 2323fte_version_format(const struct fte *fte, int index, struct ds *s)
0199c526 2324{
98f7f427 2325 const struct fte_version *version = fte->versions[index];
0199c526 2326
98f7f427
BP
2327 ds_clear(s);
2328 if (!version) {
2329 return;
2330 }
2331
2332 cls_rule_format(&fte->rule, s);
0199c526 2333 if (version->cookie != htonll(0)) {
98f7f427 2334 ds_put_format(s, " cookie=0x%"PRIx64, ntohll(version->cookie));
0199c526
BP
2335 }
2336 if (version->idle_timeout != OFP_FLOW_PERMANENT) {
98f7f427 2337 ds_put_format(s, " idle_timeout=%"PRIu16, version->idle_timeout);
0199c526
BP
2338 }
2339 if (version->hard_timeout != OFP_FLOW_PERMANENT) {
98f7f427 2340 ds_put_format(s, " hard_timeout=%"PRIu16, version->hard_timeout);
0199c526 2341 }
ca26eb44
RB
2342 if (version->importance != 0) {
2343 ds_put_format(s, " importance=%"PRIu16, version->importance);
2344 }
0199c526 2345
455ecd77 2346 ds_put_cstr(s, " actions=");
98f7f427
BP
2347 ofpacts_format(version->ofpacts, version->ofpacts_len, s);
2348
2349 ds_put_char(s, '\n');
0199c526
BP
2350}
2351
2352static struct fte *
2353fte_from_cls_rule(const struct cls_rule *cls_rule)
2354{
2355 return cls_rule ? CONTAINER_OF(cls_rule, struct fte, rule) : NULL;
2356}
2357
2358/* Frees 'fte' and its versions. */
2359static void
2360fte_free(struct fte *fte)
2361{
2362 if (fte) {
2363 fte_version_free(fte->versions[0]);
2364 fte_version_free(fte->versions[1]);
48d28ac1 2365 cls_rule_destroy(&fte->rule);
0199c526
BP
2366 free(fte);
2367 }
2368}
2369
2370/* Frees all of the FTEs within 'cls'. */
2371static void
2372fte_free_all(struct classifier *cls)
2373{
78c8df12 2374 struct fte *fte;
0199c526 2375
802f84ff 2376 classifier_defer(cls);
de4ad4a2 2377 CLS_FOR_EACH (fte, rule, cls) {
0199c526 2378 classifier_remove(cls, &fte->rule);
de4ad4a2 2379 ovsrcu_postpone(fte_free, fte);
0199c526 2380 }
e49190c4 2381 classifier_destroy(cls);
0199c526
BP
2382}
2383
2384/* Searches 'cls' for an FTE matching 'rule', inserting a new one if
2385 * necessary. Sets 'version' as the version of that rule with the given
2386 * 'index', replacing any existing version, if any.
2387 *
2388 * Takes ownership of 'version'. */
2389static void
81a76618 2390fte_insert(struct classifier *cls, const struct match *match,
eb391b76 2391 int priority, struct fte_version *version, int index)
0199c526
BP
2392{
2393 struct fte *old, *fte;
2394
2395 fte = xzalloc(sizeof *fte);
81a76618 2396 cls_rule_init(&fte->rule, match, priority);
0199c526
BP
2397 fte->versions[index] = version;
2398
18080541 2399 old = fte_from_cls_rule(classifier_replace(cls, &fte->rule, NULL, 0));
0199c526 2400 if (old) {
0199c526 2401 fte->versions[!index] = old->versions[!index];
de4ad4a2
JR
2402 old->versions[!index] = NULL;
2403
2404 ovsrcu_postpone(fte_free, old);
0199c526
BP
2405 }
2406}
2407
2408/* Reads the flows in 'filename' as flow table entries in 'cls' for the version
27527aa0
BP
2409 * with the specified 'index'. Returns the flow formats able to represent the
2410 * flows that were read. */
2411static enum ofputil_protocol
0199c526
BP
2412read_flows_from_file(const char *filename, struct classifier *cls, int index)
2413{
27527aa0 2414 enum ofputil_protocol usable_protocols;
bdda5aca 2415 int line_number;
0199c526
BP
2416 struct ds s;
2417 FILE *file;
2418
2419 file = !strcmp(filename, "-") ? stdin : fopen(filename, "r");
2420 if (file == NULL) {
2421 ovs_fatal(errno, "%s: open", filename);
2422 }
2423
2424 ds_init(&s);
27527aa0 2425 usable_protocols = OFPUTIL_P_ANY;
bdda5aca 2426 line_number = 0;
802f84ff 2427 classifier_defer(cls);
bdda5aca 2428 while (!ds_get_preprocessed_line(&s, file, &line_number)) {
0199c526 2429 struct fte_version *version;
a9a2da38 2430 struct ofputil_flow_mod fm;
bdda5aca 2431 char *error;
db0b6c29 2432 enum ofputil_protocol usable;
0199c526 2433
ba2fe8e9 2434 error = parse_ofp_str(&fm, OFPFC_ADD, ds_cstr(&s), &usable);
bdda5aca
BP
2435 if (error) {
2436 ovs_fatal(0, "%s:%d: %s", filename, line_number, error);
2437 }
db0b6c29 2438 usable_protocols &= usable;
0199c526
BP
2439
2440 version = xmalloc(sizeof *version);
623e1caf 2441 version->cookie = fm.new_cookie;
0199c526
BP
2442 version->idle_timeout = fm.idle_timeout;
2443 version->hard_timeout = fm.hard_timeout;
ca26eb44 2444 version->importance = fm.importance;
0fb88c18
BP
2445 version->flags = fm.flags & (OFPUTIL_FF_SEND_FLOW_REM
2446 | OFPUTIL_FF_EMERG);
f25d0cf3
BP
2447 version->ofpacts = fm.ofpacts;
2448 version->ofpacts_len = fm.ofpacts_len;
0199c526 2449
81a76618 2450 fte_insert(cls, &fm.match, fm.priority, version, index);
0199c526 2451 }
802f84ff 2452 classifier_publish(cls);
0199c526
BP
2453 ds_destroy(&s);
2454
2455 if (file != stdin) {
2456 fclose(file);
2457 }
2458
27527aa0 2459 return usable_protocols;
0199c526
BP
2460}
2461
4ce9c315
BP
2462static bool
2463recv_flow_stats_reply(struct vconn *vconn, ovs_be32 send_xid,
2464 struct ofpbuf **replyp,
2465 struct ofputil_flow_stats *fs, struct ofpbuf *ofpacts)
2466{
2467 struct ofpbuf *reply = *replyp;
2468
2469 for (;;) {
4ce9c315 2470 int retval;
35805806 2471 bool more;
4ce9c315
BP
2472
2473 /* Get a flow stats reply message, if we don't already have one. */
2474 if (!reply) {
982697a4
BP
2475 enum ofptype type;
2476 enum ofperr error;
4ce9c315
BP
2477
2478 do {
2479 run(vconn_recv_block(vconn, &reply),
2480 "OpenFlow packet receive failed");
6fd6ed71 2481 } while (((struct ofp_header *) reply->data)->xid != send_xid);
4ce9c315 2482
6fd6ed71 2483 error = ofptype_decode(&type, reply->data);
982697a4 2484 if (error || type != OFPTYPE_FLOW_STATS_REPLY) {
4ce9c315 2485 ovs_fatal(0, "received bad reply: %s",
6fd6ed71 2486 ofp_to_string(reply->data, reply->size,
4ce9c315
BP
2487 verbosity + 1));
2488 }
2489 }
2490
2491 /* Pull an individual flow stats reply out of the message. */
2492 retval = ofputil_decode_flow_stats_reply(fs, reply, false, ofpacts);
2493 switch (retval) {
2494 case 0:
2495 *replyp = reply;
2496 return true;
2497
2498 case EOF:
6fd6ed71 2499 more = ofpmp_more(reply->header);
4ce9c315 2500 ofpbuf_delete(reply);
296ed880 2501 reply = NULL;
35805806 2502 if (!more) {
4ce9c315
BP
2503 *replyp = NULL;
2504 return false;
2505 }
2506 break;
2507
2508 default:
2509 ovs_fatal(0, "parse error in reply (%s)",
2510 ofperr_to_string(retval));
2511 }
2512 }
2513}
2514
0199c526 2515/* Reads the OpenFlow flow table from 'vconn', which has currently active flow
27527aa0 2516 * format 'protocol', and adds them as flow table entries in 'cls' for the
0199c526
BP
2517 * version with the specified 'index'. */
2518static void
27527aa0
BP
2519read_flows_from_switch(struct vconn *vconn,
2520 enum ofputil_protocol protocol,
0199c526
BP
2521 struct classifier *cls, int index)
2522{
81d1ea94 2523 struct ofputil_flow_stats_request fsr;
4ce9c315 2524 struct ofputil_flow_stats fs;
0199c526 2525 struct ofpbuf *request;
4ce9c315
BP
2526 struct ofpbuf ofpacts;
2527 struct ofpbuf *reply;
0199c526 2528 ovs_be32 send_xid;
0199c526
BP
2529
2530 fsr.aggregate = false;
81a76618 2531 match_init_catchall(&fsr.match);
7f05e7ab 2532 fsr.out_port = OFPP_ANY;
0199c526 2533 fsr.table_id = 0xff;
ecc798ab 2534 fsr.cookie = fsr.cookie_mask = htonll(0);
27527aa0 2535 request = ofputil_encode_flow_stats_request(&fsr, protocol);
6fd6ed71 2536 send_xid = ((struct ofp_header *) request->data)->xid;
0199c526
BP
2537 send_openflow_buffer(vconn, request);
2538
4ce9c315
BP
2539 reply = NULL;
2540 ofpbuf_init(&ofpacts, 0);
802f84ff 2541 classifier_defer(cls);
4ce9c315
BP
2542 while (recv_flow_stats_reply(vconn, send_xid, &reply, &fs, &ofpacts)) {
2543 struct fte_version *version;
0199c526 2544
4ce9c315
BP
2545 version = xmalloc(sizeof *version);
2546 version->cookie = fs.cookie;
2547 version->idle_timeout = fs.idle_timeout;
2548 version->hard_timeout = fs.hard_timeout;
ca26eb44 2549 version->importance = fs.importance;
4ce9c315
BP
2550 version->flags = 0;
2551 version->ofpacts_len = fs.ofpacts_len;
2552 version->ofpacts = xmemdup(fs.ofpacts, fs.ofpacts_len);
2553
81a76618 2554 fte_insert(cls, &fs.match, fs.priority, version, index);
0199c526 2555 }
802f84ff 2556 classifier_publish(cls);
4ce9c315 2557 ofpbuf_uninit(&ofpacts);
0199c526
BP
2558}
2559
2560static void
2561fte_make_flow_mod(const struct fte *fte, int index, uint16_t command,
ca6ba700 2562 enum ofputil_protocol protocol, struct ovs_list *packets)
0199c526
BP
2563{
2564 const struct fte_version *version = fte->versions[index];
a9a2da38 2565 struct ofputil_flow_mod fm;
0199c526
BP
2566 struct ofpbuf *ofm;
2567
5cb7a798 2568 minimatch_expand(&fte->rule.match, &fm.match);
81a76618 2569 fm.priority = fte->rule.priority;
623e1caf
JP
2570 fm.cookie = htonll(0);
2571 fm.cookie_mask = htonll(0);
2572 fm.new_cookie = version->cookie;
23342857 2573 fm.modify_cookie = true;
6c1491fb 2574 fm.table_id = 0xff;
0199c526
BP
2575 fm.command = command;
2576 fm.idle_timeout = version->idle_timeout;
2577 fm.hard_timeout = version->hard_timeout;
ca26eb44 2578 fm.importance = version->importance;
0199c526 2579 fm.buffer_id = UINT32_MAX;
7f05e7ab 2580 fm.out_port = OFPP_ANY;
0199c526
BP
2581 fm.flags = version->flags;
2582 if (command == OFPFC_ADD || command == OFPFC_MODIFY ||
2583 command == OFPFC_MODIFY_STRICT) {
f25d0cf3
BP
2584 fm.ofpacts = version->ofpacts;
2585 fm.ofpacts_len = version->ofpacts_len;
0199c526 2586 } else {
f25d0cf3
BP
2587 fm.ofpacts = NULL;
2588 fm.ofpacts_len = 0;
0199c526 2589 }
cc40d06b 2590 fm.delete_reason = OFPRR_DELETE;
0199c526 2591
27527aa0 2592 ofm = ofputil_encode_flow_mod(&fm, protocol);
0199c526
BP
2593 list_push_back(packets, &ofm->list_node);
2594}
2595
2596static void
1636c761 2597ofctl_replace_flows(struct ovs_cmdl_context *ctx)
0199c526
BP
2598{
2599 enum { FILE_IDX = 0, SWITCH_IDX = 1 };
27527aa0 2600 enum ofputil_protocol usable_protocols, protocol;
0199c526 2601 struct classifier cls;
ca6ba700 2602 struct ovs_list requests;
0199c526
BP
2603 struct vconn *vconn;
2604 struct fte *fte;
2605
476f36e8 2606 classifier_init(&cls, NULL);
1636c761 2607 usable_protocols = read_flows_from_file(ctx->argv[2], &cls, FILE_IDX);
0199c526 2608
1636c761 2609 protocol = open_vconn(ctx->argv[1], &vconn);
27527aa0
BP
2610 protocol = set_protocol_for_flow_dump(vconn, protocol, usable_protocols);
2611
2612 read_flows_from_switch(vconn, protocol, &cls, SWITCH_IDX);
0199c526
BP
2613
2614 list_init(&requests);
2615
2616 /* Delete flows that exist on the switch but not in the file. */
5f0476ce 2617 CLS_FOR_EACH (fte, rule, &cls) {
0199c526
BP
2618 struct fte_version *file_ver = fte->versions[FILE_IDX];
2619 struct fte_version *sw_ver = fte->versions[SWITCH_IDX];
2620
2621 if (sw_ver && !file_ver) {
2622 fte_make_flow_mod(fte, SWITCH_IDX, OFPFC_DELETE_STRICT,
27527aa0 2623 protocol, &requests);
0199c526
BP
2624 }
2625 }
2626
2627 /* Add flows that exist in the file but not on the switch.
2628 * Update flows that exist in both places but differ. */
5f0476ce 2629 CLS_FOR_EACH (fte, rule, &cls) {
0199c526
BP
2630 struct fte_version *file_ver = fte->versions[FILE_IDX];
2631 struct fte_version *sw_ver = fte->versions[SWITCH_IDX];
2632
c4ea79bf
BP
2633 if (file_ver
2634 && (readd || !sw_ver || !fte_version_equals(sw_ver, file_ver))) {
27527aa0 2635 fte_make_flow_mod(fte, FILE_IDX, OFPFC_ADD, protocol, &requests);
0199c526
BP
2636 }
2637 }
2638 transact_multiple_noreply(vconn, &requests);
2639 vconn_close(vconn);
2640
2641 fte_free_all(&cls);
2642}
2643
2644static void
2645read_flows_from_source(const char *source, struct classifier *cls, int index)
2646{
2647 struct stat s;
2648
2649 if (source[0] == '/' || source[0] == '.'
2650 || (!strchr(source, ':') && !stat(source, &s))) {
2651 read_flows_from_file(source, cls, index);
2652 } else {
27527aa0 2653 enum ofputil_protocol protocol;
0199c526
BP
2654 struct vconn *vconn;
2655
27527aa0
BP
2656 protocol = open_vconn(source, &vconn);
2657 protocol = set_protocol_for_flow_dump(vconn, protocol, OFPUTIL_P_ANY);
2658 read_flows_from_switch(vconn, protocol, cls, index);
0199c526
BP
2659 vconn_close(vconn);
2660 }
2661}
2662
2663static void
1636c761 2664ofctl_diff_flows(struct ovs_cmdl_context *ctx)
0199c526
BP
2665{
2666 bool differences = false;
0199c526 2667 struct classifier cls;
98f7f427 2668 struct ds a_s, b_s;
0199c526
BP
2669 struct fte *fte;
2670
476f36e8 2671 classifier_init(&cls, NULL);
1636c761
RB
2672 read_flows_from_source(ctx->argv[1], &cls, 0);
2673 read_flows_from_source(ctx->argv[2], &cls, 1);
0199c526 2674
98f7f427
BP
2675 ds_init(&a_s);
2676 ds_init(&b_s);
2677
5f0476ce 2678 CLS_FOR_EACH (fte, rule, &cls) {
0199c526
BP
2679 struct fte_version *a = fte->versions[0];
2680 struct fte_version *b = fte->versions[1];
2681
2682 if (!a || !b || !fte_version_equals(a, b)) {
98f7f427
BP
2683 fte_version_format(fte, 0, &a_s);
2684 fte_version_format(fte, 1, &b_s);
2685 if (strcmp(ds_cstr(&a_s), ds_cstr(&b_s))) {
2686 if (a_s.length) {
2687 printf("-%s", ds_cstr(&a_s));
2688 }
2689 if (b_s.length) {
2690 printf("+%s", ds_cstr(&b_s));
2691 }
2692 differences = true;
0199c526 2693 }
0199c526
BP
2694 }
2695 }
2696
98f7f427
BP
2697 ds_destroy(&a_s);
2698 ds_destroy(&b_s);
2699
0199c526
BP
2700 fte_free_all(&cls);
2701
2702 if (differences) {
2703 exit(2);
2704 }
2705}
3200ed58
JR
2706
2707static void
2708ofctl_meter_mod__(const char *bridge, const char *str, int command)
2709{
2710 struct ofputil_meter_mod mm;
2711 struct vconn *vconn;
2712 enum ofputil_protocol protocol;
2713 enum ofputil_protocol usable_protocols;
2714 enum ofp_version version;
2715
2716 if (str) {
2717 char *error;
2718 error = parse_ofp_meter_mod_str(&mm, str, command, &usable_protocols);
2719 if (error) {
2720 ovs_fatal(0, "%s", error);
2721 }
2722 } else {
2723 usable_protocols = OFPUTIL_P_OF13_UP;
2724 mm.command = command;
2725 mm.meter.meter_id = OFPM13_ALL;
2726 }
2727
2728 protocol = open_vconn_for_flow_mod(bridge, &vconn, usable_protocols);
2729 version = ofputil_protocol_to_ofp_version(protocol);
2730 transact_noreply(vconn, ofputil_encode_meter_mod(version, &mm));
2731 vconn_close(vconn);
2732}
2733
2734static void
2735ofctl_meter_request__(const char *bridge, const char *str,
2736 enum ofputil_meter_request_type type)
2737{
2738 struct ofputil_meter_mod mm;
2739 struct vconn *vconn;
2740 enum ofputil_protocol usable_protocols;
2741 enum ofputil_protocol protocol;
2742 enum ofp_version version;
2743
2744 if (str) {
2745 char *error;
2746 error = parse_ofp_meter_mod_str(&mm, str, -1, &usable_protocols);
2747 if (error) {
2748 ovs_fatal(0, "%s", error);
2749 }
2750 } else {
2751 usable_protocols = OFPUTIL_P_OF13_UP;
2752 mm.meter.meter_id = OFPM13_ALL;
2753 }
2754
2755 protocol = open_vconn_for_flow_mod(bridge, &vconn, usable_protocols);
2756 version = ofputil_protocol_to_ofp_version(protocol);
2757 transact_noreply(vconn, ofputil_encode_meter_request(version,
2758 type,
2759 mm.meter.meter_id));
2760 vconn_close(vconn);
2761}
2762
2763
2764static void
1636c761 2765ofctl_add_meter(struct ovs_cmdl_context *ctx)
3200ed58 2766{
1636c761 2767 ofctl_meter_mod__(ctx->argv[1], ctx->argv[2], OFPMC13_ADD);
3200ed58
JR
2768}
2769
2770static void
1636c761 2771ofctl_mod_meter(struct ovs_cmdl_context *ctx)
3200ed58 2772{
1636c761 2773 ofctl_meter_mod__(ctx->argv[1], ctx->argv[2], OFPMC13_MODIFY);
3200ed58
JR
2774}
2775
2776static void
1636c761 2777ofctl_del_meters(struct ovs_cmdl_context *ctx)
3200ed58 2778{
1636c761 2779 ofctl_meter_mod__(ctx->argv[1], ctx->argc > 2 ? ctx->argv[2] : NULL, OFPMC13_DELETE);
3200ed58
JR
2780}
2781
2782static void
1636c761 2783ofctl_dump_meters(struct ovs_cmdl_context *ctx)
3200ed58 2784{
1636c761 2785 ofctl_meter_request__(ctx->argv[1], ctx->argc > 2 ? ctx->argv[2] : NULL,
3200ed58
JR
2786 OFPUTIL_METER_CONFIG);
2787}
2788
2789static void
1636c761 2790ofctl_meter_stats(struct ovs_cmdl_context *ctx)
3200ed58 2791{
1636c761 2792 ofctl_meter_request__(ctx->argv[1], ctx->argc > 2 ? ctx->argv[2] : NULL,
3200ed58
JR
2793 OFPUTIL_METER_STATS);
2794}
2795
2796static void
1636c761 2797ofctl_meter_features(struct ovs_cmdl_context *ctx)
3200ed58 2798{
1636c761 2799 ofctl_meter_request__(ctx->argv[1], NULL, OFPUTIL_METER_FEATURES);
3200ed58
JR
2800}
2801
0199c526 2802\f
09246b99
BP
2803/* Undocumented commands for unit testing. */
2804
770f1f66 2805static void
db0b6c29
JR
2806ofctl_parse_flows__(struct ofputil_flow_mod *fms, size_t n_fms,
2807 enum ofputil_protocol usable_protocols)
770f1f66 2808{
27527aa0
BP
2809 enum ofputil_protocol protocol = 0;
2810 char *usable_s;
2811 size_t i;
770f1f66 2812
27527aa0
BP
2813 usable_s = ofputil_protocols_to_string(usable_protocols);
2814 printf("usable protocols: %s\n", usable_s);
2815 free(usable_s);
2816
2817 if (!(usable_protocols & allowed_protocols)) {
2818 ovs_fatal(0, "no usable protocol");
2819 }
2820 for (i = 0; i < sizeof(enum ofputil_protocol) * CHAR_BIT; i++) {
2821 protocol = 1 << i;
2822 if (protocol & usable_protocols & allowed_protocols) {
2823 break;
2824 }
2825 }
cc2862a9 2826 ovs_assert(is_pow2(protocol));
27527aa0
BP
2827
2828 printf("chosen protocol: %s\n", ofputil_protocol_to_string(protocol));
2829
2830 for (i = 0; i < n_fms; i++) {
2831 struct ofputil_flow_mod *fm = &fms[i];
2832 struct ofpbuf *msg;
2833
2834 msg = ofputil_encode_flow_mod(fm, protocol);
6fd6ed71 2835 ofp_print(stdout, msg->data, msg->size, verbosity);
27527aa0
BP
2836 ofpbuf_delete(msg);
2837
dc723c44 2838 free(CONST_CAST(struct ofpact *, fm->ofpacts));
770f1f66
BP
2839 }
2840}
2841
2842/* "parse-flow FLOW": parses the argument as a flow (like add-flow) and prints
2843 * it back to stdout. */
2844static void
1636c761 2845ofctl_parse_flow(struct ovs_cmdl_context *ctx)
770f1f66 2846{
db0b6c29 2847 enum ofputil_protocol usable_protocols;
27527aa0 2848 struct ofputil_flow_mod fm;
bdda5aca 2849 char *error;
770f1f66 2850
1636c761 2851 error = parse_ofp_flow_mod_str(&fm, ctx->argv[1], OFPFC_ADD, &usable_protocols);
bdda5aca
BP
2852 if (error) {
2853 ovs_fatal(0, "%s", error);
2854 }
db0b6c29 2855 ofctl_parse_flows__(&fm, 1, usable_protocols);
770f1f66
BP
2856}
2857
fec00620
BP
2858/* "parse-flows FILENAME": reads the named file as a sequence of flows (like
2859 * add-flows) and prints each of the flows back to stdout. */
0e581146 2860static void
1636c761 2861ofctl_parse_flows(struct ovs_cmdl_context *ctx)
0e581146 2862{
db0b6c29 2863 enum ofputil_protocol usable_protocols;
27527aa0
BP
2864 struct ofputil_flow_mod *fms = NULL;
2865 size_t n_fms = 0;
bdda5aca 2866 char *error;
0e581146 2867
1636c761 2868 error = parse_ofp_flow_mod_file(ctx->argv[1], OFPFC_ADD, &fms, &n_fms,
ba2fe8e9 2869 &usable_protocols);
bdda5aca
BP
2870 if (error) {
2871 ovs_fatal(0, "%s", error);
2872 }
db0b6c29 2873 ofctl_parse_flows__(fms, n_fms, usable_protocols);
27527aa0 2874 free(fms);
0e581146
BP
2875}
2876
064af421 2877static void
9d84066c 2878ofctl_parse_nxm__(bool oxm, enum ofp_version version)
09246b99
BP
2879{
2880 struct ds in;
2881
2882 ds_init(&in);
06d7ae7d 2883 while (!ds_get_test_line(&in, stdin)) {
09246b99 2884 struct ofpbuf nx_match;
81a76618 2885 struct match match;
e729e793 2886 ovs_be64 cookie, cookie_mask;
90bf1e07 2887 enum ofperr error;
09246b99 2888 int match_len;
09246b99
BP
2889
2890 /* Convert string to nx_match. */
2891 ofpbuf_init(&nx_match, 0);
7623f4dd
SH
2892 if (oxm) {
2893 match_len = oxm_match_from_string(ds_cstr(&in), &nx_match);
2894 } else {
2895 match_len = nx_match_from_string(ds_cstr(&in), &nx_match);
2896 }
09246b99 2897
81a76618 2898 /* Convert nx_match to match. */
102ce766 2899 if (strict) {
7623f4dd 2900 if (oxm) {
81a76618 2901 error = oxm_pull_match(&nx_match, &match);
7623f4dd 2902 } else {
81a76618 2903 error = nx_pull_match(&nx_match, match_len, &match,
7623f4dd
SH
2904 &cookie, &cookie_mask);
2905 }
102ce766 2906 } else {
7623f4dd 2907 if (oxm) {
81a76618 2908 error = oxm_pull_match_loose(&nx_match, &match);
7623f4dd 2909 } else {
81a76618 2910 error = nx_pull_match_loose(&nx_match, match_len, &match,
7623f4dd
SH
2911 &cookie, &cookie_mask);
2912 }
102ce766
EJ
2913 }
2914
7623f4dd 2915
09246b99
BP
2916 if (!error) {
2917 char *out;
2918
81a76618 2919 /* Convert match back to nx_match. */
09246b99
BP
2920 ofpbuf_uninit(&nx_match);
2921 ofpbuf_init(&nx_match, 0);
7623f4dd 2922 if (oxm) {
9d84066c 2923 match_len = oxm_put_match(&nx_match, &match, version);
db5a1019 2924 out = oxm_match_to_string(&nx_match, match_len);
7623f4dd 2925 } else {
81a76618 2926 match_len = nx_put_match(&nx_match, &match,
7623f4dd 2927 cookie, cookie_mask);
6fd6ed71 2928 out = nx_match_to_string(nx_match.data, match_len);
7623f4dd 2929 }
09246b99 2930
09246b99
BP
2931 puts(out);
2932 free(out);
508a9338
BP
2933
2934 if (verbosity > 0) {
6fd6ed71 2935 ovs_hex_dump(stdout, nx_match.data, nx_match.size, 0, false);
508a9338 2936 }
09246b99 2937 } else {
90bf1e07
BP
2938 printf("nx_pull_match() returned error %s\n",
2939 ofperr_get_name(error));
09246b99
BP
2940 }
2941
2942 ofpbuf_uninit(&nx_match);
2943 }
2944 ds_destroy(&in);
064af421
BP
2945}
2946
b5ae8913
SH
2947/* "parse-nxm": reads a series of NXM nx_match specifications as strings from
2948 * stdin, does some internal fussing with them, and then prints them back as
2949 * strings on stdout. */
2950static void
1636c761 2951ofctl_parse_nxm(struct ovs_cmdl_context *ctx OVS_UNUSED)
b5ae8913 2952{
2f4aba0b 2953 ofctl_parse_nxm__(false, 0);
b5ae8913
SH
2954}
2955
9d84066c
BP
2956/* "parse-oxm VERSION": reads a series of OXM nx_match specifications as
2957 * strings from stdin, does some internal fussing with them, and then prints
2958 * them back as strings on stdout. VERSION must specify an OpenFlow version,
2959 * e.g. "OpenFlow12". */
b5ae8913 2960static void
1636c761 2961ofctl_parse_oxm(struct ovs_cmdl_context *ctx)
b5ae8913 2962{
1636c761 2963 enum ofp_version version = ofputil_version_from_string(ctx->argv[1]);
9d84066c 2964 if (version < OFP12_VERSION) {
1636c761 2965 ovs_fatal(0, "%s: not a valid version for OXM", ctx->argv[1]);
9d84066c
BP
2966 }
2967
2f4aba0b 2968 ofctl_parse_nxm__(true, version);
b5ae8913
SH
2969}
2970
f25d0cf3 2971static void
96628ae8
BP
2972print_differences(const char *prefix,
2973 const void *a_, size_t a_len,
f25d0cf3
BP
2974 const void *b_, size_t b_len)
2975{
2976 const uint8_t *a = a_;
2977 const uint8_t *b = b_;
2978 size_t i;
2979
2980 for (i = 0; i < MIN(a_len, b_len); i++) {
2981 if (a[i] != b[i]) {
34582733 2982 printf("%s%2"PRIuSIZE": %02"PRIx8" -> %02"PRIx8"\n",
96628ae8 2983 prefix, i, a[i], b[i]);
f25d0cf3
BP
2984 }
2985 }
2986 for (i = a_len; i < b_len; i++) {
34582733 2987 printf("%s%2"PRIuSIZE": (none) -> %02"PRIx8"\n", prefix, i, b[i]);
f25d0cf3
BP
2988 }
2989 for (i = b_len; i < a_len; i++) {
34582733 2990 printf("%s%2"PRIuSIZE": %02"PRIx8" -> (none)\n", prefix, i, a[i]);
f25d0cf3
BP
2991 }
2992}
2993
f25d0cf3 2994static void
65a8a59e 2995ofctl_parse_actions__(const char *version_s, bool instructions)
f25d0cf3 2996{
65a8a59e 2997 enum ofp_version version;
f25d0cf3
BP
2998 struct ds in;
2999
65a8a59e
BP
3000 version = ofputil_version_from_string(version_s);
3001 if (!version) {
3002 ovs_fatal(0, "%s: not a valid OpenFlow version", version_s);
3003 }
3004
f25d0cf3 3005 ds_init(&in);
bdda5aca 3006 while (!ds_get_preprocessed_line(&in, stdin, NULL)) {
65a8a59e
BP
3007 struct ofpbuf of_out;
3008 struct ofpbuf of_in;
f25d0cf3 3009 struct ofpbuf ofpacts;
65a8a59e
BP
3010 const char *table_id;
3011 char *actions;
f25d0cf3
BP
3012 enum ofperr error;
3013 size_t size;
3014 struct ds s;
3015
65a8a59e
BP
3016 /* Parse table_id separated with the follow-up actions by ",", if
3017 * any. */
3018 actions = ds_cstr(&in);
3019 table_id = NULL;
3020 if (strstr(actions, ",")) {
3021 table_id = strsep(&actions, ",");
3022 }
3023
f25d0cf3 3024 /* Parse hex bytes. */
65a8a59e
BP
3025 ofpbuf_init(&of_in, 0);
3026 if (ofpbuf_put_hex(&of_in, actions, NULL)[0] != '\0') {
f25d0cf3
BP
3027 ovs_fatal(0, "Trailing garbage in hex data");
3028 }
3029
3030 /* Convert to ofpacts. */
3031 ofpbuf_init(&ofpacts, 0);
6fd6ed71 3032 size = of_in.size;
8f2cded4
BP
3033 error = (instructions
3034 ? ofpacts_pull_openflow_instructions
3035 : ofpacts_pull_openflow_actions)(
6fd6ed71 3036 &of_in, of_in.size, version, &ofpacts);
65a8a59e
BP
3037 if (!error && instructions) {
3038 /* Verify actions, enforce consistency. */
3039 enum ofputil_protocol protocol;
3040 struct flow flow;
3041
3042 memset(&flow, 0, sizeof flow);
3043 protocol = ofputil_protocols_from_ofp_version(version);
6fd6ed71 3044 error = ofpacts_check_consistency(ofpacts.data, ofpacts.size,
65a8a59e
BP
3045 &flow, OFPP_MAX,
3046 table_id ? atoi(table_id) : 0,
3047 255, protocol);
3048 }
f25d0cf3 3049 if (error) {
65a8a59e
BP
3050 printf("bad %s %s: %s\n\n",
3051 version_s, instructions ? "instructions" : "actions",
3052 ofperr_get_name(error));
f25d0cf3 3053 ofpbuf_uninit(&ofpacts);
65a8a59e 3054 ofpbuf_uninit(&of_in);
f25d0cf3
BP
3055 continue;
3056 }
65a8a59e 3057 ofpbuf_push_uninit(&of_in, size);
f25d0cf3
BP
3058
3059 /* Print cls_rule. */
3060 ds_init(&s);
455ecd77 3061 ds_put_cstr(&s, "actions=");
6fd6ed71 3062 ofpacts_format(ofpacts.data, ofpacts.size, &s);
f25d0cf3
BP
3063 puts(ds_cstr(&s));
3064 ds_destroy(&s);
3065
3066 /* Convert back to ofp10 actions and print differences from input. */
65a8a59e
BP
3067 ofpbuf_init(&of_out, 0);
3068 if (instructions) {
6fd6ed71
PS
3069 ofpacts_put_openflow_instructions(ofpacts.data, ofpacts.size,
3070 &of_out, version);
65a8a59e 3071 } else {
6fd6ed71 3072 ofpacts_put_openflow_actions(ofpacts.data, ofpacts.size,
65a8a59e
BP
3073 &of_out, version);
3074 }
f25d0cf3 3075
6fd6ed71
PS
3076 print_differences("", of_in.data, of_in.size,
3077 of_out.data, of_out.size);
f25d0cf3
BP
3078 putchar('\n');
3079
3080 ofpbuf_uninit(&ofpacts);
65a8a59e
BP
3081 ofpbuf_uninit(&of_in);
3082 ofpbuf_uninit(&of_out);
f25d0cf3
BP
3083 }
3084 ds_destroy(&in);
3085}
3086
65a8a59e
BP
3087/* "parse-actions VERSION": reads a series of action specifications for the
3088 * given OpenFlow VERSION as hex bytes from stdin, converts them to ofpacts,
3089 * prints them as strings on stdout, and then converts them back to hex bytes
3090 * and prints any differences from the input. */
8f2cded4 3091static void
1636c761 3092ofctl_parse_actions(struct ovs_cmdl_context *ctx)
8f2cded4 3093{
1636c761 3094 ofctl_parse_actions__(ctx->argv[1], false);
8f2cded4
BP
3095}
3096
65a8a59e
BP
3097/* "parse-actions VERSION": reads a series of instruction specifications for
3098 * the given OpenFlow VERSION as hex bytes from stdin, converts them to
3099 * ofpacts, prints them as strings on stdout, and then converts them back to
3100 * hex bytes and prints any differences from the input. */
8f2cded4 3101static void
1636c761 3102ofctl_parse_instructions(struct ovs_cmdl_context *ctx)
8f2cded4 3103{
1636c761 3104 ofctl_parse_actions__(ctx->argv[1], true);
8f2cded4
BP
3105}
3106
96628ae8
BP
3107/* "parse-ofp10-match": reads a series of ofp10_match specifications as hex
3108 * bytes from stdin, converts them to cls_rules, prints them as strings on
3109 * stdout, and then converts them back to hex bytes and prints any differences
8812ec2c
BP
3110 * from the input.
3111 *
3112 * The input hex bytes may contain "x"s to represent "don't-cares", bytes whose
3113 * values are ignored in the input and will be set to zero when OVS converts
3114 * them back to hex bytes. ovs-ofctl actually sets "x"s to random bits when
3115 * it does the conversion to hex, to ensure that in fact they are ignored. */
96628ae8 3116static void
1636c761 3117ofctl_parse_ofp10_match(struct ovs_cmdl_context *ctx OVS_UNUSED)
96628ae8 3118{
8812ec2c 3119 struct ds expout;
96628ae8
BP
3120 struct ds in;
3121
3122 ds_init(&in);
8812ec2c 3123 ds_init(&expout);
bdda5aca 3124 while (!ds_get_preprocessed_line(&in, stdin, NULL)) {
8812ec2c 3125 struct ofpbuf match_in, match_expout;
96628ae8
BP
3126 struct ofp10_match match_out;
3127 struct ofp10_match match_normal;
81a76618 3128 struct match match;
8812ec2c
BP
3129 char *p;
3130
3131 /* Parse hex bytes to use for expected output. */
3132 ds_clear(&expout);
3133 ds_put_cstr(&expout, ds_cstr(&in));
3134 for (p = ds_cstr(&expout); *p; p++) {
3135 if (*p == 'x') {
3136 *p = '0';
3137 }
3138 }
3139 ofpbuf_init(&match_expout, 0);
3140 if (ofpbuf_put_hex(&match_expout, ds_cstr(&expout), NULL)[0] != '\0') {
3141 ovs_fatal(0, "Trailing garbage in hex data");
3142 }
6fd6ed71 3143 if (match_expout.size != sizeof(struct ofp10_match)) {
437d0d22 3144 ovs_fatal(0, "Input is %"PRIu32" bytes, expected %"PRIuSIZE,
6fd6ed71 3145 match_expout.size, sizeof(struct ofp10_match));
8812ec2c 3146 }
96628ae8 3147
8812ec2c
BP
3148 /* Parse hex bytes for input. */
3149 for (p = ds_cstr(&in); *p; p++) {
3150 if (*p == 'x') {
3151 *p = "0123456789abcdef"[random_uint32() & 0xf];
3152 }
3153 }
96628ae8
BP
3154 ofpbuf_init(&match_in, 0);
3155 if (ofpbuf_put_hex(&match_in, ds_cstr(&in), NULL)[0] != '\0') {
3156 ovs_fatal(0, "Trailing garbage in hex data");
3157 }
6fd6ed71 3158 if (match_in.size != sizeof(struct ofp10_match)) {
437d0d22 3159 ovs_fatal(0, "Input is %"PRIu32" bytes, expected %"PRIuSIZE,
6fd6ed71 3160 match_in.size, sizeof(struct ofp10_match));
96628ae8
BP
3161 }
3162
3163 /* Convert to cls_rule and print. */
6fd6ed71 3164 ofputil_match_from_ofp10_match(match_in.data, &match);
81a76618 3165 match_print(&match);
96628ae8
BP
3166
3167 /* Convert back to ofp10_match and print differences from input. */
81a76618 3168 ofputil_match_to_ofp10_match(&match, &match_out);
6fd6ed71 3169 print_differences("", match_expout.data, match_expout.size,
96628ae8
BP
3170 &match_out, sizeof match_out);
3171
3172 /* Normalize, then convert and compare again. */
81a76618
BP
3173 ofputil_normalize_match(&match);
3174 ofputil_match_to_ofp10_match(&match, &match_normal);
96628ae8
BP
3175 print_differences("normal: ", &match_out, sizeof match_out,
3176 &match_normal, sizeof match_normal);
3177 putchar('\n');
3178
3179 ofpbuf_uninit(&match_in);
8812ec2c 3180 ofpbuf_uninit(&match_expout);
96628ae8
BP
3181 }
3182 ds_destroy(&in);
8812ec2c 3183 ds_destroy(&expout);
96628ae8
BP
3184}
3185
410698cf 3186/* "parse-ofp11-match": reads a series of ofp11_match specifications as hex
81a76618
BP
3187 * bytes from stdin, converts them to "struct match"es, prints them as strings
3188 * on stdout, and then converts them back to hex bytes and prints any
3189 * differences from the input. */
410698cf 3190static void
1636c761 3191ofctl_parse_ofp11_match(struct ovs_cmdl_context *ctx OVS_UNUSED)
410698cf
BP
3192{
3193 struct ds in;
3194
3195 ds_init(&in);
bdda5aca 3196 while (!ds_get_preprocessed_line(&in, stdin, NULL)) {
410698cf
BP
3197 struct ofpbuf match_in;
3198 struct ofp11_match match_out;
81a76618 3199 struct match match;
410698cf 3200 enum ofperr error;
410698cf
BP
3201
3202 /* Parse hex bytes. */
3203 ofpbuf_init(&match_in, 0);
3204 if (ofpbuf_put_hex(&match_in, ds_cstr(&in), NULL)[0] != '\0') {
3205 ovs_fatal(0, "Trailing garbage in hex data");
3206 }
6fd6ed71 3207 if (match_in.size != sizeof(struct ofp11_match)) {
437d0d22 3208 ovs_fatal(0, "Input is %"PRIu32" bytes, expected %"PRIuSIZE,
6fd6ed71 3209 match_in.size, sizeof(struct ofp11_match));
410698cf
BP
3210 }
3211
81a76618 3212 /* Convert to match. */
6fd6ed71 3213 error = ofputil_match_from_ofp11_match(match_in.data, &match);
410698cf
BP
3214 if (error) {
3215 printf("bad ofp11_match: %s\n\n", ofperr_get_name(error));
3216 ofpbuf_uninit(&match_in);
3217 continue;
3218 }
3219
81a76618
BP
3220 /* Print match. */
3221 match_print(&match);
410698cf
BP
3222
3223 /* Convert back to ofp11_match and print differences from input. */
81a76618 3224 ofputil_match_to_ofp11_match(&match, &match_out);
410698cf 3225
6fd6ed71 3226 print_differences("", match_in.data, match_in.size,
d01c980f
BP
3227 &match_out, sizeof match_out);
3228 putchar('\n');
410698cf 3229
d01c980f
BP
3230 ofpbuf_uninit(&match_in);
3231 }
3232 ds_destroy(&in);
3233}
3234
14249c02
BP
3235/* "parse-pcap PCAP": read packets from PCAP and print their flows. */
3236static void
1636c761 3237ofctl_parse_pcap(struct ovs_cmdl_context *ctx)
14249c02
BP
3238{
3239 FILE *pcap;
3240
1636c761 3241 pcap = ovs_pcap_open(ctx->argv[1], "rb");
14249c02 3242 if (!pcap) {
1636c761 3243 ovs_fatal(errno, "%s: open failed", ctx->argv[1]);
14249c02
BP
3244 }
3245
3246 for (;;) {
cf62fa4c 3247 struct dp_packet *packet;
14249c02
BP
3248 struct flow flow;
3249 int error;
3250
50aa0364 3251 error = ovs_pcap_read(pcap, &packet, NULL);
14249c02
BP
3252 if (error == EOF) {
3253 break;
3254 } else if (error) {
1636c761 3255 ovs_fatal(error, "%s: read failed", ctx->argv[1]);
14249c02
BP
3256 }
3257
cf62fa4c
PS
3258 packet->md = PKT_METADATA_INITIALIZER(ODPP_NONE);
3259 flow_extract(packet, &flow);
14249c02
BP
3260 flow_print(stdout, &flow);
3261 putchar('\n');
cf62fa4c 3262 dp_packet_delete(packet);
14249c02
BP
3263 }
3264}
3265
df778240
BP
3266/* "check-vlan VLAN_TCI VLAN_TCI_MASK": converts the specified vlan_tci and
3267 * mask values to and from various formats and prints the results. */
3268static void
1636c761 3269ofctl_check_vlan(struct ovs_cmdl_context *ctx)
df778240 3270{
81a76618 3271 struct match match;
df778240
BP
3272
3273 char *string_s;
3274 struct ofputil_flow_mod fm;
3275
3276 struct ofpbuf nxm;
81a76618 3277 struct match nxm_match;
df778240
BP
3278 int nxm_match_len;
3279 char *nxm_s;
3280
81a76618
BP
3281 struct ofp10_match of10_raw;
3282 struct match of10_match;
df778240 3283
81a76618
BP
3284 struct ofp11_match of11_raw;
3285 struct match of11_match;
df778240
BP
3286
3287 enum ofperr error;
bdda5aca 3288 char *error_s;
df778240 3289
db0b6c29
JR
3290 enum ofputil_protocol usable_protocols; /* Unused for now. */
3291
81a76618 3292 match_init_catchall(&match);
1636c761
RB
3293 match.flow.vlan_tci = htons(strtoul(ctx->argv[1], NULL, 16));
3294 match.wc.masks.vlan_tci = htons(strtoul(ctx->argv[2], NULL, 16));
df778240
BP
3295
3296 /* Convert to and from string. */
81a76618 3297 string_s = match_to_string(&match, OFP_DEFAULT_PRIORITY);
df778240
BP
3298 printf("%s -> ", string_s);
3299 fflush(stdout);
ba2fe8e9 3300 error_s = parse_ofp_str(&fm, -1, string_s, &usable_protocols);
bdda5aca
BP
3301 if (error_s) {
3302 ovs_fatal(0, "%s", error_s);
3303 }
df778240 3304 printf("%04"PRIx16"/%04"PRIx16"\n",
81a76618
BP
3305 ntohs(fm.match.flow.vlan_tci),
3306 ntohs(fm.match.wc.masks.vlan_tci));
4d859fa9 3307 free(string_s);
df778240
BP
3308
3309 /* Convert to and from NXM. */
3310 ofpbuf_init(&nxm, 0);
81a76618 3311 nxm_match_len = nx_put_match(&nxm, &match, htonll(0), htonll(0));
6fd6ed71 3312 nxm_s = nx_match_to_string(nxm.data, nxm_match_len);
81a76618 3313 error = nx_pull_match(&nxm, nxm_match_len, &nxm_match, NULL, NULL);
df778240
BP
3314 printf("NXM: %s -> ", nxm_s);
3315 if (error) {
3316 printf("%s\n", ofperr_to_string(error));
3317 } else {
3318 printf("%04"PRIx16"/%04"PRIx16"\n",
81a76618
BP
3319 ntohs(nxm_match.flow.vlan_tci),
3320 ntohs(nxm_match.wc.masks.vlan_tci));
df778240
BP
3321 }
3322 free(nxm_s);
3323 ofpbuf_uninit(&nxm);
3324
476a0e9e
SH
3325 /* Convert to and from OXM. */
3326 ofpbuf_init(&nxm, 0);
9d84066c 3327 nxm_match_len = oxm_put_match(&nxm, &match, OFP12_VERSION);
db5a1019 3328 nxm_s = oxm_match_to_string(&nxm, nxm_match_len);
81a76618 3329 error = oxm_pull_match(&nxm, &nxm_match);
476a0e9e
SH
3330 printf("OXM: %s -> ", nxm_s);
3331 if (error) {
3332 printf("%s\n", ofperr_to_string(error));
3333 } else {
81a76618 3334 uint16_t vid = ntohs(nxm_match.flow.vlan_tci) &
476a0e9e 3335 (VLAN_VID_MASK | VLAN_CFI);
81a76618 3336 uint16_t mask = ntohs(nxm_match.wc.masks.vlan_tci) &
476a0e9e
SH
3337 (VLAN_VID_MASK | VLAN_CFI);
3338
3339 printf("%04"PRIx16"/%04"PRIx16",", vid, mask);
81a76618
BP
3340 if (vid && vlan_tci_to_pcp(nxm_match.wc.masks.vlan_tci)) {
3341 printf("%02"PRIx8"\n", vlan_tci_to_pcp(nxm_match.flow.vlan_tci));
476a0e9e
SH
3342 } else {
3343 printf("--\n");
3344 }
3345 }
3346 free(nxm_s);
3347 ofpbuf_uninit(&nxm);
3348
df778240 3349 /* Convert to and from OpenFlow 1.0. */
81a76618
BP
3350 ofputil_match_to_ofp10_match(&match, &of10_raw);
3351 ofputil_match_from_ofp10_match(&of10_raw, &of10_match);
df778240 3352 printf("OF1.0: %04"PRIx16"/%d,%02"PRIx8"/%d -> %04"PRIx16"/%04"PRIx16"\n",
81a76618
BP
3353 ntohs(of10_raw.dl_vlan),
3354 (of10_raw.wildcards & htonl(OFPFW10_DL_VLAN)) != 0,
3355 of10_raw.dl_vlan_pcp,
3356 (of10_raw.wildcards & htonl(OFPFW10_DL_VLAN_PCP)) != 0,
3357 ntohs(of10_match.flow.vlan_tci),
3358 ntohs(of10_match.wc.masks.vlan_tci));
df778240
BP
3359
3360 /* Convert to and from OpenFlow 1.1. */
81a76618
BP
3361 ofputil_match_to_ofp11_match(&match, &of11_raw);
3362 ofputil_match_from_ofp11_match(&of11_raw, &of11_match);
df778240 3363 printf("OF1.1: %04"PRIx16"/%d,%02"PRIx8"/%d -> %04"PRIx16"/%04"PRIx16"\n",
81a76618
BP
3364 ntohs(of11_raw.dl_vlan),
3365 (of11_raw.wildcards & htonl(OFPFW11_DL_VLAN)) != 0,
3366 of11_raw.dl_vlan_pcp,
3367 (of11_raw.wildcards & htonl(OFPFW11_DL_VLAN_PCP)) != 0,
3368 ntohs(of11_match.flow.vlan_tci),
3369 ntohs(of11_match.wc.masks.vlan_tci));
df778240
BP
3370}
3371
2e0525bc
SH
3372/* "print-error ENUM": Prints the type and code of ENUM for every OpenFlow
3373 * version. */
3374static void
1636c761 3375ofctl_print_error(struct ovs_cmdl_context *ctx)
2e0525bc
SH
3376{
3377 enum ofperr error;
3378 int version;
3379
1636c761 3380 error = ofperr_from_name(ctx->argv[1]);
2e0525bc 3381 if (!error) {
1636c761 3382 ovs_fatal(0, "unknown error \"%s\"", ctx->argv[1]);
2e0525bc
SH
3383 }
3384
3385 for (version = 0; version <= UINT8_MAX; version++) {
688e86e1 3386 const char *name = ofperr_domain_get_name(version);
514887ee
BP
3387 if (name) {
3388 int vendor = ofperr_get_vendor(error, version);
3389 int type = ofperr_get_type(error, version);
3390 int code = ofperr_get_code(error, version);
3391
3392 if (vendor != -1 || type != -1 || code != -1) {
3393 printf("%s: vendor %#x, type %d, code %d\n",
3394 name, vendor, type, code);
3395 }
2e0525bc 3396 }
2e0525bc
SH
3397 }
3398}
3399
edd70aa7
BP
3400/* "encode-error-reply ENUM REQUEST": Encodes an error reply to REQUEST for the
3401 * error named ENUM and prints the error reply in hex. */
3402static void
1636c761 3403ofctl_encode_error_reply(struct ovs_cmdl_context *ctx)
edd70aa7
BP
3404{
3405 const struct ofp_header *oh;
3406 struct ofpbuf request, *reply;
3407 enum ofperr error;
3408
1636c761 3409 error = ofperr_from_name(ctx->argv[1]);
edd70aa7 3410 if (!error) {
1636c761 3411 ovs_fatal(0, "unknown error \"%s\"", ctx->argv[1]);
edd70aa7
BP
3412 }
3413
3414 ofpbuf_init(&request, 0);
1636c761 3415 if (ofpbuf_put_hex(&request, ctx->argv[2], NULL)[0] != '\0') {
edd70aa7
BP
3416 ovs_fatal(0, "Trailing garbage in hex data");
3417 }
6fd6ed71 3418 if (request.size < sizeof(struct ofp_header)) {
edd70aa7
BP
3419 ovs_fatal(0, "Request too short");
3420 }
3421
6fd6ed71
PS
3422 oh = request.data;
3423 if (request.size != ntohs(oh->length)) {
edd70aa7
BP
3424 ovs_fatal(0, "Request size inconsistent");
3425 }
3426
6fd6ed71 3427 reply = ofperr_encode_reply(error, request.data);
edd70aa7
BP
3428 ofpbuf_uninit(&request);
3429
6fd6ed71 3430 ovs_hex_dump(stdout, reply->data, reply->size, 0, false);
edd70aa7
BP
3431 ofpbuf_delete(reply);
3432}
3433
fec00620
BP
3434/* "ofp-print HEXSTRING [VERBOSITY]": Converts the hex digits in HEXSTRING into
3435 * binary data, interpreting them as an OpenFlow message, and prints the
8b227701
GS
3436 * OpenFlow message on stdout, at VERBOSITY (level 2 by default).
3437 *
3438 * Alternative usage: "ofp-print [VERBOSITY] - < HEXSTRING_FILE", where
3439 * HEXSTRING_FILE contains the HEXSTRING. */
fec00620 3440static void
1636c761 3441ofctl_ofp_print(struct ovs_cmdl_context *ctx)
fec00620
BP
3442{
3443 struct ofpbuf packet;
8b227701
GS
3444 char *buffer;
3445 int verbosity = 2;
3446 struct ds line;
3447
3448 ds_init(&line);
3449
1636c761 3450 if (!strcmp(ctx->argv[ctx->argc-1], "-")) {
8b227701
GS
3451 if (ds_get_line(&line, stdin)) {
3452 VLOG_FATAL("Failed to read stdin");
3453 }
3454
3455 buffer = line.string;
1636c761
RB
3456 verbosity = ctx->argc > 2 ? atoi(ctx->argv[1]) : verbosity;
3457 } else if (ctx->argc > 2) {
3458 buffer = ctx->argv[1];
3459 verbosity = atoi(ctx->argv[2]);
8b227701 3460 } else {
1636c761 3461 buffer = ctx->argv[1];
8b227701 3462 }
fec00620 3463
8b227701
GS
3464 ofpbuf_init(&packet, strlen(buffer) / 2);
3465 if (ofpbuf_put_hex(&packet, buffer, NULL)[0] != '\0') {
fec00620
BP
3466 ovs_fatal(0, "trailing garbage following hex bytes");
3467 }
6fd6ed71 3468 ofp_print(stdout, packet.data, packet.size, verbosity);
fec00620 3469 ofpbuf_uninit(&packet);
8b227701 3470 ds_destroy(&line);
fec00620
BP
3471}
3472
681ea7a0
BP
3473/* "encode-hello BITMAP...": Encodes each BITMAP as an OpenFlow hello message
3474 * and dumps each message in hex. */
3475static void
1636c761 3476ofctl_encode_hello(struct ovs_cmdl_context *ctx)
681ea7a0 3477{
1636c761 3478 uint32_t bitmap = strtol(ctx->argv[1], NULL, 0);
681ea7a0
BP
3479 struct ofpbuf *hello;
3480
3481 hello = ofputil_encode_hello(bitmap);
6fd6ed71
PS
3482 ovs_hex_dump(stdout, hello->data, hello->size, 0, false);
3483 ofp_print(stdout, hello->data, hello->size, verbosity);
681ea7a0
BP
3484 ofpbuf_delete(hello);
3485}
3486
5f383751 3487static const struct ovs_cmdl_command all_commands[] = {
451de37e
AW
3488 { "show", "switch",
3489 1, 1, ofctl_show },
3490 { "monitor", "switch [misslen] [invalid_ttl] [watch:[...]]",
3491 1, 3, ofctl_monitor },
3492 { "snoop", "switch",
3493 1, 1, ofctl_snoop },
3494 { "dump-desc", "switch",
3495 1, 1, ofctl_dump_desc },
3496 { "dump-tables", "switch",
3497 1, 1, ofctl_dump_tables },
3498 { "dump-table-features", "switch",
3499 1, 1, ofctl_dump_table_features },
3500 { "dump-flows", "switch",
3501 1, 2, ofctl_dump_flows },
3502 { "dump-aggregate", "switch",
3503 1, 2, ofctl_dump_aggregate },
3504 { "queue-stats", "switch [port [queue]]",
3505 1, 3, ofctl_queue_stats },
3506 { "queue-get-config", "switch port",
3507 2, 2, ofctl_queue_get_config },
3508 { "add-flow", "switch flow",
3509 2, 2, ofctl_add_flow },
3510 { "add-flows", "switch file",
3511 2, 2, ofctl_add_flows },
3512 { "mod-flows", "switch flow",
3513 2, 2, ofctl_mod_flows },
3514 { "del-flows", "switch [flow]",
3515 1, 2, ofctl_del_flows },
3516 { "replace-flows", "switch file",
3517 2, 2, ofctl_replace_flows },
3518 { "diff-flows", "source1 source2",
3519 2, 2, ofctl_diff_flows },
3520 { "add-meter", "switch meter",
3521 2, 2, ofctl_add_meter },
3522 { "mod-meter", "switch meter",
3523 2, 2, ofctl_mod_meter },
3524 { "del-meter", "switch meter",
3525 2, 2, ofctl_del_meters },
3526 { "del-meters", "switch",
3527 1, 1, ofctl_del_meters },
3528 { "dump-meter", "switch meter",
3529 2, 2, ofctl_dump_meters },
3530 { "dump-meters", "switch",
3531 1, 1, ofctl_dump_meters },
3532 { "meter-stats", "switch [meter]",
3533 1, 2, ofctl_meter_stats },
3534 { "meter-features", "switch",
3535 1, 1, ofctl_meter_features },
3536 { "packet-out", "switch in_port actions packet...",
3537 4, INT_MAX, ofctl_packet_out },
3538 { "dump-ports", "switch [port]",
3539 1, 2, ofctl_dump_ports },
3540 { "dump-ports-desc", "switch [port]",
3541 1, 2, ofctl_dump_ports_desc },
3542 { "mod-port", "switch iface act",
3543 3, 3, ofctl_mod_port },
3544 { "mod-table", "switch mod",
3545 3, 3, ofctl_mod_table },
3546 { "get-frags", "switch",
3547 1, 1, ofctl_get_frags },
3548 { "set-frags", "switch frag_mode",
3549 2, 2, ofctl_set_frags },
3550 { "probe", "target",
3551 1, 1, ofctl_probe },
3552 { "ping", "target [n]",
3553 1, 2, ofctl_ping },
3554 { "benchmark", "target n count",
3555 3, 3, ofctl_benchmark },
3556
3557 { "ofp-parse", "file",
3558 1, 1, ofctl_ofp_parse },
3559 { "ofp-parse-pcap", "pcap",
3560 1, INT_MAX, ofctl_ofp_parse_pcap },
3561
3562 { "add-group", "switch group",
3563 1, 2, ofctl_add_group },
3564 { "add-groups", "switch file",
3565 1, 2, ofctl_add_groups },
3566 { "mod-group", "switch group",
3567 1, 2, ofctl_mod_group },
3568 { "del-groups", "switch [group]",
3569 1, 2, ofctl_del_groups },
bdbb8426
SH
3570 { "insert-buckets", "switch [group]",
3571 1, 2, ofctl_insert_bucket },
3572 { "remove-buckets", "switch [group]",
3573 1, 2, ofctl_remove_bucket },
451de37e
AW
3574 { "dump-groups", "switch [group]",
3575 1, 2, ofctl_dump_group_desc },
3576 { "dump-group-stats", "switch [group]",
3577 1, 2, ofctl_dump_group_stats },
3578 { "dump-group-features", "switch",
3579 1, 1, ofctl_dump_group_features },
3580 { "help", NULL, 0, INT_MAX, ofctl_help },
3581 { "list-commands", NULL, 0, INT_MAX, ofctl_list_commands },
09246b99
BP
3582
3583 /* Undocumented commands for testing. */
451de37e
AW
3584 { "parse-flow", NULL, 1, 1, ofctl_parse_flow },
3585 { "parse-flows", NULL, 1, 1, ofctl_parse_flows },
3586 { "parse-nx-match", NULL, 0, 0, ofctl_parse_nxm },
3587 { "parse-nxm", NULL, 0, 0, ofctl_parse_nxm },
3588 { "parse-oxm", NULL, 1, 1, ofctl_parse_oxm },
3589 { "parse-actions", NULL, 1, 1, ofctl_parse_actions },
3590 { "parse-instructions", NULL, 1, 1, ofctl_parse_instructions },
3591 { "parse-ofp10-match", NULL, 0, 0, ofctl_parse_ofp10_match },
3592 { "parse-ofp11-match", NULL, 0, 0, ofctl_parse_ofp11_match },
3593 { "parse-pcap", NULL, 1, 1, ofctl_parse_pcap },
3594 { "check-vlan", NULL, 2, 2, ofctl_check_vlan },
3595 { "print-error", NULL, 1, 1, ofctl_print_error },
3596 { "encode-error-reply", NULL, 2, 2, ofctl_encode_error_reply },
3597 { "ofp-print", NULL, 1, 2, ofctl_ofp_print },
3598 { "encode-hello", NULL, 1, 1, ofctl_encode_hello },
3599
3600 { NULL, NULL, 0, 0, NULL },
064af421 3601};
3815d6c2 3602
5f383751 3603static const struct ovs_cmdl_command *get_all_commands(void)
3815d6c2
LS
3604{
3605 return all_commands;
3606}