2 * Copyright (c) 2008-2017 Nicira, Inc.
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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include "openvswitch/ofp-print.h"
23 #include <sys/types.h>
24 #include <netinet/in.h>
31 #include "byte-order.h"
34 #include "dp-packet.h"
37 #include "multipath.h"
41 #include "openflow/nicira-ext.h"
42 #include "openflow/openflow.h"
43 #include "openvswitch/dynamic-string.h"
44 #include "openvswitch/meta-flow.h"
45 #include "openvswitch/ofp-actions.h"
46 #include "openvswitch/ofp-bundle.h"
47 #include "openvswitch/ofp-connection.h"
48 #include "openvswitch/ofp-errors.h"
49 #include "openvswitch/ofp-group.h"
50 #include "openvswitch/ofp-ipfix.h"
51 #include "openvswitch/ofp-match.h"
52 #include "openvswitch/ofp-meter.h"
53 #include "openvswitch/ofp-monitor.h"
54 #include "openvswitch/ofp-msgs.h"
55 #include "openvswitch/ofp-port.h"
56 #include "openvswitch/ofp-queue.h"
57 #include "openvswitch/ofp-switch.h"
58 #include "openvswitch/ofp-table.h"
59 #include "openvswitch/ofp-util.h"
60 #include "openvswitch/ofpbuf.h"
61 #include "openvswitch/type-props.h"
63 #include "unaligned.h"
67 static void ofp_print_queue_name(struct ds
*string
, uint32_t port
);
68 static void ofp_print_error(struct ds
*, enum ofperr
);
70 /* Returns a string that represents the contents of the Ethernet frame in the
71 * 'len' bytes starting at 'data'. The caller must free the returned string.*/
73 ofp_packet_to_string(const void *data
, size_t len
, ovs_be32 packet_type
)
75 struct ds ds
= DS_EMPTY_INITIALIZER
;
80 dp_packet_use_const(&buf
, data
, len
);
81 buf
.packet_type
= packet_type
;
82 flow_extract(&buf
, &flow
);
83 flow_format(&ds
, &flow
, NULL
);
85 l4_size
= dp_packet_l4_size(&buf
);
87 if (flow
.nw_proto
== IPPROTO_TCP
&& l4_size
>= TCP_HEADER_LEN
) {
88 struct tcp_header
*th
= dp_packet_l4(&buf
);
89 ds_put_format(&ds
, " tcp_csum:%"PRIx16
, ntohs(th
->tcp_csum
));
90 } else if (flow
.nw_proto
== IPPROTO_UDP
&& l4_size
>= UDP_HEADER_LEN
) {
91 struct udp_header
*uh
= dp_packet_l4(&buf
);
92 ds_put_format(&ds
, " udp_csum:%"PRIx16
, ntohs(uh
->udp_csum
));
93 } else if (flow
.nw_proto
== IPPROTO_SCTP
&& l4_size
>= SCTP_HEADER_LEN
) {
94 struct sctp_header
*sh
= dp_packet_l4(&buf
);
95 ds_put_format(&ds
, " sctp_csum:%"PRIx32
,
96 ntohl(get_16aligned_be32(&sh
->sctp_csum
)));
97 } else if (flow
.nw_proto
== IPPROTO_ICMP
&& l4_size
>= ICMP_HEADER_LEN
) {
98 struct icmp_header
*icmph
= dp_packet_l4(&buf
);
99 ds_put_format(&ds
, " icmp_csum:%"PRIx16
,
100 ntohs(icmph
->icmp_csum
));
101 } else if (flow
.nw_proto
== IPPROTO_ICMPV6
&& l4_size
>= ICMP6_HEADER_LEN
) {
102 struct icmp6_header
*icmp6h
= dp_packet_l4(&buf
);
103 ds_put_format(&ds
, " icmp6_csum:%"PRIx16
,
104 ntohs(icmp6h
->icmp6_cksum
));
107 ds_put_char(&ds
, '\n');
113 ofp_dp_packet_to_string(const struct dp_packet
*packet
)
115 return ofp_packet_to_string(dp_packet_data(packet
),
116 dp_packet_size(packet
),
117 packet
->packet_type
);
121 ofp_print_packet_in(struct ds
*string
, const struct ofp_header
*oh
,
122 const struct ofputil_port_map
*port_map
,
123 const struct ofputil_table_map
*table_map
, int verbosity
)
125 struct ofputil_packet_in_private pin
;
128 enum ofperr error
= ofputil_decode_packet_in_private(oh
, true, NULL
, NULL
,
132 ofputil_packet_in_private_format(string
, &pin
, total_len
, buffer_id
,
133 port_map
, table_map
, verbosity
);
134 ofputil_packet_in_private_destroy(&pin
);
140 ofp_print_packet_out(struct ds
*string
, const struct ofp_header
*oh
,
141 const struct ofputil_port_map
*port_map
,
142 const struct ofputil_table_map
*table_map
, int verbosity
)
144 struct ofputil_packet_out po
;
145 struct ofpbuf ofpacts
;
148 ofpbuf_init(&ofpacts
, 64);
149 error
= ofputil_decode_packet_out(&po
, oh
, NULL
, &ofpacts
);
151 ofputil_packet_out_format(string
, &po
, port_map
, table_map
, verbosity
);
153 ofpbuf_uninit(&ofpacts
);
158 ofp_print_bit_names(struct ds
*string
, uint32_t bits
,
159 const char *(*bit_to_name
)(uint32_t bit
),
166 ds_put_cstr(string
, "0");
170 for (i
= 0; i
< 32; i
++) {
171 uint32_t bit
= UINT32_C(1) << i
;
174 const char *name
= bit_to_name(bit
);
177 ds_put_char(string
, separator
);
179 ds_put_cstr(string
, name
);
187 ds_put_char(string
, separator
);
189 ds_put_format(string
, "0x%"PRIx32
, bits
);
194 ofp_print_switch_features(struct ds
*string
, const struct ofp_header
*oh
)
196 struct ofputil_switch_features features
;
197 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
198 enum ofperr error
= ofputil_pull_switch_features(&b
, &features
);
200 ofputil_switch_features_format(string
, &features
);
201 error
= ofputil_phy_ports_format(string
, oh
->version
, &b
);
207 ofp_print_set_config(struct ds
*string
, const struct ofp_header
*oh
)
209 struct ofputil_switch_config config
;
212 error
= ofputil_decode_set_config(oh
, &config
);
216 ofputil_switch_config_format(string
, &config
);
221 ofp_print_get_config_reply(struct ds
*string
, const struct ofp_header
*oh
)
223 struct ofputil_switch_config config
;
224 ofputil_decode_get_config_reply(oh
, &config
);
225 ofputil_switch_config_format(string
, &config
);
230 ofp_print_table_features_reply(struct ds
*s
, const struct ofp_header
*oh
,
231 const struct ofputil_table_map
*table_map
)
233 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
235 struct ofputil_table_features prev
;
236 for (int i
= 0; ; i
++) {
237 struct ofputil_table_features tf
;
240 retval
= ofputil_decode_table_features(&b
, &tf
, true);
242 return retval
!= EOF
? retval
: 0;
245 ds_put_char(s
, '\n');
246 ofputil_table_features_format(s
, &tf
, i
? &prev
: NULL
, NULL
, NULL
,
253 ofp_print_duration(struct ds
*string
, unsigned int sec
, unsigned int nsec
)
255 ds_put_format(string
, "%u", sec
);
257 /* If there are no fractional seconds, don't print any decimals.
259 * If the fractional seconds can be expressed exactly as milliseconds,
260 * print 3 decimals. Open vSwitch provides millisecond precision for most
261 * time measurements, so printing 3 decimals every time makes it easier to
262 * spot real changes in flow dumps that refresh themselves quickly.
264 * If the fractional seconds are more precise than milliseconds, print the
265 * number of decimals needed to express them exactly.
268 unsigned int msec
= nsec
/ 1000000;
269 if (msec
* 1000000 == nsec
) {
270 ds_put_format(string
, ".%03u", msec
);
272 ds_put_format(string
, ".%09u", nsec
);
273 while (string
->string
[string
->length
- 1] == '0') {
278 ds_put_char(string
, 's');
282 ofp_print_flow_removed(struct ds
*string
, const struct ofp_header
*oh
,
283 const struct ofputil_port_map
*port_map
,
284 const struct ofputil_table_map
*table_map
)
286 struct ofputil_flow_removed fr
;
287 enum ofperr error
= ofputil_decode_flow_removed(&fr
, oh
);
289 ofputil_flow_removed_format(string
, &fr
, port_map
, table_map
);
295 ofp_print_port_mod(struct ds
*string
, const struct ofp_header
*oh
,
296 const struct ofputil_port_map
*port_map
)
298 struct ofputil_port_mod pm
;
299 enum ofperr error
= ofputil_decode_port_mod(oh
, &pm
, true);
301 ofputil_port_mod_format(string
, &pm
, port_map
);
307 ofp_print_table_mod(struct ds
*string
, const struct ofp_header
*oh
,
308 const struct ofputil_table_map
*table_map
)
310 struct ofputil_table_mod tm
;
311 enum ofperr error
= ofputil_decode_table_mod(oh
, &tm
);
313 ofputil_table_mod_format(string
, &tm
, table_map
);
319 ofp_print_table_status_message(struct ds
*string
, const struct ofp_header
*oh
,
320 const struct ofputil_table_map
*table_map
)
322 struct ofputil_table_status ts
;
325 error
= ofputil_decode_table_status(oh
, &ts
);
330 if (ts
.reason
== OFPTR_VACANCY_DOWN
) {
331 ds_put_format(string
, " reason=VACANCY_DOWN");
332 } else if (ts
.reason
== OFPTR_VACANCY_UP
) {
333 ds_put_format(string
, " reason=VACANCY_UP");
336 ds_put_format(string
, "\ntable_desc:-");
337 ofputil_table_desc_format(string
, &ts
.desc
, table_map
);
343 ofp_print_queue_get_config_request(struct ds
*string
,
344 const struct ofp_header
*oh
,
345 const struct ofputil_port_map
*port_map
)
351 error
= ofputil_decode_queue_get_config_request(oh
, &port
, &queue
);
356 ds_put_cstr(string
, " port=");
357 ofputil_format_port(port
, port_map
, string
);
359 if (queue
!= OFPQ_ALL
) {
360 ds_put_cstr(string
, " queue=");
361 ofp_print_queue_name(string
, queue
);
368 print_queue_rate(struct ds
*string
, const char *name
, unsigned int rate
)
371 ds_put_format(string
, " %s:%u.%u%%", name
, rate
/ 10, rate
% 10);
372 } else if (rate
< UINT16_MAX
) {
373 ds_put_format(string
, " %s:(disabled)", name
);
377 /* qsort comparison function. */
379 compare_queues(const void *a_
, const void *b_
)
381 const struct ofputil_queue_config
*a
= a_
;
382 const struct ofputil_queue_config
*b
= b_
;
384 uint16_t ap
= ofp_to_u16(a
->port
);
385 uint16_t bp
= ofp_to_u16(b
->port
);
387 return ap
< bp
? -1 : 1;
390 uint32_t aq
= a
->queue
;
391 uint32_t bq
= b
->queue
;
392 return aq
< bq
? -1 : aq
> bq
;
396 ofp_print_queue_get_config_reply(struct ds
*string
,
397 const struct ofp_header
*oh
,
398 const struct ofputil_port_map
*port_map
)
400 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
402 struct ofputil_queue_config
*queues
= NULL
;
403 size_t allocated_queues
= 0;
408 if (n
>= allocated_queues
) {
409 queues
= x2nrealloc(queues
, &allocated_queues
, sizeof *queues
);
411 retval
= ofputil_pull_queue_get_config_reply(&b
, &queues
[n
]);
418 qsort(queues
, n
, sizeof *queues
, compare_queues
);
420 ds_put_char(string
, ' ');
423 for (const struct ofputil_queue_config
*q
= queues
; q
< &queues
[n
]; q
++) {
424 if (q
->port
!= port
) {
427 ds_put_cstr(string
, "port=");
428 ofputil_format_port(port
, port_map
, string
);
429 ds_put_char(string
, '\n');
432 ds_put_format(string
, "queue %"PRIu32
":", q
->queue
);
433 print_queue_rate(string
, "min_rate", q
->min_rate
);
434 print_queue_rate(string
, "max_rate", q
->max_rate
);
435 ds_put_char(string
, '\n');
438 ds_chomp(string
, ' ');
441 return retval
!= EOF
? retval
: 0;
445 ofp_print_meter_flags(struct ds
*s
, uint16_t flags
)
447 if (flags
& OFPMF13_KBPS
) {
448 ds_put_cstr(s
, "kbps ");
450 if (flags
& OFPMF13_PKTPS
) {
451 ds_put_cstr(s
, "pktps ");
453 if (flags
& OFPMF13_BURST
) {
454 ds_put_cstr(s
, "burst ");
456 if (flags
& OFPMF13_STATS
) {
457 ds_put_cstr(s
, "stats ");
460 flags
&= ~(OFPMF13_KBPS
| OFPMF13_PKTPS
| OFPMF13_BURST
| OFPMF13_STATS
);
462 ds_put_format(s
, "flags:0x%"PRIx16
" ", flags
);
467 ofp_print_meter_band(struct ds
*s
, uint16_t flags
,
468 const struct ofputil_meter_band
*mb
)
470 ds_put_cstr(s
, "\ntype=");
473 ds_put_cstr(s
, "drop");
475 case OFPMBT13_DSCP_REMARK
:
476 ds_put_cstr(s
, "dscp_remark");
479 ds_put_format(s
, "%u", mb
->type
);
482 ds_put_format(s
, " rate=%"PRIu32
, mb
->rate
);
484 if (flags
& OFPMF13_BURST
) {
485 ds_put_format(s
, " burst_size=%"PRIu32
, mb
->burst_size
);
487 if (mb
->type
== OFPMBT13_DSCP_REMARK
) {
488 ds_put_format(s
, " prec_level=%"PRIu8
, mb
->prec_level
);
493 ofp_print_meter_id(struct ds
*s
, uint32_t meter_id
, char seperator
)
495 if (meter_id
<= OFPM13_MAX
) {
496 ds_put_format(s
, "meter%c%"PRIu32
, seperator
, meter_id
);
500 case OFPM13_SLOWPATH
:
503 case OFPM13_CONTROLLER
:
512 ds_put_format(s
, "meter%c%s", seperator
, name
);
517 ofp_print_meter_stats(struct ds
*s
, const struct ofputil_meter_stats
*ms
)
521 ofp_print_meter_id(s
, ms
->meter_id
, ':');
523 ds_put_format(s
, "flow_count:%"PRIu32
" ", ms
->flow_count
);
524 ds_put_format(s
, "packet_in_count:%"PRIu64
" ", ms
->packet_in_count
);
525 ds_put_format(s
, "byte_in_count:%"PRIu64
" ", ms
->byte_in_count
);
526 ds_put_cstr(s
, "duration:");
527 ofp_print_duration(s
, ms
->duration_sec
, ms
->duration_nsec
);
530 ds_put_cstr(s
, "bands:\n");
531 for (i
= 0; i
< ms
->n_bands
; ++i
) {
532 ds_put_format(s
, "%d: ", i
);
533 ds_put_format(s
, "packet_count:%"PRIu64
" ", ms
->bands
[i
].packet_count
);
534 ds_put_format(s
, "byte_count:%"PRIu64
"\n", ms
->bands
[i
].byte_count
);
539 ofp_print_meter_config(struct ds
*s
, const struct ofputil_meter_config
*mc
)
543 ofp_print_meter_id(s
, mc
->meter_id
, '=');
546 ofp_print_meter_flags(s
, mc
->flags
);
548 ds_put_cstr(s
, "bands=");
549 for (i
= 0; i
< mc
->n_bands
; ++i
) {
550 ofp_print_meter_band(s
, mc
->flags
, &mc
->bands
[i
]);
552 ds_put_char(s
, '\n');
556 ofp_print_meter_mod__(struct ds
*s
, const struct ofputil_meter_mod
*mm
)
558 switch (mm
->command
) {
560 ds_put_cstr(s
, " ADD ");
563 ds_put_cstr(s
, " MOD ");
566 ds_put_cstr(s
, " DEL ");
569 ds_put_format(s
, " cmd:%d ", mm
->command
);
572 ofp_print_meter_config(s
, &mm
->meter
);
576 ofp_print_meter_mod(struct ds
*s
, const struct ofp_header
*oh
)
578 struct ofputil_meter_mod mm
;
582 ofpbuf_init(&bands
, 64);
583 error
= ofputil_decode_meter_mod(oh
, &mm
, &bands
);
585 ofp_print_meter_mod__(s
, &mm
);
587 ofpbuf_uninit(&bands
);
593 ofp_print_meter_stats_request(struct ds
*s
, const struct ofp_header
*oh
)
597 ofputil_decode_meter_request(oh
, &meter_id
);
600 ofp_print_meter_id(s
, meter_id
, '=');
606 ofputil_meter_capabilities_to_name(uint32_t bit
)
608 enum ofp13_meter_flags flag
= bit
;
611 case OFPMF13_KBPS
: return "kbps";
612 case OFPMF13_PKTPS
: return "pktps";
613 case OFPMF13_BURST
: return "burst";
614 case OFPMF13_STATS
: return "stats";
621 ofputil_meter_band_types_to_name(uint32_t bit
)
624 case 1 << OFPMBT13_DROP
: return "drop";
625 case 1 << OFPMBT13_DSCP_REMARK
: return "dscp_remark";
632 ofp_print_meter_features_reply(struct ds
*s
, const struct ofp_header
*oh
)
634 struct ofputil_meter_features mf
;
636 ofputil_decode_meter_features(oh
, &mf
);
638 ds_put_format(s
, "\nmax_meter:%"PRIu32
, mf
.max_meters
);
639 ds_put_format(s
, " max_bands:%"PRIu8
, mf
.max_bands
);
640 ds_put_format(s
, " max_color:%"PRIu8
"\n", mf
.max_color
);
642 ds_put_cstr(s
, "band_types: ");
643 ofp_print_bit_names(s
, mf
.band_types
,
644 ofputil_meter_band_types_to_name
, ' ');
645 ds_put_char(s
, '\n');
647 ds_put_cstr(s
, "capabilities: ");
648 ofp_print_bit_names(s
, mf
.capabilities
,
649 ofputil_meter_capabilities_to_name
, ' ');
650 ds_put_char(s
, '\n');
656 ofp_print_meter_config_reply(struct ds
*s
, const struct ofp_header
*oh
)
658 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
662 ofpbuf_init(&bands
, 64);
664 struct ofputil_meter_config mc
;
666 retval
= ofputil_decode_meter_config(&b
, &mc
, &bands
);
670 ds_put_char(s
, '\n');
671 ofp_print_meter_config(s
, &mc
);
673 ofpbuf_uninit(&bands
);
675 return retval
!= EOF
? retval
: 0;
679 ofp_print_meter_stats_reply(struct ds
*s
, const struct ofp_header
*oh
)
681 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
685 ofpbuf_init(&bands
, 64);
687 struct ofputil_meter_stats ms
;
689 retval
= ofputil_decode_meter_stats(&b
, &ms
, &bands
);
693 ds_put_char(s
, '\n');
694 ofp_print_meter_stats(s
, &ms
);
696 ofpbuf_uninit(&bands
);
698 return retval
!= EOF
? retval
: 0;
702 ofp_print_error(struct ds
*string
, enum ofperr error
)
704 ds_put_format(string
, "***decode error: %s***\n", ofperr_get_name(error
));
708 ofp_print_hello(struct ds
*string
, const struct ofp_header
*oh
)
710 ofputil_hello_format(string
, oh
);
715 ofp_print_error_msg(struct ds
*string
, const struct ofp_header
*oh
,
716 const struct ofputil_port_map
*port_map
,
717 const struct ofputil_table_map
*table_map
)
719 struct ofpbuf payload
;
720 enum ofperr error
= ofperr_decode_msg(oh
, &payload
);
722 return OFPERR_OFPBRC_BAD_LEN
;
724 ofperr_msg_format(string
, error
, &payload
, port_map
, table_map
);
725 ofpbuf_uninit(&payload
);
731 ofp_print_port_status(struct ds
*string
, const struct ofp_header
*oh
)
733 struct ofputil_port_status ps
;
734 enum ofperr error
= ofputil_decode_port_status(oh
, &ps
);
736 ofputil_port_status_format(string
, &ps
);
742 ofp_print_ofpst_desc_reply(struct ds
*string
, const struct ofp_header
*oh
)
744 const struct ofp_desc_stats
*ods
= ofpmsg_body(oh
);
746 ds_put_char(string
, '\n');
747 ds_put_format(string
, "Manufacturer: %.*s\n",
748 (int) sizeof ods
->mfr_desc
, ods
->mfr_desc
);
749 ds_put_format(string
, "Hardware: %.*s\n",
750 (int) sizeof ods
->hw_desc
, ods
->hw_desc
);
751 ds_put_format(string
, "Software: %.*s\n",
752 (int) sizeof ods
->sw_desc
, ods
->sw_desc
);
753 ds_put_format(string
, "Serial Num: %.*s\n",
754 (int) sizeof ods
->serial_num
, ods
->serial_num
);
755 ds_put_format(string
, "DP Description: %.*s\n",
756 (int) sizeof ods
->dp_desc
, ods
->dp_desc
);
762 ofp_print_flow_stats_request(struct ds
*string
, const struct ofp_header
*oh
,
763 const struct ofputil_port_map
*port_map
,
764 const struct ofputil_table_map
*table_map
)
766 struct ofputil_flow_stats_request fsr
;
767 enum ofperr error
= ofputil_decode_flow_stats_request(&fsr
, oh
, NULL
,
770 ofputil_flow_stats_request_format(string
, &fsr
, port_map
, table_map
);
776 ofp_print_flow_stats_reply(struct ds
*string
, const struct ofp_header
*oh
,
777 const struct ofputil_port_map
*port_map
,
778 const struct ofputil_table_map
*table_map
)
780 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
781 struct ofpbuf ofpacts
;
784 ofpbuf_init(&ofpacts
, 64);
786 struct ofputil_flow_stats fs
;
788 retval
= ofputil_decode_flow_stats_reply(&fs
, &b
, true, &ofpacts
);
792 ds_put_cstr(string
, "\n ");
793 ofputil_flow_stats_format(string
, &fs
, port_map
, table_map
, true);
795 ofpbuf_uninit(&ofpacts
);
797 return retval
!= EOF
? retval
: 0;
801 ofp_print_aggregate_stats_reply(struct ds
*string
, const struct ofp_header
*oh
)
803 struct ofputil_aggregate_stats as
;
806 error
= ofputil_decode_aggregate_stats_reply(&as
, oh
);
808 ofputil_aggregate_stats_format(string
, &as
);
814 print_port_stat(struct ds
*string
, const char *leader
, uint64_t stat
, int more
)
816 ds_put_cstr(string
, leader
);
817 if (stat
!= UINT64_MAX
) {
818 ds_put_format(string
, "%"PRIu64
, stat
);
820 ds_put_char(string
, '?');
823 ds_put_cstr(string
, ", ");
825 ds_put_cstr(string
, "\n");
830 print_port_stat_cond(struct ds
*string
, const char *leader
, uint64_t stat
)
832 if (stat
!= UINT64_MAX
) {
833 ds_put_format(string
, "%s%"PRIu64
", ", leader
, stat
);
838 ofp_print_ofpst_port_request(struct ds
*string
, const struct ofp_header
*oh
,
839 const struct ofputil_port_map
*port_map
)
841 ofp_port_t ofp10_port
;
844 error
= ofputil_decode_port_stats_request(oh
, &ofp10_port
);
849 ds_put_cstr(string
, " port_no=");
850 ofputil_format_port(ofp10_port
, port_map
, string
);
856 ofp_print_ofpst_port_reply(struct ds
*string
, const struct ofp_header
*oh
,
857 const struct ofputil_port_map
*port_map
,
861 ds_put_format(string
, " %"PRIuSIZE
" ports\n", ofputil_count_port_stats(oh
));
866 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
868 struct ofputil_port_stats ps
;
871 retval
= ofputil_decode_port_stats(&ps
, &b
);
873 return retval
!= EOF
? retval
: 0;
876 ds_put_cstr(string
, " port ");
877 if (ofp_to_u16(ps
.port_no
) < 10) {
878 ds_put_char(string
, ' ');
880 ofputil_format_port(ps
.port_no
, port_map
, string
);
882 ds_put_cstr(string
, ": rx ");
883 print_port_stat(string
, "pkts=", ps
.stats
.rx_packets
, 1);
884 print_port_stat(string
, "bytes=", ps
.stats
.rx_bytes
, 1);
885 print_port_stat(string
, "drop=", ps
.stats
.rx_dropped
, 1);
886 print_port_stat(string
, "errs=", ps
.stats
.rx_errors
, 1);
887 print_port_stat(string
, "frame=", ps
.stats
.rx_frame_errors
, 1);
888 print_port_stat(string
, "over=", ps
.stats
.rx_over_errors
, 1);
889 print_port_stat(string
, "crc=", ps
.stats
.rx_crc_errors
, 0);
891 ds_put_cstr(string
, " tx ");
892 print_port_stat(string
, "pkts=", ps
.stats
.tx_packets
, 1);
893 print_port_stat(string
, "bytes=", ps
.stats
.tx_bytes
, 1);
894 print_port_stat(string
, "drop=", ps
.stats
.tx_dropped
, 1);
895 print_port_stat(string
, "errs=", ps
.stats
.tx_errors
, 1);
896 print_port_stat(string
, "coll=", ps
.stats
.collisions
, 0);
898 if (ps
.duration_sec
!= UINT32_MAX
) {
899 ds_put_cstr(string
, " duration=");
900 ofp_print_duration(string
, ps
.duration_sec
, ps
.duration_nsec
);
901 ds_put_char(string
, '\n');
903 struct ds string_ext_stats
= DS_EMPTY_INITIALIZER
;
905 ds_init(&string_ext_stats
);
907 print_port_stat_cond(&string_ext_stats
, "1_to_64_packets=",
908 ps
.stats
.rx_1_to_64_packets
);
909 print_port_stat_cond(&string_ext_stats
, "65_to_127_packets=",
910 ps
.stats
.rx_65_to_127_packets
);
911 print_port_stat_cond(&string_ext_stats
, "128_to_255_packets=",
912 ps
.stats
.rx_128_to_255_packets
);
913 print_port_stat_cond(&string_ext_stats
, "256_to_511_packets=",
914 ps
.stats
.rx_256_to_511_packets
);
915 print_port_stat_cond(&string_ext_stats
, "512_to_1023_packets=",
916 ps
.stats
.rx_512_to_1023_packets
);
917 print_port_stat_cond(&string_ext_stats
, "1024_to_1522_packets=",
918 ps
.stats
.rx_1024_to_1522_packets
);
919 print_port_stat_cond(&string_ext_stats
, "1523_to_max_packets=",
920 ps
.stats
.rx_1523_to_max_packets
);
921 print_port_stat_cond(&string_ext_stats
, "broadcast_packets=",
922 ps
.stats
.rx_broadcast_packets
);
923 print_port_stat_cond(&string_ext_stats
, "undersized_errors=",
924 ps
.stats
.rx_undersized_errors
);
925 print_port_stat_cond(&string_ext_stats
, "oversize_errors=",
926 ps
.stats
.rx_oversize_errors
);
927 print_port_stat_cond(&string_ext_stats
, "rx_fragmented_errors=",
928 ps
.stats
.rx_fragmented_errors
);
929 print_port_stat_cond(&string_ext_stats
, "rx_jabber_errors=",
930 ps
.stats
.rx_jabber_errors
);
932 if (string_ext_stats
.length
!= 0) {
933 /* If at least one statistics counter is reported: */
934 ds_put_cstr(string
, " rx rfc2819 ");
935 ds_put_buffer(string
, string_ext_stats
.string
,
936 string_ext_stats
.length
);
937 ds_put_cstr(string
, "\n");
938 ds_destroy(&string_ext_stats
);
941 ds_init(&string_ext_stats
);
943 print_port_stat_cond(&string_ext_stats
, "1_to_64_packets=",
944 ps
.stats
.tx_1_to_64_packets
);
945 print_port_stat_cond(&string_ext_stats
, "65_to_127_packets=",
946 ps
.stats
.tx_65_to_127_packets
);
947 print_port_stat_cond(&string_ext_stats
, "128_to_255_packets=",
948 ps
.stats
.tx_128_to_255_packets
);
949 print_port_stat_cond(&string_ext_stats
, "256_to_511_packets=",
950 ps
.stats
.tx_256_to_511_packets
);
951 print_port_stat_cond(&string_ext_stats
, "512_to_1023_packets=",
952 ps
.stats
.tx_512_to_1023_packets
);
953 print_port_stat_cond(&string_ext_stats
, "1024_to_1522_packets=",
954 ps
.stats
.tx_1024_to_1522_packets
);
955 print_port_stat_cond(&string_ext_stats
, "1523_to_max_packets=",
956 ps
.stats
.tx_1523_to_max_packets
);
957 print_port_stat_cond(&string_ext_stats
, "multicast_packets=",
958 ps
.stats
.tx_multicast_packets
);
959 print_port_stat_cond(&string_ext_stats
, "broadcast_packets=",
960 ps
.stats
.tx_broadcast_packets
);
962 if (string_ext_stats
.length
!= 0) {
963 /* If at least one statistics counter is reported: */
964 ds_put_cstr(string
, " tx rfc2819 ");
965 ds_put_buffer(string
, string_ext_stats
.string
,
966 string_ext_stats
.length
);
967 ds_put_cstr(string
, "\n");
968 ds_destroy(&string_ext_stats
);
971 if (ps
.custom_stats
.size
) {
972 ds_put_cstr(string
, " CUSTOM Statistics");
973 for (i
= 0; i
< ps
.custom_stats
.size
; i
++) {
974 /* 3 counters in the row */
975 if (ps
.custom_stats
.counters
[i
].name
[0]) {
977 ds_put_cstr(string
, "\n");
978 ds_put_cstr(string
, " ");
980 ds_put_char(string
, ' ');
982 ds_put_format(string
, "%s=%"PRIu64
",",
983 ps
.custom_stats
.counters
[i
].name
,
984 ps
.custom_stats
.counters
[i
].value
);
987 ds_put_cstr(string
, "\n");
993 ofp_print_table_stats_reply(struct ds
*string
, const struct ofp_header
*oh
,
994 const struct ofputil_table_map
*table_map
)
996 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
997 ofpraw_pull_assert(&b
);
999 struct ofputil_table_features prev_features
;
1000 struct ofputil_table_stats prev_stats
;
1001 for (int i
= 0;; i
++) {
1002 struct ofputil_table_features features
;
1003 struct ofputil_table_stats stats
;
1006 retval
= ofputil_decode_table_stats_reply(&b
, &stats
, &features
);
1008 return retval
!= EOF
? retval
: 0;
1011 ds_put_char(string
, '\n');
1012 ofputil_table_features_format(string
,
1013 &features
, i
? &prev_features
: NULL
,
1014 &stats
, i
? &prev_stats
: NULL
,
1016 prev_features
= features
;
1022 ofp_print_queue_name(struct ds
*string
, uint32_t queue_id
)
1024 if (queue_id
== OFPQ_ALL
) {
1025 ds_put_cstr(string
, "ALL");
1027 ds_put_format(string
, "%"PRIu32
, queue_id
);
1032 ofp_print_ofpst_queue_request(struct ds
*string
, const struct ofp_header
*oh
,
1033 const struct ofputil_port_map
*port_map
)
1035 struct ofputil_queue_stats_request oqsr
;
1038 error
= ofputil_decode_queue_stats_request(oh
, &oqsr
);
1043 ds_put_cstr(string
, " port=");
1044 ofputil_format_port(oqsr
.port_no
, port_map
, string
);
1046 ds_put_cstr(string
, " queue=");
1047 ofp_print_queue_name(string
, oqsr
.queue_id
);
1053 ofp_print_ofpst_queue_reply(struct ds
*string
, const struct ofp_header
*oh
,
1054 const struct ofputil_port_map
*port_map
,
1057 ds_put_format(string
, " %"PRIuSIZE
" queues\n", ofputil_count_queue_stats(oh
));
1058 if (verbosity
< 1) {
1062 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
1064 struct ofputil_queue_stats qs
;
1067 retval
= ofputil_decode_queue_stats(&qs
, &b
);
1069 return retval
!= EOF
? retval
: 0;
1072 ds_put_cstr(string
, " port ");
1073 ofputil_format_port(qs
.port_no
, port_map
, string
);
1074 ds_put_cstr(string
, " queue ");
1075 ofp_print_queue_name(string
, qs
.queue_id
);
1076 ds_put_cstr(string
, ": ");
1078 print_port_stat(string
, "bytes=", qs
.tx_bytes
, 1);
1079 print_port_stat(string
, "pkts=", qs
.tx_packets
, 1);
1080 print_port_stat(string
, "errors=", qs
.tx_errors
, 1);
1082 ds_put_cstr(string
, "duration=");
1083 if (qs
.duration_sec
!= UINT32_MAX
) {
1084 ofp_print_duration(string
, qs
.duration_sec
, qs
.duration_nsec
);
1086 ds_put_char(string
, '?');
1088 ds_put_char(string
, '\n');
1093 ofp_print_ofpst_port_desc_request(struct ds
*string
,
1094 const struct ofp_header
*oh
,
1095 const struct ofputil_port_map
*port_map
)
1100 error
= ofputil_decode_port_desc_stats_request(oh
, &port
);
1105 ds_put_cstr(string
, " port=");
1106 ofputil_format_port(port
, port_map
, string
);
1112 ofp_print_ofpst_port_desc_reply(struct ds
*string
,
1113 const struct ofp_header
*oh
)
1115 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
1116 ofpraw_pull_assert(&b
);
1117 ds_put_char(string
, '\n');
1118 return ofputil_phy_ports_format(string
, oh
->version
, &b
);
1122 ofp_print_stats(struct ds
*string
, const struct ofp_header
*oh
)
1124 uint16_t flags
= ofpmp_flags(oh
);
1127 ds_put_cstr(string
, " flags=");
1128 if ((!ofpmsg_is_stat_request(oh
) || oh
->version
>= OFP13_VERSION
)
1129 && (flags
& OFPSF_REPLY_MORE
)) {
1130 ds_put_cstr(string
, "[more]");
1131 flags
&= ~OFPSF_REPLY_MORE
;
1134 ds_put_format(string
, "[***unknown flags 0x%04"PRIx16
"***]",
1141 ofp_print_echo(struct ds
*string
, const struct ofp_header
*oh
, int verbosity
)
1143 size_t len
= ntohs(oh
->length
);
1145 ds_put_format(string
, " %"PRIuSIZE
" bytes of payload\n", len
- sizeof *oh
);
1146 if (verbosity
> 1) {
1147 ds_put_hex_dump(string
, oh
+ 1, len
- sizeof *oh
, 0, true);
1154 ofp_print_role_generic(struct ds
*string
, enum ofp12_controller_role role
,
1155 uint64_t generation_id
)
1157 ds_put_cstr(string
, " role=");
1160 case OFPCR12_ROLE_NOCHANGE
:
1161 ds_put_cstr(string
, "nochange");
1163 case OFPCR12_ROLE_EQUAL
:
1164 ds_put_cstr(string
, "equal"); /* OF 1.2 wording */
1166 case OFPCR12_ROLE_MASTER
:
1167 ds_put_cstr(string
, "master");
1169 case OFPCR12_ROLE_SLAVE
:
1170 ds_put_cstr(string
, "slave");
1176 if (generation_id
!= UINT64_MAX
) {
1177 ds_put_format(string
, " generation_id=%"PRIu64
, generation_id
);
1182 ofp_print_role_message(struct ds
*string
, const struct ofp_header
*oh
)
1184 struct ofputil_role_request rr
;
1187 error
= ofputil_decode_role_message(oh
, &rr
);
1192 ofp_print_role_generic(string
, rr
.role
, rr
.have_generation_id
? rr
.generation_id
: UINT64_MAX
);
1198 ofp_print_role_status_message(struct ds
*string
, const struct ofp_header
*oh
)
1200 struct ofputil_role_status rs
;
1203 error
= ofputil_decode_role_status(oh
, &rs
);
1208 ofp_print_role_generic(string
, rs
.role
, rs
.generation_id
);
1210 ds_put_cstr(string
, " reason=");
1212 switch (rs
.reason
) {
1213 case OFPCRR_MASTER_REQUEST
:
1214 ds_put_cstr(string
, "master_request");
1217 ds_put_cstr(string
, "configuration_changed");
1219 case OFPCRR_EXPERIMENTER
:
1220 ds_put_cstr(string
, "experimenter_data_changed");
1222 case OFPCRR_N_REASONS
:
1224 ds_put_cstr(string
, "(unknown)");
1232 ofp_print_nxt_flow_mod_table_id(struct ds
*string
, const struct ofp_header
*oh
)
1234 bool enable
= ofputil_decode_nx_flow_mod_table_id(oh
);
1235 ds_put_format(string
, " %s", enable
? "enable" : "disable");
1240 ofp_print_nxt_set_flow_format(struct ds
*string
, const struct ofp_header
*oh
)
1242 enum ofputil_protocol p
= ofputil_decode_nx_set_flow_format(oh
);
1243 ds_put_format(string
, " format=%s",
1244 p
== OFPUTIL_P_OF10_STD
? "openflow10"
1245 : p
== OFPUTIL_P_OF10_NXM
? "nxm"
1251 ofp_print_nxt_set_packet_in_format(struct ds
*string
,
1252 const struct ofp_header
*oh
)
1254 enum ofputil_packet_in_format format
;
1255 enum ofperr error
= ofputil_decode_set_packet_in_format(oh
, &format
);
1257 ds_put_format(string
, " format=%s",
1258 ofputil_packet_in_format_to_string(format
));
1263 /* Returns a string form of 'reason'. The return value is either a statically
1264 * allocated constant string or the 'bufsize'-byte buffer 'reasonbuf'.
1265 * 'bufsize' should be at least OFP_PORT_REASON_BUFSIZE. */
1266 #define OFP_PORT_REASON_BUFSIZE (INT_STRLEN(int) + 1)
1268 ofp_port_reason_to_string(enum ofp_port_reason reason
,
1269 char *reasonbuf
, size_t bufsize
)
1281 case OFPPR_N_REASONS
:
1283 snprintf(reasonbuf
, bufsize
, "%d", (int) reason
);
1288 /* Returns a string form of 'reason'. The return value is either a statically
1289 * allocated constant string or the 'bufsize'-byte buffer 'reasonbuf'.
1290 * 'bufsize' should be at least OFP_ASYNC_CONFIG_REASON_BUFSIZE. */
1292 ofp_role_reason_to_string(enum ofp14_controller_role_reason reason
,
1293 char *reasonbuf
, size_t bufsize
)
1296 case OFPCRR_MASTER_REQUEST
:
1297 return "master_request";
1300 return "configuration_changed";
1302 case OFPCRR_EXPERIMENTER
:
1303 return "experimenter_data_changed";
1305 case OFPCRR_N_REASONS
:
1307 snprintf(reasonbuf
, bufsize
, "%d", (int) reason
);
1312 /* Returns a string form of 'reason'. The return value is either a statically
1313 * allocated constant string or the 'bufsize'-byte buffer 'reasonbuf'.
1314 * 'bufsize' should be at least OFP_ASYNC_CONFIG_REASON_BUFSIZE. */
1316 ofp_table_reason_to_string(enum ofp14_table_reason reason
,
1317 char *reasonbuf
, size_t bufsize
)
1320 case OFPTR_VACANCY_DOWN
:
1321 return "vacancy_down";
1323 case OFPTR_VACANCY_UP
:
1324 return "vacancy_up";
1327 snprintf(reasonbuf
, bufsize
, "%d", (int) reason
);
1332 /* Returns a string form of 'reason'. The return value is either a statically
1333 * allocated constant string or the 'bufsize'-byte buffer 'reasonbuf'.
1334 * 'bufsize' should be at least OFP_ASYNC_CONFIG_REASON_BUFSIZE. */
1336 ofp_requestforward_reason_to_string(enum ofp14_requestforward_reason reason
,
1337 char *reasonbuf
, size_t bufsize
)
1340 case OFPRFR_GROUP_MOD
:
1341 return "group_mod_request";
1343 case OFPRFR_METER_MOD
:
1344 return "meter_mod_request";
1346 case OFPRFR_N_REASONS
:
1348 snprintf(reasonbuf
, bufsize
, "%d", (int) reason
);
1354 ofp_async_config_reason_to_string(uint32_t reason
,
1355 enum ofputil_async_msg_type type
,
1356 char *reasonbuf
, size_t bufsize
)
1360 return ofputil_packet_in_reason_to_string(reason
, reasonbuf
, bufsize
);
1362 case OAM_PORT_STATUS
:
1363 return ofp_port_reason_to_string(reason
, reasonbuf
, bufsize
);
1365 case OAM_FLOW_REMOVED
:
1366 return ofp_flow_removed_reason_to_string(reason
, reasonbuf
, bufsize
);
1368 case OAM_ROLE_STATUS
:
1369 return ofp_role_reason_to_string(reason
, reasonbuf
, bufsize
);
1371 case OAM_TABLE_STATUS
:
1372 return ofp_table_reason_to_string(reason
, reasonbuf
, bufsize
);
1374 case OAM_REQUESTFORWARD
:
1375 return ofp_requestforward_reason_to_string(reason
, reasonbuf
, bufsize
);
1379 return "Unknown asynchronous configuration message type";
1384 #define OFP_ASYNC_CONFIG_REASON_BUFSIZE (INT_STRLEN(int) + 1)
1386 ofp_print_set_async_config(struct ds
*string
, const struct ofp_header
*oh
,
1387 enum ofptype ofptype
)
1389 struct ofputil_async_cfg basis
= OFPUTIL_ASYNC_CFG_INIT
;
1390 struct ofputil_async_cfg ac
;
1392 bool is_reply
= ofptype
== OFPTYPE_GET_ASYNC_REPLY
;
1393 enum ofperr error
= ofputil_decode_set_async_config(oh
, is_reply
,
1399 for (int i
= 0; i
< 2; i
++) {
1400 ds_put_format(string
, "\n %s:\n", i
== 0 ? "master" : "slave");
1401 for (uint32_t type
= 0; type
< OAM_N_TYPES
; type
++) {
1402 ds_put_format(string
, "%16s:",
1403 ofputil_async_msg_type_to_string(type
));
1405 uint32_t role
= i
== 0 ? ac
.master
[type
] : ac
.slave
[type
];
1406 for (int j
= 0; j
< 32; j
++) {
1407 if (role
& (1u << j
)) {
1408 char reasonbuf
[OFP_ASYNC_CONFIG_REASON_BUFSIZE
];
1411 reason
= ofp_async_config_reason_to_string(
1412 j
, type
, reasonbuf
, sizeof reasonbuf
);
1414 ds_put_format(string
, " %s", reason
);
1419 ds_put_cstr(string
, " (off)");
1421 ds_put_char(string
, '\n');
1429 ofp_print_nxt_set_controller_id(struct ds
*string
,
1430 const struct nx_controller_id
*nci
)
1432 ds_put_format(string
, " id=%"PRIu16
, ntohs(nci
->controller_id
));
1437 ofp_print_nxt_flow_monitor_cancel(struct ds
*string
,
1438 const struct ofp_header
*oh
)
1440 ds_put_format(string
, " id=%"PRIu32
,
1441 ofputil_decode_flow_monitor_cancel(oh
));
1446 ofp_print_nxst_flow_monitor_request(struct ds
*string
,
1447 const struct ofp_header
*oh
,
1448 const struct ofputil_port_map
*port_map
,
1449 const struct ofputil_table_map
*table_map
)
1451 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
1453 struct ofputil_flow_monitor_request request
;
1456 retval
= ofputil_decode_flow_monitor_request(&request
, &b
);
1458 return retval
!= EOF
? retval
: 0;
1461 ofputil_flow_monitor_request_format(string
, &request
,
1462 port_map
, table_map
);
1467 ofp_print_nxst_flow_monitor_reply(struct ds
*string
,
1468 const struct ofp_header
*oh
,
1469 const struct ofputil_port_map
*port_map
,
1470 const struct ofputil_table_map
*table_map
)
1472 uint64_t ofpacts_stub
[1024 / 8];
1473 struct ofpbuf ofpacts
= OFPBUF_STUB_INITIALIZER(ofpacts_stub
);
1474 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
1477 struct ofputil_flow_update update
;
1478 int retval
= ofputil_decode_flow_update(&update
, &b
, &ofpacts
);
1480 ofpbuf_uninit(&ofpacts
);
1481 return retval
!= EOF
? retval
: 0;
1483 ofputil_flow_update_format(string
, &update
, port_map
, table_map
);
1488 ofp_print_version(const struct ofp_header
*oh
,
1491 switch (oh
->version
) {
1495 ds_put_cstr(string
, " (OF1.1)");
1498 ds_put_cstr(string
, " (OF1.2)");
1501 ds_put_cstr(string
, " (OF1.3)");
1504 ds_put_cstr(string
, " (OF1.4)");
1507 ds_put_cstr(string
, " (OF1.5)");
1510 ds_put_cstr(string
, " (OF1.6)");
1513 ds_put_format(string
, " (OF 0x%02"PRIx8
")", oh
->version
);
1516 ds_put_format(string
, " (xid=0x%"PRIx32
"):", ntohl(oh
->xid
));
1520 ofp_header_to_string__(const struct ofp_header
*oh
, enum ofpraw raw
,
1523 ds_put_cstr(string
, ofpraw_get_name(raw
));
1524 ofp_print_version(oh
, string
);
1528 ofp_print_table_desc_reply(struct ds
*s
, const struct ofp_header
*oh
,
1529 const struct ofputil_table_map
*table_map
)
1531 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
1533 struct ofputil_table_desc td
;
1536 retval
= ofputil_decode_table_desc(&b
, &td
, oh
->version
);
1538 return retval
!= EOF
? retval
: 0;
1540 ofputil_table_desc_format(s
, &td
, table_map
);
1545 bundle_flags_to_name(uint32_t bit
)
1558 ofp_print_bundle_ctrl(struct ds
*s
, const struct ofp_header
*oh
)
1561 struct ofputil_bundle_ctrl_msg bctrl
;
1563 error
= ofputil_decode_bundle_ctrl(oh
, &bctrl
);
1568 ds_put_char(s
, '\n');
1570 ds_put_format(s
, " bundle_id=%#"PRIx32
" type=", bctrl
.bundle_id
);
1571 switch (bctrl
.type
) {
1572 case OFPBCT_OPEN_REQUEST
:
1573 ds_put_cstr(s
, "OPEN_REQUEST");
1575 case OFPBCT_OPEN_REPLY
:
1576 ds_put_cstr(s
, "OPEN_REPLY");
1578 case OFPBCT_CLOSE_REQUEST
:
1579 ds_put_cstr(s
, "CLOSE_REQUEST");
1581 case OFPBCT_CLOSE_REPLY
:
1582 ds_put_cstr(s
, "CLOSE_REPLY");
1584 case OFPBCT_COMMIT_REQUEST
:
1585 ds_put_cstr(s
, "COMMIT_REQUEST");
1587 case OFPBCT_COMMIT_REPLY
:
1588 ds_put_cstr(s
, "COMMIT_REPLY");
1590 case OFPBCT_DISCARD_REQUEST
:
1591 ds_put_cstr(s
, "DISCARD_REQUEST");
1593 case OFPBCT_DISCARD_REPLY
:
1594 ds_put_cstr(s
, "DISCARD_REPLY");
1598 ds_put_cstr(s
, " flags=");
1599 ofp_print_bit_names(s
, bctrl
.flags
, bundle_flags_to_name
, ' ');
1605 ofp_print_bundle_add(struct ds
*s
, const struct ofp_header
*oh
,
1606 const struct ofputil_port_map
*port_map
,
1607 const struct ofputil_table_map
*table_map
,
1611 struct ofputil_bundle_add_msg badd
;
1613 error
= ofputil_decode_bundle_add(oh
, &badd
, NULL
);
1618 ds_put_char(s
, '\n');
1619 ds_put_format(s
, " bundle_id=%#"PRIx32
, badd
.bundle_id
);
1620 ds_put_cstr(s
, " flags=");
1621 ofp_print_bit_names(s
, badd
.flags
, bundle_flags_to_name
, ' ');
1623 ds_put_char(s
, '\n');
1624 char *msg
= ofp_to_string(badd
.msg
, ntohs(badd
.msg
->length
), port_map
,
1625 table_map
, verbosity
);
1626 ds_put_and_free_cstr(s
, msg
);
1632 print_tlv_table(struct ds
*s
, struct ovs_list
*mappings
)
1634 struct ofputil_tlv_map
*map
;
1636 ds_put_cstr(s
, " mapping table:\n");
1637 ds_put_cstr(s
, " class type length match field\n");
1638 ds_put_cstr(s
, " ------ ---- ------ --------------");
1640 LIST_FOR_EACH (map
, list_node
, mappings
) {
1641 ds_put_format(s
, "\n %#6"PRIx16
" %#4"PRIx8
" %6"PRIu8
" "
1642 "tun_metadata%"PRIu16
,
1643 map
->option_class
, map
->option_type
, map
->option_len
,
1649 ofp_print_tlv_table_mod(struct ds
*s
, const struct ofp_header
*oh
)
1652 struct ofputil_tlv_table_mod ttm
;
1654 error
= ofputil_decode_tlv_table_mod(oh
, &ttm
);
1659 ds_put_cstr(s
, "\n ");
1661 switch (ttm
.command
) {
1663 ds_put_cstr(s
, "ADD");
1666 ds_put_cstr(s
, "DEL");
1669 ds_put_cstr(s
, "CLEAR");
1673 if (ttm
.command
!= NXTTMC_CLEAR
) {
1674 print_tlv_table(s
, &ttm
.mappings
);
1677 ofputil_uninit_tlv_table(&ttm
.mappings
);
1683 ofp_print_tlv_table_reply(struct ds
*s
, const struct ofp_header
*oh
)
1686 struct ofputil_tlv_table_reply ttr
;
1687 struct ofputil_tlv_map
*map
;
1688 int allocated_space
= 0;
1690 error
= ofputil_decode_tlv_table_reply(oh
, &ttr
);
1695 ds_put_char(s
, '\n');
1697 LIST_FOR_EACH (map
, list_node
, &ttr
.mappings
) {
1698 allocated_space
+= map
->option_len
;
1701 ds_put_format(s
, " max option space=%"PRIu32
" max fields=%"PRIu16
"\n",
1702 ttr
.max_option_space
, ttr
.max_fields
);
1703 ds_put_format(s
, " allocated option space=%d\n", allocated_space
);
1704 ds_put_char(s
, '\n');
1705 print_tlv_table(s
, &ttr
.mappings
);
1707 ofputil_uninit_tlv_table(&ttr
.mappings
);
1712 /* This function will print the request forward message. The reason for
1713 * request forward is taken from rf.request.type */
1715 ofp_print_requestforward(struct ds
*string
, const struct ofp_header
*oh
,
1716 const struct ofputil_port_map
*port_map
,
1717 const struct ofputil_table_map
*table_map
)
1719 struct ofputil_requestforward rf
;
1722 error
= ofputil_decode_requestforward(oh
, &rf
);
1727 ds_put_cstr(string
, " reason=");
1729 switch (rf
.reason
) {
1730 case OFPRFR_GROUP_MOD
:
1731 ds_put_cstr(string
, "group_mod");
1732 ofputil_group_mod_format__(string
, oh
->version
, rf
.group_mod
, port_map
,
1736 case OFPRFR_METER_MOD
:
1737 ds_put_cstr(string
, "meter_mod");
1738 ofp_print_meter_mod__(string
, rf
.meter_mod
);
1741 case OFPRFR_N_REASONS
:
1744 ofputil_destroy_requestforward(&rf
);
1750 print_ipfix_stat(struct ds
*string
, const char *leader
, uint64_t stat
, int more
)
1752 ds_put_cstr(string
, leader
);
1753 if (stat
!= UINT64_MAX
) {
1754 ds_put_format(string
, "%"PRIu64
, stat
);
1756 ds_put_char(string
, '?');
1759 ds_put_cstr(string
, ", ");
1761 ds_put_cstr(string
, "\n");
1766 ofp_print_nxst_ipfix_bridge_reply(struct ds
*string
, const struct ofp_header
*oh
)
1768 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
1770 struct ofputil_ipfix_stats is
;
1773 retval
= ofputil_pull_ipfix_stats(&is
, &b
);
1775 return retval
!= EOF
? retval
: 0;
1778 ds_put_cstr(string
, "\n bridge ipfix: ");
1779 print_ipfix_stat(string
, "flows=", is
.total_flows
, 1);
1780 print_ipfix_stat(string
, "current flows=", is
.current_flows
, 1);
1781 print_ipfix_stat(string
, "sampled pkts=", is
.pkts
, 1);
1782 print_ipfix_stat(string
, "ipv4 ok=", is
.ipv4_pkts
, 1);
1783 print_ipfix_stat(string
, "ipv6 ok=", is
.ipv6_pkts
, 1);
1784 print_ipfix_stat(string
, "tx pkts=", is
.tx_pkts
, 0);
1785 ds_put_cstr(string
, " ");
1786 print_ipfix_stat(string
, "pkts errs=", is
.error_pkts
, 1);
1787 print_ipfix_stat(string
, "ipv4 errs=", is
.ipv4_error_pkts
, 1);
1788 print_ipfix_stat(string
, "ipv6 errs=", is
.ipv6_error_pkts
, 1);
1789 print_ipfix_stat(string
, "tx errs=", is
.tx_errors
, 0);
1794 ofp_print_nxst_ipfix_flow_reply(struct ds
*string
, const struct ofp_header
*oh
)
1796 ds_put_format(string
, " %"PRIuSIZE
" ids\n", ofputil_count_ipfix_stats(oh
));
1798 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
1800 struct ofputil_ipfix_stats is
;
1803 retval
= ofputil_pull_ipfix_stats(&is
, &b
);
1805 return retval
!= EOF
? retval
: 0;
1808 ds_put_cstr(string
, " id");
1809 ds_put_format(string
, " %3"PRIuSIZE
": ", (size_t) is
.collector_set_id
);
1810 print_ipfix_stat(string
, "flows=", is
.total_flows
, 1);
1811 print_ipfix_stat(string
, "current flows=", is
.current_flows
, 1);
1812 print_ipfix_stat(string
, "sampled pkts=", is
.pkts
, 1);
1813 print_ipfix_stat(string
, "ipv4 ok=", is
.ipv4_pkts
, 1);
1814 print_ipfix_stat(string
, "ipv6 ok=", is
.ipv6_pkts
, 1);
1815 print_ipfix_stat(string
, "tx pkts=", is
.tx_pkts
, 0);
1816 ds_put_cstr(string
, " ");
1817 print_ipfix_stat(string
, "pkts errs=", is
.error_pkts
, 1);
1818 print_ipfix_stat(string
, "ipv4 errs=", is
.ipv4_error_pkts
, 1);
1819 print_ipfix_stat(string
, "ipv6 errs=", is
.ipv6_error_pkts
, 1);
1820 print_ipfix_stat(string
, "tx errs=", is
.tx_errors
, 0);
1825 ofp_print_nxt_ct_flush_zone(struct ds
*string
, const struct nx_zone_id
*nzi
)
1827 ds_put_format(string
, " zone_id=%"PRIu16
, ntohs(nzi
->zone_id
));
1832 ofp_to_string__(const struct ofp_header
*oh
,
1833 const struct ofputil_port_map
*port_map
,
1834 const struct ofputil_table_map
*table_map
, enum ofpraw raw
,
1835 struct ds
*string
, int verbosity
)
1837 if (ofpmsg_is_stat(oh
)) {
1838 ofp_print_stats(string
, oh
);
1841 const void *msg
= oh
;
1842 enum ofptype type
= ofptype_from_ofpraw(raw
);
1844 case OFPTYPE_GROUP_STATS_REQUEST
:
1845 return ofputil_group_stats_request_format(string
, oh
);
1847 case OFPTYPE_GROUP_STATS_REPLY
:
1848 return ofputil_group_stats_format(string
, oh
);
1850 case OFPTYPE_GROUP_DESC_STATS_REQUEST
:
1851 return ofputil_group_desc_request_format(string
, oh
);
1853 case OFPTYPE_GROUP_DESC_STATS_REPLY
:
1854 return ofputil_group_desc_format(string
, oh
, port_map
, table_map
);
1856 case OFPTYPE_GROUP_FEATURES_STATS_REQUEST
:
1859 case OFPTYPE_GROUP_FEATURES_STATS_REPLY
:
1860 return ofputil_group_features_format(string
, oh
);
1862 case OFPTYPE_GROUP_MOD
:
1863 return ofputil_group_mod_format(string
, oh
, port_map
, table_map
);
1865 case OFPTYPE_TABLE_FEATURES_STATS_REQUEST
:
1866 case OFPTYPE_TABLE_FEATURES_STATS_REPLY
:
1867 return ofp_print_table_features_reply(string
, oh
, table_map
);
1869 case OFPTYPE_TABLE_DESC_REQUEST
:
1870 case OFPTYPE_TABLE_DESC_REPLY
:
1871 return ofp_print_table_desc_reply(string
, oh
, table_map
);
1874 return ofp_print_hello(string
, oh
);
1877 return ofp_print_error_msg(string
, oh
, port_map
, table_map
);
1879 case OFPTYPE_ECHO_REQUEST
:
1880 case OFPTYPE_ECHO_REPLY
:
1881 return ofp_print_echo(string
, oh
, verbosity
);
1883 case OFPTYPE_FEATURES_REQUEST
:
1886 case OFPTYPE_FEATURES_REPLY
:
1887 return ofp_print_switch_features(string
, oh
);
1889 case OFPTYPE_GET_CONFIG_REQUEST
:
1892 case OFPTYPE_GET_CONFIG_REPLY
:
1893 return ofp_print_get_config_reply(string
, oh
);
1895 case OFPTYPE_SET_CONFIG
:
1896 return ofp_print_set_config(string
, oh
);
1898 case OFPTYPE_PACKET_IN
:
1899 return ofp_print_packet_in(string
, oh
, port_map
, table_map
, verbosity
);
1901 case OFPTYPE_FLOW_REMOVED
:
1902 return ofp_print_flow_removed(string
, oh
, port_map
, table_map
);
1904 case OFPTYPE_PORT_STATUS
:
1905 return ofp_print_port_status(string
, oh
);
1907 case OFPTYPE_PACKET_OUT
:
1908 return ofp_print_packet_out(string
, oh
, port_map
, table_map
,
1911 case OFPTYPE_FLOW_MOD
:
1912 return ofputil_flow_mod_format(string
, oh
, port_map
, table_map
,
1915 case OFPTYPE_PORT_MOD
:
1916 return ofp_print_port_mod(string
, oh
, port_map
);
1918 case OFPTYPE_TABLE_MOD
:
1919 return ofp_print_table_mod(string
, oh
, table_map
);
1921 case OFPTYPE_METER_MOD
:
1922 return ofp_print_meter_mod(string
, oh
);
1924 case OFPTYPE_BARRIER_REQUEST
:
1925 case OFPTYPE_BARRIER_REPLY
:
1928 case OFPTYPE_QUEUE_GET_CONFIG_REQUEST
:
1929 return ofp_print_queue_get_config_request(string
, oh
, port_map
);
1931 case OFPTYPE_QUEUE_GET_CONFIG_REPLY
:
1932 return ofp_print_queue_get_config_reply(string
, oh
, port_map
);
1934 case OFPTYPE_ROLE_REQUEST
:
1935 case OFPTYPE_ROLE_REPLY
:
1936 return ofp_print_role_message(string
, oh
);
1937 case OFPTYPE_ROLE_STATUS
:
1938 return ofp_print_role_status_message(string
, oh
);
1940 case OFPTYPE_REQUESTFORWARD
:
1941 return ofp_print_requestforward(string
, oh
, port_map
, table_map
);
1943 case OFPTYPE_TABLE_STATUS
:
1944 return ofp_print_table_status_message(string
, oh
, table_map
);
1946 case OFPTYPE_METER_STATS_REQUEST
:
1947 case OFPTYPE_METER_CONFIG_STATS_REQUEST
:
1948 return ofp_print_meter_stats_request(string
, oh
);
1950 case OFPTYPE_METER_STATS_REPLY
:
1951 return ofp_print_meter_stats_reply(string
, oh
);
1953 case OFPTYPE_METER_CONFIG_STATS_REPLY
:
1954 return ofp_print_meter_config_reply(string
, oh
);
1956 case OFPTYPE_METER_FEATURES_STATS_REPLY
:
1957 return ofp_print_meter_features_reply(string
, oh
);
1959 case OFPTYPE_DESC_STATS_REQUEST
:
1960 case OFPTYPE_METER_FEATURES_STATS_REQUEST
:
1963 case OFPTYPE_FLOW_STATS_REQUEST
:
1964 case OFPTYPE_AGGREGATE_STATS_REQUEST
:
1965 return ofp_print_flow_stats_request(string
, oh
, port_map
, table_map
);
1967 case OFPTYPE_TABLE_STATS_REQUEST
:
1970 case OFPTYPE_PORT_STATS_REQUEST
:
1971 return ofp_print_ofpst_port_request(string
, oh
, port_map
);
1973 case OFPTYPE_QUEUE_STATS_REQUEST
:
1974 return ofp_print_ofpst_queue_request(string
, oh
, port_map
);
1976 case OFPTYPE_DESC_STATS_REPLY
:
1977 return ofp_print_ofpst_desc_reply(string
, oh
);
1979 case OFPTYPE_FLOW_STATS_REPLY
:
1980 return ofp_print_flow_stats_reply(string
, oh
, port_map
, table_map
);
1982 case OFPTYPE_QUEUE_STATS_REPLY
:
1983 return ofp_print_ofpst_queue_reply(string
, oh
, port_map
, verbosity
);
1985 case OFPTYPE_PORT_STATS_REPLY
:
1986 return ofp_print_ofpst_port_reply(string
, oh
, port_map
, verbosity
);
1988 case OFPTYPE_TABLE_STATS_REPLY
:
1989 return ofp_print_table_stats_reply(string
, oh
, table_map
);
1991 case OFPTYPE_AGGREGATE_STATS_REPLY
:
1992 return ofp_print_aggregate_stats_reply(string
, oh
);
1994 case OFPTYPE_PORT_DESC_STATS_REQUEST
:
1995 return ofp_print_ofpst_port_desc_request(string
, oh
, port_map
);
1997 case OFPTYPE_PORT_DESC_STATS_REPLY
:
1998 return ofp_print_ofpst_port_desc_reply(string
, oh
);
2000 case OFPTYPE_FLOW_MOD_TABLE_ID
:
2001 return ofp_print_nxt_flow_mod_table_id(string
, oh
);
2003 case OFPTYPE_SET_FLOW_FORMAT
:
2004 return ofp_print_nxt_set_flow_format(string
, oh
);
2006 case OFPTYPE_SET_PACKET_IN_FORMAT
:
2007 return ofp_print_nxt_set_packet_in_format(string
, oh
);
2009 case OFPTYPE_FLOW_AGE
:
2012 case OFPTYPE_SET_CONTROLLER_ID
:
2013 return ofp_print_nxt_set_controller_id(string
, ofpmsg_body(oh
));
2015 case OFPTYPE_GET_ASYNC_REPLY
:
2016 case OFPTYPE_SET_ASYNC_CONFIG
:
2017 return ofp_print_set_async_config(string
, oh
, type
);
2018 case OFPTYPE_GET_ASYNC_REQUEST
:
2020 case OFPTYPE_FLOW_MONITOR_CANCEL
:
2021 return ofp_print_nxt_flow_monitor_cancel(string
, msg
);
2023 case OFPTYPE_FLOW_MONITOR_PAUSED
:
2024 case OFPTYPE_FLOW_MONITOR_RESUMED
:
2027 case OFPTYPE_FLOW_MONITOR_STATS_REQUEST
:
2028 return ofp_print_nxst_flow_monitor_request(string
, msg
, port_map
,
2031 case OFPTYPE_FLOW_MONITOR_STATS_REPLY
:
2032 return ofp_print_nxst_flow_monitor_reply(string
, msg
, port_map
,
2035 case OFPTYPE_BUNDLE_CONTROL
:
2036 return ofp_print_bundle_ctrl(string
, msg
);
2038 case OFPTYPE_BUNDLE_ADD_MESSAGE
:
2039 return ofp_print_bundle_add(string
, msg
, port_map
, table_map
,
2042 case OFPTYPE_NXT_TLV_TABLE_MOD
:
2043 return ofp_print_tlv_table_mod(string
, msg
);
2045 case OFPTYPE_NXT_TLV_TABLE_REQUEST
:
2048 case OFPTYPE_NXT_TLV_TABLE_REPLY
:
2049 return ofp_print_tlv_table_reply(string
, msg
);
2051 case OFPTYPE_NXT_RESUME
:
2052 return ofp_print_packet_in(string
, msg
, port_map
, table_map
,
2054 case OFPTYPE_IPFIX_BRIDGE_STATS_REQUEST
:
2056 case OFPTYPE_IPFIX_BRIDGE_STATS_REPLY
:
2057 return ofp_print_nxst_ipfix_bridge_reply(string
, oh
);
2058 case OFPTYPE_IPFIX_FLOW_STATS_REQUEST
:
2060 case OFPTYPE_IPFIX_FLOW_STATS_REPLY
:
2061 return ofp_print_nxst_ipfix_flow_reply(string
, oh
);
2063 case OFPTYPE_CT_FLUSH_ZONE
:
2064 return ofp_print_nxt_ct_flush_zone(string
, ofpmsg_body(oh
));
2071 add_newline(struct ds
*s
)
2073 if (s
->length
&& s
->string
[s
->length
- 1] != '\n') {
2074 ds_put_char(s
, '\n');
2078 /* Composes and returns a string representing the OpenFlow packet of 'len'
2079 * bytes at 'oh' at the given 'verbosity' level. 0 is a minimal amount of
2080 * verbosity and higher numbers increase verbosity. The caller is responsible
2081 * for freeing the string. */
2083 ofp_to_string(const void *oh_
, size_t len
,
2084 const struct ofputil_port_map
*port_map
,
2085 const struct ofputil_table_map
*table_map
,
2088 struct ds string
= DS_EMPTY_INITIALIZER
;
2089 const struct ofp_header
*oh
= oh_
;
2092 ds_put_cstr(&string
, "OpenFlow message is empty\n");
2093 } else if (len
< sizeof(struct ofp_header
)) {
2094 ds_put_format(&string
, "OpenFlow packet too short (only %"PRIuSIZE
" bytes):\n",
2096 } else if (ntohs(oh
->length
) > len
) {
2100 error
= ofpraw_decode_partial(&raw
, oh
, len
);
2102 ofp_header_to_string__(oh
, raw
, &string
);
2103 ds_put_char(&string
, '\n');
2106 ds_put_format(&string
,
2107 "(***truncated to %"PRIuSIZE
" bytes from %"PRIu16
"***)\n",
2108 len
, ntohs(oh
->length
));
2109 } else if (ntohs(oh
->length
) < len
) {
2110 ds_put_format(&string
,
2111 "(***only uses %"PRIu16
" bytes out of %"PRIuSIZE
"***)\n",
2112 ntohs(oh
->length
), len
);
2117 error
= ofpraw_decode(&raw
, oh
);
2119 ofp_header_to_string__(oh
, raw
, &string
);
2120 size_t header_len
= string
.length
;
2122 error
= ofp_to_string__(oh
, port_map
, table_map
,
2123 raw
, &string
, verbosity
);
2125 if (string
.length
> header_len
) {
2126 ds_chomp(&string
, ' ');
2127 add_newline(&string
);
2129 ds_put_char(&string
, ' ');
2131 ofp_print_error(&string
, error
);
2133 ds_chomp(&string
, ' ');
2136 ofp_print_error(&string
, error
);
2139 if (verbosity
>= 5 || error
) {
2140 add_newline(&string
);
2141 ds_put_hex_dump(&string
, oh
, len
, 0, true);
2144 add_newline(&string
);
2145 return ds_steal_cstr(&string
);
2147 ds_put_hex_dump(&string
, oh
, len
, 0, true);
2148 return ds_steal_cstr(&string
);
2152 print_and_free(FILE *stream
, char *string
)
2154 fputs(string
, stream
);
2158 /* Pretty-print the OpenFlow packet of 'len' bytes at 'oh' to 'stream' at the
2159 * given 'verbosity' level. 0 is a minimal amount of verbosity and higher
2160 * numbers increase verbosity. */
2162 ofp_print(FILE *stream
, const void *oh
, size_t len
,
2163 const struct ofputil_port_map
*port_map
,
2164 const struct ofputil_table_map
*table_map
, int verbosity
)
2166 print_and_free(stream
, ofp_to_string(oh
, len
, port_map
, table_map
,
2170 /* Dumps the contents of the Ethernet frame in the 'len' bytes starting at
2171 * 'data' to 'stream'. */
2173 ofp_print_packet(FILE *stream
, const void *data
, size_t len
,
2174 ovs_be32 packet_type
)
2176 print_and_free(stream
, ofp_packet_to_string(data
, len
, packet_type
));
2180 ofp_print_dp_packet(FILE *stream
, const struct dp_packet
*packet
)
2182 print_and_free(stream
, ofp_dp_packet_to_string(packet
));