netflow: Do 64-bit division less often.
[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     ds_put_char(string, ' ');
756     ofp_print_match(string, &ofm->match, verbosity);
757     if (ds_last(string) != ' ') {
758         ds_put_char(string, ' ');
759     }
760
761     switch (ntohs(ofm->command)) {
762     case OFPFC_ADD:
763         ds_put_cstr(string, "ADD:");
764         break;
765     case OFPFC_MODIFY:
766         ds_put_cstr(string, "MOD:");
767         break;
768     case OFPFC_MODIFY_STRICT:
769         ds_put_cstr(string, "MOD_STRICT:");
770         break;
771     case OFPFC_DELETE:
772         ds_put_cstr(string, "DEL:");
773         break;
774     case OFPFC_DELETE_STRICT:
775         ds_put_cstr(string, "DEL_STRICT:");
776         break;
777     default:
778         ds_put_format(string, "cmd:%d", ntohs(ofm->command));
779     }
780     if (ofm->cookie != htonll(0)) {
781         ds_put_format(string, " cookie:0x%"PRIx64, ntohll(ofm->cookie));
782     }
783     if (ofm->idle_timeout != htons(OFP_FLOW_PERMANENT)) {
784         ds_put_format(string, " idle:%d", ntohs(ofm->idle_timeout));
785     }
786     if (ofm->hard_timeout != htons(OFP_FLOW_PERMANENT)) {
787         ds_put_format(string, " hard:%d", ntohs(ofm->hard_timeout));
788     }
789     if (ofm->priority != htons(32768)) {
790         ds_put_format(string, " pri:%"PRIu16, ntohs(ofm->priority));
791     }
792     if (ofm->buffer_id != htonl(UINT32_MAX)) {
793         ds_put_format(string, " buf:%#"PRIx32, ntohl(ofm->buffer_id));
794     }
795     if (ofm->flags != htons(0)) {
796         ds_put_format(string, " flags:%"PRIx16, ntohs(ofm->flags));
797     }
798     ds_put_cstr(string, " ");
799     ofp_print_actions(string, ofm->actions,
800                       len - offsetof(struct ofp_flow_mod, actions));
801     ds_put_char(string, '\n');
802 }
803
804 /* Pretty-print the OFPT_FLOW_REMOVED packet of 'len' bytes at 'oh' to 'string'
805  * at the given 'verbosity' level. */
806 static void
807 ofp_print_flow_removed(struct ds *string, const void *oh,
808                        size_t len OVS_UNUSED, int verbosity)
809 {
810     const struct ofp_flow_removed *ofr = oh;
811
812     ofp_print_match(string, &ofr->match, verbosity);
813     ds_put_cstr(string, " reason=");
814     switch (ofr->reason) {
815     case OFPRR_IDLE_TIMEOUT:
816         ds_put_cstr(string, "idle");
817         break;
818     case OFPRR_HARD_TIMEOUT:
819         ds_put_cstr(string, "hard");
820         break;
821     case OFPRR_DELETE:
822         ds_put_cstr(string, "delete");
823         break;
824     default:
825         ds_put_format(string, "**%"PRIu8"**", ofr->reason);
826         break;
827     }
828
829     if (ofr->cookie != htonll(0)) {
830         ds_put_format(string, " cookie:0x%"PRIx64, ntohll(ofr->cookie));
831     }
832     if (ofr->priority != htons(32768)) {
833         ds_put_format(string, " pri:%"PRIu16, ntohs(ofr->priority));
834     }
835     ds_put_format(string, " secs%"PRIu32" nsecs%"PRIu32
836          " idle%"PRIu16" pkts%"PRIu64" bytes%"PRIu64"\n",
837          ntohl(ofr->duration_sec), ntohl(ofr->duration_nsec),
838          ntohs(ofr->idle_timeout), ntohll(ofr->packet_count),
839          ntohll(ofr->byte_count));
840 }
841
842 static void
843 ofp_print_port_mod(struct ds *string, const void *oh, size_t len OVS_UNUSED,
844                    int verbosity OVS_UNUSED)
845 {
846     const struct ofp_port_mod *opm = oh;
847
848     ds_put_format(string, "port: %d: addr:"ETH_ADDR_FMT", config: %#x, mask:%#x\n",
849             ntohs(opm->port_no), ETH_ADDR_ARGS(opm->hw_addr),
850             ntohl(opm->config), ntohl(opm->mask));
851     ds_put_format(string, "     advertise: ");
852     if (opm->advertise) {
853         ofp_print_port_features(string, ntohl(opm->advertise));
854     } else {
855         ds_put_format(string, "UNCHANGED\n");
856     }
857 }
858
859 struct error_type {
860     int type;
861     int code;
862     const char *name;
863 };
864
865 static const struct error_type error_types[] = {
866 #define ERROR_TYPE(TYPE) {TYPE, -1, #TYPE}
867 #define ERROR_CODE(TYPE, CODE) {TYPE, CODE, #CODE}
868     ERROR_TYPE(OFPET_HELLO_FAILED),
869     ERROR_CODE(OFPET_HELLO_FAILED, OFPHFC_INCOMPATIBLE),
870     ERROR_CODE(OFPET_HELLO_FAILED, OFPHFC_EPERM),
871
872     ERROR_TYPE(OFPET_BAD_REQUEST),
873     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BAD_VERSION),
874     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BAD_TYPE),
875     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BAD_STAT),
876     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BAD_VENDOR),
877     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BAD_SUBTYPE),
878     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_EPERM),
879     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN),
880     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BUFFER_EMPTY),
881     ERROR_CODE(OFPET_BAD_REQUEST, OFPBRC_BUFFER_UNKNOWN),
882
883     ERROR_TYPE(OFPET_BAD_ACTION),
884     ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_BAD_TYPE),
885     ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_BAD_LEN),
886     ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_BAD_VENDOR),
887     ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_BAD_VENDOR_TYPE),
888     ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_BAD_OUT_PORT),
889     ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_BAD_ARGUMENT),
890     ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_EPERM),
891     ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_TOO_MANY),
892
893     ERROR_TYPE(OFPET_FLOW_MOD_FAILED),
894     ERROR_CODE(OFPET_FLOW_MOD_FAILED, OFPFMFC_ALL_TABLES_FULL),
895     ERROR_CODE(OFPET_FLOW_MOD_FAILED, OFPFMFC_OVERLAP),
896     ERROR_CODE(OFPET_FLOW_MOD_FAILED, OFPFMFC_EPERM),
897     ERROR_CODE(OFPET_FLOW_MOD_FAILED, OFPFMFC_BAD_EMERG_TIMEOUT),
898     ERROR_CODE(OFPET_FLOW_MOD_FAILED, OFPFMFC_BAD_COMMAND),
899
900     ERROR_TYPE(OFPET_PORT_MOD_FAILED),
901     ERROR_CODE(OFPET_PORT_MOD_FAILED, OFPPMFC_BAD_PORT),
902     ERROR_CODE(OFPET_PORT_MOD_FAILED, OFPPMFC_BAD_HW_ADDR)
903 };
904 #define N_ERROR_TYPES ARRAY_SIZE(error_types)
905
906 static const char *
907 lookup_error_type(int type)
908 {
909     const struct error_type *t;
910
911     for (t = error_types; t < &error_types[N_ERROR_TYPES]; t++) {
912         if (t->type == type && t->code == -1) {
913             return t->name;
914         }
915     }
916     return "?";
917 }
918
919 static const char *
920 lookup_error_code(int type, int code)
921 {
922     const struct error_type *t;
923
924     for (t = error_types; t < &error_types[N_ERROR_TYPES]; t++) {
925         if (t->type == type && t->code == code) {
926             return t->name;
927         }
928     }
929     return "?";
930 }
931
932 /* Pretty-print the OFPT_ERROR packet of 'len' bytes at 'oh' to 'string'
933  * at the given 'verbosity' level. */
934 static void
935 ofp_print_error_msg(struct ds *string, const void *oh, size_t len,
936                        int verbosity OVS_UNUSED)
937 {
938     const struct ofp_error_msg *oem = oh;
939     int type = ntohs(oem->type);
940     int code = ntohs(oem->code);
941     char *s;
942
943     ds_put_format(string, " type%d(%s) code%d(%s) payload:\n",
944                   type, lookup_error_type(type),
945                   code, lookup_error_code(type, code));
946
947     switch (type) {
948     case OFPET_HELLO_FAILED:
949         ds_put_printable(string, (char *) oem->data, len - sizeof *oem);
950         break;
951
952     case OFPET_BAD_REQUEST:
953         s = ofp_to_string(oem->data, len - sizeof *oem, 1);
954         ds_put_cstr(string, s);
955         free(s);
956         break;
957
958     default:
959         ds_put_hex_dump(string, oem->data, len - sizeof *oem, 0, true);
960         break;
961     }
962 }
963
964 /* Pretty-print the OFPT_PORT_STATUS packet of 'len' bytes at 'oh' to 'string'
965  * at the given 'verbosity' level. */
966 static void
967 ofp_print_port_status(struct ds *string, const void *oh, size_t len OVS_UNUSED,
968                       int verbosity OVS_UNUSED)
969 {
970     const struct ofp_port_status *ops = oh;
971
972     if (ops->reason == OFPPR_ADD) {
973         ds_put_format(string, " ADD:");
974     } else if (ops->reason == OFPPR_DELETE) {
975         ds_put_format(string, " DEL:");
976     } else if (ops->reason == OFPPR_MODIFY) {
977         ds_put_format(string, " MOD:");
978     }
979
980     ofp_print_phy_port(string, &ops->desc);
981 }
982
983 static void
984 ofp_desc_stats_reply(struct ds *string, const void *body,
985                      size_t len OVS_UNUSED, int verbosity OVS_UNUSED)
986 {
987     const struct ofp_desc_stats *ods = body;
988
989     ds_put_format(string, "Manufacturer: %.*s\n",
990             (int) sizeof ods->mfr_desc, ods->mfr_desc);
991     ds_put_format(string, "Hardware: %.*s\n",
992             (int) sizeof ods->hw_desc, ods->hw_desc);
993     ds_put_format(string, "Software: %.*s\n",
994             (int) sizeof ods->sw_desc, ods->sw_desc);
995     ds_put_format(string, "Serial Num: %.*s\n",
996             (int) sizeof ods->serial_num, ods->serial_num);
997     ds_put_format(string, "DP Description: %.*s\n",
998             (int) sizeof ods->dp_desc, ods->dp_desc);
999 }
1000
1001 static void
1002 ofp_flow_stats_request(struct ds *string, const void *oh,
1003                        size_t len OVS_UNUSED, int verbosity)
1004 {
1005     const struct ofp_flow_stats_request *fsr = oh;
1006
1007     if (fsr->table_id == 0xff) {
1008         ds_put_format(string, " table_id=any, ");
1009     } else {
1010         ds_put_format(string, " table_id=%"PRIu8", ", fsr->table_id);
1011     }
1012
1013     ofp_print_match(string, &fsr->match, verbosity);
1014 }
1015
1016 static void
1017 ofp_flow_stats_reply(struct ds *string, const void *body_, size_t len,
1018                      int verbosity)
1019 {
1020     const char *body = body_;
1021     const char *pos = body;
1022     for (;;) {
1023         const struct ofp_flow_stats *fs;
1024         ptrdiff_t bytes_left = body + len - pos;
1025         size_t length;
1026
1027         if (bytes_left < sizeof *fs) {
1028             if (bytes_left != 0) {
1029                 ds_put_format(string, " ***%td leftover bytes at end***",
1030                               bytes_left);
1031             }
1032             break;
1033         }
1034
1035         fs = (const void *) pos;
1036         length = ntohs(fs->length);
1037         if (length < sizeof *fs) {
1038             ds_put_format(string, " ***length=%zu shorter than minimum %zu***",
1039                           length, sizeof *fs);
1040             break;
1041         } else if (length > bytes_left) {
1042             ds_put_format(string,
1043                           " ***length=%zu but only %td bytes left***",
1044                           length, bytes_left);
1045             break;
1046         } else if ((length - sizeof *fs) % sizeof fs->actions[0]) {
1047             ds_put_format(string,
1048                           " ***length=%zu has %zu bytes leftover in "
1049                           "final action***",
1050                           length,
1051                           (length - sizeof *fs) % sizeof fs->actions[0]);
1052             break;
1053         }
1054
1055         ds_put_format(string, "  cookie=0x%"PRIx64", ", ntohll(fs->cookie));
1056         ds_put_format(string, "duration_sec=%"PRIu32"s, ",
1057                     ntohl(fs->duration_sec));
1058         ds_put_format(string, "duration_nsec=%"PRIu32"ns, ",
1059                     ntohl(fs->duration_nsec));
1060         ds_put_format(string, "table_id=%"PRIu8", ", fs->table_id);
1061         ds_put_format(string, "priority=%"PRIu16", ",
1062                     fs->match.wildcards ? ntohs(fs->priority) : (uint16_t)-1);
1063         ds_put_format(string, "n_packets=%"PRIu64", ",
1064                     ntohll(fs->packet_count));
1065         ds_put_format(string, "n_bytes=%"PRIu64", ", ntohll(fs->byte_count));
1066         if (fs->idle_timeout != htons(OFP_FLOW_PERMANENT)) {
1067             ds_put_format(string, "idle_timeout=%"PRIu16",",
1068                           ntohs(fs->idle_timeout));
1069         }
1070         if (fs->hard_timeout != htons(OFP_FLOW_PERMANENT)) {
1071             ds_put_format(string, "hard_timeout=%"PRIu16",",
1072                           ntohs(fs->hard_timeout));
1073         }
1074         ofp_print_match(string, &fs->match, verbosity);
1075         ofp_print_actions(string, fs->actions, length - sizeof *fs);
1076         ds_put_char(string, '\n');
1077
1078         pos += length;
1079      }
1080 }
1081
1082 static void
1083 ofp_aggregate_stats_request(struct ds *string, const void *oh,
1084                             size_t len OVS_UNUSED, int verbosity)
1085 {
1086     const struct ofp_aggregate_stats_request *asr = oh;
1087
1088     if (asr->table_id == 0xff) {
1089         ds_put_format(string, " table_id=any, ");
1090     } else {
1091         ds_put_format(string, " table_id=%"PRIu8", ", asr->table_id);
1092     }
1093
1094     ofp_print_match(string, &asr->match, verbosity);
1095 }
1096
1097 static void
1098 ofp_aggregate_stats_reply(struct ds *string, const void *body_,
1099                           size_t len OVS_UNUSED, int verbosity OVS_UNUSED)
1100 {
1101     const struct ofp_aggregate_stats_reply *asr = body_;
1102
1103     ds_put_format(string, " packet_count=%"PRIu64, ntohll(asr->packet_count));
1104     ds_put_format(string, " byte_count=%"PRIu64, ntohll(asr->byte_count));
1105     ds_put_format(string, " flow_count=%"PRIu32, ntohl(asr->flow_count));
1106 }
1107
1108 static void print_port_stat(struct ds *string, const char *leader,
1109                             uint64_t stat, int more)
1110 {
1111     ds_put_cstr(string, leader);
1112     if (stat != -1) {
1113         ds_put_format(string, "%"PRIu64, stat);
1114     } else {
1115         ds_put_char(string, '?');
1116     }
1117     if (more) {
1118         ds_put_cstr(string, ", ");
1119     } else {
1120         ds_put_cstr(string, "\n");
1121     }
1122 }
1123
1124 static void
1125 ofp_port_stats_request(struct ds *string, const void *body_,
1126                        size_t len OVS_UNUSED, int verbosity OVS_UNUSED)
1127 {
1128     const struct ofp_port_stats_request *psr = body_;
1129     ds_put_format(string, "port_no=%"PRIu16, ntohs(psr->port_no));
1130 }
1131
1132 static void
1133 ofp_port_stats_reply(struct ds *string, const void *body, size_t len,
1134                      int verbosity)
1135 {
1136     const struct ofp_port_stats *ps = body;
1137     size_t n = len / sizeof *ps;
1138     ds_put_format(string, " %zu ports\n", n);
1139     if (verbosity < 1) {
1140         return;
1141     }
1142
1143     for (; n--; ps++) {
1144         ds_put_format(string, "  port %2"PRIu16": ", ntohs(ps->port_no));
1145
1146         ds_put_cstr(string, "rx ");
1147         print_port_stat(string, "pkts=", ntohll(ps->rx_packets), 1);
1148         print_port_stat(string, "bytes=", ntohll(ps->rx_bytes), 1);
1149         print_port_stat(string, "drop=", ntohll(ps->rx_dropped), 1);
1150         print_port_stat(string, "errs=", ntohll(ps->rx_errors), 1);
1151         print_port_stat(string, "frame=", ntohll(ps->rx_frame_err), 1);
1152         print_port_stat(string, "over=", ntohll(ps->rx_over_err), 1);
1153         print_port_stat(string, "crc=", ntohll(ps->rx_crc_err), 0);
1154
1155         ds_put_cstr(string, "           tx ");
1156         print_port_stat(string, "pkts=", ntohll(ps->tx_packets), 1);
1157         print_port_stat(string, "bytes=", ntohll(ps->tx_bytes), 1);
1158         print_port_stat(string, "drop=", ntohll(ps->tx_dropped), 1);
1159         print_port_stat(string, "errs=", ntohll(ps->tx_errors), 1);
1160         print_port_stat(string, "coll=", ntohll(ps->collisions), 0);
1161     }
1162 }
1163
1164 static void
1165 ofp_table_stats_reply(struct ds *string, const void *body, size_t len,
1166                      int verbosity)
1167 {
1168     const struct ofp_table_stats *ts = body;
1169     size_t n = len / sizeof *ts;
1170     ds_put_format(string, " %zu tables\n", n);
1171     if (verbosity < 1) {
1172         return;
1173     }
1174
1175     for (; n--; ts++) {
1176         char name[OFP_MAX_TABLE_NAME_LEN + 1];
1177         strncpy(name, ts->name, sizeof name);
1178         name[OFP_MAX_TABLE_NAME_LEN] = '\0';
1179
1180         ds_put_format(string, "  %d: %-8s: ", ts->table_id, name);
1181         ds_put_format(string, "wild=0x%05"PRIx32", ", ntohl(ts->wildcards));
1182         ds_put_format(string, "max=%6"PRIu32", ", ntohl(ts->max_entries));
1183         ds_put_format(string, "active=%"PRIu32"\n", ntohl(ts->active_count));
1184         ds_put_cstr(string, "               ");
1185         ds_put_format(string, "lookup=%"PRIu64", ",
1186                     ntohll(ts->lookup_count));
1187         ds_put_format(string, "matched=%"PRIu64"\n",
1188                     ntohll(ts->matched_count));
1189      }
1190 }
1191
1192 static void
1193 ofp_print_queue_name(struct ds *string, uint32_t queue_id)
1194 {
1195     if (queue_id == OFPQ_ALL) {
1196         ds_put_cstr(string, "ALL");
1197     } else {
1198         ds_put_format(string, "%"PRIu32, queue_id);
1199     }
1200 }
1201
1202 static void
1203 ofp_queue_stats_request(struct ds *string, const void *body_,
1204                        size_t len OVS_UNUSED, int verbosity OVS_UNUSED)
1205 {
1206     const struct ofp_queue_stats_request *qsr = body_;
1207
1208     ds_put_cstr(string, "port=");
1209     ofp_print_port_name(string, ntohs(qsr->port_no));
1210
1211     ds_put_cstr(string, " queue=");
1212     ofp_print_queue_name(string, ntohl(qsr->queue_id));
1213 }
1214
1215 static void
1216 ofp_queue_stats_reply(struct ds *string, const void *body, size_t len,
1217                      int verbosity)
1218 {
1219     const struct ofp_queue_stats *qs = body;
1220     size_t n = len / sizeof *qs;
1221     ds_put_format(string, " %zu queues\n", n);
1222     if (verbosity < 1) {
1223         return;
1224     }
1225
1226     for (; n--; qs++) {
1227         ds_put_cstr(string, "  port ");
1228         ofp_print_port_name(string, ntohs(qs->port_no));
1229         ds_put_cstr(string, " queue ");
1230         ofp_print_queue_name(string, ntohl(qs->queue_id));
1231         ds_put_cstr(string, ": ");
1232
1233         print_port_stat(string, "bytes=", ntohll(qs->tx_bytes), 1);
1234         print_port_stat(string, "pkts=", ntohll(qs->tx_packets), 1);
1235         print_port_stat(string, "errors=", ntohll(qs->tx_errors), 0);
1236     }
1237 }
1238
1239 static void
1240 vendor_stat(struct ds *string, const void *body, size_t len,
1241             int verbosity OVS_UNUSED)
1242 {
1243     ds_put_format(string, " vendor=%08"PRIx32, ntohl(*(uint32_t *) body));
1244     ds_put_format(string, " %zu bytes additional data",
1245                   len - sizeof(uint32_t));
1246 }
1247
1248 enum stats_direction {
1249     REQUEST,
1250     REPLY
1251 };
1252
1253 static void
1254 print_stats(struct ds *string, int type, const void *body, size_t body_len,
1255             int verbosity, enum stats_direction direction)
1256 {
1257     struct stats_msg {
1258         size_t min_body, max_body;
1259         void (*printer)(struct ds *, const void *, size_t len, int verbosity);
1260     };
1261
1262     struct stats_type {
1263         int type;
1264         const char *name;
1265         struct stats_msg request;
1266         struct stats_msg reply;
1267     };
1268
1269     static const struct stats_type stats_types[] = {
1270         {
1271             OFPST_DESC,
1272             "description",
1273             { 0, 0, NULL },
1274             { 0, SIZE_MAX, ofp_desc_stats_reply },
1275         },
1276         {
1277             OFPST_FLOW,
1278             "flow",
1279             { sizeof(struct ofp_flow_stats_request),
1280               sizeof(struct ofp_flow_stats_request),
1281               ofp_flow_stats_request },
1282             { 0, SIZE_MAX, ofp_flow_stats_reply },
1283         },
1284         {
1285             OFPST_AGGREGATE,
1286             "aggregate",
1287             { sizeof(struct ofp_aggregate_stats_request),
1288               sizeof(struct ofp_aggregate_stats_request),
1289               ofp_aggregate_stats_request },
1290             { sizeof(struct ofp_aggregate_stats_reply),
1291               sizeof(struct ofp_aggregate_stats_reply),
1292               ofp_aggregate_stats_reply },
1293         },
1294         {
1295             OFPST_TABLE,
1296             "table",
1297             { 0, 0, NULL },
1298             { 0, SIZE_MAX, ofp_table_stats_reply },
1299         },
1300         {
1301             OFPST_PORT,
1302             "port",
1303             { sizeof(struct ofp_port_stats_request),
1304               sizeof(struct ofp_port_stats_request),
1305               ofp_port_stats_request },
1306             { 0, SIZE_MAX, ofp_port_stats_reply },
1307         },
1308         {
1309             OFPST_QUEUE,
1310             "queue",
1311             { sizeof(struct ofp_queue_stats_request),
1312               sizeof(struct ofp_queue_stats_request),
1313               ofp_queue_stats_request },
1314             { 0, SIZE_MAX, ofp_queue_stats_reply },
1315         },
1316         {
1317             OFPST_VENDOR,
1318             "vendor-specific",
1319             { sizeof(uint32_t), SIZE_MAX, vendor_stat },
1320             { sizeof(uint32_t), SIZE_MAX, vendor_stat },
1321         },
1322         {
1323             -1,
1324             "unknown",
1325             { 0, 0, NULL, },
1326             { 0, 0, NULL, },
1327         },
1328     };
1329
1330     const struct stats_type *s;
1331     const struct stats_msg *m;
1332
1333     if (type >= ARRAY_SIZE(stats_types) || !stats_types[type].name) {
1334         ds_put_format(string, " ***unknown type %d***", type);
1335         return;
1336     }
1337     for (s = stats_types; s->type >= 0; s++) {
1338         if (s->type == type) {
1339             break;
1340         }
1341     }
1342     ds_put_format(string, " type=%d(%s)\n", type, s->name);
1343
1344     m = direction == REQUEST ? &s->request : &s->reply;
1345     if (body_len < m->min_body || body_len > m->max_body) {
1346         ds_put_format(string, " ***body_len=%zu not in %zu...%zu***",
1347                       body_len, m->min_body, m->max_body);
1348         return;
1349     }
1350     if (m->printer) {
1351         m->printer(string, body, body_len, verbosity);
1352     }
1353 }
1354
1355 static void
1356 ofp_stats_request(struct ds *string, const void *oh, size_t len, int verbosity)
1357 {
1358     const struct ofp_stats_request *srq = oh;
1359
1360     if (srq->flags) {
1361         ds_put_format(string, " ***unknown flags 0x%04"PRIx16"***",
1362                       ntohs(srq->flags));
1363     }
1364
1365     print_stats(string, ntohs(srq->type), srq->body,
1366                 len - offsetof(struct ofp_stats_request, body),
1367                 verbosity, REQUEST);
1368 }
1369
1370 static void
1371 ofp_stats_reply(struct ds *string, const void *oh, size_t len, int verbosity)
1372 {
1373     const struct ofp_stats_reply *srp = oh;
1374
1375     ds_put_cstr(string, " flags=");
1376     if (!srp->flags) {
1377         ds_put_cstr(string, "none");
1378     } else {
1379         uint16_t flags = ntohs(srp->flags);
1380         if (flags & OFPSF_REPLY_MORE) {
1381             ds_put_cstr(string, "[more]");
1382             flags &= ~OFPSF_REPLY_MORE;
1383         }
1384         if (flags) {
1385             ds_put_format(string, "[***unknown flags 0x%04"PRIx16"***]", flags);
1386         }
1387     }
1388
1389     print_stats(string, ntohs(srp->type), srp->body,
1390                 len - offsetof(struct ofp_stats_reply, body),
1391                 verbosity, REPLY);
1392 }
1393
1394 static void
1395 ofp_echo(struct ds *string, const void *oh, size_t len, int verbosity)
1396 {
1397     const struct ofp_header *hdr = oh;
1398
1399     ds_put_format(string, " %zu bytes of payload\n", len - sizeof *hdr);
1400     if (verbosity > 1) {
1401         ds_put_hex_dump(string, hdr, len - sizeof *hdr, 0, true);
1402     }
1403 }
1404
1405 struct openflow_packet {
1406     uint8_t type;
1407     const char *name;
1408     size_t min_size;
1409     void (*printer)(struct ds *, const void *, size_t len, int verbosity);
1410 };
1411
1412 static const struct openflow_packet packets[] = {
1413     {
1414         OFPT_HELLO,
1415         "hello",
1416         sizeof (struct ofp_header),
1417         NULL,
1418     },
1419     {
1420         OFPT_FEATURES_REQUEST,
1421         "features_request",
1422         sizeof (struct ofp_header),
1423         NULL,
1424     },
1425     {
1426         OFPT_FEATURES_REPLY,
1427         "features_reply",
1428         sizeof (struct ofp_switch_features),
1429         ofp_print_switch_features,
1430     },
1431     {
1432         OFPT_GET_CONFIG_REQUEST,
1433         "get_config_request",
1434         sizeof (struct ofp_header),
1435         NULL,
1436     },
1437     {
1438         OFPT_GET_CONFIG_REPLY,
1439         "get_config_reply",
1440         sizeof (struct ofp_switch_config),
1441         ofp_print_switch_config,
1442     },
1443     {
1444         OFPT_SET_CONFIG,
1445         "set_config",
1446         sizeof (struct ofp_switch_config),
1447         ofp_print_switch_config,
1448     },
1449     {
1450         OFPT_PACKET_IN,
1451         "packet_in",
1452         offsetof(struct ofp_packet_in, data),
1453         ofp_packet_in,
1454     },
1455     {
1456         OFPT_PACKET_OUT,
1457         "packet_out",
1458         sizeof (struct ofp_packet_out),
1459         ofp_packet_out,
1460     },
1461     {
1462         OFPT_FLOW_MOD,
1463         "flow_mod",
1464         sizeof (struct ofp_flow_mod),
1465         ofp_print_flow_mod,
1466     },
1467     {
1468         OFPT_FLOW_REMOVED,
1469         "flow_removed",
1470         sizeof (struct ofp_flow_removed),
1471         ofp_print_flow_removed,
1472     },
1473     {
1474         OFPT_PORT_MOD,
1475         "port_mod",
1476         sizeof (struct ofp_port_mod),
1477         ofp_print_port_mod,
1478     },
1479     {
1480         OFPT_PORT_STATUS,
1481         "port_status",
1482         sizeof (struct ofp_port_status),
1483         ofp_print_port_status
1484     },
1485     {
1486         OFPT_ERROR,
1487         "error_msg",
1488         sizeof (struct ofp_error_msg),
1489         ofp_print_error_msg,
1490     },
1491     {
1492         OFPT_STATS_REQUEST,
1493         "stats_request",
1494         sizeof (struct ofp_stats_request),
1495         ofp_stats_request,
1496     },
1497     {
1498         OFPT_STATS_REPLY,
1499         "stats_reply",
1500         sizeof (struct ofp_stats_reply),
1501         ofp_stats_reply,
1502     },
1503     {
1504         OFPT_ECHO_REQUEST,
1505         "echo_request",
1506         sizeof (struct ofp_header),
1507         ofp_echo,
1508     },
1509     {
1510         OFPT_ECHO_REPLY,
1511         "echo_reply",
1512         sizeof (struct ofp_header),
1513         ofp_echo,
1514     },
1515     {
1516         OFPT_VENDOR,
1517         "vendor",
1518         sizeof (struct ofp_vendor_header),
1519         NULL,
1520     },
1521     {
1522         OFPT_BARRIER_REQUEST,
1523         "barrier_request",
1524         sizeof (struct ofp_header),
1525         NULL,
1526     },
1527     {
1528         OFPT_BARRIER_REPLY,
1529         "barrier_reply",
1530         sizeof (struct ofp_header),
1531         NULL,
1532     }
1533 };
1534
1535 /* Composes and returns a string representing the OpenFlow packet of 'len'
1536  * bytes at 'oh' at the given 'verbosity' level.  0 is a minimal amount of
1537  * verbosity and higher numbers increase verbosity.  The caller is responsible
1538  * for freeing the string. */
1539 char *
1540 ofp_to_string(const void *oh_, size_t len, int verbosity)
1541 {
1542     struct ds string = DS_EMPTY_INITIALIZER;
1543     const struct ofp_header *oh = oh_;
1544     const struct openflow_packet *pkt;
1545
1546     if (len < sizeof(struct ofp_header)) {
1547         ds_put_cstr(&string, "OpenFlow packet too short:\n");
1548         ds_put_hex_dump(&string, oh, len, 0, true);
1549         return ds_cstr(&string);
1550     } else if (oh->version != OFP_VERSION) {
1551         ds_put_format(&string, "Bad OpenFlow version %"PRIu8":\n", oh->version);
1552         ds_put_hex_dump(&string, oh, len, 0, true);
1553         return ds_cstr(&string);
1554     }
1555
1556     for (pkt = packets; ; pkt++) {
1557         if (pkt >= &packets[ARRAY_SIZE(packets)]) {
1558             ds_put_format(&string, "Unknown OpenFlow packet type %"PRIu8":\n",
1559                           oh->type);
1560             ds_put_hex_dump(&string, oh, len, 0, true);
1561             return ds_cstr(&string);
1562         } else if (oh->type == pkt->type) {
1563             break;
1564         }
1565     }
1566
1567     ds_put_format(&string, "%s (xid=0x%"PRIx32"):", pkt->name, oh->xid);
1568
1569     if (ntohs(oh->length) > len)
1570         ds_put_format(&string, " (***truncated to %zu bytes from %"PRIu16"***)",
1571                 len, ntohs(oh->length));
1572     else if (ntohs(oh->length) < len) {
1573         ds_put_format(&string, " (***only uses %"PRIu16" bytes out of %zu***)\n",
1574                 ntohs(oh->length), len);
1575         len = ntohs(oh->length);
1576     }
1577
1578     if (len < pkt->min_size) {
1579         ds_put_format(&string, " (***length=%zu < min_size=%zu***)\n",
1580                 len, pkt->min_size);
1581     } else if (!pkt->printer) {
1582         if (len > sizeof *oh) {
1583             ds_put_format(&string, " length=%"PRIu16" (decoder not implemented)\n",
1584                           ntohs(oh->length));
1585         }
1586     } else {
1587         pkt->printer(&string, oh, len, verbosity);
1588     }
1589     if (verbosity >= 3) {
1590         ds_put_hex_dump(&string, oh, len, 0, true);
1591     }
1592     if (string.string[string.length - 1] != '\n') {
1593         ds_put_char(&string, '\n');
1594     }
1595     return ds_cstr(&string);
1596 }
1597
1598 /* Returns the name for the specified OpenFlow message type as a string,
1599  * e.g. "OFPT_FEATURES_REPLY".  If no name is known, the string returned is a
1600  * hex number, e.g. "0x55".
1601  *
1602  * The caller must free the returned string when it is no longer needed. */
1603 char *
1604 ofp_message_type_to_string(uint8_t type)
1605 {
1606     struct ds s = DS_EMPTY_INITIALIZER;
1607     const struct openflow_packet *pkt;
1608     for (pkt = packets; ; pkt++) {
1609         if (pkt >= &packets[ARRAY_SIZE(packets)]) {
1610             ds_put_format(&s, "0x%02"PRIx8, type);
1611             break;
1612         } else if (type == pkt->type) {
1613             const char *p;
1614
1615             ds_put_cstr(&s, "OFPT_");
1616             for (p = pkt->name; *p; p++) {
1617                 ds_put_char(&s, toupper((unsigned char) *p));
1618             }
1619             break;
1620         }
1621     }
1622     return ds_cstr(&s);
1623 }
1624 \f
1625 static void
1626 print_and_free(FILE *stream, char *string)
1627 {
1628     fputs(string, stream);
1629     free(string);
1630 }
1631
1632 /* Pretty-print the OpenFlow packet of 'len' bytes at 'oh' to 'stream' at the
1633  * given 'verbosity' level.  0 is a minimal amount of verbosity and higher
1634  * numbers increase verbosity. */
1635 void
1636 ofp_print(FILE *stream, const void *oh, size_t len, int verbosity)
1637 {
1638     print_and_free(stream, ofp_to_string(oh, len, verbosity));
1639 }
1640
1641 /* Dumps the contents of the Ethernet frame in the 'len' bytes starting at
1642  * 'data' to 'stream' using tcpdump.  'total_len' specifies the full length of
1643  * the Ethernet frame (of which 'len' bytes were captured).
1644  *
1645  * This starts and kills a tcpdump subprocess so it's quite expensive. */
1646 void
1647 ofp_print_packet(FILE *stream, const void *data, size_t len, size_t total_len)
1648 {
1649     print_and_free(stream, ofp_packet_to_string(data, len, total_len));
1650 }