ovs-ofctl: Add "queue-stats" command to print queue stats.
[sliver-openvswitch.git] / lib / ofp-print.c
1 /*
2  * Copyright (c) 2008, 2009, 2010 Nicira Networks.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <config.h>
18 #include "ofp-print.h"
19
20 #include <errno.h>
21 #include <inttypes.h>
22 #include <sys/types.h>
23 #include <netinet/in.h>
24 #include <sys/wait.h>
25 #include <stdarg.h>
26 #include <stdlib.h>
27 #include <ctype.h>
28
29 #include "compiler.h"
30 #include "dynamic-string.h"
31 #include "flow.h"
32 #include "ofpbuf.h"
33 #include "openflow/openflow.h"
34 #include "openflow/nicira-ext.h"
35 #include "packets.h"
36 #include "pcap.h"
37 #include "util.h"
38 #include "xtoxll.h"
39
40 static void ofp_print_port_name(struct ds *string, uint16_t port);
41 static void ofp_print_queue_name(struct ds *string, uint32_t port);
42
43 /* Returns a string that represents the contents of the Ethernet frame in the
44  * 'len' bytes starting at 'data' to 'stream' as output by tcpdump.
45  * 'total_len' specifies the full length of the Ethernet frame (of which 'len'
46  * bytes were captured).
47  *
48  * The caller must free the returned string.
49  *
50  * This starts and kills a tcpdump subprocess so it's quite expensive. */
51 char *
52 ofp_packet_to_string(const void *data, size_t len, size_t total_len OVS_UNUSED)
53 {
54     struct ds ds = DS_EMPTY_INITIALIZER;
55     struct ofpbuf buf;
56
57     char command[128];
58     FILE *pcap;
59     FILE *tcpdump;
60     int status;
61     int c;
62
63     buf.data = (void *) data;
64     buf.size = len;
65
66     pcap = tmpfile();
67     if (!pcap) {
68         ovs_error(errno, "tmpfile");
69         return xstrdup("<error>");
70     }
71     pcap_write_header(pcap);
72     pcap_write(pcap, &buf);
73     fflush(pcap);
74     if (ferror(pcap)) {
75         ovs_error(errno, "error writing temporary file");
76     }
77     rewind(pcap);
78
79     snprintf(command, sizeof command, "/usr/sbin/tcpdump -e -n -r /dev/fd/%d 2>/dev/null",
80              fileno(pcap));
81     tcpdump = popen(command, "r");
82     fclose(pcap);
83     if (!tcpdump) {
84         ovs_error(errno, "exec(\"%s\")", command);
85         return xstrdup("<error>");
86     }
87
88     while ((c = getc(tcpdump)) != EOF) {
89         ds_put_char(&ds, c);
90     }
91
92     status = pclose(tcpdump);
93     if (WIFEXITED(status)) {
94         if (WEXITSTATUS(status))
95             ovs_error(0, "tcpdump exited with status %d", WEXITSTATUS(status));
96     } else if (WIFSIGNALED(status)) {
97         ovs_error(0, "tcpdump exited with signal %d", WTERMSIG(status));
98     }
99     return ds_cstr(&ds);
100 }
101
102 /* Pretty-print the OFPT_PACKET_IN packet of 'len' bytes at 'oh' to 'stream'
103  * at the given 'verbosity' level. */
104 static void
105 ofp_packet_in(struct ds *string, const void *oh, size_t len, int verbosity)
106 {
107     const struct ofp_packet_in *op = oh;
108     size_t data_len;
109
110     ds_put_format(string, " total_len=%"PRIu16" in_port=",
111                   ntohs(op->total_len));
112     ofp_print_port_name(string, ntohs(op->in_port));
113
114     if (op->reason == OFPR_ACTION)
115         ds_put_cstr(string, " (via action)");
116     else if (op->reason != OFPR_NO_MATCH)
117         ds_put_format(string, " (***reason %"PRIu8"***)", op->reason);
118
119     data_len = len - offsetof(struct ofp_packet_in, data);
120     ds_put_format(string, " data_len=%zu", data_len);
121     if (htonl(op->buffer_id) == UINT32_MAX) {
122         ds_put_format(string, " (unbuffered)");
123         if (ntohs(op->total_len) != data_len)
124             ds_put_format(string, " (***total_len != data_len***)");
125     } else {
126         ds_put_format(string, " buffer=0x%08"PRIx32, ntohl(op->buffer_id));
127         if (ntohs(op->total_len) < data_len)
128             ds_put_format(string, " (***total_len < data_len***)");
129     }
130     ds_put_char(string, '\n');
131
132     if (verbosity > 0) {
133         flow_t flow;
134         struct ofpbuf packet;
135         struct ofp_match match;
136         packet.data = (void *) op->data;
137         packet.size = data_len;
138         flow_extract(&packet, 0, ntohs(op->in_port), &flow);
139         flow_to_match(&flow, 0, false, &match);
140         ofp_print_match(string, &match, verbosity);
141         ds_put_char(string, '\n');
142     }
143     if (verbosity > 1) {
144         char *packet = ofp_packet_to_string(op->data, data_len,
145                                             ntohs(op->total_len));
146         ds_put_cstr(string, packet);
147         free(packet);
148     }
149 }
150
151 static void ofp_print_port_name(struct ds *string, uint16_t port)
152 {
153     const char *name;
154     switch (port) {
155     case OFPP_IN_PORT:
156         name = "IN_PORT";
157         break;
158     case OFPP_TABLE:
159         name = "TABLE";
160         break;
161     case OFPP_NORMAL:
162         name = "NORMAL";
163         break;
164     case OFPP_FLOOD:
165         name = "FLOOD";
166         break;
167     case OFPP_ALL:
168         name = "ALL";
169         break;
170     case OFPP_CONTROLLER:
171         name = "CONTROLLER";
172         break;
173     case OFPP_LOCAL:
174         name = "LOCAL";
175         break;
176     case OFPP_NONE:
177         name = "NONE";
178         break;
179     default:
180         ds_put_format(string, "%"PRIu16, port);
181         return;
182     }
183     ds_put_cstr(string, name);
184 }
185
186 static void
187 ofp_print_nx_action(struct ds *string, const struct nx_action_header *nah)
188 {
189     switch (ntohs(nah->subtype)) {
190     case NXAST_RESUBMIT: {
191         const struct nx_action_resubmit *nar = (struct nx_action_resubmit *)nah;
192         ds_put_format(string, "resubmit:");
193         ofp_print_port_name(string, ntohs(nar->in_port));
194         break;
195     }
196
197     case NXAST_SET_TUNNEL: {
198         const struct nx_action_set_tunnel *nast =
199                                             (struct nx_action_set_tunnel *)nah;
200         ds_put_format(string, "set_tunnel:0x%08"PRIx32, ntohl(nast->tun_id));
201         break;
202     }
203
204     case NXAST_DROP_SPOOFED_ARP:
205         ds_put_cstr(string, "drop_spoofed_arp");
206         break;
207
208     default:
209         ds_put_format(string, "***unknown Nicira action:%d***",
210                       ntohs(nah->subtype));
211     }
212 }
213
214 static int
215 ofp_print_action(struct ds *string, const struct ofp_action_header *ah,
216         size_t actions_len)
217 {
218     uint16_t type;
219     size_t len;
220
221     struct openflow_action {
222         size_t min_size;
223         size_t max_size;
224     };
225
226     const struct openflow_action of_actions[] = {
227         [OFPAT_OUTPUT] = {
228             sizeof(struct ofp_action_output),
229             sizeof(struct ofp_action_output),
230         },
231         [OFPAT_SET_VLAN_VID] = {
232             sizeof(struct ofp_action_vlan_vid),
233             sizeof(struct ofp_action_vlan_vid),
234         },
235         [OFPAT_SET_VLAN_PCP] = {
236             sizeof(struct ofp_action_vlan_pcp),
237             sizeof(struct ofp_action_vlan_pcp),
238         },
239         [OFPAT_STRIP_VLAN] = {
240             sizeof(struct ofp_action_header),
241             sizeof(struct ofp_action_header),
242         },
243         [OFPAT_SET_DL_SRC] = {
244             sizeof(struct ofp_action_dl_addr),
245             sizeof(struct ofp_action_dl_addr),
246         },
247         [OFPAT_SET_DL_DST] = {
248             sizeof(struct ofp_action_dl_addr),
249             sizeof(struct ofp_action_dl_addr),
250         },
251         [OFPAT_SET_NW_SRC] = {
252             sizeof(struct ofp_action_nw_addr),
253             sizeof(struct ofp_action_nw_addr),
254         },
255         [OFPAT_SET_NW_DST] = {
256             sizeof(struct ofp_action_nw_addr),
257             sizeof(struct ofp_action_nw_addr),
258         },
259         [OFPAT_SET_NW_TOS] = {
260             sizeof(struct ofp_action_nw_tos),
261             sizeof(struct ofp_action_nw_tos),
262         },
263         [OFPAT_SET_TP_SRC] = {
264             sizeof(struct ofp_action_tp_port),
265             sizeof(struct ofp_action_tp_port),
266         },
267         [OFPAT_SET_TP_DST] = {
268             sizeof(struct ofp_action_tp_port),
269             sizeof(struct ofp_action_tp_port),
270         }
271         /* OFPAT_VENDOR is not here, since it would blow up the array size. */
272     };
273
274     if (actions_len < sizeof *ah) {
275         ds_put_format(string, "***action array too short for next action***\n");
276         return -1;
277     }
278
279     type = ntohs(ah->type);
280     len = ntohs(ah->len);
281     if (actions_len < len) {
282         ds_put_format(string, "***truncated action %"PRIu16"***\n", type);
283         return -1;
284     }
285
286     if ((len % 8) != 0) {
287         ds_put_format(string,
288                 "***action %"PRIu16" length not a multiple of 8***\n",
289                 type);
290         return -1;
291     }
292
293     if (type < ARRAY_SIZE(of_actions)) {
294         const struct openflow_action *act = &of_actions[type];
295         if ((len < act->min_size) || (len > act->max_size)) {
296             ds_put_format(string,
297                     "***action %"PRIu16" wrong length: %zu***\n", type, len);
298             return -1;
299         }
300     }
301
302     switch (type) {
303     case OFPAT_OUTPUT: {
304         struct ofp_action_output *oa = (struct ofp_action_output *)ah;
305         uint16_t port = ntohs(oa->port);
306         if (port < OFPP_MAX) {
307             ds_put_format(string, "output:%"PRIu16, port);
308         } else {
309             ofp_print_port_name(string, port);
310             if (port == OFPP_CONTROLLER) {
311                 if (oa->max_len) {
312                     ds_put_format(string, ":%"PRIu16, ntohs(oa->max_len));
313                 } else {
314                     ds_put_cstr(string, ":all");
315                 }
316             }
317         }
318         break;
319     }
320
321     case OFPAT_ENQUEUE: {
322         struct ofp_action_enqueue *ea = (struct ofp_action_enqueue *)ah;
323         unsigned int port = ntohs(ea->port);
324         unsigned int queue_id = ntohl(ea->queue_id);
325         ds_put_format(string, "enqueue:");
326         if (port != OFPP_IN_PORT) {
327             ds_put_format(string, "%u", port);
328         } else {
329             ds_put_cstr(string, "IN_PORT");
330         }
331         ds_put_format(string, "q%u", queue_id);
332         break;
333     }
334
335     case OFPAT_SET_VLAN_VID: {
336         struct ofp_action_vlan_vid *va = (struct ofp_action_vlan_vid *)ah;
337         ds_put_format(string, "mod_vlan_vid:%"PRIu16, ntohs(va->vlan_vid));
338         break;
339     }
340
341     case OFPAT_SET_VLAN_PCP: {
342         struct ofp_action_vlan_pcp *va = (struct ofp_action_vlan_pcp *)ah;
343         ds_put_format(string, "mod_vlan_pcp:%"PRIu8, va->vlan_pcp);
344         break;
345     }
346
347     case OFPAT_STRIP_VLAN:
348         ds_put_cstr(string, "strip_vlan");
349         break;
350
351     case OFPAT_SET_DL_SRC: {
352         struct ofp_action_dl_addr *da = (struct ofp_action_dl_addr *)ah;
353         ds_put_format(string, "mod_dl_src:"ETH_ADDR_FMT,
354                 ETH_ADDR_ARGS(da->dl_addr));
355         break;
356     }
357
358     case OFPAT_SET_DL_DST: {
359         struct ofp_action_dl_addr *da = (struct ofp_action_dl_addr *)ah;
360         ds_put_format(string, "mod_dl_dst:"ETH_ADDR_FMT,
361                 ETH_ADDR_ARGS(da->dl_addr));
362         break;
363     }
364
365     case OFPAT_SET_NW_SRC: {
366         struct ofp_action_nw_addr *na = (struct ofp_action_nw_addr *)ah;
367         ds_put_format(string, "mod_nw_src:"IP_FMT, IP_ARGS(&na->nw_addr));
368         break;
369     }
370
371     case OFPAT_SET_NW_DST: {
372         struct ofp_action_nw_addr *na = (struct ofp_action_nw_addr *)ah;
373         ds_put_format(string, "mod_nw_dst:"IP_FMT, IP_ARGS(&na->nw_addr));
374         break;
375     }
376
377     case OFPAT_SET_NW_TOS: {
378         struct ofp_action_nw_tos *nt = (struct ofp_action_nw_tos *)ah;
379         ds_put_format(string, "mod_nw_tos:%d", nt->nw_tos);
380         break;
381     }
382
383     case OFPAT_SET_TP_SRC: {
384         struct ofp_action_tp_port *ta = (struct ofp_action_tp_port *)ah;
385         ds_put_format(string, "mod_tp_src:%d", ntohs(ta->tp_port));
386         break;
387     }
388
389     case OFPAT_SET_TP_DST: {
390         struct ofp_action_tp_port *ta = (struct ofp_action_tp_port *)ah;
391         ds_put_format(string, "mod_tp_dst:%d", ntohs(ta->tp_port));
392         break;
393     }
394
395     case OFPAT_VENDOR: {
396         struct ofp_action_vendor_header *avh
397                 = (struct ofp_action_vendor_header *)ah;
398         if (len < sizeof *avh) {
399             ds_put_format(string, "***ofpat_vendor truncated***\n");
400             return -1;
401         }
402         if (avh->vendor == htonl(NX_VENDOR_ID)) {
403             ofp_print_nx_action(string, (struct nx_action_header *)avh);
404         } else {
405             ds_put_format(string, "vendor action:0x%x", ntohl(avh->vendor));
406         }
407         break;
408     }
409
410     default:
411         ds_put_format(string, "(decoder %"PRIu16" not implemented)", type);
412         break;
413     }
414
415     return len;
416 }
417
418 void
419 ofp_print_actions(struct ds *string, const struct ofp_action_header *action,
420                   size_t actions_len)
421 {
422     uint8_t *p = (uint8_t *)action;
423     int len = 0;
424
425     ds_put_cstr(string, "actions=");
426     if (!actions_len) {
427         ds_put_cstr(string, "drop");
428     }
429     while (actions_len > 0) {
430         if (len) {
431             ds_put_cstr(string, ",");
432         }
433         len = ofp_print_action(string, (struct ofp_action_header *)p,
434                 actions_len);
435         if (len < 0) {
436             return;
437         }
438         p += len;
439         actions_len -= len;
440     }
441 }
442
443 /* Pretty-print the OFPT_PACKET_OUT packet of 'len' bytes at 'oh' to 'string'
444  * at the given 'verbosity' level. */
445 static void ofp_packet_out(struct ds *string, const void *oh, size_t len,
446                            int verbosity)
447 {
448     const struct ofp_packet_out *opo = oh;
449     size_t actions_len = ntohs(opo->actions_len);
450
451     ds_put_cstr(string, " in_port=");
452     ofp_print_port_name(string, ntohs(opo->in_port));
453
454     ds_put_format(string, " actions_len=%zu ", actions_len);
455     if (actions_len > (ntohs(opo->header.length) - sizeof *opo)) {
456         ds_put_format(string, "***packet too short for action length***\n");
457         return;
458     }
459     ofp_print_actions(string, opo->actions, actions_len);
460
461     if (ntohl(opo->buffer_id) == UINT32_MAX) {
462         int data_len = len - sizeof *opo - actions_len;
463         ds_put_format(string, " data_len=%d", data_len);
464         if (verbosity > 0 && len > sizeof *opo) {
465             char *packet = ofp_packet_to_string(
466                     (uint8_t *)opo->actions + actions_len, data_len, data_len);
467             ds_put_char(string, '\n');
468             ds_put_cstr(string, packet);
469             free(packet);
470         }
471     } else {
472         ds_put_format(string, " buffer=0x%08"PRIx32, ntohl(opo->buffer_id));
473     }
474     ds_put_char(string, '\n');
475 }
476
477 /* qsort comparison function. */
478 static int
479 compare_ports(const void *a_, const void *b_)
480 {
481     const struct ofp_phy_port *a = a_;
482     const struct ofp_phy_port *b = b_;
483     uint16_t ap = ntohs(a->port_no);
484     uint16_t bp = ntohs(b->port_no);
485
486     return ap < bp ? -1 : ap > bp;
487 }
488
489 static void ofp_print_port_features(struct ds *string, uint32_t features)
490 {
491     if (features == 0) {
492         ds_put_cstr(string, "Unsupported\n");
493         return;
494     }
495     if (features & OFPPF_10MB_HD) {
496         ds_put_cstr(string, "10MB-HD ");
497     }
498     if (features & OFPPF_10MB_FD) {
499         ds_put_cstr(string, "10MB-FD ");
500     }
501     if (features & OFPPF_100MB_HD) {
502         ds_put_cstr(string, "100MB-HD ");
503     }
504     if (features & OFPPF_100MB_FD) {
505         ds_put_cstr(string, "100MB-FD ");
506     }
507     if (features & OFPPF_1GB_HD) {
508         ds_put_cstr(string, "1GB-HD ");
509     }
510     if (features & OFPPF_1GB_FD) {
511         ds_put_cstr(string, "1GB-FD ");
512     }
513     if (features & OFPPF_10GB_FD) {
514         ds_put_cstr(string, "10GB-FD ");
515     }
516     if (features & OFPPF_COPPER) {
517         ds_put_cstr(string, "COPPER ");
518     }
519     if (features & OFPPF_FIBER) {
520         ds_put_cstr(string, "FIBER ");
521     }
522     if (features & OFPPF_AUTONEG) {
523         ds_put_cstr(string, "AUTO_NEG ");
524     }
525     if (features & OFPPF_PAUSE) {
526         ds_put_cstr(string, "AUTO_PAUSE ");
527     }
528     if (features & OFPPF_PAUSE_ASYM) {
529         ds_put_cstr(string, "AUTO_PAUSE_ASYM ");
530     }
531     ds_put_char(string, '\n');
532 }
533
534 static void
535 ofp_print_phy_port(struct ds *string, const struct ofp_phy_port *port)
536 {
537     uint8_t name[OFP_MAX_PORT_NAME_LEN];
538     int j;
539
540     memcpy(name, port->name, sizeof name);
541     for (j = 0; j < sizeof name - 1; j++) {
542         if (!isprint(name[j])) {
543             break;
544         }
545     }
546     name[j] = '\0';
547
548     ds_put_char(string, ' ');
549     ofp_print_port_name(string, ntohs(port->port_no));
550     ds_put_format(string, "(%s): addr:"ETH_ADDR_FMT", config: %#x, state:%#x\n",
551             name, ETH_ADDR_ARGS(port->hw_addr), ntohl(port->config),
552             ntohl(port->state));
553     if (port->curr) {
554         ds_put_format(string, "     current:    ");
555         ofp_print_port_features(string, ntohl(port->curr));
556     }
557     if (port->advertised) {
558         ds_put_format(string, "     advertised: ");
559         ofp_print_port_features(string, ntohl(port->advertised));
560     }
561     if (port->supported) {
562         ds_put_format(string, "     supported:  ");
563         ofp_print_port_features(string, ntohl(port->supported));
564     }
565     if (port->peer) {
566         ds_put_format(string, "     peer:       ");
567         ofp_print_port_features(string, ntohl(port->peer));
568     }
569 }
570
571 /* Pretty-print the struct ofp_switch_features of 'len' bytes at 'oh' to
572  * 'string' at the given 'verbosity' level. */
573 static void
574 ofp_print_switch_features(struct ds *string, const void *oh, size_t len,
575                           int verbosity OVS_UNUSED)
576 {
577     const struct ofp_switch_features *osf = oh;
578     struct ofp_phy_port *port_list;
579     int n_ports;
580     int i;
581
582     ds_put_format(string, " ver:0x%x, dpid:%016"PRIx64"\n",
583             osf->header.version, ntohll(osf->datapath_id));
584     ds_put_format(string, "n_tables:%d, n_buffers:%d\n", osf->n_tables,
585             ntohl(osf->n_buffers));
586     ds_put_format(string, "features: capabilities:%#x, actions:%#x\n",
587            ntohl(osf->capabilities), ntohl(osf->actions));
588
589     if (ntohs(osf->header.length) >= sizeof *osf) {
590         len = MIN(len, ntohs(osf->header.length));
591     }
592     n_ports = (len - sizeof *osf) / sizeof *osf->ports;
593
594     port_list = xmemdup(osf->ports, len - sizeof *osf);
595     qsort(port_list, n_ports, sizeof *port_list, compare_ports);
596     for (i = 0; i < n_ports; i++) {
597         ofp_print_phy_port(string, &port_list[i]);
598     }
599     free(port_list);
600 }
601
602 /* Pretty-print the struct ofp_switch_config of 'len' bytes at 'oh' to 'string'
603  * at the given 'verbosity' level. */
604 static void
605 ofp_print_switch_config(struct ds *string, const void *oh,
606                         size_t len OVS_UNUSED, int verbosity OVS_UNUSED)
607 {
608     const struct ofp_switch_config *osc = oh;
609     uint16_t flags;
610
611     flags = ntohs(osc->flags);
612     if (flags) {
613         ds_put_format(string, " ***unknown flags 0x%04"PRIx16"***", flags);
614     }
615
616     ds_put_format(string, " miss_send_len=%"PRIu16"\n", ntohs(osc->miss_send_len));
617 }
618
619 static void print_wild(struct ds *string, const char *leader, int is_wild,
620             int verbosity, const char *format, ...)
621             __attribute__((format(printf, 5, 6)));
622
623 static void print_wild(struct ds *string, const char *leader, int is_wild,
624                        int verbosity, const char *format, ...)
625 {
626     if (is_wild && verbosity < 2) {
627         return;
628     }
629     ds_put_cstr(string, leader);
630     if (!is_wild) {
631         va_list args;
632
633         va_start(args, format);
634         ds_put_format_valist(string, format, args);
635         va_end(args);
636     } else {
637         ds_put_char(string, '*');
638     }
639     ds_put_char(string, ',');
640 }
641
642 static void
643 print_ip_netmask(struct ds *string, const char *leader, uint32_t ip,
644                  uint32_t wild_bits, int verbosity)
645 {
646     if (wild_bits >= 32 && verbosity < 2) {
647         return;
648     }
649     ds_put_cstr(string, leader);
650     if (wild_bits < 32) {
651         ds_put_format(string, IP_FMT, IP_ARGS(&ip));
652         if (wild_bits) {
653             ds_put_format(string, "/%d", 32 - wild_bits);
654         }
655     } else {
656         ds_put_char(string, '*');
657     }
658     ds_put_char(string, ',');
659 }
660
661 void
662 ofp_print_match(struct ds *f, const struct ofp_match *om, int verbosity)
663 {
664     char *s = ofp_match_to_string(om, verbosity);
665     ds_put_cstr(f, s);
666     free(s);
667 }
668
669 char *
670 ofp_match_to_string(const struct ofp_match *om, int verbosity)
671 {
672     struct ds f = DS_EMPTY_INITIALIZER;
673     uint32_t w = ntohl(om->wildcards);
674     bool skip_type = false;
675     bool skip_proto = false;
676
677     if (!(w & OFPFW_DL_TYPE)) {
678         skip_type = true;
679         if (om->dl_type == htons(ETH_TYPE_IP)) {
680             if (!(w & OFPFW_NW_PROTO)) {
681                 skip_proto = true;
682                 if (om->nw_proto == IP_TYPE_ICMP) {
683                     ds_put_cstr(&f, "icmp,");
684                 } else if (om->nw_proto == IP_TYPE_TCP) {
685                     ds_put_cstr(&f, "tcp,");
686                 } else if (om->nw_proto == IP_TYPE_UDP) {
687                     ds_put_cstr(&f, "udp,");
688                 } else {
689                     ds_put_cstr(&f, "ip,");
690                     skip_proto = false;
691                 }
692             } else {
693                 ds_put_cstr(&f, "ip,");
694             }
695         } else if (om->dl_type == htons(ETH_TYPE_ARP)) {
696             ds_put_cstr(&f, "arp,");
697         } else {
698             skip_type = false;
699         }
700     }
701     if (w & NXFW_TUN_ID) {
702         ds_put_cstr(&f, "tun_id_wild,");
703     }
704     print_wild(&f, "in_port=", w & OFPFW_IN_PORT, verbosity,
705                "%d", ntohs(om->in_port));
706     print_wild(&f, "dl_vlan=", w & OFPFW_DL_VLAN, verbosity,
707                "%d", ntohs(om->dl_vlan));
708     print_wild(&f, "dl_vlan_pcp=", w & OFPFW_DL_VLAN_PCP, verbosity,
709                "%d", om->dl_vlan_pcp);
710     print_wild(&f, "dl_src=", w & OFPFW_DL_SRC, verbosity,
711                ETH_ADDR_FMT, ETH_ADDR_ARGS(om->dl_src));
712     print_wild(&f, "dl_dst=", w & OFPFW_DL_DST, verbosity,
713                ETH_ADDR_FMT, ETH_ADDR_ARGS(om->dl_dst));
714     if (!skip_type) {
715         print_wild(&f, "dl_type=", w & OFPFW_DL_TYPE, verbosity,
716                    "0x%04x", ntohs(om->dl_type));
717     }
718     print_ip_netmask(&f, "nw_src=", om->nw_src,
719                      (w & OFPFW_NW_SRC_MASK) >> OFPFW_NW_SRC_SHIFT, verbosity);
720     print_ip_netmask(&f, "nw_dst=", om->nw_dst,
721                      (w & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT, verbosity);
722     if (!skip_proto) {
723         if (om->dl_type == htons(ETH_TYPE_ARP)) {
724             print_wild(&f, "opcode=", w & OFPFW_NW_PROTO, verbosity,
725                        "%u", om->nw_proto);
726         } else {
727             print_wild(&f, "nw_proto=", w & OFPFW_NW_PROTO, verbosity,
728                        "%u", om->nw_proto);
729             print_wild(&f, "nw_tos=", w & OFPFW_NW_TOS, verbosity,
730                        "%u", om->nw_tos);
731         }
732     }
733     if (om->nw_proto == IP_TYPE_ICMP) {
734         print_wild(&f, "icmp_type=", w & OFPFW_ICMP_TYPE, verbosity,
735                    "%d", ntohs(om->icmp_type));
736         print_wild(&f, "icmp_code=", w & OFPFW_ICMP_CODE, verbosity,
737                    "%d", ntohs(om->icmp_code));
738     } else {
739         print_wild(&f, "tp_src=", w & OFPFW_TP_SRC, verbosity,
740                    "%d", ntohs(om->tp_src));
741         print_wild(&f, "tp_dst=", w & OFPFW_TP_DST, verbosity,
742                    "%d", ntohs(om->tp_dst));
743     }
744     return ds_cstr(&f);
745 }
746
747 /* Pretty-print the OFPT_FLOW_MOD packet of 'len' bytes at 'oh' to 'string'
748  * at the given 'verbosity' level. */
749 static void
750 ofp_print_flow_mod(struct ds *string, const void *oh, size_t len,
751                    int verbosity)
752 {
753     const struct ofp_flow_mod *ofm = oh;
754
755     ofp_print_match(string, &ofm->match, verbosity);
756     switch (ntohs(ofm->command)) {
757     case OFPFC_ADD:
758         ds_put_cstr(string, " ADD: ");
759         break;
760     case OFPFC_MODIFY:
761         ds_put_cstr(string, " MOD: ");
762         break;
763     case OFPFC_MODIFY_STRICT:
764         ds_put_cstr(string, " MOD_STRICT: ");
765         break;
766     case OFPFC_DELETE:
767         ds_put_cstr(string, " DEL: ");
768         break;
769     case OFPFC_DELETE_STRICT:
770         ds_put_cstr(string, " DEL_STRICT: ");
771         break;
772     default:
773         ds_put_format(string, " cmd:%d ", ntohs(ofm->command));
774     }
775     ds_put_format(string, "cookie:0x%"PRIx64" idle:%d hard:%d pri:%d "
776             "buf:%#x flags:%"PRIx16" ", ntohll(ofm->cookie),
777             ntohs(ofm->idle_timeout), ntohs(ofm->hard_timeout),
778             ofm->match.wildcards ? ntohs(ofm->priority) : (uint16_t)-1,
779             ntohl(ofm->buffer_id), ntohs(ofm->flags));
780     ofp_print_actions(string, ofm->actions,
781                       len - offsetof(struct ofp_flow_mod, actions));
782     ds_put_char(string, '\n');
783 }
784
785 /* Pretty-print the OFPT_FLOW_REMOVED packet of 'len' bytes at 'oh' to 'string'
786  * at the given 'verbosity' level. */
787 static void
788 ofp_print_flow_removed(struct ds *string, const void *oh,
789                        size_t len OVS_UNUSED, int verbosity)
790 {
791     const struct ofp_flow_removed *ofr = oh;
792
793     ofp_print_match(string, &ofr->match, verbosity);
794     ds_put_cstr(string, " reason=");
795     switch (ofr->reason) {
796     case OFPRR_IDLE_TIMEOUT:
797         ds_put_cstr(string, "idle");
798         break;
799     case OFPRR_HARD_TIMEOUT:
800         ds_put_cstr(string, "hard");
801         break;
802     case OFPRR_DELETE:
803         ds_put_cstr(string, "delete");
804         break;
805     default:
806         ds_put_format(string, "**%"PRIu8"**", ofr->reason);
807         break;
808     }
809     ds_put_format(string,
810          " cookie0x%"PRIx64" pri%"PRIu16" secs%"PRIu32" nsecs%"PRIu32
811          " idle%"PRIu16" pkts%"PRIu64" bytes%"PRIu64"\n",
812          ntohll(ofr->cookie),
813          ofr->match.wildcards ? ntohs(ofr->priority) : (uint16_t)-1,
814          ntohl(ofr->duration_sec), ntohl(ofr->duration_nsec),
815          ntohs(ofr->idle_timeout), ntohll(ofr->packet_count),
816          ntohll(ofr->byte_count));
817 }
818
819 static void
820 ofp_print_port_mod(struct ds *string, const void *oh, size_t len OVS_UNUSED,
821                    int verbosity OVS_UNUSED)
822 {
823     const struct ofp_port_mod *opm = oh;
824
825     ds_put_format(string, "port: %d: addr:"ETH_ADDR_FMT", config: %#x, mask:%#x\n",
826             ntohs(opm->port_no), ETH_ADDR_ARGS(opm->hw_addr),
827             ntohl(opm->config), ntohl(opm->mask));
828     ds_put_format(string, "     advertise: ");
829     if (opm->advertise) {
830         ofp_print_port_features(string, ntohl(opm->advertise));
831     } else {
832         ds_put_format(string, "UNCHANGED\n");
833     }
834 }
835
836 struct error_type {
837     int type;
838     int code;
839     const char *name;
840 };
841
842 static const struct error_type error_types[] = {
843 #define ERROR_TYPE(TYPE) {TYPE, -1, #TYPE}
844 #define ERROR_CODE(TYPE, CODE) {TYPE, CODE, #CODE}
845     ERROR_TYPE(OFPET_HELLO_FAILED),
846     ERROR_CODE(OFPET_HELLO_FAILED, OFPHFC_INCOMPATIBLE),
847     ERROR_CODE(OFPET_HELLO_FAILED, OFPHFC_EPERM),
848
849     ERROR_TYPE(OFPET_BAD_REQUEST),
850     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION),
851     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE),
852     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BAD_STAT),
853     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BAD_VENDOR),
854     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BAD_SUBTYPE),
855     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_EPERM),
856     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN),
857     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BUFFER_EMPTY),
858     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BUFFER_UNKNOWN),
859
860     ERROR_TYPE(OFPET_BAD_ACTION),
861     ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_BAD_TYPE),
862     ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_BAD_LEN),
863     ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_BAD_VENDOR),
864     ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_BAD_VENDOR_TYPE),
865     ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_BAD_OUT_PORT),
866     ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_BAD_ARGUMENT),
867     ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_EPERM),
868     ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_TOO_MANY),
869
870     ERROR_TYPE(OFPET_FLOW_MOD_FAILED),
871     ERROR_CODE(OFPET_FLOW_MOD_FAILED, OFPFMFC_ALL_TABLES_FULL),
872     ERROR_CODE(OFPET_FLOW_MOD_FAILED, OFPFMFC_OVERLAP),
873     ERROR_CODE(OFPET_FLOW_MOD_FAILED, OFPFMFC_EPERM),
874     ERROR_CODE(OFPET_FLOW_MOD_FAILED, OFPFMFC_BAD_EMERG_TIMEOUT),
875     ERROR_CODE(OFPET_FLOW_MOD_FAILED, OFPFMFC_BAD_COMMAND),
876
877     ERROR_TYPE(OFPET_PORT_MOD_FAILED),
878     ERROR_CODE(OFPET_PORT_MOD_FAILED, OFPPMFC_BAD_PORT),
879     ERROR_CODE(OFPET_PORT_MOD_FAILED, OFPPMFC_BAD_HW_ADDR)
880 };
881 #define N_ERROR_TYPES ARRAY_SIZE(error_types)
882
883 static const char *
884 lookup_error_type(int type)
885 {
886     const struct error_type *t;
887
888     for (t = error_types; t < &error_types[N_ERROR_TYPES]; t++) {
889         if (t->type == type && t->code == -1) {
890             return t->name;
891         }
892     }
893     return "?";
894 }
895
896 static const char *
897 lookup_error_code(int type, int code)
898 {
899     const struct error_type *t;
900
901     for (t = error_types; t < &error_types[N_ERROR_TYPES]; t++) {
902         if (t->type == type && t->code == code) {
903             return t->name;
904         }
905     }
906     return "?";
907 }
908
909 /* Pretty-print the OFPT_ERROR packet of 'len' bytes at 'oh' to 'string'
910  * at the given 'verbosity' level. */
911 static void
912 ofp_print_error_msg(struct ds *string, const void *oh, size_t len,
913                        int verbosity OVS_UNUSED)
914 {
915     const struct ofp_error_msg *oem = oh;
916     int type = ntohs(oem->type);
917     int code = ntohs(oem->code);
918     char *s;
919
920     ds_put_format(string, " type%d(%s) code%d(%s) payload:\n",
921                   type, lookup_error_type(type),
922                   code, lookup_error_code(type, code));
923
924     switch (type) {
925     case OFPET_HELLO_FAILED:
926         ds_put_printable(string, (char *) oem->data, len - sizeof *oem);
927         break;
928
929     case OFPET_BAD_REQUEST:
930         s = ofp_to_string(oem->data, len - sizeof *oem, 1);
931         ds_put_cstr(string, s);
932         free(s);
933         break;
934
935     default:
936         ds_put_hex_dump(string, oem->data, len - sizeof *oem, 0, true);
937         break;
938     }
939 }
940
941 /* Pretty-print the OFPT_PORT_STATUS packet of 'len' bytes at 'oh' to 'string'
942  * at the given 'verbosity' level. */
943 static void
944 ofp_print_port_status(struct ds *string, const void *oh, size_t len OVS_UNUSED,
945                       int verbosity OVS_UNUSED)
946 {
947     const struct ofp_port_status *ops = oh;
948
949     if (ops->reason == OFPPR_ADD) {
950         ds_put_format(string, " ADD:");
951     } else if (ops->reason == OFPPR_DELETE) {
952         ds_put_format(string, " DEL:");
953     } else if (ops->reason == OFPPR_MODIFY) {
954         ds_put_format(string, " MOD:");
955     }
956
957     ofp_print_phy_port(string, &ops->desc);
958 }
959
960 static void
961 ofp_desc_stats_reply(struct ds *string, const void *body,
962                      size_t len OVS_UNUSED, int verbosity OVS_UNUSED)
963 {
964     const struct ofp_desc_stats *ods = body;
965
966     ds_put_format(string, "Manufacturer: %.*s\n",
967             (int) sizeof ods->mfr_desc, ods->mfr_desc);
968     ds_put_format(string, "Hardware: %.*s\n",
969             (int) sizeof ods->hw_desc, ods->hw_desc);
970     ds_put_format(string, "Software: %.*s\n",
971             (int) sizeof ods->sw_desc, ods->sw_desc);
972     ds_put_format(string, "Serial Num: %.*s\n",
973             (int) sizeof ods->serial_num, ods->serial_num);
974     ds_put_format(string, "DP Description: %.*s\n",
975             (int) sizeof ods->dp_desc, ods->dp_desc);
976 }
977
978 static void
979 ofp_flow_stats_request(struct ds *string, const void *oh,
980                        size_t len OVS_UNUSED, int verbosity)
981 {
982     const struct ofp_flow_stats_request *fsr = oh;
983
984     if (fsr->table_id == 0xff) {
985         ds_put_format(string, " table_id=any, ");
986     } else {
987         ds_put_format(string, " table_id=%"PRIu8", ", fsr->table_id);
988     }
989
990     ofp_print_match(string, &fsr->match, verbosity);
991 }
992
993 static void
994 ofp_flow_stats_reply(struct ds *string, const void *body_, size_t len,
995                      int verbosity)
996 {
997     const char *body = body_;
998     const char *pos = body;
999     for (;;) {
1000         const struct ofp_flow_stats *fs;
1001         ptrdiff_t bytes_left = body + len - pos;
1002         size_t length;
1003
1004         if (bytes_left < sizeof *fs) {
1005             if (bytes_left != 0) {
1006                 ds_put_format(string, " ***%td leftover bytes at end***",
1007                               bytes_left);
1008             }
1009             break;
1010         }
1011
1012         fs = (const void *) pos;
1013         length = ntohs(fs->length);
1014         if (length < sizeof *fs) {
1015             ds_put_format(string, " ***length=%zu shorter than minimum %zu***",
1016                           length, sizeof *fs);
1017             break;
1018         } else if (length > bytes_left) {
1019             ds_put_format(string,
1020                           " ***length=%zu but only %td bytes left***",
1021                           length, bytes_left);
1022             break;
1023         } else if ((length - sizeof *fs) % sizeof fs->actions[0]) {
1024             ds_put_format(string,
1025                           " ***length=%zu has %zu bytes leftover in "
1026                           "final action***",
1027                           length,
1028                           (length - sizeof *fs) % sizeof fs->actions[0]);
1029             break;
1030         }
1031
1032         ds_put_format(string, "  cookie=0x%"PRIx64", ", ntohll(fs->cookie));
1033         ds_put_format(string, "duration_sec=%"PRIu32"s, ",
1034                     ntohl(fs->duration_sec));
1035         ds_put_format(string, "duration_nsec=%"PRIu32"ns, ",
1036                     ntohl(fs->duration_nsec));
1037         ds_put_format(string, "table_id=%"PRIu8", ", fs->table_id);
1038         ds_put_format(string, "priority=%"PRIu16", ",
1039                     fs->match.wildcards ? ntohs(fs->priority) : (uint16_t)-1);
1040         ds_put_format(string, "n_packets=%"PRIu64", ",
1041                     ntohll(fs->packet_count));
1042         ds_put_format(string, "n_bytes=%"PRIu64", ", ntohll(fs->byte_count));
1043         if (fs->idle_timeout != htons(OFP_FLOW_PERMANENT)) {
1044             ds_put_format(string, "idle_timeout=%"PRIu16",",
1045                           ntohs(fs->idle_timeout));
1046         }
1047         if (fs->hard_timeout != htons(OFP_FLOW_PERMANENT)) {
1048             ds_put_format(string, "hard_timeout=%"PRIu16",",
1049                           ntohs(fs->hard_timeout));
1050         }
1051         ofp_print_match(string, &fs->match, verbosity);
1052         ofp_print_actions(string, fs->actions, length - sizeof *fs);
1053         ds_put_char(string, '\n');
1054
1055         pos += length;
1056      }
1057 }
1058
1059 static void
1060 ofp_aggregate_stats_request(struct ds *string, const void *oh,
1061                             size_t len OVS_UNUSED, int verbosity)
1062 {
1063     const struct ofp_aggregate_stats_request *asr = oh;
1064
1065     if (asr->table_id == 0xff) {
1066         ds_put_format(string, " table_id=any, ");
1067     } else {
1068         ds_put_format(string, " table_id=%"PRIu8", ", asr->table_id);
1069     }
1070
1071     ofp_print_match(string, &asr->match, verbosity);
1072 }
1073
1074 static void
1075 ofp_aggregate_stats_reply(struct ds *string, const void *body_,
1076                           size_t len OVS_UNUSED, int verbosity OVS_UNUSED)
1077 {
1078     const struct ofp_aggregate_stats_reply *asr = body_;
1079
1080     ds_put_format(string, " packet_count=%"PRIu64, ntohll(asr->packet_count));
1081     ds_put_format(string, " byte_count=%"PRIu64, ntohll(asr->byte_count));
1082     ds_put_format(string, " flow_count=%"PRIu32, ntohl(asr->flow_count));
1083 }
1084
1085 static void print_port_stat(struct ds *string, const char *leader,
1086                             uint64_t stat, int more)
1087 {
1088     ds_put_cstr(string, leader);
1089     if (stat != -1) {
1090         ds_put_format(string, "%"PRIu64, stat);
1091     } else {
1092         ds_put_char(string, '?');
1093     }
1094     if (more) {
1095         ds_put_cstr(string, ", ");
1096     } else {
1097         ds_put_cstr(string, "\n");
1098     }
1099 }
1100
1101 static void
1102 ofp_port_stats_request(struct ds *string, const void *body_,
1103                        size_t len OVS_UNUSED, int verbosity OVS_UNUSED)
1104 {
1105     const struct ofp_port_stats_request *psr = body_;
1106     ds_put_format(string, "port_no=%"PRIu16, ntohs(psr->port_no));
1107 }
1108
1109 static void
1110 ofp_port_stats_reply(struct ds *string, const void *body, size_t len,
1111                      int verbosity)
1112 {
1113     const struct ofp_port_stats *ps = body;
1114     size_t n = len / sizeof *ps;
1115     ds_put_format(string, " %zu ports\n", n);
1116     if (verbosity < 1) {
1117         return;
1118     }
1119
1120     for (; n--; ps++) {
1121         ds_put_format(string, "  port %2"PRIu16": ", ntohs(ps->port_no));
1122
1123         ds_put_cstr(string, "rx ");
1124         print_port_stat(string, "pkts=", ntohll(ps->rx_packets), 1);
1125         print_port_stat(string, "bytes=", ntohll(ps->rx_bytes), 1);
1126         print_port_stat(string, "drop=", ntohll(ps->rx_dropped), 1);
1127         print_port_stat(string, "errs=", ntohll(ps->rx_errors), 1);
1128         print_port_stat(string, "frame=", ntohll(ps->rx_frame_err), 1);
1129         print_port_stat(string, "over=", ntohll(ps->rx_over_err), 1);
1130         print_port_stat(string, "crc=", ntohll(ps->rx_crc_err), 0);
1131
1132         ds_put_cstr(string, "           tx ");
1133         print_port_stat(string, "pkts=", ntohll(ps->tx_packets), 1);
1134         print_port_stat(string, "bytes=", ntohll(ps->tx_bytes), 1);
1135         print_port_stat(string, "drop=", ntohll(ps->tx_dropped), 1);
1136         print_port_stat(string, "errs=", ntohll(ps->tx_errors), 1);
1137         print_port_stat(string, "coll=", ntohll(ps->collisions), 0);
1138     }
1139 }
1140
1141 static void
1142 ofp_table_stats_reply(struct ds *string, const void *body, size_t len,
1143                      int verbosity)
1144 {
1145     const struct ofp_table_stats *ts = body;
1146     size_t n = len / sizeof *ts;
1147     ds_put_format(string, " %zu tables\n", n);
1148     if (verbosity < 1) {
1149         return;
1150     }
1151
1152     for (; n--; ts++) {
1153         char name[OFP_MAX_TABLE_NAME_LEN + 1];
1154         strncpy(name, ts->name, sizeof name);
1155         name[OFP_MAX_TABLE_NAME_LEN] = '\0';
1156
1157         ds_put_format(string, "  %d: %-8s: ", ts->table_id, name);
1158         ds_put_format(string, "wild=0x%05"PRIx32", ", ntohl(ts->wildcards));
1159         ds_put_format(string, "max=%6"PRIu32", ", ntohl(ts->max_entries));
1160         ds_put_format(string, "active=%"PRIu32"\n", ntohl(ts->active_count));
1161         ds_put_cstr(string, "               ");
1162         ds_put_format(string, "lookup=%"PRIu64", ",
1163                     ntohll(ts->lookup_count));
1164         ds_put_format(string, "matched=%"PRIu64"\n",
1165                     ntohll(ts->matched_count));
1166      }
1167 }
1168
1169 static void
1170 ofp_print_queue_name(struct ds *string, uint32_t queue_id)
1171 {
1172     if (queue_id == OFPQ_ALL) {
1173         ds_put_cstr(string, "ALL");
1174     } else {
1175         ds_put_format(string, "%"PRIu32, queue_id);
1176     }
1177 }
1178
1179 static void
1180 ofp_queue_stats_request(struct ds *string, const void *body_,
1181                        size_t len OVS_UNUSED, int verbosity OVS_UNUSED)
1182 {
1183     const struct ofp_queue_stats_request *qsr = body_;
1184
1185     ds_put_cstr(string, "port=");
1186     ofp_print_port_name(string, ntohs(qsr->port_no));
1187
1188     ds_put_cstr(string, " queue=");
1189     ofp_print_queue_name(string, ntohl(qsr->queue_id));
1190 }
1191
1192 static void
1193 ofp_queue_stats_reply(struct ds *string, const void *body, size_t len,
1194                      int verbosity)
1195 {
1196     const struct ofp_queue_stats *qs = body;
1197     size_t n = len / sizeof *qs;
1198     ds_put_format(string, " %zu queues\n", n);
1199     if (verbosity < 1) {
1200         return;
1201     }
1202
1203     for (; n--; qs++) {
1204         ds_put_cstr(string, "  port ");
1205         ofp_print_port_name(string, ntohs(qs->port_no));
1206         ds_put_cstr(string, " queue ");
1207         ofp_print_queue_name(string, ntohl(qs->queue_id));
1208         ds_put_cstr(string, ": ");
1209
1210         print_port_stat(string, "bytes=", ntohll(qs->tx_bytes), 1);
1211         print_port_stat(string, "pkts=", ntohll(qs->tx_packets), 1);
1212         print_port_stat(string, "errors=", ntohll(qs->tx_errors), 0);
1213     }
1214 }
1215
1216 static void
1217 vendor_stat(struct ds *string, const void *body, size_t len,
1218             int verbosity OVS_UNUSED)
1219 {
1220     ds_put_format(string, " vendor=%08"PRIx32, ntohl(*(uint32_t *) body));
1221     ds_put_format(string, " %zu bytes additional data",
1222                   len - sizeof(uint32_t));
1223 }
1224
1225 enum stats_direction {
1226     REQUEST,
1227     REPLY
1228 };
1229
1230 static void
1231 print_stats(struct ds *string, int type, const void *body, size_t body_len,
1232             int verbosity, enum stats_direction direction)
1233 {
1234     struct stats_msg {
1235         size_t min_body, max_body;
1236         void (*printer)(struct ds *, const void *, size_t len, int verbosity);
1237     };
1238
1239     struct stats_type {
1240         int type;
1241         const char *name;
1242         struct stats_msg request;
1243         struct stats_msg reply;
1244     };
1245
1246     static const struct stats_type stats_types[] = {
1247         {
1248             OFPST_DESC,
1249             "description",
1250             { 0, 0, NULL },
1251             { 0, SIZE_MAX, ofp_desc_stats_reply },
1252         },
1253         {
1254             OFPST_FLOW,
1255             "flow",
1256             { sizeof(struct ofp_flow_stats_request),
1257               sizeof(struct ofp_flow_stats_request),
1258               ofp_flow_stats_request },
1259             { 0, SIZE_MAX, ofp_flow_stats_reply },
1260         },
1261         {
1262             OFPST_AGGREGATE,
1263             "aggregate",
1264             { sizeof(struct ofp_aggregate_stats_request),
1265               sizeof(struct ofp_aggregate_stats_request),
1266               ofp_aggregate_stats_request },
1267             { sizeof(struct ofp_aggregate_stats_reply),
1268               sizeof(struct ofp_aggregate_stats_reply),
1269               ofp_aggregate_stats_reply },
1270         },
1271         {
1272             OFPST_TABLE,
1273             "table",
1274             { 0, 0, NULL },
1275             { 0, SIZE_MAX, ofp_table_stats_reply },
1276         },
1277         {
1278             OFPST_PORT,
1279             "port",
1280             { sizeof(struct ofp_port_stats_request),
1281               sizeof(struct ofp_port_stats_request),
1282               ofp_port_stats_request },
1283             { 0, SIZE_MAX, ofp_port_stats_reply },
1284         },
1285         {
1286             OFPST_QUEUE,
1287             "queue",
1288             { sizeof(struct ofp_queue_stats_request),
1289               sizeof(struct ofp_queue_stats_request),
1290               ofp_queue_stats_request },
1291             { 0, SIZE_MAX, ofp_queue_stats_reply },
1292         },
1293         {
1294             OFPST_VENDOR,
1295             "vendor-specific",
1296             { sizeof(uint32_t), SIZE_MAX, vendor_stat },
1297             { sizeof(uint32_t), SIZE_MAX, vendor_stat },
1298         },
1299         {
1300             -1,
1301             "unknown",
1302             { 0, 0, NULL, },
1303             { 0, 0, NULL, },
1304         },
1305     };
1306
1307     const struct stats_type *s;
1308     const struct stats_msg *m;
1309
1310     if (type >= ARRAY_SIZE(stats_types) || !stats_types[type].name) {
1311         ds_put_format(string, " ***unknown type %d***", type);
1312         return;
1313     }
1314     for (s = stats_types; s->type >= 0; s++) {
1315         if (s->type == type) {
1316             break;
1317         }
1318     }
1319     ds_put_format(string, " type=%d(%s)\n", type, s->name);
1320
1321     m = direction == REQUEST ? &s->request : &s->reply;
1322     if (body_len < m->min_body || body_len > m->max_body) {
1323         ds_put_format(string, " ***body_len=%zu not in %zu...%zu***",
1324                       body_len, m->min_body, m->max_body);
1325         return;
1326     }
1327     if (m->printer) {
1328         m->printer(string, body, body_len, verbosity);
1329     }
1330 }
1331
1332 static void
1333 ofp_stats_request(struct ds *string, const void *oh, size_t len, int verbosity)
1334 {
1335     const struct ofp_stats_request *srq = oh;
1336
1337     if (srq->flags) {
1338         ds_put_format(string, " ***unknown flags 0x%04"PRIx16"***",
1339                       ntohs(srq->flags));
1340     }
1341
1342     print_stats(string, ntohs(srq->type), srq->body,
1343                 len - offsetof(struct ofp_stats_request, body),
1344                 verbosity, REQUEST);
1345 }
1346
1347 static void
1348 ofp_stats_reply(struct ds *string, const void *oh, size_t len, int verbosity)
1349 {
1350     const struct ofp_stats_reply *srp = oh;
1351
1352     ds_put_cstr(string, " flags=");
1353     if (!srp->flags) {
1354         ds_put_cstr(string, "none");
1355     } else {
1356         uint16_t flags = ntohs(srp->flags);
1357         if (flags & OFPSF_REPLY_MORE) {
1358             ds_put_cstr(string, "[more]");
1359             flags &= ~OFPSF_REPLY_MORE;
1360         }
1361         if (flags) {
1362             ds_put_format(string, "[***unknown flags 0x%04"PRIx16"***]", flags);
1363         }
1364     }
1365
1366     print_stats(string, ntohs(srp->type), srp->body,
1367                 len - offsetof(struct ofp_stats_reply, body),
1368                 verbosity, REPLY);
1369 }
1370
1371 static void
1372 ofp_echo(struct ds *string, const void *oh, size_t len, int verbosity)
1373 {
1374     const struct ofp_header *hdr = oh;
1375
1376     ds_put_format(string, " %zu bytes of payload\n", len - sizeof *hdr);
1377     if (verbosity > 1) {
1378         ds_put_hex_dump(string, hdr, len - sizeof *hdr, 0, true);
1379     }
1380 }
1381
1382 struct openflow_packet {
1383     uint8_t type;
1384     const char *name;
1385     size_t min_size;
1386     void (*printer)(struct ds *, const void *, size_t len, int verbosity);
1387 };
1388
1389 static const struct openflow_packet packets[] = {
1390     {
1391         OFPT_HELLO,
1392         "hello",
1393         sizeof (struct ofp_header),
1394         NULL,
1395     },
1396     {
1397         OFPT_FEATURES_REQUEST,
1398         "features_request",
1399         sizeof (struct ofp_header),
1400         NULL,
1401     },
1402     {
1403         OFPT_FEATURES_REPLY,
1404         "features_reply",
1405         sizeof (struct ofp_switch_features),
1406         ofp_print_switch_features,
1407     },
1408     {
1409         OFPT_GET_CONFIG_REQUEST,
1410         "get_config_request",
1411         sizeof (struct ofp_header),
1412         NULL,
1413     },
1414     {
1415         OFPT_GET_CONFIG_REPLY,
1416         "get_config_reply",
1417         sizeof (struct ofp_switch_config),
1418         ofp_print_switch_config,
1419     },
1420     {
1421         OFPT_SET_CONFIG,
1422         "set_config",
1423         sizeof (struct ofp_switch_config),
1424         ofp_print_switch_config,
1425     },
1426     {
1427         OFPT_PACKET_IN,
1428         "packet_in",
1429         offsetof(struct ofp_packet_in, data),
1430         ofp_packet_in,
1431     },
1432     {
1433         OFPT_PACKET_OUT,
1434         "packet_out",
1435         sizeof (struct ofp_packet_out),
1436         ofp_packet_out,
1437     },
1438     {
1439         OFPT_FLOW_MOD,
1440         "flow_mod",
1441         sizeof (struct ofp_flow_mod),
1442         ofp_print_flow_mod,
1443     },
1444     {
1445         OFPT_FLOW_REMOVED,
1446         "flow_removed",
1447         sizeof (struct ofp_flow_removed),
1448         ofp_print_flow_removed,
1449     },
1450     {
1451         OFPT_PORT_MOD,
1452         "port_mod",
1453         sizeof (struct ofp_port_mod),
1454         ofp_print_port_mod,
1455     },
1456     {
1457         OFPT_PORT_STATUS,
1458         "port_status",
1459         sizeof (struct ofp_port_status),
1460         ofp_print_port_status
1461     },
1462     {
1463         OFPT_ERROR,
1464         "error_msg",
1465         sizeof (struct ofp_error_msg),
1466         ofp_print_error_msg,
1467     },
1468     {
1469         OFPT_STATS_REQUEST,
1470         "stats_request",
1471         sizeof (struct ofp_stats_request),
1472         ofp_stats_request,
1473     },
1474     {
1475         OFPT_STATS_REPLY,
1476         "stats_reply",
1477         sizeof (struct ofp_stats_reply),
1478         ofp_stats_reply,
1479     },
1480     {
1481         OFPT_ECHO_REQUEST,
1482         "echo_request",
1483         sizeof (struct ofp_header),
1484         ofp_echo,
1485     },
1486     {
1487         OFPT_ECHO_REPLY,
1488         "echo_reply",
1489         sizeof (struct ofp_header),
1490         ofp_echo,
1491     },
1492     {
1493         OFPT_VENDOR,
1494         "vendor",
1495         sizeof (struct ofp_vendor_header),
1496         NULL,
1497     },
1498     {
1499         OFPT_BARRIER_REQUEST,
1500         "barrier_request",
1501         sizeof (struct ofp_header),
1502         NULL,
1503     },
1504     {
1505         OFPT_BARRIER_REPLY,
1506         "barrier_reply",
1507         sizeof (struct ofp_header),
1508         NULL,
1509     }
1510 };
1511
1512 /* Composes and returns a string representing the OpenFlow packet of 'len'
1513  * bytes at 'oh' at the given 'verbosity' level.  0 is a minimal amount of
1514  * verbosity and higher numbers increase verbosity.  The caller is responsible
1515  * for freeing the string. */
1516 char *
1517 ofp_to_string(const void *oh_, size_t len, int verbosity)
1518 {
1519     struct ds string = DS_EMPTY_INITIALIZER;
1520     const struct ofp_header *oh = oh_;
1521     const struct openflow_packet *pkt;
1522
1523     if (len < sizeof(struct ofp_header)) {
1524         ds_put_cstr(&string, "OpenFlow packet too short:\n");
1525         ds_put_hex_dump(&string, oh, len, 0, true);
1526         return ds_cstr(&string);
1527     } else if (oh->version != OFP_VERSION) {
1528         ds_put_format(&string, "Bad OpenFlow version %"PRIu8":\n", oh->version);
1529         ds_put_hex_dump(&string, oh, len, 0, true);
1530         return ds_cstr(&string);
1531     }
1532
1533     for (pkt = packets; ; pkt++) {
1534         if (pkt >= &packets[ARRAY_SIZE(packets)]) {
1535             ds_put_format(&string, "Unknown OpenFlow packet type %"PRIu8":\n",
1536                           oh->type);
1537             ds_put_hex_dump(&string, oh, len, 0, true);
1538             return ds_cstr(&string);
1539         } else if (oh->type == pkt->type) {
1540             break;
1541         }
1542     }
1543
1544     ds_put_format(&string, "%s (xid=0x%"PRIx32"):", pkt->name, oh->xid);
1545
1546     if (ntohs(oh->length) > len)
1547         ds_put_format(&string, " (***truncated to %zu bytes from %"PRIu16"***)",
1548                 len, ntohs(oh->length));
1549     else if (ntohs(oh->length) < len) {
1550         ds_put_format(&string, " (***only uses %"PRIu16" bytes out of %zu***)\n",
1551                 ntohs(oh->length), len);
1552         len = ntohs(oh->length);
1553     }
1554
1555     if (len < pkt->min_size) {
1556         ds_put_format(&string, " (***length=%zu < min_size=%zu***)\n",
1557                 len, pkt->min_size);
1558     } else if (!pkt->printer) {
1559         if (len > sizeof *oh) {
1560             ds_put_format(&string, " length=%"PRIu16" (decoder not implemented)\n",
1561                           ntohs(oh->length));
1562         }
1563     } else {
1564         pkt->printer(&string, oh, len, verbosity);
1565     }
1566     if (verbosity >= 3) {
1567         ds_put_hex_dump(&string, oh, len, 0, true);
1568     }
1569     if (string.string[string.length - 1] != '\n') {
1570         ds_put_char(&string, '\n');
1571     }
1572     return ds_cstr(&string);
1573 }
1574
1575 /* Returns the name for the specified OpenFlow message type as a string,
1576  * e.g. "OFPT_FEATURES_REPLY".  If no name is known, the string returned is a
1577  * hex number, e.g. "0x55".
1578  *
1579  * The caller must free the returned string when it is no longer needed. */
1580 char *
1581 ofp_message_type_to_string(uint8_t type)
1582 {
1583     struct ds s = DS_EMPTY_INITIALIZER;
1584     const struct openflow_packet *pkt;
1585     for (pkt = packets; ; pkt++) {
1586         if (pkt >= &packets[ARRAY_SIZE(packets)]) {
1587             ds_put_format(&s, "0x%02"PRIx8, type);
1588             break;
1589         } else if (type == pkt->type) {
1590             const char *p;
1591
1592             ds_put_cstr(&s, "OFPT_");
1593             for (p = pkt->name; *p; p++) {
1594                 ds_put_char(&s, toupper((unsigned char) *p));
1595             }
1596             break;
1597         }
1598     }
1599     return ds_cstr(&s);
1600 }
1601 \f
1602 static void
1603 print_and_free(FILE *stream, char *string)
1604 {
1605     fputs(string, stream);
1606     free(string);
1607 }
1608
1609 /* Pretty-print the OpenFlow packet of 'len' bytes at 'oh' to 'stream' at the
1610  * given 'verbosity' level.  0 is a minimal amount of verbosity and higher
1611  * numbers increase verbosity. */
1612 void
1613 ofp_print(FILE *stream, const void *oh, size_t len, int verbosity)
1614 {
1615     print_and_free(stream, ofp_to_string(oh, len, verbosity));
1616 }
1617
1618 /* Dumps the contents of the Ethernet frame in the 'len' bytes starting at
1619  * 'data' to 'stream' using tcpdump.  'total_len' specifies the full length of
1620  * the Ethernet frame (of which 'len' bytes were captured).
1621  *
1622  * This starts and kills a tcpdump subprocess so it's quite expensive. */
1623 void
1624 ofp_print_packet(FILE *stream, const void *data, size_t len, size_t total_len)
1625 {
1626     print_and_free(stream, ofp_packet_to_string(data, len, total_len));
1627 }