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_error(struct ds
*, enum ofperr
);
69 /* Returns a string that represents the contents of the Ethernet frame in the
70 * 'len' bytes starting at 'data'. The caller must free the returned string.*/
72 ofp_packet_to_string(const void *data
, size_t len
, ovs_be32 packet_type
)
74 struct ds ds
= DS_EMPTY_INITIALIZER
;
79 dp_packet_use_const(&buf
, data
, len
);
80 buf
.packet_type
= packet_type
;
81 flow_extract(&buf
, &flow
);
82 flow_format(&ds
, &flow
, NULL
);
84 l4_size
= dp_packet_l4_size(&buf
);
86 if (flow
.nw_proto
== IPPROTO_TCP
&& l4_size
>= TCP_HEADER_LEN
) {
87 struct tcp_header
*th
= dp_packet_l4(&buf
);
88 ds_put_format(&ds
, " tcp_csum:%"PRIx16
, ntohs(th
->tcp_csum
));
89 } else if (flow
.nw_proto
== IPPROTO_UDP
&& l4_size
>= UDP_HEADER_LEN
) {
90 struct udp_header
*uh
= dp_packet_l4(&buf
);
91 ds_put_format(&ds
, " udp_csum:%"PRIx16
, ntohs(uh
->udp_csum
));
92 } else if (flow
.nw_proto
== IPPROTO_SCTP
&& l4_size
>= SCTP_HEADER_LEN
) {
93 struct sctp_header
*sh
= dp_packet_l4(&buf
);
94 ds_put_format(&ds
, " sctp_csum:%"PRIx32
,
95 ntohl(get_16aligned_be32(&sh
->sctp_csum
)));
96 } else if (flow
.nw_proto
== IPPROTO_ICMP
&& l4_size
>= ICMP_HEADER_LEN
) {
97 struct icmp_header
*icmph
= dp_packet_l4(&buf
);
98 ds_put_format(&ds
, " icmp_csum:%"PRIx16
,
99 ntohs(icmph
->icmp_csum
));
100 } else if (flow
.nw_proto
== IPPROTO_ICMPV6
&& l4_size
>= ICMP6_HEADER_LEN
) {
101 struct icmp6_header
*icmp6h
= dp_packet_l4(&buf
);
102 ds_put_format(&ds
, " icmp6_csum:%"PRIx16
,
103 ntohs(icmp6h
->icmp6_cksum
));
106 ds_put_char(&ds
, '\n');
112 ofp_dp_packet_to_string(const struct dp_packet
*packet
)
114 return ofp_packet_to_string(dp_packet_data(packet
),
115 dp_packet_size(packet
),
116 packet
->packet_type
);
120 ofp_print_packet_in(struct ds
*string
, const struct ofp_header
*oh
,
121 const struct ofputil_port_map
*port_map
,
122 const struct ofputil_table_map
*table_map
, int verbosity
)
124 struct ofputil_packet_in_private pin
;
127 enum ofperr error
= ofputil_decode_packet_in_private(oh
, true, NULL
, NULL
,
131 ofputil_packet_in_private_format(string
, &pin
, total_len
, buffer_id
,
132 port_map
, table_map
, verbosity
);
133 ofputil_packet_in_private_destroy(&pin
);
139 ofp_print_packet_out(struct ds
*string
, const struct ofp_header
*oh
,
140 const struct ofputil_port_map
*port_map
,
141 const struct ofputil_table_map
*table_map
, int verbosity
)
143 struct ofputil_packet_out po
;
144 struct ofpbuf ofpacts
;
147 ofpbuf_init(&ofpacts
, 64);
148 error
= ofputil_decode_packet_out(&po
, oh
, NULL
, &ofpacts
);
150 ofputil_packet_out_format(string
, &po
, port_map
, table_map
, verbosity
);
152 ofpbuf_uninit(&ofpacts
);
157 ofp_print_bit_names(struct ds
*string
, uint32_t bits
,
158 const char *(*bit_to_name
)(uint32_t bit
),
165 ds_put_cstr(string
, "0");
169 for (i
= 0; i
< 32; i
++) {
170 uint32_t bit
= UINT32_C(1) << i
;
173 const char *name
= bit_to_name(bit
);
176 ds_put_char(string
, separator
);
178 ds_put_cstr(string
, name
);
186 ds_put_char(string
, separator
);
188 ds_put_format(string
, "0x%"PRIx32
, bits
);
193 ofp_print_switch_features(struct ds
*string
, const struct ofp_header
*oh
)
195 struct ofputil_switch_features features
;
196 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
197 enum ofperr error
= ofputil_pull_switch_features(&b
, &features
);
199 ofputil_switch_features_format(string
, &features
);
200 error
= ofputil_phy_ports_format(string
, oh
->version
, &b
);
206 ofp_print_set_config(struct ds
*string
, const struct ofp_header
*oh
)
208 struct ofputil_switch_config config
;
211 error
= ofputil_decode_set_config(oh
, &config
);
215 ofputil_switch_config_format(string
, &config
);
220 ofp_print_get_config_reply(struct ds
*string
, const struct ofp_header
*oh
)
222 struct ofputil_switch_config config
;
223 ofputil_decode_get_config_reply(oh
, &config
);
224 ofputil_switch_config_format(string
, &config
);
229 ofp_print_table_features_reply(struct ds
*s
, const struct ofp_header
*oh
)
231 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
233 struct ofputil_table_features prev
;
234 int first_ditto
= -1, last_ditto
= -1;
235 for (int i
= 0; ; i
++) {
236 struct ofputil_table_features tf
;
237 struct ofpbuf raw_properties
;
238 int retval
= ofputil_decode_table_features(&b
, &tf
, &raw_properties
);
240 ofputil_table_features_format_finish(s
, first_ditto
, last_ditto
);
241 return retval
!= EOF
? retval
: 0;
244 ofputil_table_features_format(s
, &tf
, i
? &prev
: NULL
, NULL
, NULL
,
245 &first_ditto
, &last_ditto
);
251 ofp_print_duration(struct ds
*string
, unsigned int sec
, unsigned int nsec
)
253 ds_put_format(string
, "%u", sec
);
255 /* If there are no fractional seconds, don't print any decimals.
257 * If the fractional seconds can be expressed exactly as milliseconds,
258 * print 3 decimals. Open vSwitch provides millisecond precision for most
259 * time measurements, so printing 3 decimals every time makes it easier to
260 * spot real changes in flow dumps that refresh themselves quickly.
262 * If the fractional seconds are more precise than milliseconds, print the
263 * number of decimals needed to express them exactly.
266 unsigned int msec
= nsec
/ 1000000;
267 if (msec
* 1000000 == nsec
) {
268 ds_put_format(string
, ".%03u", msec
);
270 ds_put_format(string
, ".%09u", nsec
);
271 while (string
->string
[string
->length
- 1] == '0') {
276 ds_put_char(string
, 's');
280 ofp_print_flow_removed(struct ds
*string
, const struct ofp_header
*oh
,
281 const struct ofputil_port_map
*port_map
,
282 const struct ofputil_table_map
*table_map
)
284 struct ofputil_flow_removed fr
;
285 enum ofperr error
= ofputil_decode_flow_removed(&fr
, oh
);
287 ofputil_flow_removed_format(string
, &fr
, port_map
, table_map
);
293 ofp_print_port_mod(struct ds
*string
, const struct ofp_header
*oh
,
294 const struct ofputil_port_map
*port_map
)
296 struct ofputil_port_mod pm
;
297 enum ofperr error
= ofputil_decode_port_mod(oh
, &pm
, true);
299 ofputil_port_mod_format(string
, &pm
, port_map
);
305 ofp_print_table_mod(struct ds
*string
, const struct ofp_header
*oh
,
306 const struct ofputil_table_map
*table_map
)
308 struct ofputil_table_mod tm
;
309 enum ofperr error
= ofputil_decode_table_mod(oh
, &tm
);
311 ofputil_table_mod_format(string
, &tm
, table_map
);
317 ofp_print_table_status_message(struct ds
*string
, const struct ofp_header
*oh
,
318 const struct ofputil_table_map
*table_map
)
320 struct ofputil_table_status ts
;
321 enum ofperr error
= ofputil_decode_table_status(oh
, &ts
);
323 ofputil_format_table_status(string
, &ts
, table_map
);
329 ofp_print_meter_mod(struct ds
*s
, const struct ofp_header
*oh
)
331 struct ofputil_meter_mod mm
;
334 ofpbuf_init(&bands
, 64);
335 enum ofperr error
= ofputil_decode_meter_mod(oh
, &mm
, &bands
);
337 ofputil_format_meter_mod(s
, &mm
);
339 ofpbuf_uninit(&bands
);
345 ofp_print_meter_stats_request(struct ds
*s
, const struct ofp_header
*oh
)
349 ofputil_decode_meter_request(oh
, &meter_id
);
352 ofputil_format_meter_id(s
, meter_id
, '=');
358 ofp_print_meter_features_reply(struct ds
*s
, const struct ofp_header
*oh
)
360 struct ofputil_meter_features mf
;
361 ofputil_decode_meter_features(oh
, &mf
);
362 ofputil_format_meter_features(s
, &mf
);
367 ofp_print_meter_config_reply(struct ds
*s
, const struct ofp_header
*oh
)
369 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
373 ofpbuf_init(&bands
, 64);
375 struct ofputil_meter_config mc
;
377 retval
= ofputil_decode_meter_config(&b
, &mc
, &bands
);
381 ds_put_char(s
, '\n');
382 ofputil_format_meter_config(s
, &mc
);
384 ofpbuf_uninit(&bands
);
386 return retval
!= EOF
? retval
: 0;
390 ofp_print_meter_stats_reply(struct ds
*s
, const struct ofp_header
*oh
)
392 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
396 ofpbuf_init(&bands
, 64);
398 struct ofputil_meter_stats ms
;
400 retval
= ofputil_decode_meter_stats(&b
, &ms
, &bands
);
404 ds_put_char(s
, '\n');
405 ofputil_format_meter_stats(s
, &ms
);
407 ofpbuf_uninit(&bands
);
409 return retval
!= EOF
? retval
: 0;
413 ofp_print_error(struct ds
*string
, enum ofperr error
)
415 ds_put_format(string
, "***decode error: %s***\n", ofperr_get_name(error
));
419 ofp_print_hello(struct ds
*string
, const struct ofp_header
*oh
)
421 ofputil_hello_format(string
, oh
);
426 ofp_print_error_msg(struct ds
*string
, const struct ofp_header
*oh
,
427 const struct ofputil_port_map
*port_map
,
428 const struct ofputil_table_map
*table_map
)
430 struct ofpbuf payload
;
431 enum ofperr error
= ofperr_decode_msg(oh
, &payload
);
433 return OFPERR_OFPBRC_BAD_LEN
;
435 ofperr_msg_format(string
, error
, &payload
, port_map
, table_map
);
436 ofpbuf_uninit(&payload
);
442 ofp_print_port_status(struct ds
*string
, const struct ofp_header
*oh
)
444 struct ofputil_port_status ps
;
445 enum ofperr error
= ofputil_decode_port_status(oh
, &ps
);
447 ofputil_port_status_format(string
, &ps
);
453 ofp_print_ofpst_desc_reply(struct ds
*string
, const struct ofp_header
*oh
)
455 const struct ofp_desc_stats
*ods
= ofpmsg_body(oh
);
457 ds_put_char(string
, '\n');
458 ds_put_format(string
, "Manufacturer: %.*s\n",
459 (int) sizeof ods
->mfr_desc
, ods
->mfr_desc
);
460 ds_put_format(string
, "Hardware: %.*s\n",
461 (int) sizeof ods
->hw_desc
, ods
->hw_desc
);
462 ds_put_format(string
, "Software: %.*s\n",
463 (int) sizeof ods
->sw_desc
, ods
->sw_desc
);
464 ds_put_format(string
, "Serial Num: %.*s\n",
465 (int) sizeof ods
->serial_num
, ods
->serial_num
);
466 ds_put_format(string
, "DP Description: %.*s\n",
467 (int) sizeof ods
->dp_desc
, ods
->dp_desc
);
473 ofp_print_flow_stats_request(struct ds
*string
, const struct ofp_header
*oh
,
474 const struct ofputil_port_map
*port_map
,
475 const struct ofputil_table_map
*table_map
)
477 struct ofputil_flow_stats_request fsr
;
478 enum ofperr error
= ofputil_decode_flow_stats_request(&fsr
, oh
, NULL
,
481 ofputil_flow_stats_request_format(string
, &fsr
, port_map
, table_map
);
487 ofp_print_flow_stats_reply(struct ds
*string
, const struct ofp_header
*oh
,
488 const struct ofputil_port_map
*port_map
,
489 const struct ofputil_table_map
*table_map
)
491 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
492 struct ofpbuf ofpacts
;
495 ofpbuf_init(&ofpacts
, 64);
497 struct ofputil_flow_stats fs
;
499 retval
= ofputil_decode_flow_stats_reply(&fs
, &b
, true, &ofpacts
);
503 ds_put_cstr(string
, "\n ");
504 ofputil_flow_stats_format(string
, &fs
, port_map
, table_map
, true);
506 ofpbuf_uninit(&ofpacts
);
508 return retval
!= EOF
? retval
: 0;
512 ofp_print_aggregate_stats_reply(struct ds
*string
, const struct ofp_header
*oh
)
514 struct ofputil_aggregate_stats as
;
517 error
= ofputil_decode_aggregate_stats_reply(&as
, oh
);
519 ofputil_aggregate_stats_format(string
, &as
);
525 ofp_print_ofpst_port_request(struct ds
*string
, const struct ofp_header
*oh
,
526 const struct ofputil_port_map
*port_map
)
528 ofp_port_t ofp10_port
;
531 error
= ofputil_decode_port_stats_request(oh
, &ofp10_port
);
536 ds_put_cstr(string
, " port_no=");
537 ofputil_format_port(ofp10_port
, port_map
, string
);
543 ofp_print_ofpst_port_reply(struct ds
*string
, const struct ofp_header
*oh
,
544 const struct ofputil_port_map
*port_map
,
547 ds_put_format(string
, " %"PRIuSIZE
" ports\n",
548 ofputil_count_port_stats(oh
));
553 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
555 struct ofputil_port_stats ps
;
558 retval
= ofputil_decode_port_stats(&ps
, &b
);
560 return retval
!= EOF
? retval
: 0;
562 ofputil_format_port_stats(string
, &ps
, port_map
);
563 netdev_free_custom_stats_counters(&ps
.custom_stats
);
568 ofp_print_table_stats_reply(struct ds
*string
, const struct ofp_header
*oh
)
570 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
571 ofpraw_pull_assert(&b
);
573 struct ofputil_table_features prev_features
;
574 struct ofputil_table_stats prev_stats
;
575 int first_ditto
= -1, last_ditto
= -1;
576 for (int i
= 0;; i
++) {
577 struct ofputil_table_features features
;
578 struct ofputil_table_stats stats
;
581 retval
= ofputil_decode_table_stats_reply(&b
, &stats
, &features
);
583 ofputil_table_features_format_finish(string
,
584 first_ditto
, last_ditto
);
585 return retval
!= EOF
? retval
: 0;
588 ofputil_table_features_format(string
,
589 &features
, i
? &prev_features
: NULL
,
590 &stats
, i
? &prev_stats
: NULL
,
591 &first_ditto
, &last_ditto
);
592 prev_features
= features
;
598 ofp_print_ofpst_port_desc_request(struct ds
*string
,
599 const struct ofp_header
*oh
,
600 const struct ofputil_port_map
*port_map
)
605 error
= ofputil_decode_port_desc_stats_request(oh
, &port
);
610 ds_put_cstr(string
, " port=");
611 ofputil_format_port(port
, port_map
, string
);
617 ofp_print_ofpst_port_desc_reply(struct ds
*string
,
618 const struct ofp_header
*oh
)
620 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
621 ofpraw_pull_assert(&b
);
622 ds_put_char(string
, '\n');
623 return ofputil_phy_ports_format(string
, oh
->version
, &b
);
627 ofp_print_stats(struct ds
*string
, const struct ofp_header
*oh
)
629 uint16_t flags
= ofpmp_flags(oh
);
632 ds_put_cstr(string
, " flags=");
633 if ((!ofpmsg_is_stat_request(oh
) || oh
->version
>= OFP13_VERSION
)
634 && (flags
& OFPSF_REPLY_MORE
)) {
635 ds_put_cstr(string
, "[more]");
636 flags
&= ~OFPSF_REPLY_MORE
;
639 ds_put_format(string
, "[***unknown flags 0x%04"PRIx16
"***]",
646 ofp_print_echo(struct ds
*string
, const struct ofp_header
*oh
, int verbosity
)
648 size_t len
= ntohs(oh
->length
);
650 ds_put_format(string
, " %"PRIuSIZE
" bytes of payload\n", len
- sizeof *oh
);
652 ds_put_hex_dump(string
, oh
+ 1, len
- sizeof *oh
, 0, true);
659 ofp_print_role_message(struct ds
*string
, const struct ofp_header
*oh
)
661 struct ofputil_role_request rr
;
662 enum ofperr error
= ofputil_decode_role_message(oh
, &rr
);
664 ofputil_format_role_message(string
, &rr
);
670 ofp_print_role_status_message(struct ds
*string
, const struct ofp_header
*oh
)
672 struct ofputil_role_status rs
;
673 enum ofperr error
= ofputil_decode_role_status(oh
, &rs
);
675 ofputil_format_role_status(string
, &rs
);
681 ofp_print_nxt_flow_mod_table_id(struct ds
*string
, const struct ofp_header
*oh
)
683 bool enable
= ofputil_decode_nx_flow_mod_table_id(oh
);
684 ds_put_format(string
, " %s", enable
? "enable" : "disable");
689 ofp_print_nxt_set_flow_format(struct ds
*string
, const struct ofp_header
*oh
)
691 enum ofputil_protocol p
= ofputil_decode_nx_set_flow_format(oh
);
692 ds_put_format(string
, " format=%s",
693 p
== OFPUTIL_P_OF10_STD
? "openflow10"
694 : p
== OFPUTIL_P_OF10_NXM
? "nxm"
700 ofp_print_nxt_set_packet_in_format(struct ds
*string
,
701 const struct ofp_header
*oh
)
703 enum ofputil_packet_in_format format
;
704 enum ofperr error
= ofputil_decode_set_packet_in_format(oh
, &format
);
706 ds_put_format(string
, " format=%s",
707 ofputil_packet_in_format_to_string(format
));
713 ofp_print_set_async_config(struct ds
*string
, const struct ofp_header
*oh
,
714 enum ofptype ofptype
)
716 struct ofputil_async_cfg basis
= OFPUTIL_ASYNC_CFG_INIT
;
717 struct ofputil_async_cfg ac
;
719 bool is_reply
= ofptype
== OFPTYPE_GET_ASYNC_REPLY
;
720 enum ofperr error
= ofputil_decode_set_async_config(oh
, is_reply
,
725 ofputil_format_set_async_config(string
, &ac
);
730 ofp_print_nxt_set_controller_id(struct ds
*string
,
731 const struct nx_controller_id
*nci
)
733 ds_put_format(string
, " id=%"PRIu16
, ntohs(nci
->controller_id
));
738 ofp_print_nxt_flow_monitor_cancel(struct ds
*string
,
739 const struct ofp_header
*oh
)
741 ds_put_format(string
, " id=%"PRIu32
,
742 ofputil_decode_flow_monitor_cancel(oh
));
747 ofp_print_nxst_flow_monitor_request(struct ds
*string
,
748 const struct ofp_header
*oh
,
749 const struct ofputil_port_map
*port_map
,
750 const struct ofputil_table_map
*table_map
)
752 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
754 struct ofputil_flow_monitor_request request
;
757 retval
= ofputil_decode_flow_monitor_request(&request
, &b
);
759 return retval
!= EOF
? retval
: 0;
762 ofputil_flow_monitor_request_format(string
, &request
,
763 port_map
, table_map
);
768 ofp_print_nxst_flow_monitor_reply(struct ds
*string
,
769 const struct ofp_header
*oh
,
770 const struct ofputil_port_map
*port_map
,
771 const struct ofputil_table_map
*table_map
)
773 uint64_t ofpacts_stub
[1024 / 8];
774 struct ofpbuf ofpacts
= OFPBUF_STUB_INITIALIZER(ofpacts_stub
);
775 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
778 struct ofputil_flow_update update
;
779 int retval
= ofputil_decode_flow_update(&update
, &b
, &ofpacts
);
781 ofpbuf_uninit(&ofpacts
);
782 return retval
!= EOF
? retval
: 0;
784 ofputil_flow_update_format(string
, &update
, port_map
, table_map
);
789 ofp_print_version(const struct ofp_header
*oh
,
792 switch (oh
->version
) {
796 ds_put_cstr(string
, " (OF1.1)");
799 ds_put_cstr(string
, " (OF1.2)");
802 ds_put_cstr(string
, " (OF1.3)");
805 ds_put_cstr(string
, " (OF1.4)");
808 ds_put_cstr(string
, " (OF1.5)");
811 ds_put_format(string
, " (OF 0x%02"PRIx8
")", oh
->version
);
814 ds_put_format(string
, " (xid=0x%"PRIx32
"):", ntohl(oh
->xid
));
818 ofp_header_to_string__(const struct ofp_header
*oh
, enum ofpraw raw
,
821 ds_put_cstr(string
, ofpraw_get_name(raw
));
822 ofp_print_version(oh
, string
);
826 ofp_print_table_desc_reply(struct ds
*s
, const struct ofp_header
*oh
,
827 const struct ofputil_table_map
*table_map
)
829 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
831 struct ofputil_table_desc td
;
834 retval
= ofputil_decode_table_desc(&b
, &td
, oh
->version
);
836 return retval
!= EOF
? retval
: 0;
838 ofputil_table_desc_format(s
, &td
, table_map
);
843 ofp_print_bundle_ctrl(struct ds
*s
, const struct ofp_header
*oh
)
846 struct ofputil_bundle_ctrl_msg bctrl
;
848 error
= ofputil_decode_bundle_ctrl(oh
, &bctrl
);
852 ofputil_format_bundle_ctrl_request(s
, &bctrl
);
857 ofp_print_bundle_add(struct ds
*s
, const struct ofp_header
*oh
,
858 const struct ofputil_port_map
*port_map
,
859 const struct ofputil_table_map
*table_map
,
862 struct ofputil_bundle_add_msg badd
;
863 int error
= ofputil_decode_bundle_add(oh
, &badd
, NULL
);
865 ofputil_format_bundle_add(s
, &badd
, port_map
, table_map
, verbosity
);
871 ofp_print_tlv_table_mod(struct ds
*s
, const struct ofp_header
*oh
)
873 struct ofputil_tlv_table_mod ttm
;
874 int error
= ofputil_decode_tlv_table_mod(oh
, &ttm
);
876 ofputil_format_tlv_table_mod(s
, &ttm
);
877 ofputil_uninit_tlv_table(&ttm
.mappings
);
883 ofp_print_tlv_table_reply(struct ds
*s
, const struct ofp_header
*oh
)
885 struct ofputil_tlv_table_reply ttr
;
886 int error
= ofputil_decode_tlv_table_reply(oh
, &ttr
);
888 ofputil_format_tlv_table_reply(s
, &ttr
);
889 ofputil_uninit_tlv_table(&ttr
.mappings
);
894 /* This function will print the request forward message. The reason for
895 * request forward is taken from rf.request.type */
897 ofp_print_requestforward(struct ds
*string
, const struct ofp_header
*oh
,
898 const struct ofputil_port_map
*port_map
,
899 const struct ofputil_table_map
*table_map
)
901 struct ofputil_requestforward rf
;
902 enum ofperr error
= ofputil_decode_requestforward(oh
, &rf
);
904 ofputil_format_requestforward(string
, oh
->version
,
905 &rf
, port_map
, table_map
);
906 ofputil_destroy_requestforward(&rf
);
912 ofp_print_nxst_ipfix_bridge_reply(struct ds
*string
, const struct ofp_header
*oh
)
914 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
916 struct ofputil_ipfix_stats is
;
919 retval
= ofputil_pull_ipfix_stats(&is
, &b
);
921 return retval
!= EOF
? retval
: 0;
923 ofputil_format_ipfix_stats_bridge(string
, &is
);
928 ofp_print_nxst_ipfix_flow_reply(struct ds
*string
, const struct ofp_header
*oh
)
930 ds_put_format(string
, " %"PRIuSIZE
" ids\n", ofputil_count_ipfix_stats(oh
));
932 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
934 struct ofputil_ipfix_stats is
;
937 retval
= ofputil_pull_ipfix_stats(&is
, &b
);
939 return retval
!= EOF
? retval
: 0;
941 ofputil_format_ipfix_stats_flow(string
, &is
);
946 ofp_print_nxt_ct_flush_zone(struct ds
*string
, const struct nx_zone_id
*nzi
)
948 ds_put_format(string
, " zone_id=%"PRIu16
, ntohs(nzi
->zone_id
));
953 ofp_to_string__(const struct ofp_header
*oh
,
954 const struct ofputil_port_map
*port_map
,
955 const struct ofputil_table_map
*table_map
, enum ofpraw raw
,
956 struct ds
*string
, int verbosity
)
958 if (ofpmsg_is_stat(oh
)) {
959 ofp_print_stats(string
, oh
);
962 const void *msg
= oh
;
963 enum ofptype type
= ofptype_from_ofpraw(raw
);
965 case OFPTYPE_GROUP_STATS_REQUEST
:
966 return ofputil_group_stats_request_format(string
, oh
);
968 case OFPTYPE_GROUP_STATS_REPLY
:
969 return ofputil_group_stats_format(string
, oh
);
971 case OFPTYPE_GROUP_DESC_STATS_REQUEST
:
972 return ofputil_group_desc_request_format(string
, oh
);
974 case OFPTYPE_GROUP_DESC_STATS_REPLY
:
975 return ofputil_group_desc_format(string
, oh
, port_map
, table_map
);
977 case OFPTYPE_GROUP_FEATURES_STATS_REQUEST
:
980 case OFPTYPE_GROUP_FEATURES_STATS_REPLY
:
981 return ofputil_group_features_format(string
, oh
);
983 case OFPTYPE_GROUP_MOD
:
984 return ofputil_group_mod_format(string
, oh
, port_map
, table_map
);
986 case OFPTYPE_TABLE_FEATURES_STATS_REQUEST
:
987 case OFPTYPE_TABLE_FEATURES_STATS_REPLY
:
988 return ofp_print_table_features_reply(string
, oh
);
990 case OFPTYPE_TABLE_DESC_REQUEST
:
991 case OFPTYPE_TABLE_DESC_REPLY
:
992 return ofp_print_table_desc_reply(string
, oh
, table_map
);
995 return ofp_print_hello(string
, oh
);
998 return ofp_print_error_msg(string
, oh
, port_map
, table_map
);
1000 case OFPTYPE_ECHO_REQUEST
:
1001 case OFPTYPE_ECHO_REPLY
:
1002 return ofp_print_echo(string
, oh
, verbosity
);
1004 case OFPTYPE_FEATURES_REQUEST
:
1007 case OFPTYPE_FEATURES_REPLY
:
1008 return ofp_print_switch_features(string
, oh
);
1010 case OFPTYPE_GET_CONFIG_REQUEST
:
1013 case OFPTYPE_GET_CONFIG_REPLY
:
1014 return ofp_print_get_config_reply(string
, oh
);
1016 case OFPTYPE_SET_CONFIG
:
1017 return ofp_print_set_config(string
, oh
);
1019 case OFPTYPE_PACKET_IN
:
1020 return ofp_print_packet_in(string
, oh
, port_map
, table_map
, verbosity
);
1022 case OFPTYPE_FLOW_REMOVED
:
1023 return ofp_print_flow_removed(string
, oh
, port_map
, table_map
);
1025 case OFPTYPE_PORT_STATUS
:
1026 return ofp_print_port_status(string
, oh
);
1028 case OFPTYPE_PACKET_OUT
:
1029 return ofp_print_packet_out(string
, oh
, port_map
, table_map
,
1032 case OFPTYPE_FLOW_MOD
:
1033 return ofputil_flow_mod_format(string
, oh
, port_map
, table_map
,
1036 case OFPTYPE_PORT_MOD
:
1037 return ofp_print_port_mod(string
, oh
, port_map
);
1039 case OFPTYPE_TABLE_MOD
:
1040 return ofp_print_table_mod(string
, oh
, table_map
);
1042 case OFPTYPE_METER_MOD
:
1043 return ofp_print_meter_mod(string
, oh
);
1045 case OFPTYPE_BARRIER_REQUEST
:
1046 case OFPTYPE_BARRIER_REPLY
:
1049 case OFPTYPE_QUEUE_GET_CONFIG_REQUEST
:
1050 return ofputil_queue_get_config_request_format(string
, oh
, port_map
);
1052 case OFPTYPE_QUEUE_GET_CONFIG_REPLY
:
1053 return ofputil_queue_get_config_reply_format(string
, oh
, port_map
);
1055 case OFPTYPE_ROLE_REQUEST
:
1056 case OFPTYPE_ROLE_REPLY
:
1057 return ofp_print_role_message(string
, oh
);
1058 case OFPTYPE_ROLE_STATUS
:
1059 return ofp_print_role_status_message(string
, oh
);
1061 case OFPTYPE_REQUESTFORWARD
:
1062 return ofp_print_requestforward(string
, oh
, port_map
, table_map
);
1064 case OFPTYPE_TABLE_STATUS
:
1065 return ofp_print_table_status_message(string
, oh
, table_map
);
1067 case OFPTYPE_METER_STATS_REQUEST
:
1068 case OFPTYPE_METER_CONFIG_STATS_REQUEST
:
1069 return ofp_print_meter_stats_request(string
, oh
);
1071 case OFPTYPE_METER_STATS_REPLY
:
1072 return ofp_print_meter_stats_reply(string
, oh
);
1074 case OFPTYPE_METER_CONFIG_STATS_REPLY
:
1075 return ofp_print_meter_config_reply(string
, oh
);
1077 case OFPTYPE_METER_FEATURES_STATS_REPLY
:
1078 return ofp_print_meter_features_reply(string
, oh
);
1080 case OFPTYPE_DESC_STATS_REQUEST
:
1081 case OFPTYPE_METER_FEATURES_STATS_REQUEST
:
1084 case OFPTYPE_FLOW_STATS_REQUEST
:
1085 case OFPTYPE_AGGREGATE_STATS_REQUEST
:
1086 return ofp_print_flow_stats_request(string
, oh
, port_map
, table_map
);
1088 case OFPTYPE_TABLE_STATS_REQUEST
:
1091 case OFPTYPE_PORT_STATS_REQUEST
:
1092 return ofp_print_ofpst_port_request(string
, oh
, port_map
);
1094 case OFPTYPE_QUEUE_STATS_REQUEST
:
1095 return ofputil_queue_stats_request_format(string
, oh
, port_map
);
1097 case OFPTYPE_DESC_STATS_REPLY
:
1098 return ofp_print_ofpst_desc_reply(string
, oh
);
1100 case OFPTYPE_FLOW_STATS_REPLY
:
1101 return ofp_print_flow_stats_reply(string
, oh
, port_map
, table_map
);
1103 case OFPTYPE_QUEUE_STATS_REPLY
:
1104 return ofputil_queue_stats_reply_format(string
, oh
, port_map
,
1107 case OFPTYPE_PORT_STATS_REPLY
:
1108 return ofp_print_ofpst_port_reply(string
, oh
, port_map
, verbosity
);
1110 case OFPTYPE_TABLE_STATS_REPLY
:
1111 return ofp_print_table_stats_reply(string
, oh
);
1113 case OFPTYPE_AGGREGATE_STATS_REPLY
:
1114 return ofp_print_aggregate_stats_reply(string
, oh
);
1116 case OFPTYPE_PORT_DESC_STATS_REQUEST
:
1117 return ofp_print_ofpst_port_desc_request(string
, oh
, port_map
);
1119 case OFPTYPE_PORT_DESC_STATS_REPLY
:
1120 return ofp_print_ofpst_port_desc_reply(string
, oh
);
1122 case OFPTYPE_FLOW_MOD_TABLE_ID
:
1123 return ofp_print_nxt_flow_mod_table_id(string
, oh
);
1125 case OFPTYPE_SET_FLOW_FORMAT
:
1126 return ofp_print_nxt_set_flow_format(string
, oh
);
1128 case OFPTYPE_SET_PACKET_IN_FORMAT
:
1129 return ofp_print_nxt_set_packet_in_format(string
, oh
);
1131 case OFPTYPE_FLOW_AGE
:
1134 case OFPTYPE_SET_CONTROLLER_ID
:
1135 return ofp_print_nxt_set_controller_id(string
, ofpmsg_body(oh
));
1137 case OFPTYPE_GET_ASYNC_REPLY
:
1138 case OFPTYPE_SET_ASYNC_CONFIG
:
1139 return ofp_print_set_async_config(string
, oh
, type
);
1140 case OFPTYPE_GET_ASYNC_REQUEST
:
1142 case OFPTYPE_FLOW_MONITOR_CANCEL
:
1143 return ofp_print_nxt_flow_monitor_cancel(string
, msg
);
1145 case OFPTYPE_FLOW_MONITOR_PAUSED
:
1146 case OFPTYPE_FLOW_MONITOR_RESUMED
:
1149 case OFPTYPE_FLOW_MONITOR_STATS_REQUEST
:
1150 return ofp_print_nxst_flow_monitor_request(string
, msg
, port_map
,
1153 case OFPTYPE_FLOW_MONITOR_STATS_REPLY
:
1154 return ofp_print_nxst_flow_monitor_reply(string
, msg
, port_map
,
1157 case OFPTYPE_BUNDLE_CONTROL
:
1158 return ofp_print_bundle_ctrl(string
, msg
);
1160 case OFPTYPE_BUNDLE_ADD_MESSAGE
:
1161 return ofp_print_bundle_add(string
, msg
, port_map
, table_map
,
1164 case OFPTYPE_NXT_TLV_TABLE_MOD
:
1165 return ofp_print_tlv_table_mod(string
, msg
);
1167 case OFPTYPE_NXT_TLV_TABLE_REQUEST
:
1170 case OFPTYPE_NXT_TLV_TABLE_REPLY
:
1171 return ofp_print_tlv_table_reply(string
, msg
);
1173 case OFPTYPE_NXT_RESUME
:
1174 return ofp_print_packet_in(string
, msg
, port_map
, table_map
,
1176 case OFPTYPE_IPFIX_BRIDGE_STATS_REQUEST
:
1178 case OFPTYPE_IPFIX_BRIDGE_STATS_REPLY
:
1179 return ofp_print_nxst_ipfix_bridge_reply(string
, oh
);
1180 case OFPTYPE_IPFIX_FLOW_STATS_REQUEST
:
1182 case OFPTYPE_IPFIX_FLOW_STATS_REPLY
:
1183 return ofp_print_nxst_ipfix_flow_reply(string
, oh
);
1185 case OFPTYPE_CT_FLUSH_ZONE
:
1186 return ofp_print_nxt_ct_flush_zone(string
, ofpmsg_body(oh
));
1193 add_newline(struct ds
*s
)
1195 if (s
->length
&& s
->string
[s
->length
- 1] != '\n') {
1196 ds_put_char(s
, '\n');
1200 /* Composes and returns a string representing the OpenFlow packet of 'len'
1201 * bytes at 'oh' at the given 'verbosity' level. 0 is a minimal amount of
1202 * verbosity and higher numbers increase verbosity. The caller is responsible
1203 * for freeing the string. */
1205 ofp_to_string(const void *oh_
, size_t len
,
1206 const struct ofputil_port_map
*port_map
,
1207 const struct ofputil_table_map
*table_map
,
1210 struct ds string
= DS_EMPTY_INITIALIZER
;
1211 const struct ofp_header
*oh
= oh_
;
1214 ds_put_cstr(&string
, "OpenFlow message is empty\n");
1215 } else if (len
< sizeof(struct ofp_header
)) {
1216 ds_put_format(&string
, "OpenFlow packet too short (only %"PRIuSIZE
" bytes):\n",
1218 } else if (ntohs(oh
->length
) > len
) {
1222 error
= ofpraw_decode_partial(&raw
, oh
, len
);
1224 ofp_header_to_string__(oh
, raw
, &string
);
1225 ds_put_char(&string
, '\n');
1228 ds_put_format(&string
,
1229 "(***truncated to %"PRIuSIZE
" bytes from %"PRIu16
"***)\n",
1230 len
, ntohs(oh
->length
));
1231 } else if (ntohs(oh
->length
) < len
) {
1232 ds_put_format(&string
,
1233 "(***only uses %"PRIu16
" bytes out of %"PRIuSIZE
"***)\n",
1234 ntohs(oh
->length
), len
);
1239 error
= ofpraw_decode(&raw
, oh
);
1241 ofp_header_to_string__(oh
, raw
, &string
);
1242 size_t header_len
= string
.length
;
1244 error
= ofp_to_string__(oh
, port_map
, table_map
,
1245 raw
, &string
, verbosity
);
1247 if (string
.length
> header_len
) {
1248 ds_chomp(&string
, ' ');
1249 add_newline(&string
);
1251 ds_put_char(&string
, ' ');
1253 ofp_print_error(&string
, error
);
1255 ds_chomp(&string
, ' ');
1258 ofp_print_error(&string
, error
);
1261 if (verbosity
>= 5 || error
) {
1262 add_newline(&string
);
1263 ds_put_hex_dump(&string
, oh
, len
, 0, true);
1266 add_newline(&string
);
1267 return ds_steal_cstr(&string
);
1269 ds_put_hex_dump(&string
, oh
, len
, 0, true);
1270 return ds_steal_cstr(&string
);
1274 print_and_free(FILE *stream
, char *string
)
1276 fputs(string
, stream
);
1280 /* Pretty-print the OpenFlow packet of 'len' bytes at 'oh' to 'stream' at the
1281 * given 'verbosity' level. 0 is a minimal amount of verbosity and higher
1282 * numbers increase verbosity. */
1284 ofp_print(FILE *stream
, const void *oh
, size_t len
,
1285 const struct ofputil_port_map
*port_map
,
1286 const struct ofputil_table_map
*table_map
, int verbosity
)
1288 print_and_free(stream
, ofp_to_string(oh
, len
, port_map
, table_map
,
1292 /* Dumps the contents of the Ethernet frame in the 'len' bytes starting at
1293 * 'data' to 'stream'. */
1295 ofp_print_packet(FILE *stream
, const void *data
, size_t len
,
1296 ovs_be32 packet_type
)
1298 print_and_free(stream
, ofp_packet_to_string(data
, len
, packet_type
));
1302 ofp_print_dp_packet(FILE *stream
, const struct dp_packet
*packet
)
1304 print_and_free(stream
, ofp_dp_packet_to_string(packet
));