return ds_cstr(&ds);
}
+static void
+format_hex_arg(struct ds *s, const uint8_t *data, size_t len)
+{
+ for (size_t i = 0; i < len; i++) {
+ if (i) {
+ ds_put_char(s, '.');
+ }
+ ds_put_format(s, "%02"PRIx8, data[i]);
+ }
+}
+
static void
ofp_print_packet_in(struct ds *string, const struct ofp_header *oh,
int verbosity)
{
char reasonbuf[OFPUTIL_PACKET_IN_REASON_BUFSIZE];
- struct ofputil_packet_in pin;
- int error;
+ struct ofputil_packet_in_private pin;
+ const struct ofputil_packet_in *public = &pin.public;
+ uint32_t buffer_id;
+ size_t total_len;
+ enum ofperr error;
- error = ofputil_decode_packet_in(&pin, oh);
+ error = ofputil_decode_packet_in_private(oh, true,
+ &pin, &total_len, &buffer_id);
if (error) {
ofp_print_error(string, error);
return;
}
- if (pin.table_id) {
- ds_put_format(string, " table_id=%"PRIu8, pin.table_id);
+ if (public->table_id) {
+ ds_put_format(string, " table_id=%"PRIu8, public->table_id);
}
- if (pin.cookie != OVS_BE64_MAX) {
- ds_put_format(string, " cookie=0x%"PRIx64, ntohll(pin.cookie));
+ if (public->cookie != OVS_BE64_MAX) {
+ ds_put_format(string, " cookie=0x%"PRIx64, ntohll(public->cookie));
}
- ds_put_format(string, " total_len=%"PRIuSIZE" ", pin.total_len);
+ ds_put_format(string, " total_len=%"PRIuSIZE" ", total_len);
- match_format(&pin.flow_metadata, string, OFP_DEFAULT_PRIORITY);
+ match_format(&public->flow_metadata, string, OFP_DEFAULT_PRIORITY);
ds_put_format(string, " (via %s)",
- ofputil_packet_in_reason_to_string(pin.reason, reasonbuf,
+ ofputil_packet_in_reason_to_string(public->reason,
+ reasonbuf,
sizeof reasonbuf));
- ds_put_format(string, " data_len=%"PRIuSIZE, pin.packet_len);
- if (pin.buffer_id == UINT32_MAX) {
+ ds_put_format(string, " data_len=%"PRIuSIZE, public->packet_len);
+ if (buffer_id == UINT32_MAX) {
ds_put_format(string, " (unbuffered)");
- if (pin.total_len != pin.packet_len) {
+ if (total_len != public->packet_len) {
ds_put_format(string, " (***total_len != data_len***)");
}
} else {
- ds_put_format(string, " buffer=0x%08"PRIx32, pin.buffer_id);
- if (pin.total_len < pin.packet_len) {
+ ds_put_format(string, " buffer=0x%08"PRIx32, buffer_id);
+ if (total_len < public->packet_len) {
ds_put_format(string, " (***total_len < data_len***)");
}
}
ds_put_char(string, '\n');
+ if (public->userdata_len) {
+ ds_put_cstr(string, " userdata=");
+ format_hex_arg(string, pin.public.userdata, pin.public.userdata_len);
+ ds_put_char(string, '\n');
+ }
+
+ if (!uuid_is_zero(&pin.bridge)) {
+ ds_put_format(string, " continuation.bridge="UUID_FMT"\n",
+ UUID_ARGS(&pin.bridge));
+ }
+
+ if (pin.n_stack) {
+ ds_put_cstr(string, " continuation.stack=");
+ for (size_t i = 0; i < pin.n_stack; i++) {
+ if (i) {
+ ds_put_char(string, ' ');
+ }
+ mf_subvalue_format(&pin.stack[i], string);
+ }
+ }
+
+ if (pin.mirrors) {
+ ds_put_format(string, " continuation.mirrors=0x%"PRIx32"\n",
+ pin.mirrors);
+ }
+
+ if (pin.conntracked) {
+ ds_put_cstr(string, " continuation.conntracked=true\n");
+ }
+
+ if (pin.actions_len) {
+ ds_put_cstr(string, " continuation.actions=");
+ ofpacts_format(pin.actions, pin.actions_len, string);
+ ds_put_char(string, '\n');
+ }
+
+ if (pin.action_set_len) {
+ ds_put_cstr(string, " continuation.action_set=");
+ ofpacts_format(pin.action_set, pin.action_set_len, string);
+ ds_put_char(string, '\n');
+ }
+
if (verbosity > 0) {
- char *packet = ofp_packet_to_string(pin.packet, pin.packet_len);
+ char *packet = ofp_packet_to_string(public->packet,
+ public->packet_len);
ds_put_cstr(string, packet);
free(packet);
}
if (verbosity > 2) {
- ds_put_hex_dump(string, pin.packet, pin.packet_len, 0, false);
+ ds_put_hex_dump(string, public->packet, public->packet_len, 0, false);
}
+
+ ofputil_packet_in_private_destroy(&pin);
}
static void
ofp_print_switch_features(struct ds *string, const struct ofp_header *oh)
{
struct ofputil_switch_features features;
- enum ofperr error;
- struct ofpbuf b;
-
- error = ofputil_decode_switch_features(oh, &features, &b);
+ struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
+ enum ofperr error = ofputil_pull_switch_features(&b, &features);
if (error) {
ofp_print_error(string, error);
return;
ofp_print_queue_get_config_reply(struct ds *string,
const struct ofp_header *oh)
{
- struct ofpbuf b;
+ struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
ofp_port_t port = 0;
- ofpbuf_use_const(&b, oh, ntohs(oh->length));
-
ds_put_char(string, ' ');
for (;;) {
struct ofputil_queue_config queue;
static void
ofp_print_meter_config_reply(struct ds *s, const struct ofp_header *oh)
{
+ struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
struct ofpbuf bands;
- struct ofpbuf b;
- ofpbuf_use_const(&b, oh, ntohs(oh->length));
ofpbuf_init(&bands, 64);
for (;;) {
struct ofputil_meter_config mc;
static void
ofp_print_meter_stats_reply(struct ds *s, const struct ofp_header *oh)
{
+ struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
struct ofpbuf bands;
- struct ofpbuf b;
- ofpbuf_use_const(&b, oh, ntohs(oh->length));
ofpbuf_init(&bands, 64);
for (;;) {
struct ofputil_meter_stats ms;
static void
ofp_print_flow_stats_reply(struct ds *string, const struct ofp_header *oh)
{
+ struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
struct ofpbuf ofpacts;
- struct ofpbuf b;
- ofpbuf_use_const(&b, oh, ntohs(oh->length));
ofpbuf_init(&ofpacts, 64);
for (;;) {
struct ofputil_flow_stats fs;
ofp_print_ofpst_port_reply(struct ds *string, const struct ofp_header *oh,
int verbosity)
{
- struct ofpbuf b;
-
ds_put_format(string, " %"PRIuSIZE" ports\n", ofputil_count_port_stats(oh));
if (verbosity < 1) {
return;
}
- ofpbuf_use_const(&b, oh, ntohs(oh->length));
+ struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
for (;;) {
struct ofputil_port_stats ps;
int retval;
static void
ofp_print_table_stats_reply(struct ds *string, const struct ofp_header *oh)
{
- struct ofpbuf b;
-
- ofpbuf_use_const(&b, oh, ntohs(oh->length));
+ struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
ofpraw_pull_assert(&b);
struct ofputil_table_features prev_features;
ofp_print_ofpst_queue_reply(struct ds *string, const struct ofp_header *oh,
int verbosity)
{
- struct ofpbuf b;
-
ds_put_format(string, " %"PRIuSIZE" queues\n", ofputil_count_queue_stats(oh));
if (verbosity < 1) {
return;
}
- ofpbuf_use_const(&b, oh, ntohs(oh->length));
+ struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
for (;;) {
struct ofputil_queue_stats qs;
int retval;
ofp_print_ofpst_port_desc_reply(struct ds *string,
const struct ofp_header *oh)
{
- struct ofpbuf b;
-
- ofpbuf_use_const(&b, oh, ntohs(oh->length));
+ struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
ofpraw_pull_assert(&b);
ds_put_char(string, '\n');
ofp_print_phy_ports(string, oh->version, &b);
case OFPTR_VACANCY_UP:
return "vacancy_up";
- case OFPTR_N_REASONS:
default:
snprintf(reasonbuf, bufsize, "%d", (int) reason);
return reasonbuf;
#define OFP_ASYNC_CONFIG_REASON_BUFSIZE (INT_STRLEN(int) + 1)
static void
-ofp_print_nxt_set_async_config(struct ds *string,
- const struct ofp_header *oh)
+ofp_print_set_async_config(struct ds *string, const struct ofp_header *oh,
+ enum ofptype type)
{
- int i, j;
- enum ofpraw raw;
-
- ofpraw_decode(&raw, oh);
-
- if (raw == OFPRAW_OFPT13_SET_ASYNC ||
- raw == OFPRAW_NXT_SET_ASYNC_CONFIG ||
- raw == OFPRAW_OFPT13_GET_ASYNC_REPLY) {
- const struct nx_async_config *nac = ofpmsg_body(oh);
-
- for (i = 0; i < 2; i++) {
-
- ds_put_format(string, "\n %s:\n", i == 0 ? "master" : "slave");
-
- ds_put_cstr(string, " PACKET_IN:");
- for (j = 0; j < 32; j++) {
- if (nac->packet_in_mask[i] & htonl(1u << j)) {
- char reasonbuf[OFPUTIL_PACKET_IN_REASON_BUFSIZE];
- const char *reason;
+ struct ofputil_async_cfg basis = OFPUTIL_ASYNC_CFG_INIT;
+ struct ofputil_async_cfg ac;
- reason = ofputil_packet_in_reason_to_string(j, reasonbuf,
- sizeof reasonbuf);
- ds_put_format(string, " %s", reason);
- }
- }
- if (!nac->packet_in_mask[i]) {
- ds_put_cstr(string, " (off)");
- }
- ds_put_char(string, '\n');
-
- ds_put_cstr(string, " PORT_STATUS:");
- for (j = 0; j < 32; j++) {
- if (nac->port_status_mask[i] & htonl(1u << j)) {
- char reasonbuf[OFP_PORT_REASON_BUFSIZE];
- const char *reason;
+ bool is_reply = type == OFPTYPE_GET_ASYNC_REPLY;
+ enum ofperr error = ofputil_decode_set_async_config(oh, is_reply,
+ &basis, &ac);
+ if (error) {
+ ofp_print_error(string, error);
+ return;
+ }
- reason = ofp_port_reason_to_string(j, reasonbuf,
- sizeof reasonbuf);
- ds_put_format(string, " %s", reason);
- }
- }
- if (!nac->port_status_mask[i]) {
- ds_put_cstr(string, " (off)");
- }
- ds_put_char(string, '\n');
+ 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));
- ds_put_cstr(string, " FLOW_REMOVED:");
- for (j = 0; j < 32; j++) {
- if (nac->flow_removed_mask[i] & htonl(1u << j)) {
- char reasonbuf[OFP_FLOW_REMOVED_REASON_BUFSIZE];
+ 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_flow_removed_reason_to_string(j, reasonbuf,
- sizeof reasonbuf);
- ds_put_format(string, " %s", reason);
+ reason = ofp_async_config_reason_to_string(
+ j, type, reasonbuf, sizeof reasonbuf);
+ if (reason[0]) {
+ ds_put_format(string, " %s", reason);
+ }
}
}
- if (!nac->flow_removed_mask[i]) {
+ if (!role) {
ds_put_cstr(string, " (off)");
}
ds_put_char(string, '\n');
}
- } else if (raw == OFPRAW_OFPT14_SET_ASYNC ||
- raw == OFPRAW_OFPT14_GET_ASYNC_REPLY) {
- enum ofperr error = 0;
- uint32_t role[2][OAM_N_TYPES] = {{0}};
- uint32_t type;
-
- if (raw == OFPRAW_OFPT14_GET_ASYNC_REPLY) {
- error = ofputil_decode_set_async_config(oh, role[0], role[1], true);
- }
- else if (raw == OFPRAW_OFPT14_SET_ASYNC) {
- error = ofputil_decode_set_async_config(oh, role[0], role[1],
- false);
- }
- if (error) {
- ofp_print_error(string, error);
- return;
- }
-
- for (i = 0; i < 2; i++) {
-
- ds_put_format(string, "\n %s:\n", i == 0 ? "master" : "slave");
- for (type = 0; type < OAM_N_TYPES; type++) {
- ds_put_format(string, "%16s:",
- ofputil_async_msg_type_to_string(type));
-
- for (j = 0; j < 32; j++) {
- if (role[i][type] & (1u << j)) {
- char reasonbuf[OFP_ASYNC_CONFIG_REASON_BUFSIZE];
- const char *reason;
-
- reason = ofp_async_config_reason_to_string(j, type,
- reasonbuf,
- sizeof reasonbuf);
- ds_put_format(string, " %s", reason);
- }
- }
- if (!role[i][type]) {
- ds_put_cstr(string, " (off)");
- }
- ds_put_char(string, '\n');
- }
- }
}
}
ofp_print_nxst_flow_monitor_request(struct ds *string,
const struct ofp_header *oh)
{
- struct ofpbuf b;
-
- ofpbuf_use_const(&b, oh, ntohs(oh->length));
+ struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
for (;;) {
struct ofputil_flow_monitor_request request;
int retval;
const struct ofp_header *oh)
{
uint64_t ofpacts_stub[1024 / 8];
- struct ofpbuf ofpacts;
- struct ofpbuf b;
+ struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(ofpacts_stub);
+ struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
- ofpbuf_use_const(&b, oh, ntohs(oh->length));
- ofpbuf_use_stub(&ofpacts, ofpacts_stub, sizeof ofpacts_stub);
for (;;) {
char reasonbuf[OFP_FLOW_REMOVED_REASON_BUFSIZE];
struct ofputil_flow_update update;
static void
ofp_print_group_desc(struct ds *s, const struct ofp_header *oh)
{
- struct ofpbuf b;
-
- ofpbuf_use_const(&b, oh, ntohs(oh->length));
+ struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
for (;;) {
struct ofputil_group_desc gd;
int retval;
static void
ofp_print_group_stats(struct ds *s, const struct ofp_header *oh)
{
- struct ofpbuf b;
- uint32_t bucket_i;
-
- ofpbuf_use_const(&b, oh, ntohs(oh->length));
-
+ struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
for (;;) {
struct ofputil_group_stats gs;
int retval;
ds_put_format(s, "packet_count=%"PRIu64",", gs.packet_count);
ds_put_format(s, "byte_count=%"PRIu64"", gs.byte_count);
- for (bucket_i = 0; bucket_i < gs.n_buckets; bucket_i++) {
+ for (uint32_t bucket_i = 0; bucket_i < gs.n_buckets; bucket_i++) {
if (gs.bucket_stats[bucket_i].packet_count != UINT64_MAX) {
ds_put_format(s, ",bucket%"PRIu32":", bucket_i);
ds_put_format(s, "packet_count=%"PRIu64",", gs.bucket_stats[bucket_i].packet_count);
static void
ofp_print_table_features_reply(struct ds *s, const struct ofp_header *oh)
{
- struct ofpbuf b;
-
- ofpbuf_use_const(&b, oh, ntohs(oh->length));
+ struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
struct ofputil_table_features prev;
for (int i = 0; ; i++) {
static void
ofp_print_table_desc_reply(struct ds *s, const struct ofp_header *oh)
{
- struct ofpbuf b;
-
- ofpbuf_use_const(&b, oh, ntohs(oh->length));
-
+ struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
for (;;) {
struct ofputil_table_desc td;
int retval;
const void *msg = oh;
ofp_header_to_string__(oh, raw, string);
- switch (ofptype_from_ofpraw(raw)) {
+ enum ofptype type = ofptype_from_ofpraw(raw);
+ switch (type) {
case OFPTYPE_GROUP_STATS_REQUEST:
ofp_print_stats(string, oh);
ofp_print_ofpst_group_request(string, oh);
case OFPTYPE_GET_ASYNC_REPLY:
case OFPTYPE_SET_ASYNC_CONFIG:
- ofp_print_nxt_set_async_config(string, oh);
+ ofp_print_set_async_config(string, oh, type);
break;
case OFPTYPE_GET_ASYNC_REQUEST:
break;
ofp_print_tlv_table_reply(string, msg);
break;
+ case OFPTYPE_NXT_RESUME:
+ ofp_print_packet_in(string, msg, verbosity);
+ break;
}
}