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