2 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 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.
18 #include "ofp-print.h"
22 #include <sys/types.h>
23 #include <netinet/in.h>
30 #include "byte-order.h"
32 #include "dynamic-string.h"
35 #include "multipath.h"
36 #include "meta-flow.h"
39 #include "ofp-actions.h"
41 #include "ofp-errors.h"
44 #include "openflow/openflow.h"
45 #include "openflow/nicira-ext.h"
47 #include "dp-packet.h"
48 #include "type-props.h"
49 #include "unaligned.h"
53 static void ofp_print_queue_name(struct ds
*string
, uint32_t port
);
54 static void ofp_print_error(struct ds
*, enum ofperr
);
55 static void ofp_print_table_features(struct ds
*,
56 const struct ofputil_table_features
*,
57 const struct ofputil_table_stats
*);
59 /* Returns a string that represents the contents of the Ethernet frame in the
60 * 'len' bytes starting at 'data'. The caller must free the returned string.*/
62 ofp_packet_to_string(const void *data
, size_t len
)
64 struct ds ds
= DS_EMPTY_INITIALIZER
;
69 dp_packet_use_const(&buf
, data
, len
);
70 flow_extract(&buf
, &flow
);
71 flow_format(&ds
, &flow
);
73 l4_size
= dp_packet_l4_size(&buf
);
75 if (flow
.nw_proto
== IPPROTO_TCP
&& l4_size
>= TCP_HEADER_LEN
) {
76 struct tcp_header
*th
= dp_packet_l4(&buf
);
77 ds_put_format(&ds
, " tcp_csum:%"PRIx16
, ntohs(th
->tcp_csum
));
78 } else if (flow
.nw_proto
== IPPROTO_UDP
&& l4_size
>= UDP_HEADER_LEN
) {
79 struct udp_header
*uh
= dp_packet_l4(&buf
);
80 ds_put_format(&ds
, " udp_csum:%"PRIx16
, ntohs(uh
->udp_csum
));
81 } else if (flow
.nw_proto
== IPPROTO_SCTP
&& l4_size
>= SCTP_HEADER_LEN
) {
82 struct sctp_header
*sh
= dp_packet_l4(&buf
);
83 ds_put_format(&ds
, " sctp_csum:%"PRIx32
,
84 ntohl(get_16aligned_be32(&sh
->sctp_csum
)));
85 } else if (flow
.nw_proto
== IPPROTO_ICMP
&& l4_size
>= ICMP_HEADER_LEN
) {
86 struct icmp_header
*icmph
= dp_packet_l4(&buf
);
87 ds_put_format(&ds
, " icmp_csum:%"PRIx16
,
88 ntohs(icmph
->icmp_csum
));
89 } else if (flow
.nw_proto
== IPPROTO_ICMPV6
&& l4_size
>= ICMP6_HEADER_LEN
) {
90 struct icmp6_header
*icmp6h
= dp_packet_l4(&buf
);
91 ds_put_format(&ds
, " icmp6_csum:%"PRIx16
,
92 ntohs(icmp6h
->icmp6_cksum
));
95 ds_put_char(&ds
, '\n');
101 ofp_print_packet_in(struct ds
*string
, const struct ofp_header
*oh
,
104 char reasonbuf
[OFPUTIL_PACKET_IN_REASON_BUFSIZE
];
105 struct ofputil_packet_in pin
;
109 error
= ofputil_decode_packet_in(&pin
, oh
);
111 ofp_print_error(string
, error
);
116 ds_put_format(string
, " table_id=%"PRIu8
, pin
.table_id
);
119 if (pin
.cookie
!= OVS_BE64_MAX
) {
120 ds_put_format(string
, " cookie=0x%"PRIx64
, ntohll(pin
.cookie
));
123 ds_put_format(string
, " total_len=%"PRIuSIZE
" in_port=", pin
.total_len
);
124 ofputil_format_port(pin
.fmd
.in_port
, string
);
126 if (pin
.fmd
.tun_id
!= htonll(0)) {
127 ds_put_format(string
, " tun_id=0x%"PRIx64
, ntohll(pin
.fmd
.tun_id
));
130 if (pin
.fmd
.tun_src
!= htonl(0)) {
131 ds_put_format(string
, " tun_src="IP_FMT
, IP_ARGS(pin
.fmd
.tun_src
));
134 if (pin
.fmd
.tun_dst
!= htonl(0)) {
135 ds_put_format(string
, " tun_dst="IP_FMT
, IP_ARGS(pin
.fmd
.tun_dst
));
138 if (pin
.fmd
.gbp_id
!= htons(0)) {
139 ds_put_format(string
, " gbp_id=%"PRIu16
,
140 ntohs(pin
.fmd
.gbp_id
));
143 if (pin
.fmd
.gbp_flags
) {
144 ds_put_format(string
, " gbp_flags=0x%02"PRIx8
, pin
.fmd
.gbp_flags
);
147 if (pin
.fmd
.metadata
!= htonll(0)) {
148 ds_put_format(string
, " metadata=0x%"PRIx64
, ntohll(pin
.fmd
.metadata
));
151 for (i
= 0; i
< FLOW_N_REGS
; i
++) {
152 if (pin
.fmd
.regs
[i
]) {
153 ds_put_format(string
, " reg%d=0x%"PRIx32
, i
, pin
.fmd
.regs
[i
]);
157 if (pin
.fmd
.pkt_mark
!= 0) {
158 ds_put_format(string
, " pkt_mark=0x%"PRIx32
, pin
.fmd
.pkt_mark
);
161 ds_put_format(string
, " (via %s)",
162 ofputil_packet_in_reason_to_string(pin
.reason
, reasonbuf
,
165 ds_put_format(string
, " data_len=%"PRIuSIZE
, pin
.packet_len
);
166 if (pin
.buffer_id
== UINT32_MAX
) {
167 ds_put_format(string
, " (unbuffered)");
168 if (pin
.total_len
!= pin
.packet_len
) {
169 ds_put_format(string
, " (***total_len != data_len***)");
172 ds_put_format(string
, " buffer=0x%08"PRIx32
, pin
.buffer_id
);
173 if (pin
.total_len
< pin
.packet_len
) {
174 ds_put_format(string
, " (***total_len < data_len***)");
177 ds_put_char(string
, '\n');
180 char *packet
= ofp_packet_to_string(pin
.packet
, pin
.packet_len
);
181 ds_put_cstr(string
, packet
);
185 ds_put_hex_dump(string
, pin
.packet
, pin
.packet_len
, 0, false);
190 ofp_print_packet_out(struct ds
*string
, const struct ofp_header
*oh
,
193 struct ofputil_packet_out po
;
194 struct ofpbuf ofpacts
;
197 ofpbuf_init(&ofpacts
, 64);
198 error
= ofputil_decode_packet_out(&po
, oh
, &ofpacts
);
200 ofpbuf_uninit(&ofpacts
);
201 ofp_print_error(string
, error
);
205 ds_put_cstr(string
, " in_port=");
206 ofputil_format_port(po
.in_port
, string
);
208 ds_put_cstr(string
, " actions=");
209 ofpacts_format(po
.ofpacts
, po
.ofpacts_len
, string
);
211 if (po
.buffer_id
== UINT32_MAX
) {
212 ds_put_format(string
, " data_len=%"PRIuSIZE
, po
.packet_len
);
213 if (verbosity
> 0 && po
.packet_len
> 0) {
214 char *packet
= ofp_packet_to_string(po
.packet
, po
.packet_len
);
215 ds_put_char(string
, '\n');
216 ds_put_cstr(string
, packet
);
220 ds_put_hex_dump(string
, po
.packet
, po
.packet_len
, 0, false);
223 ds_put_format(string
, " buffer=0x%08"PRIx32
, po
.buffer_id
);
226 ofpbuf_uninit(&ofpacts
);
229 /* qsort comparison function. */
231 compare_ports(const void *a_
, const void *b_
)
233 const struct ofputil_phy_port
*a
= a_
;
234 const struct ofputil_phy_port
*b
= b_
;
235 uint16_t ap
= ofp_to_u16(a
->port_no
);
236 uint16_t bp
= ofp_to_u16(b
->port_no
);
238 return ap
< bp
? -1 : ap
> bp
;
242 ofp_print_bit_names(struct ds
*string
, uint32_t bits
,
243 const char *(*bit_to_name
)(uint32_t bit
),
250 ds_put_cstr(string
, "0");
254 for (i
= 0; i
< 32; i
++) {
255 uint32_t bit
= UINT32_C(1) << i
;
258 const char *name
= bit_to_name(bit
);
261 ds_put_char(string
, separator
);
263 ds_put_cstr(string
, name
);
271 ds_put_char(string
, separator
);
273 ds_put_format(string
, "0x%"PRIx32
, bits
);
278 netdev_feature_to_name(uint32_t bit
)
280 enum netdev_features f
= bit
;
283 case NETDEV_F_10MB_HD
: return "10MB-HD";
284 case NETDEV_F_10MB_FD
: return "10MB-FD";
285 case NETDEV_F_100MB_HD
: return "100MB-HD";
286 case NETDEV_F_100MB_FD
: return "100MB-FD";
287 case NETDEV_F_1GB_HD
: return "1GB-HD";
288 case NETDEV_F_1GB_FD
: return "1GB-FD";
289 case NETDEV_F_10GB_FD
: return "10GB-FD";
290 case NETDEV_F_40GB_FD
: return "40GB-FD";
291 case NETDEV_F_100GB_FD
: return "100GB-FD";
292 case NETDEV_F_1TB_FD
: return "1TB-FD";
293 case NETDEV_F_OTHER
: return "OTHER";
294 case NETDEV_F_COPPER
: return "COPPER";
295 case NETDEV_F_FIBER
: return "FIBER";
296 case NETDEV_F_AUTONEG
: return "AUTO_NEG";
297 case NETDEV_F_PAUSE
: return "AUTO_PAUSE";
298 case NETDEV_F_PAUSE_ASYM
: return "AUTO_PAUSE_ASYM";
305 ofp_print_port_features(struct ds
*string
, enum netdev_features features
)
307 ofp_print_bit_names(string
, features
, netdev_feature_to_name
, ' ');
308 ds_put_char(string
, '\n');
312 ofputil_port_config_to_name(uint32_t bit
)
314 enum ofputil_port_config pc
= bit
;
317 case OFPUTIL_PC_PORT_DOWN
: return "PORT_DOWN";
318 case OFPUTIL_PC_NO_STP
: return "NO_STP";
319 case OFPUTIL_PC_NO_RECV
: return "NO_RECV";
320 case OFPUTIL_PC_NO_RECV_STP
: return "NO_RECV_STP";
321 case OFPUTIL_PC_NO_FLOOD
: return "NO_FLOOD";
322 case OFPUTIL_PC_NO_FWD
: return "NO_FWD";
323 case OFPUTIL_PC_NO_PACKET_IN
: return "NO_PACKET_IN";
330 ofp_print_port_config(struct ds
*string
, enum ofputil_port_config config
)
332 ofp_print_bit_names(string
, config
, ofputil_port_config_to_name
, ' ');
333 ds_put_char(string
, '\n');
337 ofputil_port_state_to_name(uint32_t bit
)
339 enum ofputil_port_state ps
= bit
;
342 case OFPUTIL_PS_LINK_DOWN
: return "LINK_DOWN";
343 case OFPUTIL_PS_BLOCKED
: return "BLOCKED";
344 case OFPUTIL_PS_LIVE
: return "LIVE";
346 case OFPUTIL_PS_STP_LISTEN
:
347 case OFPUTIL_PS_STP_LEARN
:
348 case OFPUTIL_PS_STP_FORWARD
:
349 case OFPUTIL_PS_STP_BLOCK
:
350 /* Handled elsewhere. */
358 ofp_print_port_state(struct ds
*string
, enum ofputil_port_state state
)
360 enum ofputil_port_state stp_state
;
362 /* The STP state is a 2-bit field so it doesn't fit in with the bitmask
363 * pattern. We have to special case it.
365 * OVS doesn't support STP, so this field will always be 0 if we are
366 * talking to OVS, so we'd always print STP_LISTEN in that case.
367 * Therefore, we don't print anything at all if the value is STP_LISTEN, to
368 * avoid confusing users. */
369 stp_state
= state
& OFPUTIL_PS_STP_MASK
;
372 (stp_state
== OFPUTIL_PS_STP_LEARN
? "STP_LEARN"
373 : stp_state
== OFPUTIL_PS_STP_FORWARD
? "STP_FORWARD"
375 state
&= ~OFPUTIL_PS_STP_MASK
;
377 ofp_print_bit_names(string
, state
, ofputil_port_state_to_name
,
381 ofp_print_bit_names(string
, state
, ofputil_port_state_to_name
, ' ');
383 ds_put_char(string
, '\n');
387 ofp_print_phy_port(struct ds
*string
, const struct ofputil_phy_port
*port
)
389 char name
[sizeof port
->name
];
392 memcpy(name
, port
->name
, sizeof name
);
393 for (j
= 0; j
< sizeof name
- 1; j
++) {
394 if (!isprint((unsigned char) name
[j
])) {
400 ds_put_char(string
, ' ');
401 ofputil_format_port(port
->port_no
, string
);
402 ds_put_format(string
, "(%s): addr:"ETH_ADDR_FMT
"\n",
403 name
, ETH_ADDR_ARGS(port
->hw_addr
));
405 ds_put_cstr(string
, " config: ");
406 ofp_print_port_config(string
, port
->config
);
408 ds_put_cstr(string
, " state: ");
409 ofp_print_port_state(string
, port
->state
);
412 ds_put_format(string
, " current: ");
413 ofp_print_port_features(string
, port
->curr
);
415 if (port
->advertised
) {
416 ds_put_format(string
, " advertised: ");
417 ofp_print_port_features(string
, port
->advertised
);
419 if (port
->supported
) {
420 ds_put_format(string
, " supported: ");
421 ofp_print_port_features(string
, port
->supported
);
424 ds_put_format(string
, " peer: ");
425 ofp_print_port_features(string
, port
->peer
);
427 ds_put_format(string
, " speed: %"PRIu32
" Mbps now, "
428 "%"PRIu32
" Mbps max\n",
429 port
->curr_speed
/ UINT32_C(1000),
430 port
->max_speed
/ UINT32_C(1000));
433 /* Given a buffer 'b' that contains an array of OpenFlow ports of type
434 * 'ofp_version', writes a detailed description of each port into
437 ofp_print_phy_ports(struct ds
*string
, uint8_t ofp_version
,
440 struct ofputil_phy_port
*ports
;
441 size_t allocated_ports
, n_ports
;
447 for (n_ports
= 0; ; n_ports
++) {
448 if (n_ports
>= allocated_ports
) {
449 ports
= x2nrealloc(ports
, &allocated_ports
, sizeof *ports
);
452 retval
= ofputil_pull_phy_port(ofp_version
, b
, &ports
[n_ports
]);
458 qsort(ports
, n_ports
, sizeof *ports
, compare_ports
);
459 for (i
= 0; i
< n_ports
; i
++) {
460 ofp_print_phy_port(string
, &ports
[i
]);
465 ofp_print_error(string
, retval
);
470 ofputil_capabilities_to_name(uint32_t bit
)
472 enum ofputil_capabilities capabilities
= bit
;
474 switch (capabilities
) {
475 case OFPUTIL_C_FLOW_STATS
: return "FLOW_STATS";
476 case OFPUTIL_C_TABLE_STATS
: return "TABLE_STATS";
477 case OFPUTIL_C_PORT_STATS
: return "PORT_STATS";
478 case OFPUTIL_C_IP_REASM
: return "IP_REASM";
479 case OFPUTIL_C_QUEUE_STATS
: return "QUEUE_STATS";
480 case OFPUTIL_C_ARP_MATCH_IP
: return "ARP_MATCH_IP";
481 case OFPUTIL_C_STP
: return "STP";
482 case OFPUTIL_C_GROUP_STATS
: return "GROUP_STATS";
483 case OFPUTIL_C_PORT_BLOCKED
: return "PORT_BLOCKED";
490 ofp_print_switch_features(struct ds
*string
, const struct ofp_header
*oh
)
492 struct ofputil_switch_features features
;
496 error
= ofputil_decode_switch_features(oh
, &features
, &b
);
498 ofp_print_error(string
, error
);
502 ds_put_format(string
, " dpid:%016"PRIx64
"\n", features
.datapath_id
);
504 ds_put_format(string
, "n_tables:%"PRIu8
", n_buffers:%"PRIu32
,
505 features
.n_tables
, features
.n_buffers
);
506 if (features
.auxiliary_id
) {
507 ds_put_format(string
, ", auxiliary_id:%"PRIu8
, features
.auxiliary_id
);
509 ds_put_char(string
, '\n');
511 ds_put_cstr(string
, "capabilities: ");
512 ofp_print_bit_names(string
, features
.capabilities
,
513 ofputil_capabilities_to_name
, ' ');
514 ds_put_char(string
, '\n');
516 switch ((enum ofp_version
)oh
->version
) {
518 ds_put_cstr(string
, "actions: ");
519 ofpact_bitmap_format(features
.ofpacts
, string
);
520 ds_put_char(string
, '\n');
528 return; /* no ports in ofp13_switch_features */
533 ofp_print_phy_ports(string
, oh
->version
, &b
);
537 ofp_print_switch_config(struct ds
*string
, const struct ofp_switch_config
*osc
)
539 enum ofp_config_flags flags
;
541 flags
= ntohs(osc
->flags
);
543 ds_put_format(string
, " frags=%s", ofputil_frag_handling_to_string(flags
));
544 flags
&= ~OFPC_FRAG_MASK
;
546 if (flags
& OFPC_INVALID_TTL_TO_CONTROLLER
) {
547 ds_put_format(string
, " invalid_ttl_to_controller");
548 flags
&= ~OFPC_INVALID_TTL_TO_CONTROLLER
;
552 ds_put_format(string
, " ***unknown flags 0x%04"PRIx16
"***", flags
);
555 ds_put_format(string
, " miss_send_len=%"PRIu16
"\n", ntohs(osc
->miss_send_len
));
558 static void print_wild(struct ds
*string
, const char *leader
, int is_wild
,
559 int verbosity
, const char *format
, ...)
560 OVS_PRINTF_FORMAT(5, 6);
562 static void print_wild(struct ds
*string
, const char *leader
, int is_wild
,
563 int verbosity
, const char *format
, ...)
565 if (is_wild
&& verbosity
< 2) {
568 ds_put_cstr(string
, leader
);
572 va_start(args
, format
);
573 ds_put_format_valist(string
, format
, args
);
576 ds_put_char(string
, '*');
578 ds_put_char(string
, ',');
582 print_wild_port(struct ds
*string
, const char *leader
, int is_wild
,
583 int verbosity
, ofp_port_t port
)
585 if (is_wild
&& verbosity
< 2) {
588 ds_put_cstr(string
, leader
);
590 ofputil_format_port(port
, string
);
592 ds_put_char(string
, '*');
594 ds_put_char(string
, ',');
598 print_ip_netmask(struct ds
*string
, const char *leader
, ovs_be32 ip
,
599 uint32_t wild_bits
, int verbosity
)
601 if (wild_bits
>= 32 && verbosity
< 2) {
604 ds_put_cstr(string
, leader
);
605 if (wild_bits
< 32) {
606 ds_put_format(string
, IP_FMT
, IP_ARGS(ip
));
608 ds_put_format(string
, "/%d", 32 - wild_bits
);
611 ds_put_char(string
, '*');
613 ds_put_char(string
, ',');
617 ofp10_match_print(struct ds
*f
, const struct ofp10_match
*om
, int verbosity
)
619 char *s
= ofp10_match_to_string(om
, verbosity
);
625 ofp10_match_to_string(const struct ofp10_match
*om
, int verbosity
)
627 struct ds f
= DS_EMPTY_INITIALIZER
;
628 uint32_t w
= ntohl(om
->wildcards
);
629 bool skip_type
= false;
630 bool skip_proto
= false;
632 if (!(w
& OFPFW10_DL_TYPE
)) {
634 if (om
->dl_type
== htons(ETH_TYPE_IP
)) {
635 if (!(w
& OFPFW10_NW_PROTO
)) {
637 if (om
->nw_proto
== IPPROTO_ICMP
) {
638 ds_put_cstr(&f
, "icmp,");
639 } else if (om
->nw_proto
== IPPROTO_TCP
) {
640 ds_put_cstr(&f
, "tcp,");
641 } else if (om
->nw_proto
== IPPROTO_UDP
) {
642 ds_put_cstr(&f
, "udp,");
643 } else if (om
->nw_proto
== IPPROTO_SCTP
) {
644 ds_put_cstr(&f
, "sctp,");
646 ds_put_cstr(&f
, "ip,");
650 ds_put_cstr(&f
, "ip,");
652 } else if (om
->dl_type
== htons(ETH_TYPE_ARP
)) {
653 ds_put_cstr(&f
, "arp,");
654 } else if (om
->dl_type
== htons(ETH_TYPE_RARP
)){
655 ds_put_cstr(&f
, "rarp,");
656 } else if (om
->dl_type
== htons(ETH_TYPE_MPLS
)) {
657 ds_put_cstr(&f
, "mpls,");
658 } else if (om
->dl_type
== htons(ETH_TYPE_MPLS_MCAST
)) {
659 ds_put_cstr(&f
, "mplsm,");
664 print_wild_port(&f
, "in_port=", w
& OFPFW10_IN_PORT
, verbosity
,
665 u16_to_ofp(ntohs(om
->in_port
)));
666 print_wild(&f
, "dl_vlan=", w
& OFPFW10_DL_VLAN
, verbosity
,
667 "%d", ntohs(om
->dl_vlan
));
668 print_wild(&f
, "dl_vlan_pcp=", w
& OFPFW10_DL_VLAN_PCP
, verbosity
,
669 "%d", om
->dl_vlan_pcp
);
670 print_wild(&f
, "dl_src=", w
& OFPFW10_DL_SRC
, verbosity
,
671 ETH_ADDR_FMT
, ETH_ADDR_ARGS(om
->dl_src
));
672 print_wild(&f
, "dl_dst=", w
& OFPFW10_DL_DST
, verbosity
,
673 ETH_ADDR_FMT
, ETH_ADDR_ARGS(om
->dl_dst
));
675 print_wild(&f
, "dl_type=", w
& OFPFW10_DL_TYPE
, verbosity
,
676 "0x%04x", ntohs(om
->dl_type
));
678 print_ip_netmask(&f
, "nw_src=", om
->nw_src
,
679 (w
& OFPFW10_NW_SRC_MASK
) >> OFPFW10_NW_SRC_SHIFT
,
681 print_ip_netmask(&f
, "nw_dst=", om
->nw_dst
,
682 (w
& OFPFW10_NW_DST_MASK
) >> OFPFW10_NW_DST_SHIFT
,
685 if (om
->dl_type
== htons(ETH_TYPE_ARP
) ||
686 om
->dl_type
== htons(ETH_TYPE_RARP
)) {
687 print_wild(&f
, "arp_op=", w
& OFPFW10_NW_PROTO
, verbosity
,
690 print_wild(&f
, "nw_proto=", w
& OFPFW10_NW_PROTO
, verbosity
,
694 print_wild(&f
, "nw_tos=", w
& OFPFW10_NW_TOS
, verbosity
,
696 if (om
->nw_proto
== IPPROTO_ICMP
) {
697 print_wild(&f
, "icmp_type=", w
& OFPFW10_ICMP_TYPE
, verbosity
,
698 "%d", ntohs(om
->tp_src
));
699 print_wild(&f
, "icmp_code=", w
& OFPFW10_ICMP_CODE
, verbosity
,
700 "%d", ntohs(om
->tp_dst
));
702 print_wild(&f
, "tp_src=", w
& OFPFW10_TP_SRC
, verbosity
,
703 "%d", ntohs(om
->tp_src
));
704 print_wild(&f
, "tp_dst=", w
& OFPFW10_TP_DST
, verbosity
,
705 "%d", ntohs(om
->tp_dst
));
712 ofp_print_flow_flags(struct ds
*s
, enum ofputil_flow_mod_flags flags
)
714 if (flags
& OFPUTIL_FF_SEND_FLOW_REM
) {
715 ds_put_cstr(s
, "send_flow_rem ");
717 if (flags
& OFPUTIL_FF_CHECK_OVERLAP
) {
718 ds_put_cstr(s
, "check_overlap ");
720 if (flags
& OFPUTIL_FF_RESET_COUNTS
) {
721 ds_put_cstr(s
, "reset_counts ");
723 if (flags
& OFPUTIL_FF_NO_PKT_COUNTS
) {
724 ds_put_cstr(s
, "no_packet_counts ");
726 if (flags
& OFPUTIL_FF_NO_BYT_COUNTS
) {
727 ds_put_cstr(s
, "no_byte_counts ");
729 if (flags
& OFPUTIL_FF_HIDDEN_FIELDS
) {
730 ds_put_cstr(s
, "allow_hidden_fields ");
732 if (flags
& OFPUTIL_FF_NO_READONLY
) {
733 ds_put_cstr(s
, "no_readonly_table ");
738 ofp_print_flow_mod(struct ds
*s
, const struct ofp_header
*oh
, int verbosity
)
740 struct ofputil_flow_mod fm
;
741 struct ofpbuf ofpacts
;
745 enum ofputil_protocol protocol
;
747 protocol
= ofputil_protocol_from_ofp_version(oh
->version
);
748 protocol
= ofputil_protocol_set_tid(protocol
, true);
750 ofpbuf_init(&ofpacts
, 64);
751 error
= ofputil_decode_flow_mod(&fm
, oh
, protocol
, &ofpacts
,
754 ofpbuf_uninit(&ofpacts
);
755 ofp_print_error(s
, error
);
760 switch (fm
.command
) {
762 ds_put_cstr(s
, "ADD");
765 ds_put_cstr(s
, "MOD");
767 case OFPFC_MODIFY_STRICT
:
768 ds_put_cstr(s
, "MOD_STRICT");
771 ds_put_cstr(s
, "DEL");
773 case OFPFC_DELETE_STRICT
:
774 ds_put_cstr(s
, "DEL_STRICT");
777 ds_put_format(s
, "cmd:%d", fm
.command
);
779 if (fm
.table_id
!= 0) {
780 ds_put_format(s
, " table:%d", fm
.table_id
);
784 ofpraw_decode(&raw
, oh
);
785 if (verbosity
>= 3 && raw
== OFPRAW_OFPT10_FLOW_MOD
) {
786 const struct ofp10_flow_mod
*ofm
= ofpmsg_body(oh
);
787 ofp10_match_print(s
, &ofm
->match
, verbosity
);
789 /* ofp_print_match() doesn't print priority. */
790 need_priority
= true;
791 } else if (verbosity
>= 3 && raw
== OFPRAW_NXT_FLOW_MOD
) {
792 const struct nx_flow_mod
*nfm
= ofpmsg_body(oh
);
793 const void *nxm
= nfm
+ 1;
796 nxm_s
= nx_match_to_string(nxm
, ntohs(nfm
->match_len
));
797 ds_put_cstr(s
, nxm_s
);
800 /* nx_match_to_string() doesn't print priority. */
801 need_priority
= true;
803 match_format(&fm
.match
, s
, fm
.priority
);
805 /* match_format() does print priority. */
806 need_priority
= false;
809 if (ds_last(s
) != ' ') {
812 if (fm
.new_cookie
!= htonll(0) && fm
.new_cookie
!= OVS_BE64_MAX
) {
813 ds_put_format(s
, "cookie:0x%"PRIx64
" ", ntohll(fm
.new_cookie
));
815 if (fm
.cookie_mask
!= htonll(0)) {
816 ds_put_format(s
, "cookie:0x%"PRIx64
"/0x%"PRIx64
" ",
817 ntohll(fm
.cookie
), ntohll(fm
.cookie_mask
));
819 if (fm
.idle_timeout
!= OFP_FLOW_PERMANENT
) {
820 ds_put_format(s
, "idle:%"PRIu16
" ", fm
.idle_timeout
);
822 if (fm
.hard_timeout
!= OFP_FLOW_PERMANENT
) {
823 ds_put_format(s
, "hard:%"PRIu16
" ", fm
.hard_timeout
);
825 if (fm
.importance
!= 0) {
826 ds_put_format(s
, "importance:%"PRIu16
" ", fm
.importance
);
828 if (fm
.priority
!= OFP_DEFAULT_PRIORITY
&& need_priority
) {
829 ds_put_format(s
, "pri:%"PRIu16
" ", fm
.priority
);
831 if (fm
.buffer_id
!= UINT32_MAX
) {
832 ds_put_format(s
, "buf:0x%"PRIx32
" ", fm
.buffer_id
);
834 if (fm
.out_port
!= OFPP_ANY
) {
835 ds_put_format(s
, "out_port:");
836 ofputil_format_port(fm
.out_port
, s
);
840 if (oh
->version
== OFP10_VERSION
|| oh
->version
== OFP11_VERSION
) {
841 /* Don't print the reset_counts flag for OF1.0 and OF1.1 because those
842 * versions don't really have such a flag and printing one is likely to
844 fm
.flags
&= ~OFPUTIL_FF_RESET_COUNTS
;
846 ofp_print_flow_flags(s
, fm
.flags
);
848 ds_put_cstr(s
, "actions=");
849 ofpacts_format(fm
.ofpacts
, fm
.ofpacts_len
, s
);
850 ofpbuf_uninit(&ofpacts
);
854 ofp_print_duration(struct ds
*string
, unsigned int sec
, unsigned int nsec
)
856 ds_put_format(string
, "%u", sec
);
858 /* If there are no fractional seconds, don't print any decimals.
860 * If the fractional seconds can be expressed exactly as milliseconds,
861 * print 3 decimals. Open vSwitch provides millisecond precision for most
862 * time measurements, so printing 3 decimals every time makes it easier to
863 * spot real changes in flow dumps that refresh themselves quickly.
865 * If the fractional seconds are more precise than milliseconds, print the
866 * number of decimals needed to express them exactly.
869 unsigned int msec
= nsec
/ 1000000;
870 if (msec
* 1000000 == nsec
) {
871 ds_put_format(string
, ".%03u", msec
);
873 ds_put_format(string
, ".%09u", nsec
);
874 while (string
->string
[string
->length
- 1] == '0') {
879 ds_put_char(string
, 's');
882 /* Returns a string form of 'reason'. The return value is either a statically
883 * allocated constant string or the 'bufsize'-byte buffer 'reasonbuf'.
884 * 'bufsize' should be at least OFP_FLOW_REMOVED_REASON_BUFSIZE. */
885 #define OFP_FLOW_REMOVED_REASON_BUFSIZE (INT_STRLEN(int) + 1)
887 ofp_flow_removed_reason_to_string(enum ofp_flow_removed_reason reason
,
888 char *reasonbuf
, size_t bufsize
)
891 case OFPRR_IDLE_TIMEOUT
:
893 case OFPRR_HARD_TIMEOUT
:
897 case OFPRR_GROUP_DELETE
:
898 return "group_delete";
901 case OFPRR_METER_DELETE
:
902 return "meter_delete";
904 snprintf(reasonbuf
, bufsize
, "%d", (int) reason
);
910 ofp_print_flow_removed(struct ds
*string
, const struct ofp_header
*oh
)
912 char reasonbuf
[OFP_FLOW_REMOVED_REASON_BUFSIZE
];
913 struct ofputil_flow_removed fr
;
916 error
= ofputil_decode_flow_removed(&fr
, oh
);
918 ofp_print_error(string
, error
);
922 ds_put_char(string
, ' ');
923 match_format(&fr
.match
, string
, fr
.priority
);
925 ds_put_format(string
, " reason=%s",
926 ofp_flow_removed_reason_to_string(fr
.reason
, reasonbuf
,
929 if (fr
.table_id
!= 255) {
930 ds_put_format(string
, " table_id=%"PRIu8
, fr
.table_id
);
933 if (fr
.cookie
!= htonll(0)) {
934 ds_put_format(string
, " cookie:0x%"PRIx64
, ntohll(fr
.cookie
));
936 ds_put_cstr(string
, " duration");
937 ofp_print_duration(string
, fr
.duration_sec
, fr
.duration_nsec
);
938 ds_put_format(string
, " idle%"PRIu16
, fr
.idle_timeout
);
939 if (fr
.hard_timeout
) {
940 /* The hard timeout was only added in OF1.2, so only print it if it is
941 * actually in use to avoid gratuitous change to the formatting. */
942 ds_put_format(string
, " hard%"PRIu16
, fr
.hard_timeout
);
944 ds_put_format(string
, " pkts%"PRIu64
" bytes%"PRIu64
"\n",
945 fr
.packet_count
, fr
.byte_count
);
949 ofp_print_port_mod(struct ds
*string
, const struct ofp_header
*oh
)
951 struct ofputil_port_mod pm
;
954 error
= ofputil_decode_port_mod(oh
, &pm
, true);
956 ofp_print_error(string
, error
);
960 ds_put_cstr(string
, "port: ");
961 ofputil_format_port(pm
.port_no
, string
);
962 ds_put_format(string
, ": addr:"ETH_ADDR_FMT
"\n",
963 ETH_ADDR_ARGS(pm
.hw_addr
));
965 ds_put_cstr(string
, " config: ");
966 ofp_print_port_config(string
, pm
.config
);
968 ds_put_cstr(string
, " mask: ");
969 ofp_print_port_config(string
, pm
.mask
);
971 ds_put_cstr(string
, " advertise: ");
973 ofp_print_port_features(string
, pm
.advertise
);
975 ds_put_cstr(string
, "UNCHANGED\n");
980 ofp_print_table_miss_config(struct ds
*string
, enum ofputil_table_miss miss
)
983 case OFPUTIL_TABLE_MISS_CONTROLLER
:
984 ds_put_cstr(string
, "controller\n");
986 case OFPUTIL_TABLE_MISS_CONTINUE
:
987 ds_put_cstr(string
, "continue\n");
989 case OFPUTIL_TABLE_MISS_DROP
:
990 ds_put_cstr(string
, "drop\n");
992 case OFPUTIL_TABLE_MISS_DEFAULT
:
994 ds_put_format(string
, "Unknown (%d)\n", miss
);
1000 ofp_print_table_mod(struct ds
*string
, const struct ofp_header
*oh
)
1002 struct ofputil_table_mod pm
;
1005 error
= ofputil_decode_table_mod(oh
, &pm
);
1007 ofp_print_error(string
, error
);
1011 if (pm
.table_id
== 0xff) {
1012 ds_put_cstr(string
, " table_id: ALL_TABLES");
1014 ds_put_format(string
, " table_id=%"PRIu8
, pm
.table_id
);
1017 if (pm
.miss_config
!= OFPUTIL_TABLE_MISS_DEFAULT
) {
1018 ds_put_cstr(string
, ", flow_miss_config=");
1019 ofp_print_table_miss_config(string
, pm
.miss_config
);
1024 ofp_print_queue_get_config_request(struct ds
*string
,
1025 const struct ofp_header
*oh
)
1030 error
= ofputil_decode_queue_get_config_request(oh
, &port
);
1032 ofp_print_error(string
, error
);
1036 ds_put_cstr(string
, " port=");
1037 ofputil_format_port(port
, string
);
1041 print_queue_rate(struct ds
*string
, const char *name
, unsigned int rate
)
1044 ds_put_format(string
, " %s:%u.%u%%", name
, rate
/ 10, rate
% 10);
1045 } else if (rate
< UINT16_MAX
) {
1046 ds_put_format(string
, " %s:(disabled)", name
);
1051 ofp_print_queue_get_config_reply(struct ds
*string
,
1052 const struct ofp_header
*oh
)
1058 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
1059 error
= ofputil_decode_queue_get_config_reply(&b
, &port
);
1061 ofp_print_error(string
, error
);
1065 ds_put_cstr(string
, " port=");
1066 ofputil_format_port(port
, string
);
1067 ds_put_char(string
, '\n');
1070 struct ofputil_queue_config queue
;
1073 retval
= ofputil_pull_queue_get_config_reply(&b
, &queue
);
1075 if (retval
!= EOF
) {
1076 ofp_print_error(string
, retval
);
1081 ds_put_format(string
, "queue %"PRIu32
":", queue
.queue_id
);
1082 print_queue_rate(string
, "min_rate", queue
.min_rate
);
1083 print_queue_rate(string
, "max_rate", queue
.max_rate
);
1084 ds_put_char(string
, '\n');
1089 ofp_print_meter_flags(struct ds
*s
, uint16_t flags
)
1091 if (flags
& OFPMF13_KBPS
) {
1092 ds_put_cstr(s
, "kbps ");
1094 if (flags
& OFPMF13_PKTPS
) {
1095 ds_put_cstr(s
, "pktps ");
1097 if (flags
& OFPMF13_BURST
) {
1098 ds_put_cstr(s
, "burst ");
1100 if (flags
& OFPMF13_STATS
) {
1101 ds_put_cstr(s
, "stats ");
1104 flags
&= ~(OFPMF13_KBPS
| OFPMF13_PKTPS
| OFPMF13_BURST
| OFPMF13_STATS
);
1106 ds_put_format(s
, "flags:0x%"PRIx16
" ", flags
);
1111 ofp_print_meter_band(struct ds
*s
, uint16_t flags
,
1112 const struct ofputil_meter_band
*mb
)
1114 ds_put_cstr(s
, "\ntype=");
1117 ds_put_cstr(s
, "drop");
1119 case OFPMBT13_DSCP_REMARK
:
1120 ds_put_cstr(s
, "dscp_remark");
1123 ds_put_format(s
, "%u", mb
->type
);
1126 ds_put_format(s
, " rate=%"PRIu32
, mb
->rate
);
1128 if (flags
& OFPMF13_BURST
) {
1129 ds_put_format(s
, " burst_size=%"PRIu32
, mb
->burst_size
);
1131 if (mb
->type
== OFPMBT13_DSCP_REMARK
) {
1132 ds_put_format(s
, " prec_level=%"PRIu8
, mb
->prec_level
);
1137 ofp_print_meter_stats(struct ds
*s
, const struct ofputil_meter_stats
*ms
)
1141 ds_put_format(s
, "meter:%"PRIu32
" ", ms
->meter_id
);
1142 ds_put_format(s
, "flow_count:%"PRIu32
" ", ms
->flow_count
);
1143 ds_put_format(s
, "packet_in_count:%"PRIu64
" ", ms
->packet_in_count
);
1144 ds_put_format(s
, "byte_in_count:%"PRIu64
" ", ms
->byte_in_count
);
1145 ds_put_cstr(s
, "duration:");
1146 ofp_print_duration(s
, ms
->duration_sec
, ms
->duration_nsec
);
1147 ds_put_char(s
, ' ');
1149 ds_put_cstr(s
, "bands:\n");
1150 for (i
= 0; i
< ms
->n_bands
; ++i
) {
1151 ds_put_format(s
, "%d: ", i
);
1152 ds_put_format(s
, "packet_count:%"PRIu64
" ", ms
->bands
[i
].packet_count
);
1153 ds_put_format(s
, "byte_count:%"PRIu64
"\n", ms
->bands
[i
].byte_count
);
1158 ofp_print_meter_config(struct ds
*s
, const struct ofputil_meter_config
*mc
)
1162 ds_put_format(s
, "meter=%"PRIu32
" ", mc
->meter_id
);
1164 ofp_print_meter_flags(s
, mc
->flags
);
1166 ds_put_cstr(s
, "bands=");
1167 for (i
= 0; i
< mc
->n_bands
; ++i
) {
1168 ofp_print_meter_band(s
, mc
->flags
, &mc
->bands
[i
]);
1170 ds_put_char(s
, '\n');
1174 ofp_print_meter_mod(struct ds
*s
, const struct ofp_header
*oh
)
1176 struct ofputil_meter_mod mm
;
1177 struct ofpbuf bands
;
1180 ofpbuf_init(&bands
, 64);
1181 error
= ofputil_decode_meter_mod(oh
, &mm
, &bands
);
1183 ofpbuf_uninit(&bands
);
1184 ofp_print_error(s
, error
);
1188 switch (mm
.command
) {
1190 ds_put_cstr(s
, " ADD ");
1192 case OFPMC13_MODIFY
:
1193 ds_put_cstr(s
, " MOD ");
1195 case OFPMC13_DELETE
:
1196 ds_put_cstr(s
, " DEL ");
1199 ds_put_format(s
, " cmd:%d ", mm
.command
);
1202 ofp_print_meter_config(s
, &mm
.meter
);
1203 ofpbuf_uninit(&bands
);
1207 ofp_print_meter_stats_request(struct ds
*s
, const struct ofp_header
*oh
)
1211 ofputil_decode_meter_request(oh
, &meter_id
);
1213 ds_put_format(s
, " meter=%"PRIu32
, meter_id
);
1217 ofputil_meter_capabilities_to_name(uint32_t bit
)
1219 enum ofp13_meter_flags flag
= bit
;
1222 case OFPMF13_KBPS
: return "kbps";
1223 case OFPMF13_PKTPS
: return "pktps";
1224 case OFPMF13_BURST
: return "burst";
1225 case OFPMF13_STATS
: return "stats";
1232 ofputil_meter_band_types_to_name(uint32_t bit
)
1235 case 1 << OFPMBT13_DROP
: return "drop";
1236 case 1 << OFPMBT13_DSCP_REMARK
: return "dscp_remark";
1243 ofp_print_meter_features_reply(struct ds
*s
, const struct ofp_header
*oh
)
1245 struct ofputil_meter_features mf
;
1247 ofputil_decode_meter_features(oh
, &mf
);
1249 ds_put_format(s
, "\nmax_meter:%"PRIu32
, mf
.max_meters
);
1250 ds_put_format(s
, " max_bands:%"PRIu8
, mf
.max_bands
);
1251 ds_put_format(s
, " max_color:%"PRIu8
"\n", mf
.max_color
);
1253 ds_put_cstr(s
, "band_types: ");
1254 ofp_print_bit_names(s
, mf
.band_types
,
1255 ofputil_meter_band_types_to_name
, ' ');
1256 ds_put_char(s
, '\n');
1258 ds_put_cstr(s
, "capabilities: ");
1259 ofp_print_bit_names(s
, mf
.capabilities
,
1260 ofputil_meter_capabilities_to_name
, ' ');
1261 ds_put_char(s
, '\n');
1265 ofp_print_meter_config_reply(struct ds
*s
, const struct ofp_header
*oh
)
1267 struct ofpbuf bands
;
1270 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
1271 ofpbuf_init(&bands
, 64);
1273 struct ofputil_meter_config mc
;
1276 retval
= ofputil_decode_meter_config(&b
, &mc
, &bands
);
1278 if (retval
!= EOF
) {
1279 ofp_print_error(s
, retval
);
1283 ds_put_char(s
, '\n');
1284 ofp_print_meter_config(s
, &mc
);
1286 ofpbuf_uninit(&bands
);
1290 ofp_print_meter_stats_reply(struct ds
*s
, const struct ofp_header
*oh
)
1292 struct ofpbuf bands
;
1295 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
1296 ofpbuf_init(&bands
, 64);
1298 struct ofputil_meter_stats ms
;
1301 retval
= ofputil_decode_meter_stats(&b
, &ms
, &bands
);
1303 if (retval
!= EOF
) {
1304 ofp_print_error(s
, retval
);
1308 ds_put_char(s
, '\n');
1309 ofp_print_meter_stats(s
, &ms
);
1311 ofpbuf_uninit(&bands
);
1315 ofp_print_error(struct ds
*string
, enum ofperr error
)
1317 if (string
->length
) {
1318 ds_put_char(string
, ' ');
1320 ds_put_format(string
, "***decode error: %s***\n", ofperr_get_name(error
));
1324 ofp_print_hello(struct ds
*string
, const struct ofp_header
*oh
)
1326 uint32_t allowed_versions
;
1329 ok
= ofputil_decode_hello(oh
, &allowed_versions
);
1331 ds_put_cstr(string
, "\n version bitmap: ");
1332 ofputil_format_version_bitmap(string
, allowed_versions
);
1335 ds_put_cstr(string
, "\n unknown data in hello:\n");
1336 ds_put_hex_dump(string
, oh
, ntohs(oh
->length
), 0, true);
1341 ofp_print_error_msg(struct ds
*string
, const struct ofp_header
*oh
)
1343 size_t len
= ntohs(oh
->length
);
1344 struct ofpbuf payload
;
1348 error
= ofperr_decode_msg(oh
, &payload
);
1350 ds_put_cstr(string
, "***decode error***");
1351 ds_put_hex_dump(string
, oh
+ 1, len
- sizeof *oh
, 0, true);
1355 ds_put_format(string
, " %s\n", ofperr_get_name(error
));
1357 if (error
== OFPERR_OFPHFC_INCOMPATIBLE
|| error
== OFPERR_OFPHFC_EPERM
) {
1358 ds_put_printable(string
, payload
.data
, payload
.size
);
1360 s
= ofp_to_string(payload
.data
, payload
.size
, 1);
1361 ds_put_cstr(string
, s
);
1364 ofpbuf_uninit(&payload
);
1368 ofp_print_port_status(struct ds
*string
, const struct ofp_header
*oh
)
1370 struct ofputil_port_status ps
;
1373 error
= ofputil_decode_port_status(oh
, &ps
);
1375 ofp_print_error(string
, error
);
1379 if (ps
.reason
== OFPPR_ADD
) {
1380 ds_put_format(string
, " ADD:");
1381 } else if (ps
.reason
== OFPPR_DELETE
) {
1382 ds_put_format(string
, " DEL:");
1383 } else if (ps
.reason
== OFPPR_MODIFY
) {
1384 ds_put_format(string
, " MOD:");
1387 ofp_print_phy_port(string
, &ps
.desc
);
1391 ofp_print_ofpst_desc_reply(struct ds
*string
, const struct ofp_header
*oh
)
1393 const struct ofp_desc_stats
*ods
= ofpmsg_body(oh
);
1395 ds_put_char(string
, '\n');
1396 ds_put_format(string
, "Manufacturer: %.*s\n",
1397 (int) sizeof ods
->mfr_desc
, ods
->mfr_desc
);
1398 ds_put_format(string
, "Hardware: %.*s\n",
1399 (int) sizeof ods
->hw_desc
, ods
->hw_desc
);
1400 ds_put_format(string
, "Software: %.*s\n",
1401 (int) sizeof ods
->sw_desc
, ods
->sw_desc
);
1402 ds_put_format(string
, "Serial Num: %.*s\n",
1403 (int) sizeof ods
->serial_num
, ods
->serial_num
);
1404 ds_put_format(string
, "DP Description: %.*s\n",
1405 (int) sizeof ods
->dp_desc
, ods
->dp_desc
);
1409 ofp_print_flow_stats_request(struct ds
*string
, const struct ofp_header
*oh
)
1411 struct ofputil_flow_stats_request fsr
;
1414 error
= ofputil_decode_flow_stats_request(&fsr
, oh
);
1416 ofp_print_error(string
, error
);
1420 if (fsr
.table_id
!= 0xff) {
1421 ds_put_format(string
, " table=%"PRIu8
, fsr
.table_id
);
1424 if (fsr
.out_port
!= OFPP_ANY
) {
1425 ds_put_cstr(string
, " out_port=");
1426 ofputil_format_port(fsr
.out_port
, string
);
1429 ds_put_char(string
, ' ');
1430 match_format(&fsr
.match
, string
, OFP_DEFAULT_PRIORITY
);
1434 ofp_print_flow_stats(struct ds
*string
, struct ofputil_flow_stats
*fs
)
1436 ds_put_format(string
, " cookie=0x%"PRIx64
", duration=",
1437 ntohll(fs
->cookie
));
1439 ofp_print_duration(string
, fs
->duration_sec
, fs
->duration_nsec
);
1440 ds_put_format(string
, ", table=%"PRIu8
", ", fs
->table_id
);
1441 ds_put_format(string
, "n_packets=%"PRIu64
", ", fs
->packet_count
);
1442 ds_put_format(string
, "n_bytes=%"PRIu64
", ", fs
->byte_count
);
1443 if (fs
->idle_timeout
!= OFP_FLOW_PERMANENT
) {
1444 ds_put_format(string
, "idle_timeout=%"PRIu16
", ", fs
->idle_timeout
);
1446 if (fs
->hard_timeout
!= OFP_FLOW_PERMANENT
) {
1447 ds_put_format(string
, "hard_timeout=%"PRIu16
", ", fs
->hard_timeout
);
1450 ofp_print_flow_flags(string
, fs
->flags
);
1452 if (fs
->importance
!= 0) {
1453 ds_put_format(string
, "importance=%"PRIu16
", ", fs
->importance
);
1455 if (fs
->idle_age
>= 0) {
1456 ds_put_format(string
, "idle_age=%d, ", fs
->idle_age
);
1458 if (fs
->hard_age
>= 0 && fs
->hard_age
!= fs
->duration_sec
) {
1459 ds_put_format(string
, "hard_age=%d, ", fs
->hard_age
);
1462 match_format(&fs
->match
, string
, fs
->priority
);
1463 if (string
->string
[string
->length
- 1] != ' ') {
1464 ds_put_char(string
, ' ');
1467 ds_put_cstr(string
, "actions=");
1468 ofpacts_format(fs
->ofpacts
, fs
->ofpacts_len
, string
);
1472 ofp_print_flow_stats_reply(struct ds
*string
, const struct ofp_header
*oh
)
1474 struct ofpbuf ofpacts
;
1477 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
1478 ofpbuf_init(&ofpacts
, 64);
1480 struct ofputil_flow_stats fs
;
1483 retval
= ofputil_decode_flow_stats_reply(&fs
, &b
, true, &ofpacts
);
1485 if (retval
!= EOF
) {
1486 ds_put_cstr(string
, " ***parse error***");
1490 ds_put_char(string
, '\n');
1491 ofp_print_flow_stats(string
, &fs
);
1493 ofpbuf_uninit(&ofpacts
);
1497 ofp_print_aggregate_stats_reply(struct ds
*string
, const struct ofp_header
*oh
)
1499 struct ofputil_aggregate_stats as
;
1502 error
= ofputil_decode_aggregate_stats_reply(&as
, oh
);
1504 ofp_print_error(string
, error
);
1508 ds_put_format(string
, " packet_count=%"PRIu64
, as
.packet_count
);
1509 ds_put_format(string
, " byte_count=%"PRIu64
, as
.byte_count
);
1510 ds_put_format(string
, " flow_count=%"PRIu32
, as
.flow_count
);
1514 print_port_stat(struct ds
*string
, const char *leader
, uint64_t stat
, int more
)
1516 ds_put_cstr(string
, leader
);
1517 if (stat
!= UINT64_MAX
) {
1518 ds_put_format(string
, "%"PRIu64
, stat
);
1520 ds_put_char(string
, '?');
1523 ds_put_cstr(string
, ", ");
1525 ds_put_cstr(string
, "\n");
1530 ofp_print_ofpst_port_request(struct ds
*string
, const struct ofp_header
*oh
)
1532 ofp_port_t ofp10_port
;
1535 error
= ofputil_decode_port_stats_request(oh
, &ofp10_port
);
1537 ofp_print_error(string
, error
);
1541 ds_put_cstr(string
, " port_no=");
1542 ofputil_format_port(ofp10_port
, string
);
1546 ofp_print_ofpst_port_reply(struct ds
*string
, const struct ofp_header
*oh
,
1551 ds_put_format(string
, " %"PRIuSIZE
" ports\n", ofputil_count_port_stats(oh
));
1552 if (verbosity
< 1) {
1556 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
1558 struct ofputil_port_stats ps
;
1561 retval
= ofputil_decode_port_stats(&ps
, &b
);
1563 if (retval
!= EOF
) {
1564 ds_put_cstr(string
, " ***parse error***");
1569 ds_put_cstr(string
, " port ");
1570 if (ofp_to_u16(ps
.port_no
) < 10) {
1571 ds_put_char(string
, ' ');
1573 ofputil_format_port(ps
.port_no
, string
);
1575 ds_put_cstr(string
, ": rx ");
1576 print_port_stat(string
, "pkts=", ps
.stats
.rx_packets
, 1);
1577 print_port_stat(string
, "bytes=", ps
.stats
.rx_bytes
, 1);
1578 print_port_stat(string
, "drop=", ps
.stats
.rx_dropped
, 1);
1579 print_port_stat(string
, "errs=", ps
.stats
.rx_errors
, 1);
1580 print_port_stat(string
, "frame=", ps
.stats
.rx_frame_errors
, 1);
1581 print_port_stat(string
, "over=", ps
.stats
.rx_over_errors
, 1);
1582 print_port_stat(string
, "crc=", ps
.stats
.rx_crc_errors
, 0);
1584 ds_put_cstr(string
, " tx ");
1585 print_port_stat(string
, "pkts=", ps
.stats
.tx_packets
, 1);
1586 print_port_stat(string
, "bytes=", ps
.stats
.tx_bytes
, 1);
1587 print_port_stat(string
, "drop=", ps
.stats
.tx_dropped
, 1);
1588 print_port_stat(string
, "errs=", ps
.stats
.tx_errors
, 1);
1589 print_port_stat(string
, "coll=", ps
.stats
.collisions
, 0);
1591 if (ps
.duration_sec
!= UINT32_MAX
) {
1592 ds_put_cstr(string
, " duration=");
1593 ofp_print_duration(string
, ps
.duration_sec
, ps
.duration_nsec
);
1594 ds_put_char(string
, '\n');
1600 ofp_print_table_stats_reply(struct ds
*string
, const struct ofp_header
*oh
)
1604 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
1605 ofpraw_pull_assert(&b
);
1608 struct ofputil_table_features features
;
1609 struct ofputil_table_stats stats
;
1612 retval
= ofputil_decode_table_stats_reply(&b
, &stats
, &features
);
1614 if (retval
!= EOF
) {
1615 ofp_print_error(string
, retval
);
1620 ofp_print_table_features(string
, &features
, &stats
);
1625 ofp_print_queue_name(struct ds
*string
, uint32_t queue_id
)
1627 if (queue_id
== OFPQ_ALL
) {
1628 ds_put_cstr(string
, "ALL");
1630 ds_put_format(string
, "%"PRIu32
, queue_id
);
1635 ofp_print_ofpst_queue_request(struct ds
*string
, const struct ofp_header
*oh
)
1637 struct ofputil_queue_stats_request oqsr
;
1640 error
= ofputil_decode_queue_stats_request(oh
, &oqsr
);
1642 ds_put_format(string
, "***decode error: %s***\n", ofperr_get_name(error
));
1646 ds_put_cstr(string
, "port=");
1647 ofputil_format_port(oqsr
.port_no
, string
);
1649 ds_put_cstr(string
, " queue=");
1650 ofp_print_queue_name(string
, oqsr
.queue_id
);
1654 ofp_print_ofpst_queue_reply(struct ds
*string
, const struct ofp_header
*oh
,
1659 ds_put_format(string
, " %"PRIuSIZE
" queues\n", ofputil_count_queue_stats(oh
));
1660 if (verbosity
< 1) {
1664 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
1666 struct ofputil_queue_stats qs
;
1669 retval
= ofputil_decode_queue_stats(&qs
, &b
);
1671 if (retval
!= EOF
) {
1672 ds_put_cstr(string
, " ***parse error***");
1677 ds_put_cstr(string
, " port ");
1678 ofputil_format_port(qs
.port_no
, string
);
1679 ds_put_cstr(string
, " queue ");
1680 ofp_print_queue_name(string
, qs
.queue_id
);
1681 ds_put_cstr(string
, ": ");
1683 print_port_stat(string
, "bytes=", qs
.tx_bytes
, 1);
1684 print_port_stat(string
, "pkts=", qs
.tx_packets
, 1);
1685 print_port_stat(string
, "errors=", qs
.tx_errors
, 1);
1687 ds_put_cstr(string
, "duration=");
1688 if (qs
.duration_sec
!= UINT32_MAX
) {
1689 ofp_print_duration(string
, qs
.duration_sec
, qs
.duration_nsec
);
1691 ds_put_char(string
, '?');
1693 ds_put_char(string
, '\n');
1698 ofp_print_ofpst_port_desc_request(struct ds
*string
,
1699 const struct ofp_header
*oh
)
1704 error
= ofputil_decode_port_desc_stats_request(oh
, &port
);
1706 ofp_print_error(string
, error
);
1710 ds_put_cstr(string
, " port=");
1711 ofputil_format_port(port
, string
);
1715 ofp_print_ofpst_port_desc_reply(struct ds
*string
,
1716 const struct ofp_header
*oh
)
1720 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
1721 ofpraw_pull_assert(&b
);
1722 ds_put_char(string
, '\n');
1723 ofp_print_phy_ports(string
, oh
->version
, &b
);
1727 ofp_print_stats(struct ds
*string
, const struct ofp_header
*oh
)
1729 uint16_t flags
= ofpmp_flags(oh
);
1732 ds_put_cstr(string
, " flags=");
1733 if ((!ofpmsg_is_stat_request(oh
) || oh
->version
>= OFP13_VERSION
)
1734 && (flags
& OFPSF_REPLY_MORE
)) {
1735 ds_put_cstr(string
, "[more]");
1736 flags
&= ~OFPSF_REPLY_MORE
;
1739 ds_put_format(string
, "[***unknown flags 0x%04"PRIx16
"***]",
1746 ofp_print_echo(struct ds
*string
, const struct ofp_header
*oh
, int verbosity
)
1748 size_t len
= ntohs(oh
->length
);
1750 ds_put_format(string
, " %"PRIuSIZE
" bytes of payload\n", len
- sizeof *oh
);
1751 if (verbosity
> 1) {
1752 ds_put_hex_dump(string
, oh
+ 1, len
- sizeof *oh
, 0, true);
1757 ofp_print_role_generic(struct ds
*string
, enum ofp12_controller_role role
,
1758 uint64_t generation_id
)
1760 ds_put_cstr(string
, " role=");
1763 case OFPCR12_ROLE_NOCHANGE
:
1764 ds_put_cstr(string
, "nochange");
1766 case OFPCR12_ROLE_EQUAL
:
1767 ds_put_cstr(string
, "equal"); /* OF 1.2 wording */
1769 case OFPCR12_ROLE_MASTER
:
1770 ds_put_cstr(string
, "master");
1772 case OFPCR12_ROLE_SLAVE
:
1773 ds_put_cstr(string
, "slave");
1779 if (generation_id
!= UINT64_MAX
) {
1780 ds_put_format(string
, " generation_id=%"PRIu64
, generation_id
);
1785 ofp_print_role_message(struct ds
*string
, const struct ofp_header
*oh
)
1787 struct ofputil_role_request rr
;
1790 error
= ofputil_decode_role_message(oh
, &rr
);
1792 ofp_print_error(string
, error
);
1796 ofp_print_role_generic(string
, rr
.role
, rr
.have_generation_id
? rr
.generation_id
: UINT64_MAX
);
1800 ofp_print_role_status_message(struct ds
*string
, const struct ofp_header
*oh
)
1802 struct ofputil_role_status rs
;
1805 error
= ofputil_decode_role_status(oh
, &rs
);
1807 ofp_print_error(string
, error
);
1811 ofp_print_role_generic(string
, rs
.role
, rs
.generation_id
);
1813 ds_put_cstr(string
, " reason=");
1815 switch (rs
.reason
) {
1816 case OFPCRR_MASTER_REQUEST
:
1817 ds_put_cstr(string
, "master_request");
1820 ds_put_cstr(string
, "configuration_changed");
1822 case OFPCRR_EXPERIMENTER
:
1823 ds_put_cstr(string
, "experimenter_data_changed");
1831 ofp_print_nxt_flow_mod_table_id(struct ds
*string
,
1832 const struct nx_flow_mod_table_id
*nfmti
)
1834 ds_put_format(string
, " %s", nfmti
->set
? "enable" : "disable");
1838 ofp_print_nxt_set_flow_format(struct ds
*string
,
1839 const struct nx_set_flow_format
*nsff
)
1841 uint32_t format
= ntohl(nsff
->format
);
1843 ds_put_cstr(string
, " format=");
1844 if (ofputil_nx_flow_format_is_valid(format
)) {
1845 ds_put_cstr(string
, ofputil_nx_flow_format_to_string(format
));
1847 ds_put_format(string
, "%"PRIu32
, format
);
1852 ofp_print_nxt_set_packet_in_format(struct ds
*string
,
1853 const struct nx_set_packet_in_format
*nspf
)
1855 uint32_t format
= ntohl(nspf
->format
);
1857 ds_put_cstr(string
, " format=");
1858 if (ofputil_packet_in_format_is_valid(format
)) {
1859 ds_put_cstr(string
, ofputil_packet_in_format_to_string(format
));
1861 ds_put_format(string
, "%"PRIu32
, format
);
1865 /* Returns a string form of 'reason'. The return value is either a statically
1866 * allocated constant string or the 'bufsize'-byte buffer 'reasonbuf'.
1867 * 'bufsize' should be at least OFP_PORT_REASON_BUFSIZE. */
1868 #define OFP_PORT_REASON_BUFSIZE (INT_STRLEN(int) + 1)
1870 ofp_port_reason_to_string(enum ofp_port_reason reason
,
1871 char *reasonbuf
, size_t bufsize
)
1884 snprintf(reasonbuf
, bufsize
, "%d", (int) reason
);
1890 ofp_print_nxt_set_async_config(struct ds
*string
,
1891 const struct nx_async_config
*nac
)
1895 for (i
= 0; i
< 2; i
++) {
1898 ds_put_format(string
, "\n %s:\n", i
== 0 ? "master" : "slave");
1900 ds_put_cstr(string
, " PACKET_IN:");
1901 for (j
= 0; j
< 32; j
++) {
1902 if (nac
->packet_in_mask
[i
] & htonl(1u << j
)) {
1903 char reasonbuf
[OFPUTIL_PACKET_IN_REASON_BUFSIZE
];
1906 reason
= ofputil_packet_in_reason_to_string(j
, reasonbuf
,
1908 ds_put_format(string
, " %s", reason
);
1911 if (!nac
->packet_in_mask
[i
]) {
1912 ds_put_cstr(string
, " (off)");
1914 ds_put_char(string
, '\n');
1916 ds_put_cstr(string
, " PORT_STATUS:");
1917 for (j
= 0; j
< 32; j
++) {
1918 if (nac
->port_status_mask
[i
] & htonl(1u << j
)) {
1919 char reasonbuf
[OFP_PORT_REASON_BUFSIZE
];
1922 reason
= ofp_port_reason_to_string(j
, reasonbuf
,
1924 ds_put_format(string
, " %s", reason
);
1927 if (!nac
->port_status_mask
[i
]) {
1928 ds_put_cstr(string
, " (off)");
1930 ds_put_char(string
, '\n');
1932 ds_put_cstr(string
, " FLOW_REMOVED:");
1933 for (j
= 0; j
< 32; j
++) {
1934 if (nac
->flow_removed_mask
[i
] & htonl(1u << j
)) {
1935 char reasonbuf
[OFP_FLOW_REMOVED_REASON_BUFSIZE
];
1938 reason
= ofp_flow_removed_reason_to_string(j
, reasonbuf
,
1940 ds_put_format(string
, " %s", reason
);
1943 if (!nac
->flow_removed_mask
[i
]) {
1944 ds_put_cstr(string
, " (off)");
1946 ds_put_char(string
, '\n');
1951 ofp_print_nxt_set_controller_id(struct ds
*string
,
1952 const struct nx_controller_id
*nci
)
1954 ds_put_format(string
, " id=%"PRIu16
, ntohs(nci
->controller_id
));
1958 ofp_print_nxt_flow_monitor_cancel(struct ds
*string
,
1959 const struct ofp_header
*oh
)
1961 ds_put_format(string
, " id=%"PRIu32
,
1962 ofputil_decode_flow_monitor_cancel(oh
));
1966 nx_flow_monitor_flags_to_name(uint32_t bit
)
1968 enum nx_flow_monitor_flags fmf
= bit
;
1971 case NXFMF_INITIAL
: return "initial";
1972 case NXFMF_ADD
: return "add";
1973 case NXFMF_DELETE
: return "delete";
1974 case NXFMF_MODIFY
: return "modify";
1975 case NXFMF_ACTIONS
: return "actions";
1976 case NXFMF_OWN
: return "own";
1983 ofp_print_nxst_flow_monitor_request(struct ds
*string
,
1984 const struct ofp_header
*oh
)
1988 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
1990 struct ofputil_flow_monitor_request request
;
1993 retval
= ofputil_decode_flow_monitor_request(&request
, &b
);
1995 if (retval
!= EOF
) {
1996 ofp_print_error(string
, retval
);
2001 ds_put_format(string
, "\n id=%"PRIu32
" flags=", request
.id
);
2002 ofp_print_bit_names(string
, request
.flags
,
2003 nx_flow_monitor_flags_to_name
, ',');
2005 if (request
.out_port
!= OFPP_NONE
) {
2006 ds_put_cstr(string
, " out_port=");
2007 ofputil_format_port(request
.out_port
, string
);
2010 if (request
.table_id
!= 0xff) {
2011 ds_put_format(string
, " table=%"PRIu8
, request
.table_id
);
2014 ds_put_char(string
, ' ');
2015 match_format(&request
.match
, string
, OFP_DEFAULT_PRIORITY
);
2016 ds_chomp(string
, ' ');
2021 ofp_print_nxst_flow_monitor_reply(struct ds
*string
,
2022 const struct ofp_header
*oh
)
2024 uint64_t ofpacts_stub
[1024 / 8];
2025 struct ofpbuf ofpacts
;
2028 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
2029 ofpbuf_use_stub(&ofpacts
, ofpacts_stub
, sizeof ofpacts_stub
);
2031 char reasonbuf
[OFP_FLOW_REMOVED_REASON_BUFSIZE
];
2032 struct ofputil_flow_update update
;
2036 update
.match
= &match
;
2037 retval
= ofputil_decode_flow_update(&update
, &b
, &ofpacts
);
2039 if (retval
!= EOF
) {
2040 ofp_print_error(string
, retval
);
2042 ofpbuf_uninit(&ofpacts
);
2046 ds_put_cstr(string
, "\n event=");
2047 switch (update
.event
) {
2049 ds_put_cstr(string
, "ADDED");
2053 ds_put_format(string
, "DELETED reason=%s",
2054 ofp_flow_removed_reason_to_string(update
.reason
,
2059 case NXFME_MODIFIED
:
2060 ds_put_cstr(string
, "MODIFIED");
2064 ds_put_format(string
, "ABBREV xid=0x%"PRIx32
, ntohl(update
.xid
));
2068 ds_put_format(string
, " table=%"PRIu8
, update
.table_id
);
2069 if (update
.idle_timeout
!= OFP_FLOW_PERMANENT
) {
2070 ds_put_format(string
, " idle_timeout=%"PRIu16
,
2071 update
.idle_timeout
);
2073 if (update
.hard_timeout
!= OFP_FLOW_PERMANENT
) {
2074 ds_put_format(string
, " hard_timeout=%"PRIu16
,
2075 update
.hard_timeout
);
2077 ds_put_format(string
, " cookie=%#"PRIx64
, ntohll(update
.cookie
));
2079 ds_put_char(string
, ' ');
2080 match_format(update
.match
, string
, OFP_DEFAULT_PRIORITY
);
2082 if (update
.ofpacts_len
) {
2083 if (string
->string
[string
->length
- 1] != ' ') {
2084 ds_put_char(string
, ' ');
2086 ds_put_cstr(string
, "actions=");
2087 ofpacts_format(update
.ofpacts
, update
.ofpacts_len
, string
);
2093 ofp_print_version(const struct ofp_header
*oh
,
2096 switch (oh
->version
) {
2100 ds_put_cstr(string
, " (OF1.1)");
2103 ds_put_cstr(string
, " (OF1.2)");
2106 ds_put_cstr(string
, " (OF1.3)");
2109 ds_put_cstr(string
, " (OF1.4)");
2112 ds_put_cstr(string
, " (OF1.5)");
2115 ds_put_format(string
, " (OF 0x%02"PRIx8
")", oh
->version
);
2118 ds_put_format(string
, " (xid=0x%"PRIx32
"):", ntohl(oh
->xid
));
2122 ofp_header_to_string__(const struct ofp_header
*oh
, enum ofpraw raw
,
2125 ds_put_cstr(string
, ofpraw_get_name(raw
));
2126 ofp_print_version(oh
, string
);
2130 ofp_print_bucket_id(struct ds
*s
, const char *label
, uint32_t bucket_id
,
2131 enum ofp_version ofp_version
)
2133 if (ofp_version
< OFP15_VERSION
) {
2137 ds_put_cstr(s
, label
);
2139 switch (bucket_id
) {
2140 case OFPG15_BUCKET_FIRST
:
2141 ds_put_cstr(s
, "first");
2143 case OFPG15_BUCKET_LAST
:
2144 ds_put_cstr(s
, "last");
2146 case OFPG15_BUCKET_ALL
:
2147 ds_put_cstr(s
, "all");
2150 ds_put_format(s
, "%"PRIu32
, bucket_id
);
2154 ds_put_char(s
, ',');
2158 ofp_print_group(struct ds
*s
, uint32_t group_id
, uint8_t type
,
2159 struct ovs_list
*p_buckets
, struct ofputil_group_props
*props
,
2160 enum ofp_version ofp_version
, bool suppress_type
)
2162 struct ofputil_bucket
*bucket
;
2164 ds_put_format(s
, "group_id=%"PRIu32
, group_id
);
2166 if (!suppress_type
) {
2167 static const char *type_str
[] = { "all", "select", "indirect",
2169 ds_put_format(s
, ",type=%s", type_str
[type
> 4 ? 4 : type
]);
2172 if (props
->selection_method
[0]) {
2175 ds_put_format(s
, ",selection_method=%s,", props
->selection_method
);
2176 if (props
->selection_method_param
) {
2177 ds_put_format(s
, "selection_method_param=%"PRIu64
",",
2178 props
->selection_method_param
);
2181 /* Allow rewinding to immediately before the trailing ',' */
2182 mark
= s
->length
- 1;
2184 ds_put_cstr(s
, "fields=");
2186 oxm_format_field_array(s
, &props
->fields
);
2187 if (s
->length
== start
) {
2188 ds_truncate(s
, mark
);
2196 ds_put_char(s
, ',');
2198 LIST_FOR_EACH (bucket
, list_node
, p_buckets
) {
2199 ds_put_cstr(s
, "bucket=");
2201 ofp_print_bucket_id(s
, "bucket_id:", bucket
->bucket_id
, ofp_version
);
2202 if (bucket
->weight
!= 1) {
2203 ds_put_format(s
, "weight:%"PRIu16
",", bucket
->weight
);
2205 if (bucket
->watch_port
!= OFPP_NONE
) {
2206 ds_put_format(s
, "watch_port:%"PRIu32
",", bucket
->watch_port
);
2208 if (bucket
->watch_group
!= OFPG11_ANY
) {
2209 ds_put_format(s
, "watch_group:%"PRIu32
",", bucket
->watch_group
);
2212 ds_put_cstr(s
, "actions=");
2213 ofpacts_format(bucket
->ofpacts
, bucket
->ofpacts_len
, s
);
2214 ds_put_char(s
, ',');
2221 ofp_print_ofpst_group_desc_request(struct ds
*string
,
2222 const struct ofp_header
*oh
)
2224 uint32_t group_id
= ofputil_decode_group_desc_request(oh
);
2225 ds_put_cstr(string
, " group_id=");
2226 ofputil_format_group(group_id
, string
);
2230 ofp_print_group_desc(struct ds
*s
, const struct ofp_header
*oh
)
2234 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
2236 struct ofputil_group_desc gd
;
2239 retval
= ofputil_decode_group_desc_reply(&gd
, &b
, oh
->version
);
2241 if (retval
!= EOF
) {
2242 ds_put_cstr(s
, " ***parse error***");
2247 ds_put_char(s
, '\n');
2248 ds_put_char(s
, ' ');
2249 ofp_print_group(s
, gd
.group_id
, gd
.type
, &gd
.buckets
, &gd
.props
,
2250 oh
->version
, false);
2251 ofputil_bucket_list_destroy(&gd
.buckets
);
2256 ofp_print_ofpst_group_request(struct ds
*string
, const struct ofp_header
*oh
)
2261 error
= ofputil_decode_group_stats_request(oh
, &group_id
);
2263 ofp_print_error(string
, error
);
2267 ds_put_cstr(string
, " group_id=");
2268 ofputil_format_group(group_id
, string
);
2272 ofp_print_group_stats(struct ds
*s
, const struct ofp_header
*oh
)
2277 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
2280 struct ofputil_group_stats gs
;
2283 retval
= ofputil_decode_group_stats_reply(&b
, &gs
);
2285 if (retval
!= EOF
) {
2286 ds_put_cstr(s
, " ***parse error***");
2291 ds_put_char(s
, '\n');
2293 ds_put_char(s
, ' ');
2294 ds_put_format(s
, "group_id=%"PRIu32
",", gs
.group_id
);
2296 if (gs
.duration_sec
!= UINT32_MAX
) {
2297 ds_put_cstr(s
, "duration=");
2298 ofp_print_duration(s
, gs
.duration_sec
, gs
.duration_nsec
);
2299 ds_put_char(s
, ',');
2301 ds_put_format(s
, "ref_count=%"PRIu32
",", gs
.ref_count
);
2302 ds_put_format(s
, "packet_count=%"PRIu64
",", gs
.packet_count
);
2303 ds_put_format(s
, "byte_count=%"PRIu64
"", gs
.byte_count
);
2305 for (bucket_i
= 0; bucket_i
< gs
.n_buckets
; bucket_i
++) {
2306 if (gs
.bucket_stats
[bucket_i
].packet_count
!= UINT64_MAX
) {
2307 ds_put_format(s
, ",bucket%"PRIu32
":", bucket_i
);
2308 ds_put_format(s
, "packet_count=%"PRIu64
",", gs
.bucket_stats
[bucket_i
].packet_count
);
2309 ds_put_format(s
, "byte_count=%"PRIu64
"", gs
.bucket_stats
[bucket_i
].byte_count
);
2313 free(gs
.bucket_stats
);
2318 group_type_to_string(enum ofp11_group_type type
)
2321 case OFPGT11_ALL
: return "all";
2322 case OFPGT11_SELECT
: return "select";
2323 case OFPGT11_INDIRECT
: return "indirect";
2324 case OFPGT11_FF
: return "fast failover";
2325 default: OVS_NOT_REACHED();
2330 ofp_print_group_features(struct ds
*string
, const struct ofp_header
*oh
)
2332 struct ofputil_group_features features
;
2335 ofputil_decode_group_features_reply(oh
, &features
);
2337 ds_put_format(string
, "\n Group table:\n");
2338 ds_put_format(string
, " Types: 0x%"PRIx32
"\n", features
.types
);
2339 ds_put_format(string
, " Capabilities: 0x%"PRIx32
"\n",
2340 features
.capabilities
);
2342 for (i
= 0; i
< OFPGT12_N_TYPES
; i
++) {
2343 if (features
.types
& (1u << i
)) {
2344 ds_put_format(string
, " %s group:\n", group_type_to_string(i
));
2345 ds_put_format(string
, " max_groups=%#"PRIx32
"\n",
2346 features
.max_groups
[i
]);
2347 ds_put_format(string
, " actions: ");
2348 ofpact_bitmap_format(features
.ofpacts
[i
], string
);
2349 ds_put_char(string
, '\n');
2355 ofp_print_group_mod(struct ds
*s
, const struct ofp_header
*oh
)
2357 struct ofputil_group_mod gm
;
2359 bool bucket_command
= false;
2361 error
= ofputil_decode_group_mod(oh
, &gm
);
2363 ofp_print_error(s
, error
);
2367 ds_put_char(s
, '\n');
2369 ds_put_char(s
, ' ');
2370 switch (gm
.command
) {
2372 ds_put_cstr(s
, "ADD");
2375 case OFPGC11_MODIFY
:
2376 ds_put_cstr(s
, "MOD");
2379 case OFPGC11_DELETE
:
2380 ds_put_cstr(s
, "DEL");
2383 case OFPGC15_INSERT_BUCKET
:
2384 ds_put_cstr(s
, "INSERT_BUCKET");
2385 bucket_command
= true;
2388 case OFPGC15_REMOVE_BUCKET
:
2389 ds_put_cstr(s
, "REMOVE_BUCKET");
2390 bucket_command
= true;
2394 ds_put_format(s
, "cmd:%"PRIu16
"", gm
.command
);
2396 ds_put_char(s
, ' ');
2398 if (bucket_command
) {
2399 ofp_print_bucket_id(s
, "command_bucket_id:",
2400 gm
.command_bucket_id
, oh
->version
);
2403 ofp_print_group(s
, gm
.group_id
, gm
.type
, &gm
.buckets
, &gm
.props
,
2404 oh
->version
, bucket_command
);
2405 ofputil_bucket_list_destroy(&gm
.buckets
);
2409 print_table_action_features(struct ds
*s
,
2410 const struct ofputil_table_action_features
*taf
)
2413 ds_put_cstr(s
, " actions: ");
2414 ofpact_bitmap_format(taf
->ofpacts
, s
);
2415 ds_put_char(s
, '\n');
2418 if (!bitmap_is_all_zeros(taf
->set_fields
.bm
, MFF_N_IDS
)) {
2421 ds_put_cstr(s
, " supported on Set-Field:");
2422 BITMAP_FOR_EACH_1 (i
, MFF_N_IDS
, taf
->set_fields
.bm
) {
2423 ds_put_format(s
, " %s", mf_from_id(i
)->name
);
2425 ds_put_char(s
, '\n');
2430 table_action_features_equal(const struct ofputil_table_action_features
*a
,
2431 const struct ofputil_table_action_features
*b
)
2433 return (a
->ofpacts
== b
->ofpacts
2434 && bitmap_equal(a
->set_fields
.bm
, b
->set_fields
.bm
, MFF_N_IDS
));
2438 table_action_features_empty(const struct ofputil_table_action_features
*taf
)
2440 return !taf
->ofpacts
&& bitmap_is_all_zeros(taf
->set_fields
.bm
, MFF_N_IDS
);
2444 print_table_instruction_features(
2445 struct ds
*s
, const struct ofputil_table_instruction_features
*tif
)
2449 if (!bitmap_is_all_zeros(tif
->next
, 255)) {
2450 ds_put_cstr(s
, " next tables: ");
2451 for (start
= bitmap_scan(tif
->next
, 1, 0, 255); start
< 255;
2452 start
= bitmap_scan(tif
->next
, 1, end
, 255)) {
2453 end
= bitmap_scan(tif
->next
, 0, start
+ 1, 255);
2454 if (end
== start
+ 1) {
2455 ds_put_format(s
, "%d,", start
);
2457 ds_put_format(s
, "%d-%d,", start
, end
- 1);
2461 if (ds_last(s
) == ' ') {
2462 ds_put_cstr(s
, "none");
2464 ds_put_char(s
, '\n');
2467 if (tif
->instructions
) {
2468 ds_put_cstr(s
, " instructions: ");
2471 for (i
= 0; i
< 32; i
++) {
2472 if (tif
->instructions
& (1u << i
)) {
2473 ds_put_format(s
, "%s,", ovs_instruction_name_from_type(i
));
2477 ds_put_char(s
, '\n');
2480 if (!table_action_features_equal(&tif
->write
, &tif
->apply
)) {
2481 ds_put_cstr(s
, " Write-Actions features:\n");
2482 print_table_action_features(s
, &tif
->write
);
2483 ds_put_cstr(s
, " Apply-Actions features:\n");
2484 print_table_action_features(s
, &tif
->apply
);
2485 } else if (tif
->write
.ofpacts
2486 || !bitmap_is_all_zeros(tif
->write
.set_fields
.bm
, MFF_N_IDS
)) {
2487 ds_put_cstr(s
, " Write-Actions and Apply-Actions features:\n");
2488 print_table_action_features(s
, &tif
->write
);
2493 table_instruction_features_equal(
2494 const struct ofputil_table_instruction_features
*a
,
2495 const struct ofputil_table_instruction_features
*b
)
2497 return (bitmap_equal(a
->next
, b
->next
, 255)
2498 && a
->instructions
== b
->instructions
2499 && table_action_features_equal(&a
->write
, &b
->write
)
2500 && table_action_features_equal(&a
->apply
, &b
->apply
));
2504 table_instruction_features_empty(
2505 const struct ofputil_table_instruction_features
*tif
)
2507 return (bitmap_is_all_zeros(tif
->next
, 255)
2508 && !tif
->instructions
2509 && table_action_features_empty(&tif
->write
)
2510 && table_action_features_empty(&tif
->apply
));
2514 ofp_print_table_features(struct ds
*s
,
2515 const struct ofputil_table_features
*features
,
2516 const struct ofputil_table_stats
*stats
)
2520 ds_put_format(s
, "\n table %"PRIu8
, features
->table_id
);
2521 if (features
->name
[0]) {
2522 ds_put_format(s
, " (\"%s\")", features
->name
);
2524 ds_put_cstr(s
, ":\n");
2526 ds_put_format(s
, " active=%"PRIu32
", ", stats
->active_count
);
2527 ds_put_format(s
, "lookup=%"PRIu64
", ", stats
->lookup_count
);
2528 ds_put_format(s
, "matched=%"PRIu64
"\n", stats
->matched_count
);
2530 if (features
->metadata_match
|| features
->metadata_match
) {
2531 ds_put_format(s
, " metadata: match=%#"PRIx64
" write=%#"PRIx64
"\n",
2532 ntohll(features
->metadata_match
),
2533 ntohll(features
->metadata_write
));
2536 if (features
->miss_config
!= OFPUTIL_TABLE_MISS_DEFAULT
) {
2537 ds_put_cstr(s
, " config=");
2538 ofp_print_table_miss_config(s
, features
->miss_config
);
2541 if (features
->max_entries
) {
2542 ds_put_format(s
, " max_entries=%"PRIu32
"\n", features
->max_entries
);
2545 if (!table_instruction_features_equal(&features
->nonmiss
,
2547 ds_put_cstr(s
, " instructions (other than table miss):\n");
2548 print_table_instruction_features(s
, &features
->nonmiss
);
2549 ds_put_cstr(s
, " instructions (table miss):\n");
2550 print_table_instruction_features(s
, &features
->miss
);
2551 } else if (!table_instruction_features_empty(&features
->nonmiss
)) {
2552 ds_put_cstr(s
, " instructions (table miss and others):\n");
2553 print_table_instruction_features(s
, &features
->nonmiss
);
2556 if (!bitmap_is_all_zeros(features
->match
.bm
, MFF_N_IDS
)){
2557 ds_put_cstr(s
, " matching:\n");
2558 BITMAP_FOR_EACH_1 (i
, MFF_N_IDS
, features
->match
.bm
) {
2559 const struct mf_field
*f
= mf_from_id(i
);
2560 bool mask
= bitmap_is_set(features
->mask
.bm
, i
);
2561 bool wildcard
= bitmap_is_set(features
->wildcard
.bm
, i
);
2563 ds_put_format(s
, " %s: %s\n",
2565 (mask
? "arbitrary mask"
2566 : wildcard
? "exact match or wildcard"
2567 : "must exact match"));
2573 ofp_print_table_features_reply(struct ds
*s
, const struct ofp_header
*oh
)
2577 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
2580 struct ofputil_table_features tf
;
2583 retval
= ofputil_decode_table_features(&b
, &tf
, true);
2585 if (retval
!= EOF
) {
2586 ofp_print_error(s
, retval
);
2590 ofp_print_table_features(s
, &tf
, NULL
);
2595 bundle_flags_to_name(uint32_t bit
)
2608 ofp_print_bundle_ctrl(struct ds
*s
, const struct ofp_header
*oh
)
2611 struct ofputil_bundle_ctrl_msg bctrl
;
2613 error
= ofputil_decode_bundle_ctrl(oh
, &bctrl
);
2615 ofp_print_error(s
, error
);
2619 ds_put_char(s
, '\n');
2621 ds_put_format(s
, " bundle_id=%#"PRIx32
" type=", bctrl
.bundle_id
);
2622 switch (bctrl
.type
) {
2623 case OFPBCT_OPEN_REQUEST
:
2624 ds_put_cstr(s
, "OPEN_REQUEST");
2626 case OFPBCT_OPEN_REPLY
:
2627 ds_put_cstr(s
, "OPEN_REPLY");
2629 case OFPBCT_CLOSE_REQUEST
:
2630 ds_put_cstr(s
, "CLOSE_REQUEST");
2632 case OFPBCT_CLOSE_REPLY
:
2633 ds_put_cstr(s
, "CLOSE_REPLY");
2635 case OFPBCT_COMMIT_REQUEST
:
2636 ds_put_cstr(s
, "COMMIT_REQUEST");
2638 case OFPBCT_COMMIT_REPLY
:
2639 ds_put_cstr(s
, "COMMIT_REPLY");
2641 case OFPBCT_DISCARD_REQUEST
:
2642 ds_put_cstr(s
, "DISCARD_REQUEST");
2644 case OFPBCT_DISCARD_REPLY
:
2645 ds_put_cstr(s
, "DISCARD_REPLY");
2649 ds_put_cstr(s
, " flags=");
2650 ofp_print_bit_names(s
, bctrl
.flags
, bundle_flags_to_name
, ' ');
2654 ofp_print_bundle_add(struct ds
*s
, const struct ofp_header
*oh
, int verbosity
)
2657 struct ofputil_bundle_add_msg badd
;
2660 error
= ofputil_decode_bundle_add(oh
, &badd
);
2662 ofp_print_error(s
, error
);
2666 ds_put_char(s
, '\n');
2667 ds_put_format(s
, " bundle_id=%#"PRIx32
, badd
.bundle_id
);
2668 ds_put_cstr(s
, " flags=");
2669 ofp_print_bit_names(s
, badd
.flags
, bundle_flags_to_name
, ' ');
2671 ds_put_char(s
, '\n');
2672 msg
= ofp_to_string(badd
.msg
, ntohs(badd
.msg
->length
), verbosity
);
2674 ds_put_cstr(s
, msg
);
2679 ofp_to_string__(const struct ofp_header
*oh
, enum ofpraw raw
,
2680 struct ds
*string
, int verbosity
)
2682 const void *msg
= oh
;
2684 ofp_header_to_string__(oh
, raw
, string
);
2685 switch (ofptype_from_ofpraw(raw
)) {
2687 case OFPTYPE_GROUP_STATS_REQUEST
:
2688 ofp_print_stats(string
, oh
);
2689 ofp_print_ofpst_group_request(string
, oh
);
2692 case OFPTYPE_GROUP_STATS_REPLY
:
2693 ofp_print_group_stats(string
, oh
);
2696 case OFPTYPE_GROUP_DESC_STATS_REQUEST
:
2697 ofp_print_stats(string
, oh
);
2698 ofp_print_ofpst_group_desc_request(string
, oh
);
2701 case OFPTYPE_GROUP_DESC_STATS_REPLY
:
2702 ofp_print_group_desc(string
, oh
);
2705 case OFPTYPE_GROUP_FEATURES_STATS_REQUEST
:
2706 ofp_print_stats(string
, oh
);
2709 case OFPTYPE_GROUP_FEATURES_STATS_REPLY
:
2710 ofp_print_group_features(string
, oh
);
2713 case OFPTYPE_GROUP_MOD
:
2714 ofp_print_group_mod(string
, oh
);
2717 case OFPTYPE_TABLE_FEATURES_STATS_REQUEST
:
2718 case OFPTYPE_TABLE_FEATURES_STATS_REPLY
:
2719 ofp_print_table_features_reply(string
, oh
);
2723 ofp_print_hello(string
, oh
);
2727 ofp_print_error_msg(string
, oh
);
2730 case OFPTYPE_ECHO_REQUEST
:
2731 case OFPTYPE_ECHO_REPLY
:
2732 ofp_print_echo(string
, oh
, verbosity
);
2735 case OFPTYPE_FEATURES_REQUEST
:
2738 case OFPTYPE_FEATURES_REPLY
:
2739 ofp_print_switch_features(string
, oh
);
2742 case OFPTYPE_GET_CONFIG_REQUEST
:
2745 case OFPTYPE_GET_CONFIG_REPLY
:
2746 case OFPTYPE_SET_CONFIG
:
2747 ofp_print_switch_config(string
, ofpmsg_body(oh
));
2750 case OFPTYPE_PACKET_IN
:
2751 ofp_print_packet_in(string
, oh
, verbosity
);
2754 case OFPTYPE_FLOW_REMOVED
:
2755 ofp_print_flow_removed(string
, oh
);
2758 case OFPTYPE_PORT_STATUS
:
2759 ofp_print_port_status(string
, oh
);
2762 case OFPTYPE_PACKET_OUT
:
2763 ofp_print_packet_out(string
, oh
, verbosity
);
2766 case OFPTYPE_FLOW_MOD
:
2767 ofp_print_flow_mod(string
, oh
, verbosity
);
2770 case OFPTYPE_PORT_MOD
:
2771 ofp_print_port_mod(string
, oh
);
2774 case OFPTYPE_TABLE_MOD
:
2775 ofp_print_table_mod(string
, oh
);
2778 case OFPTYPE_METER_MOD
:
2779 ofp_print_meter_mod(string
, oh
);
2782 case OFPTYPE_BARRIER_REQUEST
:
2783 case OFPTYPE_BARRIER_REPLY
:
2786 case OFPTYPE_QUEUE_GET_CONFIG_REQUEST
:
2787 ofp_print_queue_get_config_request(string
, oh
);
2790 case OFPTYPE_QUEUE_GET_CONFIG_REPLY
:
2791 ofp_print_queue_get_config_reply(string
, oh
);
2794 case OFPTYPE_ROLE_REQUEST
:
2795 case OFPTYPE_ROLE_REPLY
:
2796 ofp_print_role_message(string
, oh
);
2798 case OFPTYPE_ROLE_STATUS
:
2799 ofp_print_role_status_message(string
, oh
);
2802 case OFPTYPE_METER_STATS_REQUEST
:
2803 case OFPTYPE_METER_CONFIG_STATS_REQUEST
:
2804 ofp_print_stats(string
, oh
);
2805 ofp_print_meter_stats_request(string
, oh
);
2808 case OFPTYPE_METER_STATS_REPLY
:
2809 ofp_print_stats(string
, oh
);
2810 ofp_print_meter_stats_reply(string
, oh
);
2813 case OFPTYPE_METER_CONFIG_STATS_REPLY
:
2814 ofp_print_stats(string
, oh
);
2815 ofp_print_meter_config_reply(string
, oh
);
2818 case OFPTYPE_METER_FEATURES_STATS_REPLY
:
2819 ofp_print_stats(string
, oh
);
2820 ofp_print_meter_features_reply(string
, oh
);
2823 case OFPTYPE_DESC_STATS_REQUEST
:
2824 case OFPTYPE_METER_FEATURES_STATS_REQUEST
:
2825 ofp_print_stats(string
, oh
);
2828 case OFPTYPE_FLOW_STATS_REQUEST
:
2829 case OFPTYPE_AGGREGATE_STATS_REQUEST
:
2830 ofp_print_stats(string
, oh
);
2831 ofp_print_flow_stats_request(string
, oh
);
2834 case OFPTYPE_TABLE_STATS_REQUEST
:
2835 ofp_print_stats(string
, oh
);
2838 case OFPTYPE_PORT_STATS_REQUEST
:
2839 ofp_print_stats(string
, oh
);
2840 ofp_print_ofpst_port_request(string
, oh
);
2843 case OFPTYPE_QUEUE_STATS_REQUEST
:
2844 ofp_print_stats(string
, oh
);
2845 ofp_print_ofpst_queue_request(string
, oh
);
2848 case OFPTYPE_DESC_STATS_REPLY
:
2849 ofp_print_stats(string
, oh
);
2850 ofp_print_ofpst_desc_reply(string
, oh
);
2853 case OFPTYPE_FLOW_STATS_REPLY
:
2854 ofp_print_stats(string
, oh
);
2855 ofp_print_flow_stats_reply(string
, oh
);
2858 case OFPTYPE_QUEUE_STATS_REPLY
:
2859 ofp_print_stats(string
, oh
);
2860 ofp_print_ofpst_queue_reply(string
, oh
, verbosity
);
2863 case OFPTYPE_PORT_STATS_REPLY
:
2864 ofp_print_stats(string
, oh
);
2865 ofp_print_ofpst_port_reply(string
, oh
, verbosity
);
2868 case OFPTYPE_TABLE_STATS_REPLY
:
2869 ofp_print_stats(string
, oh
);
2870 ofp_print_table_stats_reply(string
, oh
);
2873 case OFPTYPE_AGGREGATE_STATS_REPLY
:
2874 ofp_print_stats(string
, oh
);
2875 ofp_print_aggregate_stats_reply(string
, oh
);
2878 case OFPTYPE_PORT_DESC_STATS_REQUEST
:
2879 ofp_print_stats(string
, oh
);
2880 ofp_print_ofpst_port_desc_request(string
, oh
);
2883 case OFPTYPE_PORT_DESC_STATS_REPLY
:
2884 ofp_print_stats(string
, oh
);
2885 ofp_print_ofpst_port_desc_reply(string
, oh
);
2888 case OFPTYPE_FLOW_MOD_TABLE_ID
:
2889 ofp_print_nxt_flow_mod_table_id(string
, ofpmsg_body(oh
));
2892 case OFPTYPE_SET_FLOW_FORMAT
:
2893 ofp_print_nxt_set_flow_format(string
, ofpmsg_body(oh
));
2896 case OFPTYPE_SET_PACKET_IN_FORMAT
:
2897 ofp_print_nxt_set_packet_in_format(string
, ofpmsg_body(oh
));
2900 case OFPTYPE_FLOW_AGE
:
2903 case OFPTYPE_SET_CONTROLLER_ID
:
2904 ofp_print_nxt_set_controller_id(string
, ofpmsg_body(oh
));
2907 case OFPTYPE_GET_ASYNC_REPLY
:
2908 case OFPTYPE_SET_ASYNC_CONFIG
:
2909 ofp_print_nxt_set_async_config(string
, ofpmsg_body(oh
));
2911 case OFPTYPE_GET_ASYNC_REQUEST
:
2913 case OFPTYPE_FLOW_MONITOR_CANCEL
:
2914 ofp_print_nxt_flow_monitor_cancel(string
, msg
);
2917 case OFPTYPE_FLOW_MONITOR_PAUSED
:
2918 case OFPTYPE_FLOW_MONITOR_RESUMED
:
2921 case OFPTYPE_FLOW_MONITOR_STATS_REQUEST
:
2922 ofp_print_nxst_flow_monitor_request(string
, msg
);
2925 case OFPTYPE_FLOW_MONITOR_STATS_REPLY
:
2926 ofp_print_nxst_flow_monitor_reply(string
, msg
);
2929 case OFPTYPE_BUNDLE_CONTROL
:
2930 ofp_print_bundle_ctrl(string
, msg
);
2933 case OFPTYPE_BUNDLE_ADD_MESSAGE
:
2934 ofp_print_bundle_add(string
, msg
, verbosity
);
2939 /* Composes and returns a string representing the OpenFlow packet of 'len'
2940 * bytes at 'oh' at the given 'verbosity' level. 0 is a minimal amount of
2941 * verbosity and higher numbers increase verbosity. The caller is responsible
2942 * for freeing the string. */
2944 ofp_to_string(const void *oh_
, size_t len
, int verbosity
)
2946 struct ds string
= DS_EMPTY_INITIALIZER
;
2947 const struct ofp_header
*oh
= oh_
;
2950 ds_put_cstr(&string
, "OpenFlow message is empty\n");
2951 } else if (len
< sizeof(struct ofp_header
)) {
2952 ds_put_format(&string
, "OpenFlow packet too short (only %"PRIuSIZE
" bytes):\n",
2954 } else if (ntohs(oh
->length
) > len
) {
2958 error
= ofpraw_decode_partial(&raw
, oh
, len
);
2960 ofp_header_to_string__(oh
, raw
, &string
);
2961 ds_put_char(&string
, '\n');
2964 ds_put_format(&string
,
2965 "(***truncated to %"PRIuSIZE
" bytes from %"PRIu16
"***)\n",
2966 len
, ntohs(oh
->length
));
2967 } else if (ntohs(oh
->length
) < len
) {
2968 ds_put_format(&string
,
2969 "(***only uses %"PRIu16
" bytes out of %"PRIuSIZE
"***)\n",
2970 ntohs(oh
->length
), len
);
2975 error
= ofpraw_decode(&raw
, oh
);
2977 ofp_to_string__(oh
, raw
, &string
, verbosity
);
2978 if (verbosity
>= 5) {
2979 if (ds_last(&string
) != '\n') {
2980 ds_put_char(&string
, '\n');
2982 ds_put_hex_dump(&string
, oh
, len
, 0, true);
2984 if (ds_last(&string
) != '\n') {
2985 ds_put_char(&string
, '\n');
2987 return ds_steal_cstr(&string
);
2990 ofp_print_error(&string
, error
);
2992 ds_put_hex_dump(&string
, oh
, len
, 0, true);
2993 return ds_steal_cstr(&string
);
2997 print_and_free(FILE *stream
, char *string
)
2999 fputs(string
, stream
);
3003 /* Pretty-print the OpenFlow packet of 'len' bytes at 'oh' to 'stream' at the
3004 * given 'verbosity' level. 0 is a minimal amount of verbosity and higher
3005 * numbers increase verbosity. */
3007 ofp_print(FILE *stream
, const void *oh
, size_t len
, int verbosity
)
3009 print_and_free(stream
, ofp_to_string(oh
, len
, verbosity
));
3012 /* Dumps the contents of the Ethernet frame in the 'len' bytes starting at
3013 * 'data' to 'stream'. */
3015 ofp_print_packet(FILE *stream
, const void *data
, size_t len
)
3017 print_and_free(stream
, ofp_packet_to_string(data
, len
));