summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Pfaff <blp@ovn.org>2018-06-15 17:06:56 -0700
committerBen Pfaff <blp@ovn.org>2018-06-18 15:25:44 -0700
commitfe2c69f49cb3cb0ab2cc2ae84b364970f5e77392 (patch)
treed2f803e322099a4d8e754b3d36ce43cc4c94007d
parent16ee87263e31dc6520937a0dcefd676f3582d8ee (diff)
downloadopenvswitch-fe2c69f49cb3cb0ab2cc2ae84b364970f5e77392.tar.gz
ofp-print: Move significant formatting code into more specific .c files.
Signed-off-by: Ben Pfaff <blp@ovn.org> Acked-by: Justin Pettit <jpettit@ovn.org>
-rw-r--r--include/openvswitch/ofp-bundle.h11
-rw-r--r--include/openvswitch/ofp-connection.h18
-rw-r--r--include/openvswitch/ofp-ipfix.h5
-rw-r--r--include/openvswitch/ofp-match.h9
-rw-r--r--include/openvswitch/ofp-meter.h12
-rw-r--r--include/openvswitch/ofp-monitor.h4
-rw-r--r--include/openvswitch/ofp-port.h3
-rw-r--r--include/openvswitch/ofp-queue.h14
-rw-r--r--include/openvswitch/ofp-table.h6
-rw-r--r--lib/ofp-bundle.c70
-rw-r--r--lib/ofp-connection.c197
-rw-r--r--lib/ofp-ipfix.c51
-rw-r--r--lib/ofp-match.c59
-rw-r--r--lib/ofp-meter.c178
-rw-r--r--lib/ofp-monitor.c27
-rw-r--r--lib/ofp-port.c145
-rw-r--r--lib/ofp-print.c976
-rw-r--r--lib/ofp-queue.c196
-rw-r--r--lib/ofp-table.c35
19 files changed, 1080 insertions, 936 deletions
diff --git a/include/openvswitch/ofp-bundle.h b/include/openvswitch/ofp-bundle.h
index 78a44d6f0..b4c29c0d9 100644
--- a/include/openvswitch/ofp-bundle.h
+++ b/include/openvswitch/ofp-bundle.h
@@ -36,9 +36,11 @@ struct ofputil_bundle_ctrl_msg {
enum ofperr ofputil_decode_bundle_ctrl(const struct ofp_header *,
struct ofputil_bundle_ctrl_msg *);
-
struct ofpbuf *ofputil_encode_bundle_ctrl_request(
enum ofp_version, struct ofputil_bundle_ctrl_msg *);
+void ofputil_format_bundle_ctrl_request(
+ struct ds *, const struct ofputil_bundle_ctrl_msg *);
+
struct ofpbuf *ofputil_encode_bundle_ctrl_reply(
const struct ofp_header *, struct ofputil_bundle_ctrl_msg *);
@@ -51,10 +53,15 @@ struct ofputil_bundle_add_msg {
struct ofpbuf *ofputil_encode_bundle_add(enum ofp_version,
struct ofputil_bundle_add_msg *);
-
enum ofperr ofputil_decode_bundle_add(const struct ofp_header *,
struct ofputil_bundle_add_msg *,
enum ofptype *);
+void ofputil_format_bundle_add(struct ds *,
+ const struct ofputil_bundle_add_msg *,
+ const struct ofputil_port_map *,
+ const struct ofputil_table_map *,
+ int verbosity);
+
/* Bundle message as produced by ofp-parse. */
struct ofputil_bundle_msg {
diff --git a/include/openvswitch/ofp-connection.h b/include/openvswitch/ofp-connection.h
index 540ce9ed9..5fb143157 100644
--- a/include/openvswitch/ofp-connection.h
+++ b/include/openvswitch/ofp-connection.h
@@ -31,22 +31,26 @@ struct ofputil_role_request {
uint64_t generation_id;
};
+enum ofperr ofputil_decode_role_message(const struct ofp_header *,
+ struct ofputil_role_request *);
+void ofputil_format_role_message(struct ds *,
+ const struct ofputil_role_request *);
+struct ofpbuf *ofputil_encode_role_reply(const struct ofp_header *,
+ const struct ofputil_role_request *);
+
+/* Abstract OFPT_ROLE_STATUS. */
struct ofputil_role_status {
enum ofp12_controller_role role;
enum ofp14_controller_role_reason reason;
uint64_t generation_id;
};
-enum ofperr ofputil_decode_role_message(const struct ofp_header *,
- struct ofputil_role_request *);
-struct ofpbuf *ofputil_encode_role_reply(const struct ofp_header *,
- const struct ofputil_role_request *);
-
struct ofpbuf *ofputil_encode_role_status(const struct ofputil_role_status *,
enum ofputil_protocol);
-
enum ofperr ofputil_decode_role_status(const struct ofp_header *,
struct ofputil_role_status *);
+void ofputil_format_role_status(struct ds *,
+ const struct ofputil_role_status *);
enum ofputil_async_msg_type {
/* Standard asynchronous messages. */
@@ -79,6 +83,8 @@ struct ofpbuf *ofputil_encode_get_async_reply(
const struct ofp_header *, const struct ofputil_async_cfg *);
struct ofpbuf *ofputil_encode_set_async_config(
const struct ofputil_async_cfg *, uint32_t oams, enum ofp_version);
+void ofputil_format_set_async_config(struct ds *,
+ const struct ofputil_async_cfg *);
struct ofputil_async_cfg ofputil_async_cfg_default(enum ofp_version);
diff --git a/include/openvswitch/ofp-ipfix.h b/include/openvswitch/ofp-ipfix.h
index 75eefc005..34ff2b9b2 100644
--- a/include/openvswitch/ofp-ipfix.h
+++ b/include/openvswitch/ofp-ipfix.h
@@ -19,6 +19,7 @@
#include "openflow/openflow.h"
+struct ds;
struct ofpbuf;
struct ovs_list;
@@ -44,6 +45,10 @@ void ofputil_append_ipfix_stat(struct ovs_list *replies,
const struct ofputil_ipfix_stats *);
size_t ofputil_count_ipfix_stats(const struct ofp_header *);
int ofputil_pull_ipfix_stats(struct ofputil_ipfix_stats *, struct ofpbuf *msg);
+void ofputil_format_ipfix_stats_bridge(struct ds *,
+ const struct ofputil_ipfix_stats *);
+void ofputil_format_ipfix_stats_flow(struct ds *,
+ const struct ofputil_ipfix_stats *);
#ifdef __cplusplus
}
diff --git a/include/openvswitch/ofp-match.h b/include/openvswitch/ofp-match.h
index 6ed373e2b..f279d4661 100644
--- a/include/openvswitch/ofp-match.h
+++ b/include/openvswitch/ofp-match.h
@@ -79,9 +79,12 @@ struct ofputil_tlv_table_reply {
};
struct ofpbuf *ofputil_encode_tlv_table_mod(enum ofp_version ofp_version,
- struct ofputil_tlv_table_mod *);
-enum ofperr ofputil_decode_tlv_table_mod(const struct ofp_header *,
struct ofputil_tlv_table_mod *);
+enum ofperr ofputil_decode_tlv_table_mod(const struct ofp_header *,
+ struct ofputil_tlv_table_mod *);
+void ofputil_format_tlv_table_mod(struct ds *,
+ const struct ofputil_tlv_table_mod *);
+
struct ofpbuf *ofputil_encode_tlv_table_reply(
const struct ofp_header *, struct ofputil_tlv_table_reply *);
enum ofperr ofputil_decode_tlv_table_reply(
@@ -90,6 +93,8 @@ char *parse_ofp_tlv_table_mod_str(struct ofputil_tlv_table_mod *,
uint16_t command, const char *string,
enum ofputil_protocol *usable_protocols)
OVS_WARN_UNUSED_RESULT;
+void ofputil_format_tlv_table_reply(struct ds *,
+ const struct ofputil_tlv_table_reply *);
void ofputil_uninit_tlv_table(struct ovs_list *mappings);
diff --git a/include/openvswitch/ofp-meter.h b/include/openvswitch/ofp-meter.h
index 18267a6fa..6776eae87 100644
--- a/include/openvswitch/ofp-meter.h
+++ b/include/openvswitch/ofp-meter.h
@@ -30,6 +30,8 @@ extern "C" {
/* Type for meter_id in ofproto provider interface, UINT32_MAX if invalid. */
typedef struct { uint32_t uint32; } ofproto_meter_id;
+void ofputil_format_meter_id(struct ds *s, uint32_t meter_id, char separator);
+
/* Meter band configuration for all supported band types. */
struct ofputil_meter_band {
uint16_t type;
@@ -38,6 +40,9 @@ struct ofputil_meter_band {
uint32_t burst_size;
};
+void ofputil_format_meter_band(struct ds *, enum ofp13_meter_flags,
+ const struct ofputil_meter_band *);
+
struct ofputil_meter_band_stats {
uint64_t packet_count;
uint64_t byte_count;
@@ -55,6 +60,8 @@ void ofputil_append_meter_config(struct ovs_list *replies,
int ofputil_decode_meter_config(struct ofpbuf *,
struct ofputil_meter_config *,
struct ofpbuf *bands);
+void ofputil_format_meter_config(struct ds *,
+ const struct ofputil_meter_config *);
struct ofputil_meter_mod {
uint16_t command;
@@ -70,6 +77,7 @@ char *parse_ofp_meter_mod_str(struct ofputil_meter_mod *, const char *string,
int command,
enum ofputil_protocol *usable_protocols)
OVS_WARN_UNUSED_RESULT;
+void ofputil_format_meter_mod(struct ds *, const struct ofputil_meter_mod *);
struct ofputil_meter_stats {
uint32_t meter_id;
@@ -87,6 +95,8 @@ void ofputil_append_meter_stats(struct ovs_list *replies,
int ofputil_decode_meter_stats(struct ofpbuf *,
struct ofputil_meter_stats *,
struct ofpbuf *bands);
+void ofputil_format_meter_stats(struct ds *,
+ const struct ofputil_meter_stats *);
struct ofputil_meter_features {
uint32_t max_meters; /* Maximum number of meters. */
@@ -102,6 +112,8 @@ struct ofpbuf *ofputil_encode_meter_features_reply(const struct
ofputil_meter_features *,
const struct ofp_header *
request);
+void ofputil_format_meter_features(struct ds *,
+ const struct ofputil_meter_features *);
enum ofputil_meter_request_type {
OFPUTIL_METER_FEATURES,
diff --git a/include/openvswitch/ofp-monitor.h b/include/openvswitch/ofp-monitor.h
index 47d0d0e89..3edaeb53a 100644
--- a/include/openvswitch/ofp-monitor.h
+++ b/include/openvswitch/ofp-monitor.h
@@ -133,6 +133,10 @@ struct ofpbuf *ofputil_encode_requestforward(
const struct ofputil_requestforward *, enum ofputil_protocol);
enum ofperr ofputil_decode_requestforward(const struct ofp_header *,
struct ofputil_requestforward *);
+void ofputil_format_requestforward(struct ds *, enum ofp_version,
+ const struct ofputil_requestforward *,
+ const struct ofputil_port_map *,
+ const struct ofputil_table_map *);
void ofputil_destroy_requestforward(struct ofputil_requestforward *);
#ifdef __cplusplus
diff --git a/include/openvswitch/ofp-port.h b/include/openvswitch/ofp-port.h
index 4286ba19d..f1f36bf9c 100644
--- a/include/openvswitch/ofp-port.h
+++ b/include/openvswitch/ofp-port.h
@@ -169,6 +169,9 @@ void ofputil_append_port_stat(struct ovs_list *replies,
const struct ofputil_port_stats *ops);
size_t ofputil_count_port_stats(const struct ofp_header *);
int ofputil_decode_port_stats(struct ofputil_port_stats *, struct ofpbuf *msg);
+void ofputil_format_port_stats(struct ds *, const struct ofputil_port_stats *,
+ const struct ofputil_port_map *);
+
enum ofperr ofputil_decode_port_stats_request(const struct ofp_header *request,
ofp_port_t *ofp10_port);
diff --git a/include/openvswitch/ofp-queue.h b/include/openvswitch/ofp-queue.h
index b0229685b..51b98cda4 100644
--- a/include/openvswitch/ofp-queue.h
+++ b/include/openvswitch/ofp-queue.h
@@ -19,7 +19,9 @@
#include "openflow/openflow.h"
+struct ds;
struct ofpbuf;
+struct ofputil_port_map;
struct ovs_list;
#ifdef __cplusplus
@@ -45,6 +47,8 @@ void ofputil_append_queue_get_config_reply(
int ofputil_pull_queue_get_config_reply(struct ofpbuf *reply,
struct ofputil_queue_config *);
+enum ofperr ofputil_queue_get_config_reply_format(
+ struct ds *, const struct ofp_header *, const struct ofputil_port_map *);
struct ofputil_queue_stats_request {
ofp_port_t port_no; /* OFPP_ANY means "all ports". */
@@ -55,6 +59,9 @@ enum ofperr ofputil_decode_queue_stats_request(
const struct ofp_header *, struct ofputil_queue_stats_request *);
struct ofpbuf *ofputil_encode_queue_stats_request(
enum ofp_version, const struct ofputil_queue_stats_request *);
+enum ofperr ofputil_queue_stats_request_format(
+ struct ds *, const struct ofp_header *,
+ const struct ofputil_port_map *);
struct ofputil_queue_stats {
ofp_port_t port_no;
@@ -74,6 +81,10 @@ size_t ofputil_count_queue_stats(const struct ofp_header *);
int ofputil_decode_queue_stats(struct ofputil_queue_stats *, struct ofpbuf *);
void ofputil_append_queue_stat(struct ovs_list *replies,
const struct ofputil_queue_stats *);
+enum ofperr ofputil_queue_stats_reply_format(struct ds *,
+ const struct ofp_header *,
+ const struct ofputil_port_map *,
+ int verbosity);
/* Queue configuration request. */
struct ofpbuf *ofputil_encode_queue_get_config_request(enum ofp_version,
@@ -82,6 +93,9 @@ struct ofpbuf *ofputil_encode_queue_get_config_request(enum ofp_version,
enum ofperr ofputil_decode_queue_get_config_request(const struct ofp_header *,
ofp_port_t *port,
uint32_t *queue);
+enum ofperr ofputil_queue_get_config_request_format(
+ struct ds *, const struct ofp_header *,
+ const struct ofputil_port_map *);
#ifdef __cplusplus
}
diff --git a/include/openvswitch/ofp-table.h b/include/openvswitch/ofp-table.h
index e8260657f..d06ccf5ce 100644
--- a/include/openvswitch/ofp-table.h
+++ b/include/openvswitch/ofp-table.h
@@ -309,10 +309,16 @@ struct ofputil_table_status {
struct ofputil_table_desc desc; /* New table config. */
};
+const char *ofp_table_reason_to_string(enum ofp14_table_reason,
+ char *reasonbuf, size_t bufsize);
+
enum ofperr ofputil_decode_table_status(const struct ofp_header *,
struct ofputil_table_status *);
struct ofpbuf *ofputil_encode_table_status(const struct ofputil_table_status *,
enum ofputil_protocol);
+void ofputil_format_table_status(struct ds *,
+ const struct ofputil_table_status *,
+ const struct ofputil_table_map *);
#ifdef __cplusplus
}
diff --git a/lib/ofp-bundle.c b/lib/ofp-bundle.c
index 8f07a30c5..0e9b46b2f 100644
--- a/lib/ofp-bundle.c
+++ b/lib/ofp-bundle.c
@@ -19,6 +19,7 @@
#include <errno.h>
#include <stdlib.h>
#include "openvswitch/ofp-parse.h"
+#include "openvswitch/ofp-print.h"
#include "openvswitch/ofpbuf.h"
#include "openvswitch/vlog.h"
#include "util.h"
@@ -128,6 +129,57 @@ ofputil_encode_bundle_ctrl_request(enum ofp_version ofp_version,
return request;
}
+static const char *
+bundle_flags_to_name(uint32_t bit)
+{
+ switch (bit) {
+ case OFPBF_ATOMIC:
+ return "atomic";
+ case OFPBF_ORDERED:
+ return "ordered";
+ default:
+ return NULL;
+ }
+}
+
+void
+ofputil_format_bundle_ctrl_request(struct ds *s,
+ const struct ofputil_bundle_ctrl_msg *bctrl)
+{
+ ds_put_char(s, '\n');
+ ds_put_format(s, " bundle_id=%#"PRIx32" type=", bctrl->bundle_id);
+ switch (bctrl->type) {
+ case OFPBCT_OPEN_REQUEST:
+ ds_put_cstr(s, "OPEN_REQUEST");
+ break;
+ case OFPBCT_OPEN_REPLY:
+ ds_put_cstr(s, "OPEN_REPLY");
+ break;
+ case OFPBCT_CLOSE_REQUEST:
+ ds_put_cstr(s, "CLOSE_REQUEST");
+ break;
+ case OFPBCT_CLOSE_REPLY:
+ ds_put_cstr(s, "CLOSE_REPLY");
+ break;
+ case OFPBCT_COMMIT_REQUEST:
+ ds_put_cstr(s, "COMMIT_REQUEST");
+ break;
+ case OFPBCT_COMMIT_REPLY:
+ ds_put_cstr(s, "COMMIT_REPLY");
+ break;
+ case OFPBCT_DISCARD_REQUEST:
+ ds_put_cstr(s, "DISCARD_REQUEST");
+ break;
+ case OFPBCT_DISCARD_REPLY:
+ ds_put_cstr(s, "DISCARD_REPLY");
+ break;
+ }
+
+ ds_put_cstr(s, " flags=");
+ ofp_print_bit_names(s, bctrl->flags, bundle_flags_to_name, ' ');
+}
+
+
struct ofpbuf *
ofputil_encode_bundle_ctrl_reply(const struct ofp_header *oh,
struct ofputil_bundle_ctrl_msg *msg)
@@ -430,3 +482,21 @@ parse_ofp_bundle_file(const char *file_name,
}
return NULL;
}
+
+void
+ofputil_format_bundle_add(struct ds *s,
+ const struct ofputil_bundle_add_msg *badd,
+ const struct ofputil_port_map *port_map,
+ const struct ofputil_table_map *table_map,
+ int verbosity)
+{
+ ds_put_char(s, '\n');
+ ds_put_format(s, " bundle_id=%#"PRIx32, badd->bundle_id);
+ ds_put_cstr(s, " flags=");
+ ofp_print_bit_names(s, badd->flags, bundle_flags_to_name, ' ');
+
+ ds_put_char(s, '\n');
+ char *msg = ofp_to_string(badd->msg, ntohs(badd->msg->length), port_map,
+ table_map, verbosity);
+ ds_put_and_free_cstr(s, msg);
+}
diff --git a/lib/ofp-connection.c b/lib/ofp-connection.c
index 3e114ba77..23b80ff39 100644
--- a/lib/ofp-connection.c
+++ b/lib/ofp-connection.c
@@ -19,9 +19,13 @@
#include "byte-order.h"
#include "openflow/nicira-ext.h"
#include "openvswitch/ofp-errors.h"
+#include "openvswitch/ofp-monitor.h"
#include "openvswitch/ofp-msgs.h"
+#include "openvswitch/ofp-packet.h"
#include "openvswitch/ofp-prop.h"
+#include "openvswitch/ofp-table.h"
#include "openvswitch/ofpbuf.h"
+#include "openvswitch/type-props.h"
#include "openvswitch/vlog.h"
#include "util.h"
@@ -83,6 +87,43 @@ ofputil_decode_role_message(const struct ofp_header *oh,
return 0;
}
+static void
+format_role_generic(struct ds *string, enum ofp12_controller_role role,
+ uint64_t generation_id)
+{
+ ds_put_cstr(string, " role=");
+
+ switch (role) {
+ case OFPCR12_ROLE_NOCHANGE:
+ ds_put_cstr(string, "nochange");
+ break;
+ case OFPCR12_ROLE_EQUAL:
+ ds_put_cstr(string, "equal"); /* OF 1.2 wording */
+ break;
+ case OFPCR12_ROLE_MASTER:
+ ds_put_cstr(string, "master");
+ break;
+ case OFPCR12_ROLE_SLAVE:
+ ds_put_cstr(string, "slave");
+ break;
+ default:
+ OVS_NOT_REACHED();
+ }
+
+ if (generation_id != UINT64_MAX) {
+ ds_put_format(string, " generation_id=%"PRIu64, generation_id);
+ }
+}
+
+void
+ofputil_format_role_message(struct ds *string,
+ const struct ofputil_role_request *rr)
+{
+ format_role_generic(string, rr->role, (rr->have_generation_id
+ ? rr->generation_id
+ : UINT64_MAX));
+}
+
/* Returns an encoded form of a role reply suitable for the "request" in a
* buffer owned by the caller. */
struct ofpbuf *
@@ -167,6 +208,31 @@ ofputil_decode_role_status(const struct ofp_header *oh,
return 0;
}
+
+void
+ofputil_format_role_status(struct ds *string,
+ const struct ofputil_role_status *rs)
+{
+ format_role_generic(string, rs->role, rs->generation_id);
+
+ ds_put_cstr(string, " reason=");
+
+ switch (rs->reason) {
+ case OFPCRR_MASTER_REQUEST:
+ ds_put_cstr(string, "master_request");
+ break;
+ case OFPCRR_CONFIG:
+ ds_put_cstr(string, "configuration_changed");
+ break;
+ case OFPCRR_EXPERIMENTER:
+ ds_put_cstr(string, "experimenter_data_changed");
+ break;
+ case OFPCRR_N_REASONS:
+ default:
+ ds_put_cstr(string, "(unknown)");
+ break;
+ }
+}
const char *
ofputil_async_msg_type_to_string(enum ofputil_async_msg_type type)
@@ -493,6 +559,137 @@ ofputil_encode_set_async_config(const struct ofputil_async_cfg *ac,
return request;
}
+/* Returns a string form of 'reason'. The return value is either a statically
+ * allocated constant string or the 'bufsize'-byte buffer 'reasonbuf'.
+ * 'bufsize' should be at least OFP_PORT_REASON_BUFSIZE. */
+#define OFP_PORT_REASON_BUFSIZE (INT_STRLEN(int) + 1)
+static const char *
+ofp_port_reason_to_string(enum ofp_port_reason reason,
+ char *reasonbuf, size_t bufsize)
+{
+ switch (reason) {
+ case OFPPR_ADD:
+ return "add";
+
+ case OFPPR_DELETE:
+ return "delete";
+
+ case OFPPR_MODIFY:
+ return "modify";
+
+ case OFPPR_N_REASONS:
+ default:
+ snprintf(reasonbuf, bufsize, "%d", (int) reason);
+ return reasonbuf;
+ }
+}
+
+/* Returns a string form of 'reason'. The return value is either a statically
+ * allocated constant string or the 'bufsize'-byte buffer 'reasonbuf'.
+ * 'bufsize' should be at least OFP_ASYNC_CONFIG_REASON_BUFSIZE. */
+static const char*
+ofp_role_reason_to_string(enum ofp14_controller_role_reason reason,
+ char *reasonbuf, size_t bufsize)
+{
+ switch (reason) {
+ case OFPCRR_MASTER_REQUEST:
+ return "master_request";
+
+ case OFPCRR_CONFIG:
+ return "configuration_changed";
+
+ case OFPCRR_EXPERIMENTER:
+ return "experimenter_data_changed";
+
+ case OFPCRR_N_REASONS:
+ default:
+ snprintf(reasonbuf, bufsize, "%d", (int) reason);
+ return reasonbuf;
+ }
+}
+
+/* Returns a string form of 'reason'. The return value is either a statically
+ * allocated constant string or the 'bufsize'-byte buffer 'reasonbuf'.
+ * 'bufsize' should be at least OFP_ASYNC_CONFIG_REASON_BUFSIZE. */
+static const char*
+ofp_requestforward_reason_to_string(enum ofp14_requestforward_reason reason,
+ char *reasonbuf, size_t bufsize)
+{
+ switch (reason) {
+ case OFPRFR_GROUP_MOD:
+ return "group_mod_request";
+
+ case OFPRFR_METER_MOD:
+ return "meter_mod_request";
+
+ case OFPRFR_N_REASONS:
+ default:
+ snprintf(reasonbuf, bufsize, "%d", (int) reason);
+ return reasonbuf;
+ }
+}
+
+static const char *
+ofp_async_config_reason_to_string(uint32_t reason,
+ enum ofputil_async_msg_type type,
+ char *reasonbuf, size_t bufsize)
+{
+ switch (type) {
+ case OAM_PACKET_IN:
+ return ofputil_packet_in_reason_to_string(reason, reasonbuf, bufsize);
+
+ case OAM_PORT_STATUS:
+ return ofp_port_reason_to_string(reason, reasonbuf, bufsize);
+
+ case OAM_FLOW_REMOVED:
+ return ofp_flow_removed_reason_to_string(reason, reasonbuf, bufsize);
+
+ case OAM_ROLE_STATUS:
+ return ofp_role_reason_to_string(reason, reasonbuf, bufsize);
+
+ case OAM_TABLE_STATUS:
+ return ofp_table_reason_to_string(reason, reasonbuf, bufsize);
+
+ case OAM_REQUESTFORWARD:
+ return ofp_requestforward_reason_to_string(reason, reasonbuf, bufsize);
+
+ case OAM_N_TYPES:
+ default:
+ return "Unknown asynchronous configuration message type";
+ }
+}
+
+void
+ofputil_format_set_async_config(struct ds *string,
+ const struct ofputil_async_cfg *ac)
+{
+ for (int i = 0; i < 2; i++) {
+ ds_put_format(string, "\n %s:\n", i == 0 ? "master" : "slave");
+ for (uint32_t type = 0; type < OAM_N_TYPES; type++) {
+ ds_put_format(string, "%16s:",
+ ofputil_async_msg_type_to_string(type));
+
+ uint32_t role = i == 0 ? ac->master[type] : ac->slave[type];
+ for (int j = 0; j < 32; j++) {
+ if (role & (1u << j)) {
+ char reasonbuf[INT_STRLEN(int) + 1];
+ const char *reason;
+
+ reason = ofp_async_config_reason_to_string(
+ j, type, reasonbuf, sizeof reasonbuf);
+ if (reason[0]) {
+ ds_put_format(string, " %s", reason);
+ }
+ }
+ }
+ if (!role) {
+ ds_put_cstr(string, " (off)");
+ }
+ ds_put_char(string, '\n');
+ }
+ }
+}
+
struct ofputil_async_cfg
ofputil_async_cfg_default(enum ofp_version version)
{
diff --git a/lib/ofp-ipfix.c b/lib/ofp-ipfix.c
index d710b5a4b..0ffc4d936 100644
--- a/lib/ofp-ipfix.c
+++ b/lib/ofp-ipfix.c
@@ -109,3 +109,54 @@ ofputil_count_ipfix_stats(const struct ofp_header *oh)
return b.size / sizeof(struct ofputil_ipfix_stats);
}
+
+static void
+print_ipfix_stat(struct ds *string, const char *leader, uint64_t stat,
+ int more)
+{
+ ds_put_cstr(string, leader);
+ if (stat != UINT64_MAX) {
+ ds_put_format(string, "%"PRIu64, stat);
+ } else {
+ ds_put_char(string, '?');
+ }
+ if (more) {
+ ds_put_cstr(string, ", ");
+ } else {
+ ds_put_cstr(string, "\n");
+ }
+}
+
+static void
+format_ipfix_stats(struct ds *string, const struct ofputil_ipfix_stats *is,
+ int indent)
+{
+ print_ipfix_stat(string, "flows=", is->total_flows, 1);
+ print_ipfix_stat(string, "current flows=", is->current_flows, 1);
+ print_ipfix_stat(string, "sampled pkts=", is->pkts, 1);
+ print_ipfix_stat(string, "ipv4 ok=", is->ipv4_pkts, 1);
+ print_ipfix_stat(string, "ipv6 ok=", is->ipv6_pkts, 1);
+ print_ipfix_stat(string, "tx pkts=", is->tx_pkts, 0);
+ ds_put_char_multiple(string, ' ', indent);
+ print_ipfix_stat(string, "pkts errs=", is->error_pkts, 1);
+ print_ipfix_stat(string, "ipv4 errs=", is->ipv4_error_pkts, 1);
+ print_ipfix_stat(string, "ipv6 errs=", is->ipv6_error_pkts, 1);
+ print_ipfix_stat(string, "tx errs=", is->tx_errors, 0);
+}
+
+void
+ofputil_format_ipfix_stats_bridge(struct ds *string,
+ const struct ofputil_ipfix_stats *is)
+{
+ ds_put_cstr(string, "\n bridge ipfix: ");
+ format_ipfix_stats(string, is, 16);
+}
+
+void
+ofputil_format_ipfix_stats_flow(struct ds *string,
+ const struct ofputil_ipfix_stats *is)
+{
+ ds_put_cstr(string, " id");
+ ds_put_format(string, " %3"PRIuSIZE": ", (size_t) is->collector_set_id);
+ format_ipfix_stats(string, is, 10);
+}
diff --git a/lib/ofp-match.c b/lib/ofp-match.c
index 3a46b3978..e83fa9086 100644
--- a/lib/ofp-match.c
+++ b/lib/ofp-match.c
@@ -724,6 +724,46 @@ ofputil_decode_tlv_table_mod(const struct ofp_header *oh,
&ttm->mappings);
}
+static void
+print_tlv_table(struct ds *s, const struct ovs_list *mappings)
+{
+ struct ofputil_tlv_map *map;
+
+ ds_put_cstr(s, " mapping table:\n");
+ ds_put_cstr(s, " class type length match field\n");
+ ds_put_cstr(s, " ------ ---- ------ --------------");
+
+ LIST_FOR_EACH (map, list_node, mappings) {
+ ds_put_format(s, "\n %#6"PRIx16" %#4"PRIx8" %6"PRIu8" "
+ "tun_metadata%"PRIu16,
+ map->option_class, map->option_type, map->option_len,
+ map->index);
+ }
+}
+
+void
+ofputil_format_tlv_table_mod(struct ds *s,
+ const struct ofputil_tlv_table_mod *ttm)
+{
+ ds_put_cstr(s, "\n ");
+
+ switch (ttm->command) {
+ case NXTTMC_ADD:
+ ds_put_cstr(s, "ADD");
+ break;
+ case NXTTMC_DELETE:
+ ds_put_cstr(s, "DEL");
+ break;
+ case NXTTMC_CLEAR:
+ ds_put_cstr(s, "CLEAR");
+ break;
+ }
+
+ if (ttm->command != NXTTMC_CLEAR) {
+ print_tlv_table(s, &ttm->mappings);
+ }
+}
+
struct ofpbuf *
ofputil_encode_tlv_table_reply(const struct ofp_header *oh,
struct ofputil_tlv_table_reply *ttr)
@@ -796,6 +836,25 @@ parse_ofp_tlv_table_mod_str(struct ofputil_tlv_table_mod *ttm,
}
void
+ofputil_format_tlv_table_reply(struct ds *s,
+ const struct ofputil_tlv_table_reply *ttr)
+{
+ ds_put_char(s, '\n');
+
+ const struct ofputil_tlv_map *map;
+ int allocated_space = 0;
+ LIST_FOR_EACH (map, list_node, &ttr->mappings) {
+ allocated_space += map->option_len;
+ }
+
+ ds_put_format(s, " max option space=%"PRIu32" max fields=%"PRIu16"\n",
+ ttr->max_option_space, ttr->max_fields);
+ ds_put_format(s, " allocated option space=%d\n", allocated_space);
+ ds_put_char(s, '\n');
+ print_tlv_table(s, &ttr->mappings);
+}
+
+void
ofputil_uninit_tlv_table(struct ovs_list *mappings)
{
struct ofputil_tlv_map *map;
diff --git a/lib/ofp-meter.c b/lib/ofp-meter.c
index de6f2b3a0..e63daabaf 100644
--- a/lib/ofp-meter.c
+++ b/lib/ofp-meter.c
@@ -21,6 +21,7 @@
#include "openvswitch/ofp-errors.h"
#include "openvswitch/ofp-msgs.h"
#include "openvswitch/ofp-parse.h"
+#include "openvswitch/ofp-print.h"
#include "openvswitch/ofpbuf.h"
#include "openvswitch/vlog.h"
@@ -28,6 +29,56 @@ VLOG_DEFINE_THIS_MODULE(ofp_meter);
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
+void
+ofputil_format_meter_id(struct ds *s, uint32_t meter_id, char separator)
+{
+ if (meter_id <= OFPM13_MAX) {
+ ds_put_format(s, "meter%c%"PRIu32, separator, meter_id);
+ } else {
+ const char *name;
+ switch (meter_id) {
+ case OFPM13_SLOWPATH:
+ name = "slowpath";
+ break;
+ case OFPM13_CONTROLLER:
+ name = "controller";
+ break;
+ case OFPM13_ALL:
+ name = "all";
+ break;
+ default:
+ name = "unknown";
+ }
+ ds_put_format(s, "meter%c%s", separator, name);
+ }
+}
+
+void
+ofputil_format_meter_band(struct ds *s, enum ofp13_meter_flags flags,
+ const struct ofputil_meter_band *mb)
+{
+ ds_put_cstr(s, "\ntype=");
+ switch (mb->type) {
+ case OFPMBT13_DROP:
+ ds_put_cstr(s, "drop");
+ break;
+ case OFPMBT13_DSCP_REMARK:
+ ds_put_cstr(s, "dscp_remark");
+ break;
+ default:
+ ds_put_format(s, "%u", mb->type);
+ }
+
+ ds_put_format(s, " rate=%"PRIu32, mb->rate);
+
+ if (flags & OFPMF13_BURST) {
+ ds_put_format(s, " burst_size=%"PRIu32, mb->burst_size);
+ }
+ if (mb->type == OFPMBT13_DSCP_REMARK) {
+ ds_put_format(s, " prec_level=%"PRIu8, mb->prec_level);
+ }
+}
+
static enum ofperr
ofputil_pull_bands(struct ofpbuf *msg, size_t len, uint16_t *n_bands,
struct ofpbuf *bands)
@@ -268,6 +319,46 @@ ofputil_decode_meter_config(struct ofpbuf *msg,
return 0;
}
+static void
+ofp_print_meter_flags(struct ds *s, enum ofp13_meter_flags flags)
+{
+ if (flags & OFPMF13_KBPS) {
+ ds_put_cstr(s, "kbps ");
+ }
+ if (flags & OFPMF13_PKTPS) {
+ ds_put_cstr(s, "pktps ");
+ }
+ if (flags & OFPMF13_BURST) {
+ ds_put_cstr(s, "burst ");
+ }
+ if (flags & OFPMF13_STATS) {
+ ds_put_cstr(s, "stats ");
+ }
+
+ flags &= ~(OFPMF13_KBPS | OFPMF13_PKTPS | OFPMF13_BURST | OFPMF13_STATS);
+ if (flags) {
+ ds_put_format(s, "flags:0x%"PRIx16" ", flags);
+ }
+}
+
+void
+ofputil_format_meter_config(struct ds *s,
+ const struct ofputil_meter_config *mc)
+{
+ uint16_t i;
+
+ ofputil_format_meter_id(s, mc->meter_id, '=');
+ ds_put_char(s, ' ');
+
+ ofp_print_meter_flags(s, mc->flags);
+
+ ds_put_cstr(s, "bands=");
+ for (i = 0; i < mc->n_bands; ++i) {
+ ofputil_format_meter_band(s, mc->flags, &mc->bands[i]);
+ }
+ ds_put_char(s, '\n');
+}
+
static enum ofperr
ofputil_pull_band_stats(struct ofpbuf *msg, size_t len, uint16_t *n_bands,
struct ofpbuf *bands)
@@ -348,6 +439,28 @@ ofputil_decode_meter_stats(struct ofpbuf *msg,
}
void
+ofputil_format_meter_stats(struct ds *s, const struct ofputil_meter_stats *ms)
+{
+ uint16_t i;
+
+ ofputil_format_meter_id(s, ms->meter_id, ':');
+ ds_put_char(s, ' ');
+ ds_put_format(s, "flow_count:%"PRIu32" ", ms->flow_count);
+ ds_put_format(s, "packet_in_count:%"PRIu64" ", ms->packet_in_count);
+ ds_put_format(s, "byte_in_count:%"PRIu64" ", ms->byte_in_count);
+ ds_put_cstr(s, "duration:");
+ ofp_print_duration(s, ms->duration_sec, ms->duration_nsec);
+ ds_put_char(s, ' ');
+
+ ds_put_cstr(s, "bands:\n");
+ for (i = 0; i < ms->n_bands; ++i) {
+ ds_put_format(s, "%d: ", i);
+ ds_put_format(s, "packet_count:%"PRIu64" ", ms->bands[i].packet_count);
+ ds_put_format(s, "byte_count:%"PRIu64"\n", ms->bands[i].byte_count);
+ }
+}
+
+void
ofputil_decode_meter_features(const struct ofp_header *oh,
struct ofputil_meter_features *mf)
{
@@ -379,6 +492,51 @@ ofputil_encode_meter_features_reply(const struct ofputil_meter_features *mf,
return reply;
}
+static const char *
+ofputil_meter_band_types_to_name(uint32_t bit)
+{
+ switch (bit) {
+ case 1 << OFPMBT13_DROP: return "drop";
+ case 1 << OFPMBT13_DSCP_REMARK: return "dscp_remark";
+ }
+
+ return NULL;
+}
+
+static const char *
+ofputil_meter_capabilities_to_name(uint32_t bit)
+{
+ enum ofp13_meter_flags flag = bit;
+
+ switch (flag) {
+ case OFPMF13_KBPS: return "kbps";
+ case OFPMF13_PKTPS: return "pktps";
+ case OFPMF13_BURST: return "burst";
+ case OFPMF13_STATS: return "stats";
+ }
+
+ return NULL;
+}
+
+void
+ofputil_format_meter_features(struct ds *s,
+ const struct ofputil_meter_features *mf)
+{
+ ds_put_format(s, "\nmax_meter:%"PRIu32, mf->max_meters);
+ ds_put_format(s, " max_bands:%"PRIu8, mf->max_bands);
+ ds_put_format(s, " max_color:%"PRIu8"\n", mf->max_color);
+
+ ds_put_cstr(s, "band_types: ");
+ ofp_print_bit_names(s, mf->band_types,
+ ofputil_meter_band_types_to_name, ' ');
+ ds_put_char(s, '\n');
+
+ ds_put_cstr(s, "capabilities: ");
+ ofp_print_bit_names(s, mf->capabilities,
+ ofputil_meter_capabilities_to_name, ' ');
+ ds_put_char(s, '\n');
+}
+
struct ofpbuf *
ofputil_encode_meter_mod(enum ofp_version ofp_version,
const struct ofputil_meter_mod *mm)
@@ -629,3 +787,23 @@ parse_ofp_meter_mod_str(struct ofputil_meter_mod *mm, const char *str_,
return error;
}
+
+void
+ofputil_format_meter_mod(struct ds *s, const struct ofputil_meter_mod *mm)
+{
+ switch (mm->command) {
+ case OFPMC13_ADD:
+ ds_put_cstr(s, " ADD ");
+ break;
+ case OFPMC13_MODIFY:
+ ds_put_cstr(s, " MOD ");
+ break;
+ case OFPMC13_DELETE:
+ ds_put_cstr(s, " DEL ");
+ break;
+ default:
+ ds_put_format(s, " cmd:%d ", mm->command);
+ }
+
+ ofputil_format_meter_config(s, &mm->meter);
+}
diff --git a/lib/ofp-monitor.c b/lib/ofp-monitor.c
index 3d117cae8..3e02834a2 100644
--- a/lib/ofp-monitor.c
+++ b/lib/ofp-monitor.c
@@ -880,6 +880,33 @@ ofputil_decode_requestforward(const struct ofp_header *outer,
return 0;
}
+void
+ofputil_format_requestforward(struct ds *string,
+ enum ofp_version ofp_version,
+ const struct ofputil_requestforward *rf,
+ const struct ofputil_port_map *port_map,
+ const struct ofputil_table_map *table_map)
+{
+ ds_put_cstr(string, " reason=");
+
+ switch (rf->reason) {
+ case OFPRFR_GROUP_MOD:
+ ds_put_cstr(string, "group_mod");
+ ofputil_group_mod_format__(string, ofp_version, rf->group_mod,
+ port_map, table_map);
+ break;
+
+ case OFPRFR_METER_MOD:
+ ds_put_cstr(string, "meter_mod");
+ ofputil_format_meter_mod(string, rf->meter_mod);
+ break;
+
+ case OFPRFR_N_REASONS:
+ OVS_NOT_REACHED();
+ }
+}
+
+
/* Frees the content of 'rf', which should have been initialized through a
* successful call to ofputil_decode_requestforward(). */
void
diff --git a/lib/ofp-port.c b/lib/ofp-port.c
index 4d39299ed..eb5b91029 100644
--- a/lib/ofp-port.c
+++ b/lib/ofp-port.c
@@ -1815,6 +1815,151 @@ ofputil_decode_port_stats(struct ofputil_port_stats *ps, struct ofpbuf *msg)
return OFPERR_OFPBRC_BAD_LEN;
}
+static void
+print_port_stat(struct ds *string, const char *leader, uint64_t stat, int more)
+{
+ ds_put_cstr(string, leader);
+ if (stat != UINT64_MAX) {
+ ds_put_format(string, "%"PRIu64, stat);
+ } else {
+ ds_put_char(string, '?');
+ }
+ if (more) {
+ ds_put_cstr(string, ", ");
+ } else {
+ ds_put_cstr(string, "\n");
+ }
+}
+
+static void
+print_port_stat_cond(struct ds *string, const char *leader, uint64_t stat)
+{
+ if (stat != UINT64_MAX) {
+ ds_put_format(string, "%s%"PRIu64", ", leader, stat);
+ }
+}
+
+void
+ofputil_format_port_stats(struct ds *string,
+ const struct ofputil_port_stats *ps,
+ const struct ofputil_port_map *port_map)
+{
+ ds_put_cstr(string, " port ");
+ if (ofp_to_u16(ps->port_no) < 10) {
+ ds_put_char(string, ' ');
+ }
+ ofputil_format_port(ps->port_no, port_map, string);
+
+ ds_put_cstr(string, ": rx ");
+ print_port_stat(string, "pkts=", ps->stats.rx_packets, 1);
+ print_port_stat(string, "bytes=", ps->stats.rx_bytes, 1);
+ print_port_stat(string, "drop=", ps->stats.rx_dropped, 1);
+ print_port_stat(string, "errs=", ps->stats.rx_errors, 1);
+ print_port_stat(string, "frame=", ps->stats.rx_frame_errors, 1);
+ print_port_stat(string, "over=", ps->stats.rx_over_errors, 1);
+ print_port_stat(string, "crc=", ps->stats.rx_crc_errors, 0);
+
+ ds_put_cstr(string, " tx ");
+ print_port_stat(string, "pkts=", ps->stats.tx_packets, 1);
+ print_port_stat(string, "bytes=", ps->stats.tx_bytes, 1);
+ print_port_stat(string, "drop=", ps->stats.tx_dropped, 1);
+ print_port_stat(string, "errs=", ps->stats.tx_errors, 1);
+ print_port_stat(string, "coll=", ps->stats.collisions, 0);
+
+ if (ps->duration_sec != UINT32_MAX) {
+ ds_put_cstr(string, " duration=");
+ ofp_print_duration(string, ps->duration_sec, ps->duration_nsec);
+ ds_put_char(string, '\n');
+ }
+ struct ds string_ext_stats = DS_EMPTY_INITIALIZER;
+
+ ds_init(&string_ext_stats);
+
+ print_port_stat_cond(&string_ext_stats, "1_to_64_packets=",
+ ps->stats.rx_1_to_64_packets);
+ print_port_stat_cond(&string_ext_stats, "65_to_127_packets=",
+ ps->stats.rx_65_to_127_packets);
+ print_port_stat_cond(&string_ext_stats, "128_to_255_packets=",
+ ps->stats.rx_128_to_255_packets);
+ print_port_stat_cond(&string_ext_stats, "256_to_511_packets=",
+ ps->stats.rx_256_to_511_packets);
+ print_port_stat_cond(&string_ext_stats, "512_to_1023_packets=",
+ ps->stats.rx_512_to_1023_packets);
+ print_port_stat_cond(&string_ext_stats, "1024_to_1522_packets=",
+ ps->stats.rx_1024_to_1522_packets);
+ print_port_stat_cond(&string_ext_stats, "1523_to_max_packets=",
+ ps->stats.rx_1523_to_max_packets);
+ print_port_stat_cond(&string_ext_stats, "broadcast_packets=",
+ ps->stats.rx_broadcast_packets);
+ print_port_stat_cond(&string_ext_stats, "undersized_errors=",
+ ps->stats.rx_undersized_errors);
+ print_port_stat_cond(&string_ext_stats, "oversize_errors=",
+ ps->stats.rx_oversize_errors);
+ print_port_stat_cond(&string_ext_stats, "rx_fragmented_errors=",
+ ps->stats.rx_fragmented_errors);
+ print_port_stat_cond(&string_ext_stats, "rx_jabber_errors=",
+ ps->stats.rx_jabber_errors);
+
+ if (string_ext_stats.length != 0) {
+ /* If at least one statistics counter is reported: */
+ ds_put_cstr(string, " rx rfc2819 ");
+ ds_put_buffer(string, string_ext_stats.string,
+ string_ext_stats.length);
+ ds_put_cstr(string, "\n");
+ ds_destroy(&string_ext_stats);
+ }
+
+ ds_init(&string_ext_stats);
+
+ print_port_stat_cond(&string_ext_stats, "1_to_64_packets=",
+ ps->stats.tx_1_to_64_packets);
+ print_port_stat_cond(&string_ext_stats, "65_to_127_packets=",
+ ps->stats.tx_65_to_127_packets);
+ print_port_stat_cond(&string_ext_stats, "128_to_255_packets=",
+ ps->stats.tx_128_to_255_packets);
+ print_port_stat_cond(&string_ext_stats, "256_to_511_packets=",
+ ps->stats.tx_256_to_511_packets);
+ print_port_stat_cond(&string_ext_stats, "512_to_1023_packets=",
+ ps->stats.tx_512_to_1023_packets);
+ print_port_stat_cond(&string_ext_stats, "1024_to_1522_packets=",
+ ps->stats.tx_1024_to_1522_packets);
+ print_port_stat_cond(&string_ext_stats, "1523_to_max_packets=",
+ ps->stats.tx_1523_to_max_packets);
+ print_port_stat_cond(&string_ext_stats, "multicast_packets=",
+ ps->stats.tx_multicast_packets);
+ print_port_stat_cond(&string_ext_stats, "broadcast_packets=",
+ ps->stats.tx_broadcast_packets);
+
+ if (string_ext_stats.length != 0) {
+ /* If at least one statistics counter is reported: */
+ ds_put_cstr(string, " tx rfc2819 ");
+ ds_put_buffer(string, string_ext_stats.string,
+ string_ext_stats.length);
+ ds_put_cstr(string, "\n");
+ ds_destroy(&string_ext_stats);
+ }
+
+ if (ps->custom_stats.size) {
+ ds_put_cstr(string, " CUSTOM Statistics");
+ for (int i = 0; i < ps->custom_stats.size; i++) {
+ /* 3 counters in the row */
+ if (ps->custom_stats.counters[i].name[0]) {
+ if (i % 3 == 0) {
+ ds_put_cstr(string, "\n");
+ ds_put_cstr(string, " ");
+ } else {
+ ds_put_char(string, ' ');
+ }
+ ds_put_format(string, "%s=%"PRIu64",",
+ ps->custom_stats.counters[i].name,
+ ps->custom_stats.counters[i].value);
+ }
+ }
+ ds_put_cstr(string, "\n");
+ }
+}
+
+
/* Parse a port status request message into a 16 bit OpenFlow 1.0
* port number and stores the latter in '*ofp10_port'.
* Returns 0 if successful, otherwise an OFPERR_* number. */
diff --git a/lib/ofp-print.c b/lib/ofp-print.c
index 05a39c22b..cf93d2e2c 100644
--- a/lib/ofp-print.c
+++ b/lib/ofp-print.c
@@ -64,7 +64,6 @@
#include "util.h"
#include "uuid.h"
-static void ofp_print_queue_name(struct ds *string, uint32_t port);
static void ofp_print_error(struct ds *, enum ofperr);
/* Returns a string that represents the contents of the Ethernet frame in the
@@ -320,256 +319,11 @@ ofp_print_table_status_message(struct ds *string, const struct ofp_header *oh,
const struct ofputil_table_map *table_map)
{
struct ofputil_table_status ts;
- enum ofperr error;
-
- error = ofputil_decode_table_status(oh, &ts);
- if (error) {
- return error;
- }
-
- if (ts.reason == OFPTR_VACANCY_DOWN) {
- ds_put_format(string, " reason=VACANCY_DOWN");
- } else if (ts.reason == OFPTR_VACANCY_UP) {
- ds_put_format(string, " reason=VACANCY_UP");
- }
-
- ds_put_format(string, "\ntable_desc:-");
- ofputil_table_desc_format(string, &ts.desc, table_map);
-
- return 0;
-}
-
-static enum ofperr
-ofp_print_queue_get_config_request(struct ds *string,
- const struct ofp_header *oh,
- const struct ofputil_port_map *port_map)
-{
- enum ofperr error;
- ofp_port_t port;
- uint32_t queue;
-
- error = ofputil_decode_queue_get_config_request(oh, &port, &queue);
- if (error) {
- return error;
- }
-
- ds_put_cstr(string, " port=");
- ofputil_format_port(port, port_map, string);
-
- if (queue != OFPQ_ALL) {
- ds_put_cstr(string, " queue=");
- ofp_print_queue_name(string, queue);
- }
-
- return 0;
-}
-
-static void
-print_queue_rate(struct ds *string, const char *name, unsigned int rate)
-{
- if (rate <= 1000) {
- ds_put_format(string, " %s:%u.%u%%", name, rate / 10, rate % 10);
- } else if (rate < UINT16_MAX) {
- ds_put_format(string, " %s:(disabled)", name);
- }
-}
-
-/* qsort comparison function. */
-static int
-compare_queues(const void *a_, const void *b_)
-{
- const struct ofputil_queue_config *a = a_;
- const struct ofputil_queue_config *b = b_;
-
- uint16_t ap = ofp_to_u16(a->port);
- uint16_t bp = ofp_to_u16(b->port);
- if (ap != bp) {
- return ap < bp ? -1 : 1;
- }
-
- uint32_t aq = a->queue;
- uint32_t bq = b->queue;
- return aq < bq ? -1 : aq > bq;
-}
-
-static enum ofperr
-ofp_print_queue_get_config_reply(struct ds *string,
- const struct ofp_header *oh,
- const struct ofputil_port_map *port_map)
-{
- struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
-
- struct ofputil_queue_config *queues = NULL;
- size_t allocated_queues = 0;
- size_t n = 0;
-
- int retval = 0;
- for (;;) {
- if (n >= allocated_queues) {
- queues = x2nrealloc(queues, &allocated_queues, sizeof *queues);
- }
- retval = ofputil_pull_queue_get_config_reply(&b, &queues[n]);
- if (retval) {
- break;
- }
- n++;
- }
-
- qsort(queues, n, sizeof *queues, compare_queues);
-
- ds_put_char(string, ' ');
-
- ofp_port_t port = 0;
- for (const struct ofputil_queue_config *q = queues; q < &queues[n]; q++) {
- if (q->port != port) {
- port = q->port;
-
- ds_put_cstr(string, "port=");
- ofputil_format_port(port, port_map, string);
- ds_put_char(string, '\n');
- }
-
- ds_put_format(string, "queue %"PRIu32":", q->queue);
- print_queue_rate(string, "min_rate", q->min_rate);
- print_queue_rate(string, "max_rate", q->max_rate);
- ds_put_char(string, '\n');
- }
-
- ds_chomp(string, ' ');
- free(queues);
-
- return retval != EOF ? retval : 0;
-}
-
-static void
-ofp_print_meter_flags(struct ds *s, uint16_t flags)
-{
- if (flags & OFPMF13_KBPS) {
- ds_put_cstr(s, "kbps ");
- }
- if (flags & OFPMF13_PKTPS) {
- ds_put_cstr(s, "pktps ");
- }
- if (flags & OFPMF13_BURST) {
- ds_put_cstr(s, "burst ");
- }
- if (flags & OFPMF13_STATS) {
- ds_put_cstr(s, "stats ");
- }
-
- flags &= ~(OFPMF13_KBPS | OFPMF13_PKTPS | OFPMF13_BURST | OFPMF13_STATS);
- if (flags) {
- ds_put_format(s, "flags:0x%"PRIx16" ", flags);
- }
-}
-
-static void
-ofp_print_meter_band(struct ds *s, uint16_t flags,
- const struct ofputil_meter_band *mb)
-{
- ds_put_cstr(s, "\ntype=");
- switch (mb->type) {
- case OFPMBT13_DROP:
- ds_put_cstr(s, "drop");
- break;
- case OFPMBT13_DSCP_REMARK:
- ds_put_cstr(s, "dscp_remark");
- break;
- default:
- ds_put_format(s, "%u", mb->type);
- }
-
- ds_put_format(s, " rate=%"PRIu32, mb->rate);
-
- if (flags & OFPMF13_BURST) {
- ds_put_format(s, " burst_size=%"PRIu32, mb->burst_size);
- }
- if (mb->type == OFPMBT13_DSCP_REMARK) {
- ds_put_format(s, " prec_level=%"PRIu8, mb->prec_level);
- }
-}
-
-static void
-ofp_print_meter_id(struct ds *s, uint32_t meter_id, char seperator)
-{
- if (meter_id <= OFPM13_MAX) {
- ds_put_format(s, "meter%c%"PRIu32, seperator, meter_id);
- } else {
- const char *name;
- switch (meter_id) {
- case OFPM13_SLOWPATH:
- name = "slowpath";
- break;
- case OFPM13_CONTROLLER:
- name = "controller";
- break;
- case OFPM13_ALL:
- name = "all";
- break;
- default:
- name = "unknown";
- }
- ds_put_format(s, "meter%c%s", seperator, name);
- }
-}
-
-static void
-ofp_print_meter_stats(struct ds *s, const struct ofputil_meter_stats *ms)
-{
- uint16_t i;
-
- ofp_print_meter_id(s, ms->meter_id, ':');
- ds_put_char(s, ' ');
- ds_put_format(s, "flow_count:%"PRIu32" ", ms->flow_count);
- ds_put_format(s, "packet_in_count:%"PRIu64" ", ms->packet_in_count);
- ds_put_format(s, "byte_in_count:%"PRIu64" ", ms->byte_in_count);
- ds_put_cstr(s, "duration:");
- ofp_print_duration(s, ms->duration_sec, ms->duration_nsec);
- ds_put_char(s, ' ');
-
- ds_put_cstr(s, "bands:\n");
- for (i = 0; i < ms->n_bands; ++i) {
- ds_put_format(s, "%d: ", i);
- ds_put_format(s, "packet_count:%"PRIu64" ", ms->bands[i].packet_count);
- ds_put_format(s, "byte_count:%"PRIu64"\n", ms->bands[i].byte_count);
- }
-}
-
-static void
-ofp_print_meter_config(struct ds *s, const struct ofputil_meter_config *mc)
-{
- uint16_t i;
-
- ofp_print_meter_id(s, mc->meter_id, '=');
- ds_put_char(s, ' ');
-
- ofp_print_meter_flags(s, mc->flags);
-
- ds_put_cstr(s, "bands=");
- for (i = 0; i < mc->n_bands; ++i) {
- ofp_print_meter_band(s, mc->flags, &mc->bands[i]);
- }
- ds_put_char(s, '\n');
-}
-
-static void
-ofp_print_meter_mod__(struct ds *s, const struct ofputil_meter_mod *mm)
-{
- switch (mm->command) {
- case OFPMC13_ADD:
- ds_put_cstr(s, " ADD ");
- break;
- case OFPMC13_MODIFY:
- ds_put_cstr(s, " MOD ");
- break;
- case OFPMC13_DELETE:
- ds_put_cstr(s, " DEL ");
- break;
- default:
- ds_put_format(s, " cmd:%d ", mm->command);
+ enum ofperr error = ofputil_decode_table_status(oh, &ts);
+ if (!error) {
+ ofputil_format_table_status(string, &ts, table_map);
}
-
- ofp_print_meter_config(s, &mm->meter);
+ return error;
}
static enum ofperr
@@ -577,12 +331,11 @@ ofp_print_meter_mod(struct ds *s, const struct ofp_header *oh)
{
struct ofputil_meter_mod mm;
struct ofpbuf bands;
- enum ofperr error;
ofpbuf_init(&bands, 64);
- error = ofputil_decode_meter_mod(oh, &mm, &bands);
+ enum ofperr error = ofputil_decode_meter_mod(oh, &mm, &bands);
if (!error) {
- ofp_print_meter_mod__(s, &mm);
+ ofputil_format_meter_mod(s, &mm);
}
ofpbuf_uninit(&bands);
@@ -597,58 +350,17 @@ ofp_print_meter_stats_request(struct ds *s, const struct ofp_header *oh)
ofputil_decode_meter_request(oh, &meter_id);
ds_put_char(s, ' ');
- ofp_print_meter_id(s, meter_id, '=');
+ ofputil_format_meter_id(s, meter_id, '=');
return 0;
}
-static const char *
-ofputil_meter_capabilities_to_name(uint32_t bit)
-{
- enum ofp13_meter_flags flag = bit;
-
- switch (flag) {
- case OFPMF13_KBPS: return "kbps";
- case OFPMF13_PKTPS: return "pktps";
- case OFPMF13_BURST: return "burst";
- case OFPMF13_STATS: return "stats";
- }
-
- return NULL;
-}
-
-static const char *
-ofputil_meter_band_types_to_name(uint32_t bit)
-{
- switch (bit) {
- case 1 << OFPMBT13_DROP: return "drop";
- case 1 << OFPMBT13_DSCP_REMARK: return "dscp_remark";
- }
-
- return NULL;
-}
-
static enum ofperr
ofp_print_meter_features_reply(struct ds *s, const struct ofp_header *oh)
{
struct ofputil_meter_features mf;
-
ofputil_decode_meter_features(oh, &mf);
-
- ds_put_format(s, "\nmax_meter:%"PRIu32, mf.max_meters);
- ds_put_format(s, " max_bands:%"PRIu8, mf.max_bands);
- ds_put_format(s, " max_color:%"PRIu8"\n", mf.max_color);
-
- ds_put_cstr(s, "band_types: ");
- ofp_print_bit_names(s, mf.band_types,
- ofputil_meter_band_types_to_name, ' ');
- ds_put_char(s, '\n');
-
- ds_put_cstr(s, "capabilities: ");
- ofp_print_bit_names(s, mf.capabilities,
- ofputil_meter_capabilities_to_name, ' ');
- ds_put_char(s, '\n');
-
+ ofputil_format_meter_features(s, &mf);
return 0;
}
@@ -668,7 +380,7 @@ ofp_print_meter_config_reply(struct ds *s, const struct ofp_header *oh)
break;
}
ds_put_char(s, '\n');
- ofp_print_meter_config(s, &mc);
+ ofputil_format_meter_config(s, &mc);
}
ofpbuf_uninit(&bands);
@@ -691,7 +403,7 @@ ofp_print_meter_stats_reply(struct ds *s, const struct ofp_header *oh)
break;
}
ds_put_char(s, '\n');
- ofp_print_meter_stats(s, &ms);
+ ofputil_format_meter_stats(s, &ms);
}
ofpbuf_uninit(&bands);
@@ -810,30 +522,6 @@ ofp_print_aggregate_stats_reply(struct ds *string, const struct ofp_header *oh)
return error;
}
-static void
-print_port_stat(struct ds *string, const char *leader, uint64_t stat, int more)
-{
- ds_put_cstr(string, leader);
- if (stat != UINT64_MAX) {
- ds_put_format(string, "%"PRIu64, stat);
- } else {
- ds_put_char(string, '?');
- }
- if (more) {
- ds_put_cstr(string, ", ");
- } else {
- ds_put_cstr(string, "\n");
- }
-}
-
-static void
-print_port_stat_cond(struct ds *string, const char *leader, uint64_t stat)
-{
- if (stat != UINT64_MAX) {
- ds_put_format(string, "%s%"PRIu64", ", leader, stat);
- }
-}
-
static enum ofperr
ofp_print_ofpst_port_request(struct ds *string, const struct ofp_header *oh,
const struct ofputil_port_map *port_map)
@@ -857,8 +545,8 @@ ofp_print_ofpst_port_reply(struct ds *string, const struct ofp_header *oh,
const struct ofputil_port_map *port_map,
int verbosity)
{
- uint32_t i;
- ds_put_format(string, " %"PRIuSIZE" ports\n", ofputil_count_port_stats(oh));
+ ds_put_format(string, " %"PRIuSIZE" ports\n",
+ ofputil_count_port_stats(oh));
if (verbosity < 1) {
return 0;
}
@@ -872,120 +560,7 @@ ofp_print_ofpst_port_reply(struct ds *string, const struct ofp_header *oh,
if (retval) {
return retval != EOF ? retval : 0;
}
-
- ds_put_cstr(string, " port ");
- if (ofp_to_u16(ps.port_no) < 10) {
- ds_put_char(string, ' ');
- }
- ofputil_format_port(ps.port_no, port_map, string);
-
- ds_put_cstr(string, ": rx ");
- print_port_stat(string, "pkts=", ps.stats.rx_packets, 1);
- print_port_stat(string, "bytes=", ps.stats.rx_bytes, 1);
- print_port_stat(string, "drop=", ps.stats.rx_dropped, 1);
- print_port_stat(string, "errs=", ps.stats.rx_errors, 1);
- print_port_stat(string, "frame=", ps.stats.rx_frame_errors, 1);
- print_port_stat(string, "over=", ps.stats.rx_over_errors, 1);
- print_port_stat(string, "crc=", ps.stats.rx_crc_errors, 0);
-
- ds_put_cstr(string, " tx ");
- print_port_stat(string, "pkts=", ps.stats.tx_packets, 1);
- print_port_stat(string, "bytes=", ps.stats.tx_bytes, 1);
- print_port_stat(string, "drop=", ps.stats.tx_dropped, 1);
- print_port_stat(string, "errs=", ps.stats.tx_errors, 1);
- print_port_stat(string, "coll=", ps.stats.collisions, 0);
-
- if (ps.duration_sec != UINT32_MAX) {
- ds_put_cstr(string, " duration=");
- ofp_print_duration(string, ps.duration_sec, ps.duration_nsec);
- ds_put_char(string, '\n');
- }
- struct ds string_ext_stats = DS_EMPTY_INITIALIZER;
-
- ds_init(&string_ext_stats);
-
- print_port_stat_cond(&string_ext_stats, "1_to_64_packets=",
- ps.stats.rx_1_to_64_packets);
- print_port_stat_cond(&string_ext_stats, "65_to_127_packets=",
- ps.stats.rx_65_to_127_packets);
- print_port_stat_cond(&string_ext_stats, "128_to_255_packets=",
- ps.stats.rx_128_to_255_packets);
- print_port_stat_cond(&string_ext_stats, "256_to_511_packets=",
- ps.stats.rx_256_to_511_packets);
- print_port_stat_cond(&string_ext_stats, "512_to_1023_packets=",
- ps.stats.rx_512_to_1023_packets);
- print_port_stat_cond(&string_ext_stats, "1024_to_1522_packets=",
- ps.stats.rx_1024_to_1522_packets);
- print_port_stat_cond(&string_ext_stats, "1523_to_max_packets=",
- ps.stats.rx_1523_to_max_packets);
- print_port_stat_cond(&string_ext_stats, "broadcast_packets=",
- ps.stats.rx_broadcast_packets);
- print_port_stat_cond(&string_ext_stats, "undersized_errors=",
- ps.stats.rx_undersized_errors);
- print_port_stat_cond(&string_ext_stats, "oversize_errors=",
- ps.stats.rx_oversize_errors);
- print_port_stat_cond(&string_ext_stats, "rx_fragmented_errors=",
- ps.stats.rx_fragmented_errors);
- print_port_stat_cond(&string_ext_stats, "rx_jabber_errors=",
- ps.stats.rx_jabber_errors);
-
- if (string_ext_stats.length != 0) {
- /* If at least one statistics counter is reported: */
- ds_put_cstr(string, " rx rfc2819 ");
- ds_put_buffer(string, string_ext_stats.string,
- string_ext_stats.length);
- ds_put_cstr(string, "\n");
- ds_destroy(&string_ext_stats);
- }
-
- ds_init(&string_ext_stats);
-
- print_port_stat_cond(&string_ext_stats, "1_to_64_packets=",
- ps.stats.tx_1_to_64_packets);
- print_port_stat_cond(&string_ext_stats, "65_to_127_packets=",
- ps.stats.tx_65_to_127_packets);
- print_port_stat_cond(&string_ext_stats, "128_to_255_packets=",
- ps.stats.tx_128_to_255_packets);
- print_port_stat_cond(&string_ext_stats, "256_to_511_packets=",
- ps.stats.tx_256_to_511_packets);
- print_port_stat_cond(&string_ext_stats, "512_to_1023_packets=",
- ps.stats.tx_512_to_1023_packets);
- print_port_stat_cond(&string_ext_stats, "1024_to_1522_packets=",
- ps.stats.tx_1024_to_1522_packets);
- print_port_stat_cond(&string_ext_stats, "1523_to_max_packets=",
- ps.stats.tx_1523_to_max_packets);
- print_port_stat_cond(&string_ext_stats, "multicast_packets=",
- ps.stats.tx_multicast_packets);
- print_port_stat_cond(&string_ext_stats, "broadcast_packets=",
- ps.stats.tx_broadcast_packets);
-
- if (string_ext_stats.length != 0) {
- /* If at least one statistics counter is reported: */
- ds_put_cstr(string, " tx rfc2819 ");
- ds_put_buffer(string, string_ext_stats.string,
- string_ext_stats.length);
- ds_put_cstr(string, "\n");
- ds_destroy(&string_ext_stats);
- }
-
- if (ps.custom_stats.size) {
- ds_put_cstr(string, " CUSTOM Statistics");
- for (i = 0; i < ps.custom_stats.size; i++) {
- /* 3 counters in the row */
- if (ps.custom_stats.counters[i].name[0]) {
- if (i % 3 == 0) {
- ds_put_cstr(string, "\n");
- ds_put_cstr(string, " ");
- } else {
- ds_put_char(string, ' ');
- }
- ds_put_format(string, "%s=%"PRIu64",",
- ps.custom_stats.counters[i].name,
- ps.custom_stats.counters[i].value);
- }
- }
- ds_put_cstr(string, "\n");
- }
+ ofputil_format_port_stats(string, &ps, port_map);
}
}
@@ -1018,77 +593,6 @@ ofp_print_table_stats_reply(struct ds *string, const struct ofp_header *oh,
}
}
-static void
-ofp_print_queue_name(struct ds *string, uint32_t queue_id)
-{
- if (queue_id == OFPQ_ALL) {
- ds_put_cstr(string, "ALL");
- } else {
- ds_put_format(string, "%"PRIu32, queue_id);
- }
-}
-
-static enum ofperr
-ofp_print_ofpst_queue_request(struct ds *string, const struct ofp_header *oh,
- const struct ofputil_port_map *port_map)
-{
- struct ofputil_queue_stats_request oqsr;
- enum ofperr error;
-
- error = ofputil_decode_queue_stats_request(oh, &oqsr);
- if (error) {
- return error;
- }
-
- ds_put_cstr(string, " port=");
- ofputil_format_port(oqsr.port_no, port_map, string);
-
- ds_put_cstr(string, " queue=");
- ofp_print_queue_name(string, oqsr.queue_id);
-
- return 0;
-}
-
-static enum ofperr
-ofp_print_ofpst_queue_reply(struct ds *string, const struct ofp_header *oh,
- const struct ofputil_port_map *port_map,
- int verbosity)
-{
- ds_put_format(string, " %"PRIuSIZE" queues\n", ofputil_count_queue_stats(oh));
- if (verbosity < 1) {
- return 0;
- }
-
- struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
- for (;;) {
- struct ofputil_queue_stats qs;
- int retval;
-
- retval = ofputil_decode_queue_stats(&qs, &b);
- if (retval) {
- return retval != EOF ? retval : 0;
- }
-
- ds_put_cstr(string, " port ");
- ofputil_format_port(qs.port_no, port_map, string);
- ds_put_cstr(string, " queue ");
- ofp_print_queue_name(string, qs.queue_id);
- ds_put_cstr(string, ": ");
-
- print_port_stat(string, "bytes=", qs.tx_bytes, 1);
- print_port_stat(string, "pkts=", qs.tx_packets, 1);
- print_port_stat(string, "errors=", qs.tx_errors, 1);
-
- ds_put_cstr(string, "duration=");
- if (qs.duration_sec != UINT32_MAX) {
- ofp_print_duration(string, qs.duration_sec, qs.duration_nsec);
- } else {
- ds_put_char(string, '?');
- }
- ds_put_char(string, '\n');
- }
-}
-
static enum ofperr
ofp_print_ofpst_port_desc_request(struct ds *string,
const struct ofp_header *oh,
@@ -1150,82 +654,26 @@ ofp_print_echo(struct ds *string, const struct ofp_header *oh, int verbosity)
return 0;
}
-static void
-ofp_print_role_generic(struct ds *string, enum ofp12_controller_role role,
- uint64_t generation_id)
-{
- ds_put_cstr(string, " role=");
-
- switch (role) {
- case OFPCR12_ROLE_NOCHANGE:
- ds_put_cstr(string, "nochange");
- break;
- case OFPCR12_ROLE_EQUAL:
- ds_put_cstr(string, "equal"); /* OF 1.2 wording */
- break;
- case OFPCR12_ROLE_MASTER:
- ds_put_cstr(string, "master");
- break;
- case OFPCR12_ROLE_SLAVE:
- ds_put_cstr(string, "slave");
- break;
- default:
- OVS_NOT_REACHED();
- }
-
- if (generation_id != UINT64_MAX) {
- ds_put_format(string, " generation_id=%"PRIu64, generation_id);
- }
-}
-
static enum ofperr
ofp_print_role_message(struct ds *string, const struct ofp_header *oh)
{
struct ofputil_role_request rr;
- enum ofperr error;
-
- error = ofputil_decode_role_message(oh, &rr);
- if (error) {
- return error;
+ enum ofperr error = ofputil_decode_role_message(oh, &rr);
+ if (!error) {
+ ofputil_format_role_message(string, &rr);
}
-
- ofp_print_role_generic(string, rr.role, rr.have_generation_id ? rr.generation_id : UINT64_MAX);
-
- return 0;
+ return error;
}
static enum ofperr
ofp_print_role_status_message(struct ds *string, const struct ofp_header *oh)
{
struct ofputil_role_status rs;
- enum ofperr error;
-
- error = ofputil_decode_role_status(oh, &rs);
- if (error) {
- return error;
- }
-
- ofp_print_role_generic(string, rs.role, rs.generation_id);
-
- ds_put_cstr(string, " reason=");
-
- switch (rs.reason) {
- case OFPCRR_MASTER_REQUEST:
- ds_put_cstr(string, "master_request");
- break;
- case OFPCRR_CONFIG:
- ds_put_cstr(string, "configuration_changed");
- break;
- case OFPCRR_EXPERIMENTER:
- ds_put_cstr(string, "experimenter_data_changed");
- break;
- case OFPCRR_N_REASONS:
- default:
- ds_put_cstr(string, "(unknown)");
- break;
+ enum ofperr error = ofputil_decode_role_status(oh, &rs);
+ if (!error) {
+ ofputil_format_role_status(string, &rs);
}
-
- return 0;
+ return error;
}
static enum ofperr
@@ -1260,128 +708,6 @@ ofp_print_nxt_set_packet_in_format(struct ds *string,
return error;
}
-/* Returns a string form of 'reason'. The return value is either a statically
- * allocated constant string or the 'bufsize'-byte buffer 'reasonbuf'.
- * 'bufsize' should be at least OFP_PORT_REASON_BUFSIZE. */
-#define OFP_PORT_REASON_BUFSIZE (INT_STRLEN(int) + 1)
-static const char *
-ofp_port_reason_to_string(enum ofp_port_reason reason,
- char *reasonbuf, size_t bufsize)
-{
- switch (reason) {
- case OFPPR_ADD:
- return "add";
-
- case OFPPR_DELETE:
- return "delete";
-
- case OFPPR_MODIFY:
- return "modify";
-
- case OFPPR_N_REASONS:
- default:
- snprintf(reasonbuf, bufsize, "%d", (int) reason);
- return reasonbuf;
- }
-}
-
-/* Returns a string form of 'reason'. The return value is either a statically
- * allocated constant string or the 'bufsize'-byte buffer 'reasonbuf'.
- * 'bufsize' should be at least OFP_ASYNC_CONFIG_REASON_BUFSIZE. */
-static const char*
-ofp_role_reason_to_string(enum ofp14_controller_role_reason reason,
- char *reasonbuf, size_t bufsize)
-{
- switch (reason) {
- case OFPCRR_MASTER_REQUEST:
- return "master_request";
-
- case OFPCRR_CONFIG:
- return "configuration_changed";
-
- case OFPCRR_EXPERIMENTER:
- return "experimenter_data_changed";
-
- case OFPCRR_N_REASONS:
- default:
- snprintf(reasonbuf, bufsize, "%d", (int) reason);
- return reasonbuf;
- }
-}
-
-/* Returns a string form of 'reason'. The return value is either a statically
- * allocated constant string or the 'bufsize'-byte buffer 'reasonbuf'.
- * 'bufsize' should be at least OFP_ASYNC_CONFIG_REASON_BUFSIZE. */
-static const char*
-ofp_table_reason_to_string(enum ofp14_table_reason reason,
- char *reasonbuf, size_t bufsize)
-{
- switch (reason) {
- case OFPTR_VACANCY_DOWN:
- return "vacancy_down";
-
- case OFPTR_VACANCY_UP:
- return "vacancy_up";
-
- default:
- snprintf(reasonbuf, bufsize, "%d", (int) reason);
- return reasonbuf;
- }
-}
-
-/* Returns a string form of 'reason'. The return value is either a statically
- * allocated constant string or the 'bufsize'-byte buffer 'reasonbuf'.
- * 'bufsize' should be at least OFP_ASYNC_CONFIG_REASON_BUFSIZE. */
-static const char*
-ofp_requestforward_reason_to_string(enum ofp14_requestforward_reason reason,
- char *reasonbuf, size_t bufsize)
-{
- switch (reason) {
- case OFPRFR_GROUP_MOD:
- return "group_mod_request";
-
- case OFPRFR_METER_MOD:
- return "meter_mod_request";
-
- case OFPRFR_N_REASONS:
- default:
- snprintf(reasonbuf, bufsize, "%d", (int) reason);
- return reasonbuf;
- }
-}
-
-static const char *
-ofp_async_config_reason_to_string(uint32_t reason,
- enum ofputil_async_msg_type type,
- char *reasonbuf, size_t bufsize)
-{
- switch (type) {
- case OAM_PACKET_IN:
- return ofputil_packet_in_reason_to_string(reason, reasonbuf, bufsize);
-
- case OAM_PORT_STATUS:
- return ofp_port_reason_to_string(reason, reasonbuf, bufsize);
-
- case OAM_FLOW_REMOVED:
- return ofp_flow_removed_reason_to_string(reason, reasonbuf, bufsize);
-
- case OAM_ROLE_STATUS:
- return ofp_role_reason_to_string(reason, reasonbuf, bufsize);
-
- case OAM_TABLE_STATUS:
- return ofp_table_reason_to_string(reason, reasonbuf, bufsize);
-
- case OAM_REQUESTFORWARD:
- return ofp_requestforward_reason_to_string(reason, reasonbuf, bufsize);
-
- case OAM_N_TYPES:
- default:
- return "Unknown asynchronous configuration message type";
- }
-}
-
-
-#define OFP_ASYNC_CONFIG_REASON_BUFSIZE (INT_STRLEN(int) + 1)
static enum ofperr
ofp_print_set_async_config(struct ds *string, const struct ofp_header *oh,
enum ofptype ofptype)
@@ -1395,33 +721,7 @@ ofp_print_set_async_config(struct ds *string, const struct ofp_header *oh,
if (error) {
return error;
}
-
- for (int i = 0; i < 2; i++) {
- ds_put_format(string, "\n %s:\n", i == 0 ? "master" : "slave");
- for (uint32_t type = 0; type < OAM_N_TYPES; type++) {
- ds_put_format(string, "%16s:",
- ofputil_async_msg_type_to_string(type));
-
- uint32_t role = i == 0 ? ac.master[type] : ac.slave[type];
- for (int j = 0; j < 32; j++) {
- if (role & (1u << j)) {
- char reasonbuf[OFP_ASYNC_CONFIG_REASON_BUFSIZE];
- const char *reason;
-
- reason = ofp_async_config_reason_to_string(
- j, type, reasonbuf, sizeof reasonbuf);
- if (reason[0]) {
- ds_put_format(string, " %s", reason);
- }
- }
- }
- if (!role) {
- ds_put_cstr(string, " (off)");
- }
- ds_put_char(string, '\n');
- }
- }
-
+ ofputil_format_set_async_config(string, &ac);
return 0;
}
@@ -1541,19 +841,6 @@ ofp_print_table_desc_reply(struct ds *s, const struct ofp_header *oh,
}
}
-static const char *
-bundle_flags_to_name(uint32_t bit)
-{
- switch (bit) {
- case OFPBF_ATOMIC:
- return "atomic";
- case OFPBF_ORDERED:
- return "ordered";
- default:
- return NULL;
- }
-}
-
static enum ofperr
ofp_print_bundle_ctrl(struct ds *s, const struct ofp_header *oh)
{
@@ -1564,40 +851,7 @@ ofp_print_bundle_ctrl(struct ds *s, const struct ofp_header *oh)
if (error) {
return error;
}
-
- ds_put_char(s, '\n');
-
- ds_put_format(s, " bundle_id=%#"PRIx32" type=", bctrl.bundle_id);
- switch (bctrl.type) {
- case OFPBCT_OPEN_REQUEST:
- ds_put_cstr(s, "OPEN_REQUEST");
- break;
- case OFPBCT_OPEN_REPLY:
- ds_put_cstr(s, "OPEN_REPLY");
- break;
- case OFPBCT_CLOSE_REQUEST:
- ds_put_cstr(s, "CLOSE_REQUEST");
- break;
- case OFPBCT_CLOSE_REPLY:
- ds_put_cstr(s, "CLOSE_REPLY");
- break;
- case OFPBCT_COMMIT_REQUEST:
- ds_put_cstr(s, "COMMIT_REQUEST");
- break;
- case OFPBCT_COMMIT_REPLY:
- ds_put_cstr(s, "COMMIT_REPLY");
- break;
- case OFPBCT_DISCARD_REQUEST:
- ds_put_cstr(s, "DISCARD_REQUEST");
- break;
- case OFPBCT_DISCARD_REPLY:
- ds_put_cstr(s, "DISCARD_REPLY");
- break;
- }
-
- ds_put_cstr(s, " flags=");
- ofp_print_bit_names(s, bctrl.flags, bundle_flags_to_name, ' ');
-
+ ofputil_format_bundle_ctrl_request(s, &bctrl);
return 0;
}
@@ -1607,106 +861,36 @@ ofp_print_bundle_add(struct ds *s, const struct ofp_header *oh,
const struct ofputil_table_map *table_map,
int verbosity)
{
- int error;
struct ofputil_bundle_add_msg badd;
-
- error = ofputil_decode_bundle_add(oh, &badd, NULL);
- if (error) {
- return error;
- }
-
- ds_put_char(s, '\n');
- ds_put_format(s, " bundle_id=%#"PRIx32, badd.bundle_id);
- ds_put_cstr(s, " flags=");
- ofp_print_bit_names(s, badd.flags, bundle_flags_to_name, ' ');
-
- ds_put_char(s, '\n');
- char *msg = ofp_to_string(badd.msg, ntohs(badd.msg->length), port_map,
- table_map, verbosity);
- ds_put_and_free_cstr(s, msg);
-
- return 0;
-}
-
-static void
-print_tlv_table(struct ds *s, struct ovs_list *mappings)
-{
- struct ofputil_tlv_map *map;
-
- ds_put_cstr(s, " mapping table:\n");
- ds_put_cstr(s, " class type length match field\n");
- ds_put_cstr(s, " ------ ---- ------ --------------");
-
- LIST_FOR_EACH (map, list_node, mappings) {
- ds_put_format(s, "\n %#6"PRIx16" %#4"PRIx8" %6"PRIu8" "
- "tun_metadata%"PRIu16,
- map->option_class, map->option_type, map->option_len,
- map->index);
+ int error = ofputil_decode_bundle_add(oh, &badd, NULL);
+ if (!error) {
+ ofputil_format_bundle_add(s, &badd, port_map, table_map, verbosity);
}
+ return error;
}
static enum ofperr
ofp_print_tlv_table_mod(struct ds *s, const struct ofp_header *oh)
{
- int error;
struct ofputil_tlv_table_mod ttm;
-
- error = ofputil_decode_tlv_table_mod(oh, &ttm);
- if (error) {
- return error;
- }
-
- ds_put_cstr(s, "\n ");
-
- switch (ttm.command) {
- case NXTTMC_ADD:
- ds_put_cstr(s, "ADD");
- break;
- case NXTTMC_DELETE:
- ds_put_cstr(s, "DEL");
- break;
- case NXTTMC_CLEAR:
- ds_put_cstr(s, "CLEAR");
- break;
- }
-
- if (ttm.command != NXTTMC_CLEAR) {
- print_tlv_table(s, &ttm.mappings);
+ int error = ofputil_decode_tlv_table_mod(oh, &ttm);
+ if (!error) {
+ ofputil_format_tlv_table_mod(s, &ttm);
+ ofputil_uninit_tlv_table(&ttm.mappings);
}
-
- ofputil_uninit_tlv_table(&ttm.mappings);
-
- return 0;
+ return error;
}
static enum ofperr
ofp_print_tlv_table_reply(struct ds *s, const struct ofp_header *oh)
{
- int error;
struct ofputil_tlv_table_reply ttr;
- struct ofputil_tlv_map *map;
- int allocated_space = 0;
-
- error = ofputil_decode_tlv_table_reply(oh, &ttr);
- if (error) {
- return error;
- }
-
- ds_put_char(s, '\n');
-
- LIST_FOR_EACH (map, list_node, &ttr.mappings) {
- allocated_space += map->option_len;
+ int error = ofputil_decode_tlv_table_reply(oh, &ttr);
+ if (!error) {
+ ofputil_format_tlv_table_reply(s, &ttr);
+ ofputil_uninit_tlv_table(&ttr.mappings);
}
-
- ds_put_format(s, " max option space=%"PRIu32" max fields=%"PRIu16"\n",
- ttr.max_option_space, ttr.max_fields);
- ds_put_format(s, " allocated option space=%d\n", allocated_space);
- ds_put_char(s, '\n');
- print_tlv_table(s, &ttr.mappings);
-
- ofputil_uninit_tlv_table(&ttr.mappings);
-
- return 0;
+ return error;
}
/* This function will print the request forward message. The reason for
@@ -1717,49 +901,13 @@ ofp_print_requestforward(struct ds *string, const struct ofp_header *oh,
const struct ofputil_table_map *table_map)
{
struct ofputil_requestforward rf;
- enum ofperr error;
-
- error = ofputil_decode_requestforward(oh, &rf);
- if (error) {
- return error;
- }
-
- ds_put_cstr(string, " reason=");
-
- switch (rf.reason) {
- case OFPRFR_GROUP_MOD:
- ds_put_cstr(string, "group_mod");
- ofputil_group_mod_format__(string, oh->version, rf.group_mod, port_map,
- table_map);
- break;
-
- case OFPRFR_METER_MOD:
- ds_put_cstr(string, "meter_mod");
- ofp_print_meter_mod__(string, rf.meter_mod);
- break;
-
- case OFPRFR_N_REASONS:
- OVS_NOT_REACHED();
- }
- ofputil_destroy_requestforward(&rf);
-
- return 0;
-}
-
-static void
-print_ipfix_stat(struct ds *string, const char *leader, uint64_t stat, int more)
-{
- ds_put_cstr(string, leader);
- if (stat != UINT64_MAX) {
- ds_put_format(string, "%"PRIu64, stat);
- } else {
- ds_put_char(string, '?');
- }
- if (more) {
- ds_put_cstr(string, ", ");
- } else {
- ds_put_cstr(string, "\n");
+ enum ofperr error = ofputil_decode_requestforward(oh, &rf);
+ if (!error) {
+ ofputil_format_requestforward(string, oh->version,
+ &rf, port_map, table_map);
+ ofputil_destroy_requestforward(&rf);
}
+ return error;
}
static enum ofperr
@@ -1774,19 +922,7 @@ ofp_print_nxst_ipfix_bridge_reply(struct ds *string, const struct ofp_header *oh
if (retval) {
return retval != EOF ? retval : 0;
}
-
- ds_put_cstr(string, "\n bridge ipfix: ");
- print_ipfix_stat(string, "flows=", is.total_flows, 1);
- print_ipfix_stat(string, "current flows=", is.current_flows, 1);
- print_ipfix_stat(string, "sampled pkts=", is.pkts, 1);
- print_ipfix_stat(string, "ipv4 ok=", is.ipv4_pkts, 1);
- print_ipfix_stat(string, "ipv6 ok=", is.ipv6_pkts, 1);
- print_ipfix_stat(string, "tx pkts=", is.tx_pkts, 0);
- ds_put_cstr(string, " ");
- print_ipfix_stat(string, "pkts errs=", is.error_pkts, 1);
- print_ipfix_stat(string, "ipv4 errs=", is.ipv4_error_pkts, 1);
- print_ipfix_stat(string, "ipv6 errs=", is.ipv6_error_pkts, 1);
- print_ipfix_stat(string, "tx errs=", is.tx_errors, 0);
+ ofputil_format_ipfix_stats_bridge(string, &is);
}
}
@@ -1804,20 +940,7 @@ ofp_print_nxst_ipfix_flow_reply(struct ds *string, const struct ofp_header *oh)
if (retval) {
return retval != EOF ? retval : 0;
}
-
- ds_put_cstr(string, " id");
- ds_put_format(string, " %3"PRIuSIZE": ", (size_t) is.collector_set_id);
- print_ipfix_stat(string, "flows=", is.total_flows, 1);
- print_ipfix_stat(string, "current flows=", is.current_flows, 1);
- print_ipfix_stat(string, "sampled pkts=", is.pkts, 1);
- print_ipfix_stat(string, "ipv4 ok=", is.ipv4_pkts, 1);
- print_ipfix_stat(string, "ipv6 ok=", is.ipv6_pkts, 1);
- print_ipfix_stat(string, "tx pkts=", is.tx_pkts, 0);
- ds_put_cstr(string, " ");
- print_ipfix_stat(string, "pkts errs=", is.error_pkts, 1);
- print_ipfix_stat(string, "ipv4 errs=", is.ipv4_error_pkts, 1);
- print_ipfix_stat(string, "ipv6 errs=", is.ipv6_error_pkts, 1);
- print_ipfix_stat(string, "tx errs=", is.tx_errors, 0);
+ ofputil_format_ipfix_stats_flow(string, &is);
}
}
@@ -1926,10 +1049,10 @@ ofp_to_string__(const struct ofp_header *oh,
break;
case OFPTYPE_QUEUE_GET_CONFIG_REQUEST:
- return ofp_print_queue_get_config_request(string, oh, port_map);
+ return ofputil_queue_get_config_request_format(string, oh, port_map);
case OFPTYPE_QUEUE_GET_CONFIG_REPLY:
- return ofp_print_queue_get_config_reply(string, oh, port_map);
+ return ofputil_queue_get_config_reply_format(string, oh, port_map);
case OFPTYPE_ROLE_REQUEST:
case OFPTYPE_ROLE_REPLY:
@@ -1971,7 +1094,7 @@ ofp_to_string__(const struct ofp_header *oh,
return ofp_print_ofpst_port_request(string, oh, port_map);
case OFPTYPE_QUEUE_STATS_REQUEST:
- return ofp_print_ofpst_queue_request(string, oh, port_map);
+ return ofputil_queue_stats_request_format(string, oh, port_map);
case OFPTYPE_DESC_STATS_REPLY:
return ofp_print_ofpst_desc_reply(string, oh);
@@ -1980,7 +1103,8 @@ ofp_to_string__(const struct ofp_header *oh,
return ofp_print_flow_stats_reply(string, oh, port_map, table_map);
case OFPTYPE_QUEUE_STATS_REPLY:
- return ofp_print_ofpst_queue_reply(string, oh, port_map, verbosity);
+ return ofputil_queue_stats_reply_format(string, oh, port_map,
+ verbosity);
case OFPTYPE_PORT_STATS_REPLY:
return ofp_print_ofpst_port_reply(string, oh, port_map, verbosity);
diff --git a/lib/ofp-queue.c b/lib/ofp-queue.c
index b3f681b0d..1c939878e 100644
--- a/lib/ofp-queue.c
+++ b/lib/ofp-queue.c
@@ -19,6 +19,7 @@
#include "byte-order.h"
#include "flow.h"
#include "openvswitch/ofp-msgs.h"
+#include "openvswitch/ofp-print.h"
#include "openvswitch/ofp-port.h"
#include "openvswitch/ofp-prop.h"
#include "openvswitch/ofpbuf.h"
@@ -29,6 +30,18 @@ VLOG_DEFINE_THIS_MODULE(ofp_queue);
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
+static void
+ofp_print_queue_name(struct ds *string, uint32_t queue_id)
+{
+ if (queue_id == OFPQ_ALL) {
+ ds_put_cstr(string, "ALL");
+ } else {
+ ds_put_format(string, "%"PRIu32, queue_id);
+ }
+}
+
+/* OFPT_QUEUE_GET_CONFIG request and reply. */
+
/* Constructs and returns an OFPT_QUEUE_GET_CONFIG request for the specified
* 'port' and 'queue', suitable for OpenFlow version 'version'.
*
@@ -111,6 +124,31 @@ ofputil_decode_queue_get_config_request(const struct ofp_header *oh,
: OFPERR_OFPQOFC_BAD_PORT);
}
+enum ofperr
+ofputil_queue_get_config_request_format(
+ struct ds *string, const struct ofp_header *oh,
+ const struct ofputil_port_map *port_map)
+{
+ enum ofperr error;
+ ofp_port_t port;
+ uint32_t queue;
+
+ error = ofputil_decode_queue_get_config_request(oh, &port, &queue);
+ if (error) {
+ return error;
+ }
+
+ ds_put_cstr(string, " port=");
+ ofputil_format_port(port, port_map, string);
+
+ if (queue != OFPQ_ALL) {
+ ds_put_cstr(string, " queue=");
+ ofp_print_queue_name(string, queue);
+ }
+
+ return 0;
+}
+
/* Constructs and returns the beginning of a reply to
* OFPT_QUEUE_GET_CONFIG_REQUEST or OFPMP_QUEUE_DESC request 'oh'. The caller
* may append information about individual queues with
@@ -419,6 +457,83 @@ ofputil_pull_queue_get_config_reply(struct ofpbuf *msg,
return ofputil_pull_queue_get_config_reply10(msg, queue);
}
}
+
+static void
+print_queue_rate(struct ds *string, const char *name, unsigned int rate)
+{
+ if (rate <= 1000) {
+ ds_put_format(string, " %s:%u.%u%%", name, rate / 10, rate % 10);
+ } else if (rate < UINT16_MAX) {
+ ds_put_format(string, " %s:(disabled)", name);
+ }
+}
+
+/* qsort comparison function. */
+static int
+compare_queues(const void *a_, const void *b_)
+{
+ const struct ofputil_queue_config *a = a_;
+ const struct ofputil_queue_config *b = b_;
+
+ uint16_t ap = ofp_to_u16(a->port);
+ uint16_t bp = ofp_to_u16(b->port);
+ if (ap != bp) {
+ return ap < bp ? -1 : 1;
+ }
+
+ uint32_t aq = a->queue;
+ uint32_t bq = b->queue;
+ return aq < bq ? -1 : aq > bq;
+}
+
+enum ofperr
+ofputil_queue_get_config_reply_format(struct ds *string,
+ const struct ofp_header *oh,
+ const struct ofputil_port_map *port_map)
+{
+ struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
+
+ struct ofputil_queue_config *queues = NULL;
+ size_t allocated_queues = 0;
+ size_t n = 0;
+
+ int retval = 0;
+ for (;;) {
+ if (n >= allocated_queues) {
+ queues = x2nrealloc(queues, &allocated_queues, sizeof *queues);
+ }
+ retval = ofputil_pull_queue_get_config_reply(&b, &queues[n]);
+ if (retval) {
+ break;
+ }
+ n++;
+ }
+
+ qsort(queues, n, sizeof *queues, compare_queues);
+
+ ds_put_char(string, ' ');
+
+ ofp_port_t port = 0;
+ for (const struct ofputil_queue_config *q = queues; q < &queues[n]; q++) {
+ if (q->port != port) {
+ port = q->port;
+
+ ds_put_cstr(string, "port=");
+ ofputil_format_port(port, port_map, string);
+ ds_put_char(string, '\n');
+ }
+
+ ds_put_format(string, "queue %"PRIu32":", q->queue);
+ print_queue_rate(string, "min_rate", q->min_rate);
+ print_queue_rate(string, "max_rate", q->max_rate);
+ ds_put_char(string, '\n');
+ }
+
+ ds_chomp(string, ' ');
+ free(queues);
+
+ return retval != EOF ? retval : 0;
+}
/* Parse a queue status request message into 'oqsr'.
* Returns 0 if successful, otherwise an OFPERR_* number. */
@@ -495,6 +610,28 @@ ofputil_encode_queue_stats_request(
return request;
}
+enum ofperr
+ofputil_queue_stats_request_format(struct ds *string,
+ const struct ofp_header *oh,
+ const struct ofputil_port_map *port_map)
+{
+ struct ofputil_queue_stats_request oqsr;
+ enum ofperr error;
+
+ error = ofputil_decode_queue_stats_request(oh, &oqsr);
+ if (error) {
+ return error;
+ }
+
+ ds_put_cstr(string, " port=");
+ ofputil_format_port(oqsr.port_no, port_map, string);
+
+ ds_put_cstr(string, " queue=");
+ ofp_print_queue_name(string, oqsr.queue_id);
+
+ return 0;
+}
+
/* Returns the number of queue stats elements in OFPTYPE_QUEUE_STATS_REPLY
* message 'oh'. */
size_t
@@ -726,3 +863,62 @@ ofputil_append_queue_stat(struct ovs_list *replies,
}
}
+static void
+print_queue_stat(struct ds *string, const char *leader, uint64_t stat,
+ int more)
+{
+ ds_put_cstr(string, leader);
+ if (stat != UINT64_MAX) {
+ ds_put_format(string, "%"PRIu64, stat);
+ } else {
+ ds_put_char(string, '?');
+ }
+ if (more) {
+ ds_put_cstr(string, ", ");
+ } else {
+ ds_put_cstr(string, "\n");
+ }
+}
+
+enum ofperr
+ofputil_queue_stats_reply_format(struct ds *string,
+ const struct ofp_header *oh,
+ const struct ofputil_port_map *port_map,
+ int verbosity)
+{
+ ds_put_format(string, " %"PRIuSIZE" queues\n",
+ ofputil_count_queue_stats(oh));
+ if (verbosity < 1) {
+ return 0;
+ }
+
+ struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
+ for (;;) {
+ struct ofputil_queue_stats qs;
+ int retval;
+
+ retval = ofputil_decode_queue_stats(&qs, &b);
+ if (retval) {
+ return retval != EOF ? retval : 0;
+ }
+
+ ds_put_cstr(string, " port ");
+ ofputil_format_port(qs.port_no, port_map, string);
+ ds_put_cstr(string, " queue ");
+ ofp_print_queue_name(string, qs.queue_id);
+ ds_put_cstr(string, ": ");
+
+ print_queue_stat(string, "bytes=", qs.tx_bytes, 1);
+ print_queue_stat(string, "pkts=", qs.tx_packets, 1);
+ print_queue_stat(string, "errors=", qs.tx_errors, 1);
+
+ ds_put_cstr(string, "duration=");
+ if (qs.duration_sec != UINT32_MAX) {
+ ofp_print_duration(string, qs.duration_sec, qs.duration_nsec);
+ } else {
+ ds_put_char(string, '?');
+ }
+ ds_put_char(string, '\n');
+ }
+}
+
diff --git a/lib/ofp-table.c b/lib/ofp-table.c
index 595a4384d..5f14fcc3a 100644
--- a/lib/ofp-table.c
+++ b/lib/ofp-table.c
@@ -1912,6 +1912,26 @@ ofputil_decode_table_stats_reply(struct ofpbuf *msg,
}
}
+/* Returns a string form of 'reason'. The return value is either a statically
+ * allocated constant string or the 'bufsize'-byte buffer 'reasonbuf'.
+ * 'bufsize' should be at least OFP_ASYNC_CONFIG_REASON_BUFSIZE. */
+const char *
+ofp_table_reason_to_string(enum ofp14_table_reason reason,
+ char *reasonbuf, size_t bufsize)
+{
+ switch (reason) {
+ case OFPTR_VACANCY_DOWN:
+ return "vacancy_down";
+
+ case OFPTR_VACANCY_UP:
+ return "vacancy_up";
+
+ default:
+ snprintf(reasonbuf, bufsize, "%d", (int) reason);
+ return reasonbuf;
+ }
+}
+
static void
ofputil_put_ofp14_table_desc(const struct ofputil_table_desc *td,
struct ofpbuf *b, enum ofp_version version)
@@ -1997,3 +2017,18 @@ ofputil_decode_table_status(const struct ofp_header *oh,
return 0;
}
+
+void
+ofputil_format_table_status(struct ds *string,
+ const struct ofputil_table_status *ts,
+ const struct ofputil_table_map *table_map)
+{
+ if (ts->reason == OFPTR_VACANCY_DOWN) {
+ ds_put_format(string, " reason=VACANCY_DOWN");
+ } else if (ts->reason == OFPTR_VACANCY_UP) {
+ ds_put_format(string, " reason=VACANCY_UP");
+ }
+
+ ds_put_format(string, "\ntable_desc:-");
+ ofputil_table_desc_format(string, &ts->desc, table_map);
+}