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_bucket_id(struct ds
*s
, const char *label
, uint32_t bucket_id
,
1529 enum ofp_version ofp_version
)
1531 if (ofp_version
< OFP15_VERSION
) {
1535 ds_put_cstr(s
, label
);
1537 switch (bucket_id
) {
1538 case OFPG15_BUCKET_FIRST
:
1539 ds_put_cstr(s
, "first");
1541 case OFPG15_BUCKET_LAST
:
1542 ds_put_cstr(s
, "last");
1544 case OFPG15_BUCKET_ALL
:
1545 ds_put_cstr(s
, "all");
1548 ds_put_format(s
, "%"PRIu32
, bucket_id
);
1552 ds_put_char(s
, ',');
1556 ofp_print_group(struct ds
*s
, uint32_t group_id
, uint8_t type
,
1557 const struct ovs_list
*p_buckets
,
1558 const struct ofputil_group_props
*props
,
1559 enum ofp_version ofp_version
, bool suppress_type
,
1560 const struct ofputil_port_map
*port_map
,
1561 const struct ofputil_table_map
*table_map
)
1563 struct ofputil_bucket
*bucket
;
1565 ds_put_format(s
, "group_id=%"PRIu32
, group_id
);
1567 if (!suppress_type
) {
1568 static const char *type_str
[] = { "all", "select", "indirect",
1570 ds_put_format(s
, ",type=%s", type_str
[type
> 4 ? 4 : type
]);
1573 if (props
->selection_method
[0]) {
1574 ds_put_format(s
, ",selection_method=%s", props
->selection_method
);
1575 if (props
->selection_method_param
) {
1576 ds_put_format(s
, ",selection_method_param=%"PRIu64
,
1577 props
->selection_method_param
);
1580 size_t n
= bitmap_count1(props
->fields
.used
.bm
, MFF_N_IDS
);
1582 ds_put_cstr(s
, ",fields=");
1583 oxm_format_field_array(s
, &props
->fields
);
1585 ds_put_cstr(s
, ",fields(");
1586 oxm_format_field_array(s
, &props
->fields
);
1587 ds_put_char(s
, ')');
1595 ds_put_char(s
, ',');
1597 LIST_FOR_EACH (bucket
, list_node
, p_buckets
) {
1598 ds_put_cstr(s
, "bucket=");
1600 ofp_print_bucket_id(s
, "bucket_id:", bucket
->bucket_id
, ofp_version
);
1601 if (bucket
->weight
!= (type
== OFPGT11_SELECT
? 1 : 0)) {
1602 ds_put_format(s
, "weight:%"PRIu16
",", bucket
->weight
);
1604 if (bucket
->watch_port
!= OFPP_NONE
) {
1605 ds_put_cstr(s
, "watch_port:");
1606 ofputil_format_port(bucket
->watch_port
, port_map
, s
);
1607 ds_put_char(s
, ',');
1609 if (bucket
->watch_group
!= OFPG_ANY
) {
1610 ds_put_format(s
, "watch_group:%"PRIu32
",", bucket
->watch_group
);
1613 ds_put_cstr(s
, "actions=");
1614 struct ofpact_format_params fp
= {
1615 .port_map
= port_map
,
1616 .table_map
= table_map
,
1619 ofpacts_format(bucket
->ofpacts
, bucket
->ofpacts_len
, &fp
);
1620 ds_put_char(s
, ',');
1627 ofp_print_ofpst_group_desc_request(struct ds
*string
,
1628 const struct ofp_header
*oh
)
1630 uint32_t group_id
= ofputil_decode_group_desc_request(oh
);
1631 ds_put_cstr(string
, " group_id=");
1632 ofputil_format_group(group_id
, string
);
1638 ofp_print_group_desc(struct ds
*s
, const struct ofp_header
*oh
,
1639 const struct ofputil_port_map
*port_map
,
1640 const struct ofputil_table_map
*table_map
)
1642 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
1644 struct ofputil_group_desc gd
;
1647 retval
= ofputil_decode_group_desc_reply(&gd
, &b
, oh
->version
);
1649 return retval
!= EOF
? retval
: 0;
1652 ds_put_char(s
, '\n');
1653 ds_put_char(s
, ' ');
1654 ofp_print_group(s
, gd
.group_id
, gd
.type
, &gd
.buckets
, &gd
.props
,
1655 oh
->version
, false, port_map
, table_map
);
1656 ofputil_uninit_group_desc(&gd
);
1661 ofp_print_ofpst_group_request(struct ds
*string
, const struct ofp_header
*oh
)
1666 error
= ofputil_decode_group_stats_request(oh
, &group_id
);
1671 ds_put_cstr(string
, " group_id=");
1672 ofputil_format_group(group_id
, string
);
1677 ofp_print_group_stats(struct ds
*s
, const struct ofp_header
*oh
)
1679 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
1681 struct ofputil_group_stats gs
;
1684 retval
= ofputil_decode_group_stats_reply(&b
, &gs
);
1686 if (retval
!= EOF
) {
1687 ds_put_cstr(s
, " ***parse error***");
1693 ds_put_char(s
, '\n');
1695 ds_put_char(s
, ' ');
1696 ds_put_format(s
, "group_id=%"PRIu32
",", gs
.group_id
);
1698 if (gs
.duration_sec
!= UINT32_MAX
) {
1699 ds_put_cstr(s
, "duration=");
1700 ofp_print_duration(s
, gs
.duration_sec
, gs
.duration_nsec
);
1701 ds_put_char(s
, ',');
1703 ds_put_format(s
, "ref_count=%"PRIu32
",", gs
.ref_count
);
1704 ds_put_format(s
, "packet_count=%"PRIu64
",", gs
.packet_count
);
1705 ds_put_format(s
, "byte_count=%"PRIu64
"", gs
.byte_count
);
1707 for (uint32_t bucket_i
= 0; bucket_i
< gs
.n_buckets
; bucket_i
++) {
1708 if (gs
.bucket_stats
[bucket_i
].packet_count
!= UINT64_MAX
) {
1709 ds_put_format(s
, ",bucket%"PRIu32
":", bucket_i
);
1710 ds_put_format(s
, "packet_count=%"PRIu64
",", gs
.bucket_stats
[bucket_i
].packet_count
);
1711 ds_put_format(s
, "byte_count=%"PRIu64
"", gs
.bucket_stats
[bucket_i
].byte_count
);
1715 free(gs
.bucket_stats
);
1721 group_type_to_string(enum ofp11_group_type type
)
1724 case OFPGT11_ALL
: return "all";
1725 case OFPGT11_SELECT
: return "select";
1726 case OFPGT11_INDIRECT
: return "indirect";
1727 case OFPGT11_FF
: return "fast failover";
1728 default: OVS_NOT_REACHED();
1733 ofp_print_group_features(struct ds
*string
, const struct ofp_header
*oh
)
1735 struct ofputil_group_features features
;
1738 ofputil_decode_group_features_reply(oh
, &features
);
1740 ds_put_format(string
, "\n Group table:\n");
1741 ds_put_format(string
, " Types: 0x%"PRIx32
"\n", features
.types
);
1742 ds_put_format(string
, " Capabilities: 0x%"PRIx32
"\n",
1743 features
.capabilities
);
1745 for (i
= 0; i
< OFPGT12_N_TYPES
; i
++) {
1746 if (features
.types
& (1u << i
)) {
1747 ds_put_format(string
, " %s group:\n", group_type_to_string(i
));
1748 ds_put_format(string
, " max_groups=%#"PRIx32
"\n",
1749 features
.max_groups
[i
]);
1750 ds_put_format(string
, " actions: ");
1751 ofpact_bitmap_format(features
.ofpacts
[i
], string
);
1752 ds_put_char(string
, '\n');
1760 ofp_print_group_mod__(struct ds
*s
, enum ofp_version ofp_version
,
1761 const struct ofputil_group_mod
*gm
,
1762 const struct ofputil_port_map
*port_map
,
1763 const struct ofputil_table_map
*table_map
)
1765 bool bucket_command
= false;
1767 ds_put_char(s
, '\n');
1769 ds_put_char(s
, ' ');
1770 switch (gm
->command
) {
1772 ds_put_cstr(s
, "ADD");
1775 case OFPGC11_MODIFY
:
1776 ds_put_cstr(s
, "MOD");
1779 case OFPGC11_ADD_OR_MOD
:
1780 ds_put_cstr(s
, "ADD_OR_MOD");
1783 case OFPGC11_DELETE
:
1784 ds_put_cstr(s
, "DEL");
1787 case OFPGC15_INSERT_BUCKET
:
1788 ds_put_cstr(s
, "INSERT_BUCKET");
1789 bucket_command
= true;
1792 case OFPGC15_REMOVE_BUCKET
:
1793 ds_put_cstr(s
, "REMOVE_BUCKET");
1794 bucket_command
= true;
1798 ds_put_format(s
, "cmd:%"PRIu16
"", gm
->command
);
1800 ds_put_char(s
, ' ');
1802 if (bucket_command
) {
1803 ofp_print_bucket_id(s
, "command_bucket_id:",
1804 gm
->command_bucket_id
, ofp_version
);
1807 ofp_print_group(s
, gm
->group_id
, gm
->type
, &gm
->buckets
, &gm
->props
,
1808 ofp_version
, bucket_command
, port_map
, table_map
);
1812 ofp_print_group_mod(struct ds
*s
, const struct ofp_header
*oh
,
1813 const struct ofputil_port_map
*port_map
,
1814 const struct ofputil_table_map
*table_map
)
1816 struct ofputil_group_mod gm
;
1819 error
= ofputil_decode_group_mod(oh
, &gm
);
1823 ofp_print_group_mod__(s
, oh
->version
, &gm
, port_map
, table_map
);
1824 ofputil_uninit_group_mod(&gm
);
1829 ofp_print_table_desc_reply(struct ds
*s
, const struct ofp_header
*oh
,
1830 const struct ofputil_table_map
*table_map
)
1832 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
1834 struct ofputil_table_desc td
;
1837 retval
= ofputil_decode_table_desc(&b
, &td
, oh
->version
);
1839 return retval
!= EOF
? retval
: 0;
1841 ofputil_table_desc_format(s
, &td
, table_map
);
1846 bundle_flags_to_name(uint32_t bit
)
1859 ofp_print_bundle_ctrl(struct ds
*s
, const struct ofp_header
*oh
)
1862 struct ofputil_bundle_ctrl_msg bctrl
;
1864 error
= ofputil_decode_bundle_ctrl(oh
, &bctrl
);
1869 ds_put_char(s
, '\n');
1871 ds_put_format(s
, " bundle_id=%#"PRIx32
" type=", bctrl
.bundle_id
);
1872 switch (bctrl
.type
) {
1873 case OFPBCT_OPEN_REQUEST
:
1874 ds_put_cstr(s
, "OPEN_REQUEST");
1876 case OFPBCT_OPEN_REPLY
:
1877 ds_put_cstr(s
, "OPEN_REPLY");
1879 case OFPBCT_CLOSE_REQUEST
:
1880 ds_put_cstr(s
, "CLOSE_REQUEST");
1882 case OFPBCT_CLOSE_REPLY
:
1883 ds_put_cstr(s
, "CLOSE_REPLY");
1885 case OFPBCT_COMMIT_REQUEST
:
1886 ds_put_cstr(s
, "COMMIT_REQUEST");
1888 case OFPBCT_COMMIT_REPLY
:
1889 ds_put_cstr(s
, "COMMIT_REPLY");
1891 case OFPBCT_DISCARD_REQUEST
:
1892 ds_put_cstr(s
, "DISCARD_REQUEST");
1894 case OFPBCT_DISCARD_REPLY
:
1895 ds_put_cstr(s
, "DISCARD_REPLY");
1899 ds_put_cstr(s
, " flags=");
1900 ofp_print_bit_names(s
, bctrl
.flags
, bundle_flags_to_name
, ' ');
1906 ofp_print_bundle_add(struct ds
*s
, const struct ofp_header
*oh
,
1907 const struct ofputil_port_map
*port_map
,
1908 const struct ofputil_table_map
*table_map
,
1912 struct ofputil_bundle_add_msg badd
;
1914 error
= ofputil_decode_bundle_add(oh
, &badd
, NULL
);
1919 ds_put_char(s
, '\n');
1920 ds_put_format(s
, " bundle_id=%#"PRIx32
, badd
.bundle_id
);
1921 ds_put_cstr(s
, " flags=");
1922 ofp_print_bit_names(s
, badd
.flags
, bundle_flags_to_name
, ' ');
1924 ds_put_char(s
, '\n');
1925 char *msg
= ofp_to_string(badd
.msg
, ntohs(badd
.msg
->length
), port_map
,
1926 table_map
, verbosity
);
1927 ds_put_and_free_cstr(s
, msg
);
1933 print_tlv_table(struct ds
*s
, struct ovs_list
*mappings
)
1935 struct ofputil_tlv_map
*map
;
1937 ds_put_cstr(s
, " mapping table:\n");
1938 ds_put_cstr(s
, " class\ttype\tlength\tmatch field\n");
1939 ds_put_cstr(s
, " -----\t----\t------\t-----------");
1941 LIST_FOR_EACH (map
, list_node
, mappings
) {
1942 ds_put_char(s
, '\n');
1943 ds_put_format(s
, " 0x%"PRIx16
"\t0x%"PRIx8
"\t%"PRIu8
"\ttun_metadata%"PRIu16
,
1944 map
->option_class
, map
->option_type
, map
->option_len
,
1950 ofp_print_tlv_table_mod(struct ds
*s
, const struct ofp_header
*oh
)
1953 struct ofputil_tlv_table_mod ttm
;
1955 error
= ofputil_decode_tlv_table_mod(oh
, &ttm
);
1960 ds_put_cstr(s
, "\n ");
1962 switch (ttm
.command
) {
1964 ds_put_cstr(s
, "ADD");
1967 ds_put_cstr(s
, "DEL");
1970 ds_put_cstr(s
, "CLEAR");
1974 if (ttm
.command
!= NXTTMC_CLEAR
) {
1975 print_tlv_table(s
, &ttm
.mappings
);
1978 ofputil_uninit_tlv_table(&ttm
.mappings
);
1984 ofp_print_tlv_table_reply(struct ds
*s
, const struct ofp_header
*oh
)
1987 struct ofputil_tlv_table_reply ttr
;
1988 struct ofputil_tlv_map
*map
;
1989 int allocated_space
= 0;
1991 error
= ofputil_decode_tlv_table_reply(oh
, &ttr
);
1996 ds_put_char(s
, '\n');
1998 LIST_FOR_EACH (map
, list_node
, &ttr
.mappings
) {
1999 allocated_space
+= map
->option_len
;
2002 ds_put_format(s
, " max option space=%"PRIu32
" max fields=%"PRIu16
"\n",
2003 ttr
.max_option_space
, ttr
.max_fields
);
2004 ds_put_format(s
, " allocated option space=%d\n", allocated_space
);
2005 ds_put_char(s
, '\n');
2006 print_tlv_table(s
, &ttr
.mappings
);
2008 ofputil_uninit_tlv_table(&ttr
.mappings
);
2013 /* This function will print the request forward message. The reason for
2014 * request forward is taken from rf.request.type */
2016 ofp_print_requestforward(struct ds
*string
, const struct ofp_header
*oh
,
2017 const struct ofputil_port_map
*port_map
,
2018 const struct ofputil_table_map
*table_map
)
2020 struct ofputil_requestforward rf
;
2023 error
= ofputil_decode_requestforward(oh
, &rf
);
2028 ds_put_cstr(string
, " reason=");
2030 switch (rf
.reason
) {
2031 case OFPRFR_GROUP_MOD
:
2032 ds_put_cstr(string
, "group_mod");
2033 ofp_print_group_mod__(string
, oh
->version
, rf
.group_mod
, port_map
,
2037 case OFPRFR_METER_MOD
:
2038 ds_put_cstr(string
, "meter_mod");
2039 ofp_print_meter_mod__(string
, rf
.meter_mod
);
2042 case OFPRFR_N_REASONS
:
2045 ofputil_destroy_requestforward(&rf
);
2051 print_ipfix_stat(struct ds
*string
, const char *leader
, uint64_t stat
, int more
)
2053 ds_put_cstr(string
, leader
);
2054 if (stat
!= UINT64_MAX
) {
2055 ds_put_format(string
, "%"PRIu64
, stat
);
2057 ds_put_char(string
, '?');
2060 ds_put_cstr(string
, ", ");
2062 ds_put_cstr(string
, "\n");
2067 ofp_print_nxst_ipfix_bridge_reply(struct ds
*string
, const struct ofp_header
*oh
)
2069 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
2071 struct ofputil_ipfix_stats is
;
2074 retval
= ofputil_pull_ipfix_stats(&is
, &b
);
2076 return retval
!= EOF
? retval
: 0;
2079 ds_put_cstr(string
, "\n bridge ipfix: ");
2080 print_ipfix_stat(string
, "flows=", is
.total_flows
, 1);
2081 print_ipfix_stat(string
, "current flows=", is
.current_flows
, 1);
2082 print_ipfix_stat(string
, "sampled pkts=", is
.pkts
, 1);
2083 print_ipfix_stat(string
, "ipv4 ok=", is
.ipv4_pkts
, 1);
2084 print_ipfix_stat(string
, "ipv6 ok=", is
.ipv6_pkts
, 1);
2085 print_ipfix_stat(string
, "tx pkts=", is
.tx_pkts
, 0);
2086 ds_put_cstr(string
, " ");
2087 print_ipfix_stat(string
, "pkts errs=", is
.error_pkts
, 1);
2088 print_ipfix_stat(string
, "ipv4 errs=", is
.ipv4_error_pkts
, 1);
2089 print_ipfix_stat(string
, "ipv6 errs=", is
.ipv6_error_pkts
, 1);
2090 print_ipfix_stat(string
, "tx errs=", is
.tx_errors
, 0);
2095 ofp_print_nxst_ipfix_flow_reply(struct ds
*string
, const struct ofp_header
*oh
)
2097 ds_put_format(string
, " %"PRIuSIZE
" ids\n", ofputil_count_ipfix_stats(oh
));
2099 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
2101 struct ofputil_ipfix_stats is
;
2104 retval
= ofputil_pull_ipfix_stats(&is
, &b
);
2106 return retval
!= EOF
? retval
: 0;
2109 ds_put_cstr(string
, " id");
2110 ds_put_format(string
, " %3"PRIuSIZE
": ", (size_t) is
.collector_set_id
);
2111 print_ipfix_stat(string
, "flows=", is
.total_flows
, 1);
2112 print_ipfix_stat(string
, "current flows=", is
.current_flows
, 1);
2113 print_ipfix_stat(string
, "sampled pkts=", is
.pkts
, 1);
2114 print_ipfix_stat(string
, "ipv4 ok=", is
.ipv4_pkts
, 1);
2115 print_ipfix_stat(string
, "ipv6 ok=", is
.ipv6_pkts
, 1);
2116 print_ipfix_stat(string
, "tx pkts=", is
.tx_pkts
, 0);
2117 ds_put_cstr(string
, " ");
2118 print_ipfix_stat(string
, "pkts errs=", is
.error_pkts
, 1);
2119 print_ipfix_stat(string
, "ipv4 errs=", is
.ipv4_error_pkts
, 1);
2120 print_ipfix_stat(string
, "ipv6 errs=", is
.ipv6_error_pkts
, 1);
2121 print_ipfix_stat(string
, "tx errs=", is
.tx_errors
, 0);
2126 ofp_print_nxt_ct_flush_zone(struct ds
*string
, const struct nx_zone_id
*nzi
)
2128 ds_put_format(string
, " zone_id=%"PRIu16
, ntohs(nzi
->zone_id
));
2133 ofp_to_string__(const struct ofp_header
*oh
,
2134 const struct ofputil_port_map
*port_map
,
2135 const struct ofputil_table_map
*table_map
, enum ofpraw raw
,
2136 struct ds
*string
, int verbosity
)
2138 const void *msg
= oh
;
2139 enum ofptype type
= ofptype_from_ofpraw(raw
);
2141 case OFPTYPE_GROUP_STATS_REQUEST
:
2142 ofp_print_stats(string
, oh
);
2143 return ofp_print_ofpst_group_request(string
, oh
);
2145 case OFPTYPE_GROUP_STATS_REPLY
:
2146 return ofp_print_group_stats(string
, oh
);
2148 case OFPTYPE_GROUP_DESC_STATS_REQUEST
:
2149 ofp_print_stats(string
, oh
);
2150 return ofp_print_ofpst_group_desc_request(string
, oh
);
2152 case OFPTYPE_GROUP_DESC_STATS_REPLY
:
2153 return ofp_print_group_desc(string
, oh
, port_map
, table_map
);
2155 case OFPTYPE_GROUP_FEATURES_STATS_REQUEST
:
2156 ofp_print_stats(string
, oh
);
2159 case OFPTYPE_GROUP_FEATURES_STATS_REPLY
:
2160 return ofp_print_group_features(string
, oh
);
2162 case OFPTYPE_GROUP_MOD
:
2163 return ofp_print_group_mod(string
, oh
, port_map
, table_map
);
2165 case OFPTYPE_TABLE_FEATURES_STATS_REQUEST
:
2166 case OFPTYPE_TABLE_FEATURES_STATS_REPLY
:
2167 return ofp_print_table_features_reply(string
, oh
, table_map
);
2169 case OFPTYPE_TABLE_DESC_REQUEST
:
2170 case OFPTYPE_TABLE_DESC_REPLY
:
2171 return ofp_print_table_desc_reply(string
, oh
, table_map
);
2174 return ofp_print_hello(string
, oh
);
2177 return ofp_print_error_msg(string
, oh
, port_map
, table_map
);
2179 case OFPTYPE_ECHO_REQUEST
:
2180 case OFPTYPE_ECHO_REPLY
:
2181 return ofp_print_echo(string
, oh
, verbosity
);
2183 case OFPTYPE_FEATURES_REQUEST
:
2186 case OFPTYPE_FEATURES_REPLY
:
2187 return ofp_print_switch_features(string
, oh
);
2189 case OFPTYPE_GET_CONFIG_REQUEST
:
2192 case OFPTYPE_GET_CONFIG_REPLY
:
2193 return ofp_print_get_config_reply(string
, oh
);
2195 case OFPTYPE_SET_CONFIG
:
2196 return ofp_print_set_config(string
, oh
);
2198 case OFPTYPE_PACKET_IN
:
2199 return ofp_print_packet_in(string
, oh
, port_map
, table_map
, verbosity
);
2201 case OFPTYPE_FLOW_REMOVED
:
2202 return ofp_print_flow_removed(string
, oh
, port_map
, table_map
);
2204 case OFPTYPE_PORT_STATUS
:
2205 return ofp_print_port_status(string
, oh
);
2207 case OFPTYPE_PACKET_OUT
:
2208 return ofp_print_packet_out(string
, oh
, port_map
, table_map
,
2211 case OFPTYPE_FLOW_MOD
:
2212 return ofputil_flow_mod_format(string
, oh
, port_map
, table_map
,
2215 case OFPTYPE_PORT_MOD
:
2216 return ofp_print_port_mod(string
, oh
, port_map
);
2218 case OFPTYPE_TABLE_MOD
:
2219 return ofp_print_table_mod(string
, oh
, table_map
);
2221 case OFPTYPE_METER_MOD
:
2222 return ofp_print_meter_mod(string
, oh
);
2224 case OFPTYPE_BARRIER_REQUEST
:
2225 case OFPTYPE_BARRIER_REPLY
:
2228 case OFPTYPE_QUEUE_GET_CONFIG_REQUEST
:
2229 return ofp_print_queue_get_config_request(string
, oh
, port_map
);
2231 case OFPTYPE_QUEUE_GET_CONFIG_REPLY
:
2232 return ofp_print_queue_get_config_reply(string
, oh
, port_map
);
2234 case OFPTYPE_ROLE_REQUEST
:
2235 case OFPTYPE_ROLE_REPLY
:
2236 return ofp_print_role_message(string
, oh
);
2237 case OFPTYPE_ROLE_STATUS
:
2238 return ofp_print_role_status_message(string
, oh
);
2240 case OFPTYPE_REQUESTFORWARD
:
2241 return ofp_print_requestforward(string
, oh
, port_map
, table_map
);
2243 case OFPTYPE_TABLE_STATUS
:
2244 return ofp_print_table_status_message(string
, oh
, table_map
);
2246 case OFPTYPE_METER_STATS_REQUEST
:
2247 case OFPTYPE_METER_CONFIG_STATS_REQUEST
:
2248 ofp_print_stats(string
, oh
);
2249 return ofp_print_meter_stats_request(string
, oh
);
2251 case OFPTYPE_METER_STATS_REPLY
:
2252 ofp_print_stats(string
, oh
);
2253 return ofp_print_meter_stats_reply(string
, oh
);
2255 case OFPTYPE_METER_CONFIG_STATS_REPLY
:
2256 ofp_print_stats(string
, oh
);
2257 return ofp_print_meter_config_reply(string
, oh
);
2259 case OFPTYPE_METER_FEATURES_STATS_REPLY
:
2260 ofp_print_stats(string
, oh
);
2261 return ofp_print_meter_features_reply(string
, oh
);
2263 case OFPTYPE_DESC_STATS_REQUEST
:
2264 case OFPTYPE_METER_FEATURES_STATS_REQUEST
:
2265 ofp_print_stats(string
, oh
);
2268 case OFPTYPE_FLOW_STATS_REQUEST
:
2269 case OFPTYPE_AGGREGATE_STATS_REQUEST
:
2270 ofp_print_stats(string
, oh
);
2271 return ofp_print_flow_stats_request(string
, oh
, port_map
, table_map
);
2273 case OFPTYPE_TABLE_STATS_REQUEST
:
2274 ofp_print_stats(string
, oh
);
2277 case OFPTYPE_PORT_STATS_REQUEST
:
2278 ofp_print_stats(string
, oh
);
2279 return ofp_print_ofpst_port_request(string
, oh
, port_map
);
2281 case OFPTYPE_QUEUE_STATS_REQUEST
:
2282 ofp_print_stats(string
, oh
);
2283 return ofp_print_ofpst_queue_request(string
, oh
, port_map
);
2285 case OFPTYPE_DESC_STATS_REPLY
:
2286 ofp_print_stats(string
, oh
);
2287 return ofp_print_ofpst_desc_reply(string
, oh
);
2289 case OFPTYPE_FLOW_STATS_REPLY
:
2290 ofp_print_stats(string
, oh
);
2291 return ofp_print_flow_stats_reply(string
, oh
, port_map
, table_map
);
2293 case OFPTYPE_QUEUE_STATS_REPLY
:
2294 ofp_print_stats(string
, oh
);
2295 return ofp_print_ofpst_queue_reply(string
, oh
, port_map
, verbosity
);
2297 case OFPTYPE_PORT_STATS_REPLY
:
2298 ofp_print_stats(string
, oh
);
2299 return ofp_print_ofpst_port_reply(string
, oh
, port_map
, verbosity
);
2301 case OFPTYPE_TABLE_STATS_REPLY
:
2302 ofp_print_stats(string
, oh
);
2303 return ofp_print_table_stats_reply(string
, oh
, table_map
);
2305 case OFPTYPE_AGGREGATE_STATS_REPLY
:
2306 ofp_print_stats(string
, oh
);
2307 return ofp_print_aggregate_stats_reply(string
, oh
);
2309 case OFPTYPE_PORT_DESC_STATS_REQUEST
:
2310 ofp_print_stats(string
, oh
);
2311 return ofp_print_ofpst_port_desc_request(string
, oh
, port_map
);
2313 case OFPTYPE_PORT_DESC_STATS_REPLY
:
2314 ofp_print_stats(string
, oh
);
2315 return ofp_print_ofpst_port_desc_reply(string
, oh
);
2317 case OFPTYPE_FLOW_MOD_TABLE_ID
:
2318 return ofp_print_nxt_flow_mod_table_id(string
, oh
);
2320 case OFPTYPE_SET_FLOW_FORMAT
:
2321 return ofp_print_nxt_set_flow_format(string
, oh
);
2323 case OFPTYPE_SET_PACKET_IN_FORMAT
:
2324 return ofp_print_nxt_set_packet_in_format(string
, oh
);
2326 case OFPTYPE_FLOW_AGE
:
2329 case OFPTYPE_SET_CONTROLLER_ID
:
2330 return ofp_print_nxt_set_controller_id(string
, ofpmsg_body(oh
));
2332 case OFPTYPE_GET_ASYNC_REPLY
:
2333 case OFPTYPE_SET_ASYNC_CONFIG
:
2334 return ofp_print_set_async_config(string
, oh
, type
);
2335 case OFPTYPE_GET_ASYNC_REQUEST
:
2337 case OFPTYPE_FLOW_MONITOR_CANCEL
:
2338 return ofp_print_nxt_flow_monitor_cancel(string
, msg
);
2340 case OFPTYPE_FLOW_MONITOR_PAUSED
:
2341 case OFPTYPE_FLOW_MONITOR_RESUMED
:
2344 case OFPTYPE_FLOW_MONITOR_STATS_REQUEST
:
2345 return ofp_print_nxst_flow_monitor_request(string
, msg
, port_map
,
2348 case OFPTYPE_FLOW_MONITOR_STATS_REPLY
:
2349 return ofp_print_nxst_flow_monitor_reply(string
, msg
, port_map
,
2352 case OFPTYPE_BUNDLE_CONTROL
:
2353 return ofp_print_bundle_ctrl(string
, msg
);
2355 case OFPTYPE_BUNDLE_ADD_MESSAGE
:
2356 return ofp_print_bundle_add(string
, msg
, port_map
, table_map
,
2359 case OFPTYPE_NXT_TLV_TABLE_MOD
:
2360 return ofp_print_tlv_table_mod(string
, msg
);
2362 case OFPTYPE_NXT_TLV_TABLE_REQUEST
:
2365 case OFPTYPE_NXT_TLV_TABLE_REPLY
:
2366 return ofp_print_tlv_table_reply(string
, msg
);
2368 case OFPTYPE_NXT_RESUME
:
2369 return ofp_print_packet_in(string
, msg
, port_map
, table_map
,
2371 case OFPTYPE_IPFIX_BRIDGE_STATS_REQUEST
:
2373 case OFPTYPE_IPFIX_BRIDGE_STATS_REPLY
:
2374 return ofp_print_nxst_ipfix_bridge_reply(string
, oh
);
2375 case OFPTYPE_IPFIX_FLOW_STATS_REQUEST
:
2377 case OFPTYPE_IPFIX_FLOW_STATS_REPLY
:
2378 return ofp_print_nxst_ipfix_flow_reply(string
, oh
);
2380 case OFPTYPE_CT_FLUSH_ZONE
:
2381 return ofp_print_nxt_ct_flush_zone(string
, ofpmsg_body(oh
));
2388 add_newline(struct ds
*s
)
2390 if (s
->length
&& s
->string
[s
->length
- 1] != '\n') {
2391 ds_put_char(s
, '\n');
2395 /* Composes and returns a string representing the OpenFlow packet of 'len'
2396 * bytes at 'oh' at the given 'verbosity' level. 0 is a minimal amount of
2397 * verbosity and higher numbers increase verbosity. The caller is responsible
2398 * for freeing the string. */
2400 ofp_to_string(const void *oh_
, size_t len
,
2401 const struct ofputil_port_map
*port_map
,
2402 const struct ofputil_table_map
*table_map
,
2405 struct ds string
= DS_EMPTY_INITIALIZER
;
2406 const struct ofp_header
*oh
= oh_
;
2409 ds_put_cstr(&string
, "OpenFlow message is empty\n");
2410 } else if (len
< sizeof(struct ofp_header
)) {
2411 ds_put_format(&string
, "OpenFlow packet too short (only %"PRIuSIZE
" bytes):\n",
2413 } else if (ntohs(oh
->length
) > len
) {
2417 error
= ofpraw_decode_partial(&raw
, oh
, len
);
2419 ofp_header_to_string__(oh
, raw
, &string
);
2420 ds_put_char(&string
, '\n');
2423 ds_put_format(&string
,
2424 "(***truncated to %"PRIuSIZE
" bytes from %"PRIu16
"***)\n",
2425 len
, ntohs(oh
->length
));
2426 } else if (ntohs(oh
->length
) < len
) {
2427 ds_put_format(&string
,
2428 "(***only uses %"PRIu16
" bytes out of %"PRIuSIZE
"***)\n",
2429 ntohs(oh
->length
), len
);
2434 error
= ofpraw_decode(&raw
, oh
);
2436 ofp_header_to_string__(oh
, raw
, &string
);
2437 size_t header_len
= string
.length
;
2439 error
= ofp_to_string__(oh
, port_map
, table_map
,
2440 raw
, &string
, verbosity
);
2442 if (string
.length
> header_len
) {
2443 ds_chomp(&string
, ' ');
2444 add_newline(&string
);
2446 ds_put_char(&string
, ' ');
2448 ofp_print_error(&string
, error
);
2450 ds_chomp(&string
, ' ');
2453 ofp_print_error(&string
, error
);
2456 if (verbosity
>= 5 || error
) {
2457 add_newline(&string
);
2458 ds_put_hex_dump(&string
, oh
, len
, 0, true);
2461 add_newline(&string
);
2462 return ds_steal_cstr(&string
);
2464 ds_put_hex_dump(&string
, oh
, len
, 0, true);
2465 return ds_steal_cstr(&string
);
2469 print_and_free(FILE *stream
, char *string
)
2471 fputs(string
, stream
);
2475 /* Pretty-print the OpenFlow packet of 'len' bytes at 'oh' to 'stream' at the
2476 * given 'verbosity' level. 0 is a minimal amount of verbosity and higher
2477 * numbers increase verbosity. */
2479 ofp_print(FILE *stream
, const void *oh
, size_t len
,
2480 const struct ofputil_port_map
*port_map
,
2481 const struct ofputil_table_map
*table_map
, int verbosity
)
2483 print_and_free(stream
, ofp_to_string(oh
, len
, port_map
, table_map
,
2487 /* Dumps the contents of the Ethernet frame in the 'len' bytes starting at
2488 * 'data' to 'stream'. */
2490 ofp_print_packet(FILE *stream
, const void *data
, size_t len
,
2491 ovs_be32 packet_type
)
2493 print_and_free(stream
, ofp_packet_to_string(data
, len
, packet_type
));
2497 ofp_print_dp_packet(FILE *stream
, const struct dp_packet
*packet
)
2499 print_and_free(stream
, ofp_dp_packet_to_string(packet
));