mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 06:15:47 +00:00
ofp-group: Move formatting code for groups into ofp-group.
This does a better job of putting related code together. Signed-off-by: Ben Pfaff <blp@ovn.org> Acked-by: Justin Pettit <jpettit@ovn.org>
This commit is contained in:
@@ -108,6 +108,14 @@ struct ofpbuf *ofputil_encode_group_mod(enum ofp_version ofp_version,
|
||||
enum ofperr ofputil_decode_group_mod(const struct ofp_header *,
|
||||
struct ofputil_group_mod *);
|
||||
|
||||
void ofputil_group_mod_format__(struct ds *, enum ofp_version,
|
||||
const struct ofputil_group_mod *,
|
||||
const struct ofputil_port_map *,
|
||||
const struct ofputil_table_map *);
|
||||
enum ofperr ofputil_group_mod_format(struct ds *, const struct ofp_header *,
|
||||
const struct ofputil_port_map *,
|
||||
const struct ofputil_table_map *);
|
||||
|
||||
char *parse_ofp_group_mod_file(const char *file_name,
|
||||
const struct ofputil_port_map *,
|
||||
const struct ofputil_table_map *, int command,
|
||||
@@ -140,9 +148,12 @@ enum ofperr ofputil_decode_group_stats_request(
|
||||
const struct ofp_header *request, uint32_t *group_id);
|
||||
void ofputil_append_group_stats(struct ovs_list *replies,
|
||||
const struct ofputil_group_stats *);
|
||||
enum ofperr ofputil_group_stats_request_format(struct ds *,
|
||||
const struct ofp_header *);
|
||||
|
||||
int ofputil_decode_group_stats_reply(struct ofpbuf *,
|
||||
struct ofputil_group_stats *);
|
||||
enum ofperr ofputil_group_stats_format(struct ds *, const struct ofp_header *);
|
||||
|
||||
/* Group features reply, independent of protocol.
|
||||
*
|
||||
@@ -172,13 +183,19 @@ void ofputil_uninit_group_desc(struct ofputil_group_desc *gd);
|
||||
uint32_t ofputil_decode_group_desc_request(const struct ofp_header *);
|
||||
struct ofpbuf *ofputil_encode_group_desc_request(enum ofp_version,
|
||||
uint32_t group_id);
|
||||
enum ofperr ofputil_group_desc_request_format(struct ds *,
|
||||
const struct ofp_header *);
|
||||
|
||||
int ofputil_decode_group_desc_reply(struct ofputil_group_desc *,
|
||||
struct ofpbuf *, enum ofp_version);
|
||||
|
||||
void ofputil_append_group_desc_reply(const struct ofputil_group_desc *,
|
||||
const struct ovs_list *buckets,
|
||||
struct ovs_list *replies);
|
||||
enum ofperr ofputil_group_desc_format(struct ds *, const struct ofp_header *,
|
||||
const struct ofputil_port_map *,
|
||||
const struct ofputil_table_map *);
|
||||
enum ofperr ofputil_group_features_format(struct ds *,
|
||||
const struct ofp_header *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
306
lib/ofp-group.c
306
lib/ofp-group.c
@@ -25,6 +25,7 @@
|
||||
#include "openvswitch/ofp-msgs.h"
|
||||
#include "openvswitch/ofp-parse.h"
|
||||
#include "openvswitch/ofp-port.h"
|
||||
#include "openvswitch/ofp-print.h"
|
||||
#include "openvswitch/ofp-prop.h"
|
||||
#include "openvswitch/ofpbuf.h"
|
||||
#include "openvswitch/vlog.h"
|
||||
@@ -291,6 +292,18 @@ ofputil_encode_group_desc_request(enum ofp_version ofp_version,
|
||||
return request;
|
||||
}
|
||||
|
||||
|
||||
enum ofperr
|
||||
ofputil_group_desc_request_format(struct ds *string,
|
||||
const struct ofp_header *oh)
|
||||
{
|
||||
uint32_t group_id = ofputil_decode_group_desc_request(oh);
|
||||
ds_put_cstr(string, " group_id=");
|
||||
ofputil_format_group(group_id, string);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ofputil_group_bucket_counters_to_ofp11(const struct ofputil_group_stats *gs,
|
||||
struct ofp11_bucket_counter bucket_cnts[])
|
||||
@@ -371,6 +384,7 @@ ofputil_append_group_stats(struct ovs_list *replies,
|
||||
OVS_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns an OpenFlow group features request for OpenFlow version
|
||||
* 'ofp_version'. */
|
||||
struct ofpbuf *
|
||||
@@ -420,6 +434,45 @@ ofputil_decode_group_features_reply(const struct ofp_header *oh,
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
group_type_to_string(enum ofp11_group_type type)
|
||||
{
|
||||
switch (type) {
|
||||
case OFPGT11_ALL: return "all";
|
||||
case OFPGT11_SELECT: return "select";
|
||||
case OFPGT11_INDIRECT: return "indirect";
|
||||
case OFPGT11_FF: return "fast failover";
|
||||
default: OVS_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
enum ofperr
|
||||
ofputil_group_features_format(struct ds *string, const struct ofp_header *oh)
|
||||
{
|
||||
struct ofputil_group_features features;
|
||||
int i;
|
||||
|
||||
ofputil_decode_group_features_reply(oh, &features);
|
||||
|
||||
ds_put_format(string, "\n Group table:\n");
|
||||
ds_put_format(string, " Types: 0x%"PRIx32"\n", features.types);
|
||||
ds_put_format(string, " Capabilities: 0x%"PRIx32"\n",
|
||||
features.capabilities);
|
||||
|
||||
for (i = 0; i < OFPGT12_N_TYPES; i++) {
|
||||
if (features.types & (1u << i)) {
|
||||
ds_put_format(string, " %s group:\n", group_type_to_string(i));
|
||||
ds_put_format(string, " max_groups=%#"PRIx32"\n",
|
||||
features.max_groups[i]);
|
||||
ds_put_format(string, " actions: ");
|
||||
ofpact_bitmap_format(features.ofpacts[i], string);
|
||||
ds_put_char(string, '\n');
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Parse a group status request message into a 32 bit OpenFlow 1.1
|
||||
* group ID and stores the latter in '*group_id'.
|
||||
* Returns 0 if successful, otherwise an OFPERR_* number. */
|
||||
@@ -521,6 +574,68 @@ ofputil_decode_group_stats_reply(struct ofpbuf *msg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
enum ofperr
|
||||
ofputil_group_stats_request_format(struct ds *string,
|
||||
const struct ofp_header *oh)
|
||||
{
|
||||
enum ofperr error;
|
||||
uint32_t group_id;
|
||||
|
||||
error = ofputil_decode_group_stats_request(oh, &group_id);
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
ds_put_cstr(string, " group_id=");
|
||||
ofputil_format_group(group_id, string);
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum ofperr
|
||||
ofputil_group_stats_format(struct ds *s, const struct ofp_header *oh)
|
||||
{
|
||||
struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
|
||||
for (;;) {
|
||||
struct ofputil_group_stats gs;
|
||||
int retval;
|
||||
|
||||
retval = ofputil_decode_group_stats_reply(&b, &gs);
|
||||
if (retval) {
|
||||
if (retval != EOF) {
|
||||
ds_put_cstr(s, " ***parse error***");
|
||||
return retval;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ds_put_char(s, '\n');
|
||||
|
||||
ds_put_char(s, ' ');
|
||||
ds_put_format(s, "group_id=%"PRIu32",", gs.group_id);
|
||||
|
||||
if (gs.duration_sec != UINT32_MAX) {
|
||||
ds_put_cstr(s, "duration=");
|
||||
ofp_print_duration(s, gs.duration_sec, gs.duration_nsec);
|
||||
ds_put_char(s, ',');
|
||||
}
|
||||
ds_put_format(s, "ref_count=%"PRIu32",", gs.ref_count);
|
||||
ds_put_format(s, "packet_count=%"PRIu64",", gs.packet_count);
|
||||
ds_put_format(s, "byte_count=%"PRIu64"", gs.byte_count);
|
||||
|
||||
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);
|
||||
ds_put_format(s, "byte_count=%"PRIu64"", gs.bucket_stats[bucket_i].byte_count);
|
||||
}
|
||||
}
|
||||
|
||||
free(gs.bucket_stats);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char * OVS_WARN_UNUSED_RESULT
|
||||
parse_bucket_str(struct ofputil_bucket *bucket, char *str_,
|
||||
const struct ofputil_port_map *port_map,
|
||||
@@ -1667,6 +1782,128 @@ ofputil_decode_group_desc_reply(struct ofputil_group_desc *gd,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ofp_print_bucket_id(struct ds *s, const char *label, uint32_t bucket_id,
|
||||
enum ofp_version ofp_version)
|
||||
{
|
||||
if (ofp_version > OFP10_VERSION && ofp_version < OFP15_VERSION) {
|
||||
return;
|
||||
}
|
||||
|
||||
ds_put_cstr(s, label);
|
||||
|
||||
switch (bucket_id) {
|
||||
case OFPG15_BUCKET_FIRST:
|
||||
ds_put_cstr(s, "first");
|
||||
break;
|
||||
case OFPG15_BUCKET_LAST:
|
||||
ds_put_cstr(s, "last");
|
||||
break;
|
||||
case OFPG15_BUCKET_ALL:
|
||||
ds_put_cstr(s, "all");
|
||||
break;
|
||||
default:
|
||||
ds_put_format(s, "%"PRIu32, bucket_id);
|
||||
break;
|
||||
}
|
||||
|
||||
ds_put_char(s, ',');
|
||||
}
|
||||
|
||||
static void
|
||||
ofp_print_group(struct ds *s, uint32_t group_id, uint8_t type,
|
||||
const struct ovs_list *p_buckets,
|
||||
const struct ofputil_group_props *props,
|
||||
enum ofp_version ofp_version, bool suppress_type,
|
||||
const struct ofputil_port_map *port_map,
|
||||
const struct ofputil_table_map *table_map)
|
||||
{
|
||||
struct ofputil_bucket *bucket;
|
||||
|
||||
ds_put_format(s, "group_id=%"PRIu32, group_id);
|
||||
|
||||
if (!suppress_type) {
|
||||
static const char *type_str[] = { "all", "select", "indirect",
|
||||
"ff", "unknown" };
|
||||
ds_put_format(s, ",type=%s", type_str[type > 4 ? 4 : type]);
|
||||
}
|
||||
|
||||
if (props->selection_method[0]) {
|
||||
ds_put_format(s, ",selection_method=%s", props->selection_method);
|
||||
if (props->selection_method_param) {
|
||||
ds_put_format(s, ",selection_method_param=%"PRIu64,
|
||||
props->selection_method_param);
|
||||
}
|
||||
|
||||
size_t n = bitmap_count1(props->fields.used.bm, MFF_N_IDS);
|
||||
if (n == 1) {
|
||||
ds_put_cstr(s, ",fields=");
|
||||
oxm_format_field_array(s, &props->fields);
|
||||
} else if (n > 1) {
|
||||
ds_put_cstr(s, ",fields(");
|
||||
oxm_format_field_array(s, &props->fields);
|
||||
ds_put_char(s, ')');
|
||||
}
|
||||
}
|
||||
|
||||
if (!p_buckets) {
|
||||
return;
|
||||
}
|
||||
|
||||
ds_put_char(s, ',');
|
||||
|
||||
LIST_FOR_EACH (bucket, list_node, p_buckets) {
|
||||
ds_put_cstr(s, "bucket=");
|
||||
|
||||
ofp_print_bucket_id(s, "bucket_id:", bucket->bucket_id, ofp_version);
|
||||
if (bucket->weight != (type == OFPGT11_SELECT ? 1 : 0)) {
|
||||
ds_put_format(s, "weight:%"PRIu16",", bucket->weight);
|
||||
}
|
||||
if (bucket->watch_port != OFPP_NONE) {
|
||||
ds_put_cstr(s, "watch_port:");
|
||||
ofputil_format_port(bucket->watch_port, port_map, s);
|
||||
ds_put_char(s, ',');
|
||||
}
|
||||
if (bucket->watch_group != OFPG_ANY) {
|
||||
ds_put_format(s, "watch_group:%"PRIu32",", bucket->watch_group);
|
||||
}
|
||||
|
||||
ds_put_cstr(s, "actions=");
|
||||
struct ofpact_format_params fp = {
|
||||
.port_map = port_map,
|
||||
.table_map = table_map,
|
||||
.s = s,
|
||||
};
|
||||
ofpacts_format(bucket->ofpacts, bucket->ofpacts_len, &fp);
|
||||
ds_put_char(s, ',');
|
||||
}
|
||||
|
||||
ds_chomp(s, ',');
|
||||
}
|
||||
|
||||
enum ofperr
|
||||
ofputil_group_desc_format(struct ds *s, const struct ofp_header *oh,
|
||||
const struct ofputil_port_map *port_map,
|
||||
const struct ofputil_table_map *table_map)
|
||||
{
|
||||
struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
|
||||
for (;;) {
|
||||
struct ofputil_group_desc gd;
|
||||
int retval;
|
||||
|
||||
retval = ofputil_decode_group_desc_reply(&gd, &b, oh->version);
|
||||
if (retval) {
|
||||
return retval != EOF ? retval : 0;
|
||||
}
|
||||
|
||||
ds_put_char(s, '\n');
|
||||
ds_put_char(s, ' ');
|
||||
ofp_print_group(s, gd.group_id, gd.type, &gd.buckets, &gd.props,
|
||||
oh->version, false, port_map, table_map);
|
||||
ofputil_uninit_group_desc(&gd);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ofputil_uninit_group_mod(struct ofputil_group_mod *gm)
|
||||
{
|
||||
@@ -2040,3 +2277,72 @@ ofputil_decode_group_mod(const struct ofp_header *oh,
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
void
|
||||
ofputil_group_mod_format__(struct ds *s, enum ofp_version ofp_version,
|
||||
const struct ofputil_group_mod *gm,
|
||||
const struct ofputil_port_map *port_map,
|
||||
const struct ofputil_table_map *table_map)
|
||||
{
|
||||
bool bucket_command = false;
|
||||
|
||||
ds_put_char(s, '\n');
|
||||
|
||||
ds_put_char(s, ' ');
|
||||
switch (gm->command) {
|
||||
case OFPGC11_ADD:
|
||||
ds_put_cstr(s, "ADD");
|
||||
break;
|
||||
|
||||
case OFPGC11_MODIFY:
|
||||
ds_put_cstr(s, "MOD");
|
||||
break;
|
||||
|
||||
case OFPGC11_ADD_OR_MOD:
|
||||
ds_put_cstr(s, "ADD_OR_MOD");
|
||||
break;
|
||||
|
||||
case OFPGC11_DELETE:
|
||||
ds_put_cstr(s, "DEL");
|
||||
break;
|
||||
|
||||
case OFPGC15_INSERT_BUCKET:
|
||||
ds_put_cstr(s, "INSERT_BUCKET");
|
||||
bucket_command = true;
|
||||
break;
|
||||
|
||||
case OFPGC15_REMOVE_BUCKET:
|
||||
ds_put_cstr(s, "REMOVE_BUCKET");
|
||||
bucket_command = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
ds_put_format(s, "cmd:%"PRIu16"", gm->command);
|
||||
}
|
||||
ds_put_char(s, ' ');
|
||||
|
||||
if (bucket_command) {
|
||||
ofp_print_bucket_id(s, "command_bucket_id:",
|
||||
gm->command_bucket_id, ofp_version);
|
||||
}
|
||||
|
||||
ofp_print_group(s, gm->group_id, gm->type, &gm->buckets, &gm->props,
|
||||
ofp_version, bucket_command, port_map, table_map);
|
||||
}
|
||||
|
||||
enum ofperr
|
||||
ofputil_group_mod_format(struct ds *s, const struct ofp_header *oh,
|
||||
const struct ofputil_port_map *port_map,
|
||||
const struct ofputil_table_map *table_map)
|
||||
{
|
||||
struct ofputil_group_mod gm;
|
||||
int error;
|
||||
|
||||
error = ofputil_decode_group_mod(oh, &gm);
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
ofputil_group_mod_format__(s, oh->version, &gm, port_map, table_map);
|
||||
ofputil_uninit_group_mod(&gm);
|
||||
return 0;
|
||||
}
|
||||
|
317
lib/ofp-print.c
317
lib/ofp-print.c
@@ -1524,307 +1524,6 @@ ofp_header_to_string__(const struct ofp_header *oh, enum ofpraw raw,
|
||||
ofp_print_version(oh, string);
|
||||
}
|
||||
|
||||
static void
|
||||
ofp_print_bucket_id(struct ds *s, const char *label, uint32_t bucket_id,
|
||||
enum ofp_version ofp_version)
|
||||
{
|
||||
if (ofp_version > OFP10_VERSION && ofp_version < OFP15_VERSION) {
|
||||
return;
|
||||
}
|
||||
|
||||
ds_put_cstr(s, label);
|
||||
|
||||
switch (bucket_id) {
|
||||
case OFPG15_BUCKET_FIRST:
|
||||
ds_put_cstr(s, "first");
|
||||
break;
|
||||
case OFPG15_BUCKET_LAST:
|
||||
ds_put_cstr(s, "last");
|
||||
break;
|
||||
case OFPG15_BUCKET_ALL:
|
||||
ds_put_cstr(s, "all");
|
||||
break;
|
||||
default:
|
||||
ds_put_format(s, "%"PRIu32, bucket_id);
|
||||
break;
|
||||
}
|
||||
|
||||
ds_put_char(s, ',');
|
||||
}
|
||||
|
||||
static void
|
||||
ofp_print_group(struct ds *s, uint32_t group_id, uint8_t type,
|
||||
const struct ovs_list *p_buckets,
|
||||
const struct ofputil_group_props *props,
|
||||
enum ofp_version ofp_version, bool suppress_type,
|
||||
const struct ofputil_port_map *port_map,
|
||||
const struct ofputil_table_map *table_map)
|
||||
{
|
||||
struct ofputil_bucket *bucket;
|
||||
|
||||
ds_put_format(s, "group_id=%"PRIu32, group_id);
|
||||
|
||||
if (!suppress_type) {
|
||||
static const char *type_str[] = { "all", "select", "indirect",
|
||||
"ff", "unknown" };
|
||||
ds_put_format(s, ",type=%s", type_str[type > 4 ? 4 : type]);
|
||||
}
|
||||
|
||||
if (props->selection_method[0]) {
|
||||
ds_put_format(s, ",selection_method=%s", props->selection_method);
|
||||
if (props->selection_method_param) {
|
||||
ds_put_format(s, ",selection_method_param=%"PRIu64,
|
||||
props->selection_method_param);
|
||||
}
|
||||
|
||||
size_t n = bitmap_count1(props->fields.used.bm, MFF_N_IDS);
|
||||
if (n == 1) {
|
||||
ds_put_cstr(s, ",fields=");
|
||||
oxm_format_field_array(s, &props->fields);
|
||||
} else if (n > 1) {
|
||||
ds_put_cstr(s, ",fields(");
|
||||
oxm_format_field_array(s, &props->fields);
|
||||
ds_put_char(s, ')');
|
||||
}
|
||||
}
|
||||
|
||||
if (!p_buckets) {
|
||||
return;
|
||||
}
|
||||
|
||||
ds_put_char(s, ',');
|
||||
|
||||
LIST_FOR_EACH (bucket, list_node, p_buckets) {
|
||||
ds_put_cstr(s, "bucket=");
|
||||
|
||||
ofp_print_bucket_id(s, "bucket_id:", bucket->bucket_id, ofp_version);
|
||||
if (bucket->weight != (type == OFPGT11_SELECT ? 1 : 0)) {
|
||||
ds_put_format(s, "weight:%"PRIu16",", bucket->weight);
|
||||
}
|
||||
if (bucket->watch_port != OFPP_NONE) {
|
||||
ds_put_cstr(s, "watch_port:");
|
||||
ofputil_format_port(bucket->watch_port, port_map, s);
|
||||
ds_put_char(s, ',');
|
||||
}
|
||||
if (bucket->watch_group != OFPG_ANY) {
|
||||
ds_put_format(s, "watch_group:%"PRIu32",", bucket->watch_group);
|
||||
}
|
||||
|
||||
ds_put_cstr(s, "actions=");
|
||||
struct ofpact_format_params fp = {
|
||||
.port_map = port_map,
|
||||
.table_map = table_map,
|
||||
.s = s,
|
||||
};
|
||||
ofpacts_format(bucket->ofpacts, bucket->ofpacts_len, &fp);
|
||||
ds_put_char(s, ',');
|
||||
}
|
||||
|
||||
ds_chomp(s, ',');
|
||||
}
|
||||
|
||||
static enum ofperr
|
||||
ofp_print_ofpst_group_desc_request(struct ds *string,
|
||||
const struct ofp_header *oh)
|
||||
{
|
||||
uint32_t group_id = ofputil_decode_group_desc_request(oh);
|
||||
ds_put_cstr(string, " group_id=");
|
||||
ofputil_format_group(group_id, string);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum ofperr
|
||||
ofp_print_group_desc(struct ds *s, const struct ofp_header *oh,
|
||||
const struct ofputil_port_map *port_map,
|
||||
const struct ofputil_table_map *table_map)
|
||||
{
|
||||
struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
|
||||
for (;;) {
|
||||
struct ofputil_group_desc gd;
|
||||
int retval;
|
||||
|
||||
retval = ofputil_decode_group_desc_reply(&gd, &b, oh->version);
|
||||
if (retval) {
|
||||
return retval != EOF ? retval : 0;
|
||||
}
|
||||
|
||||
ds_put_char(s, '\n');
|
||||
ds_put_char(s, ' ');
|
||||
ofp_print_group(s, gd.group_id, gd.type, &gd.buckets, &gd.props,
|
||||
oh->version, false, port_map, table_map);
|
||||
ofputil_uninit_group_desc(&gd);
|
||||
}
|
||||
}
|
||||
|
||||
static enum ofperr
|
||||
ofp_print_ofpst_group_request(struct ds *string, const struct ofp_header *oh)
|
||||
{
|
||||
enum ofperr error;
|
||||
uint32_t group_id;
|
||||
|
||||
error = ofputil_decode_group_stats_request(oh, &group_id);
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
ds_put_cstr(string, " group_id=");
|
||||
ofputil_format_group(group_id, string);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum ofperr
|
||||
ofp_print_group_stats(struct ds *s, const struct ofp_header *oh)
|
||||
{
|
||||
struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
|
||||
for (;;) {
|
||||
struct ofputil_group_stats gs;
|
||||
int retval;
|
||||
|
||||
retval = ofputil_decode_group_stats_reply(&b, &gs);
|
||||
if (retval) {
|
||||
if (retval != EOF) {
|
||||
ds_put_cstr(s, " ***parse error***");
|
||||
return retval;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ds_put_char(s, '\n');
|
||||
|
||||
ds_put_char(s, ' ');
|
||||
ds_put_format(s, "group_id=%"PRIu32",", gs.group_id);
|
||||
|
||||
if (gs.duration_sec != UINT32_MAX) {
|
||||
ds_put_cstr(s, "duration=");
|
||||
ofp_print_duration(s, gs.duration_sec, gs.duration_nsec);
|
||||
ds_put_char(s, ',');
|
||||
}
|
||||
ds_put_format(s, "ref_count=%"PRIu32",", gs.ref_count);
|
||||
ds_put_format(s, "packet_count=%"PRIu64",", gs.packet_count);
|
||||
ds_put_format(s, "byte_count=%"PRIu64"", gs.byte_count);
|
||||
|
||||
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);
|
||||
ds_put_format(s, "byte_count=%"PRIu64"", gs.bucket_stats[bucket_i].byte_count);
|
||||
}
|
||||
}
|
||||
|
||||
free(gs.bucket_stats);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *
|
||||
group_type_to_string(enum ofp11_group_type type)
|
||||
{
|
||||
switch (type) {
|
||||
case OFPGT11_ALL: return "all";
|
||||
case OFPGT11_SELECT: return "select";
|
||||
case OFPGT11_INDIRECT: return "indirect";
|
||||
case OFPGT11_FF: return "fast failover";
|
||||
default: OVS_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
static enum ofperr
|
||||
ofp_print_group_features(struct ds *string, const struct ofp_header *oh)
|
||||
{
|
||||
struct ofputil_group_features features;
|
||||
int i;
|
||||
|
||||
ofputil_decode_group_features_reply(oh, &features);
|
||||
|
||||
ds_put_format(string, "\n Group table:\n");
|
||||
ds_put_format(string, " Types: 0x%"PRIx32"\n", features.types);
|
||||
ds_put_format(string, " Capabilities: 0x%"PRIx32"\n",
|
||||
features.capabilities);
|
||||
|
||||
for (i = 0; i < OFPGT12_N_TYPES; i++) {
|
||||
if (features.types & (1u << i)) {
|
||||
ds_put_format(string, " %s group:\n", group_type_to_string(i));
|
||||
ds_put_format(string, " max_groups=%#"PRIx32"\n",
|
||||
features.max_groups[i]);
|
||||
ds_put_format(string, " actions: ");
|
||||
ofpact_bitmap_format(features.ofpacts[i], string);
|
||||
ds_put_char(string, '\n');
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ofp_print_group_mod__(struct ds *s, enum ofp_version ofp_version,
|
||||
const struct ofputil_group_mod *gm,
|
||||
const struct ofputil_port_map *port_map,
|
||||
const struct ofputil_table_map *table_map)
|
||||
{
|
||||
bool bucket_command = false;
|
||||
|
||||
ds_put_char(s, '\n');
|
||||
|
||||
ds_put_char(s, ' ');
|
||||
switch (gm->command) {
|
||||
case OFPGC11_ADD:
|
||||
ds_put_cstr(s, "ADD");
|
||||
break;
|
||||
|
||||
case OFPGC11_MODIFY:
|
||||
ds_put_cstr(s, "MOD");
|
||||
break;
|
||||
|
||||
case OFPGC11_ADD_OR_MOD:
|
||||
ds_put_cstr(s, "ADD_OR_MOD");
|
||||
break;
|
||||
|
||||
case OFPGC11_DELETE:
|
||||
ds_put_cstr(s, "DEL");
|
||||
break;
|
||||
|
||||
case OFPGC15_INSERT_BUCKET:
|
||||
ds_put_cstr(s, "INSERT_BUCKET");
|
||||
bucket_command = true;
|
||||
break;
|
||||
|
||||
case OFPGC15_REMOVE_BUCKET:
|
||||
ds_put_cstr(s, "REMOVE_BUCKET");
|
||||
bucket_command = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
ds_put_format(s, "cmd:%"PRIu16"", gm->command);
|
||||
}
|
||||
ds_put_char(s, ' ');
|
||||
|
||||
if (bucket_command) {
|
||||
ofp_print_bucket_id(s, "command_bucket_id:",
|
||||
gm->command_bucket_id, ofp_version);
|
||||
}
|
||||
|
||||
ofp_print_group(s, gm->group_id, gm->type, &gm->buckets, &gm->props,
|
||||
ofp_version, bucket_command, port_map, table_map);
|
||||
}
|
||||
|
||||
static enum ofperr
|
||||
ofp_print_group_mod(struct ds *s, const struct ofp_header *oh,
|
||||
const struct ofputil_port_map *port_map,
|
||||
const struct ofputil_table_map *table_map)
|
||||
{
|
||||
struct ofputil_group_mod gm;
|
||||
int error;
|
||||
|
||||
error = ofputil_decode_group_mod(oh, &gm);
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
ofp_print_group_mod__(s, oh->version, &gm, port_map, table_map);
|
||||
ofputil_uninit_group_mod(&gm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum ofperr
|
||||
ofp_print_table_desc_reply(struct ds *s, const struct ofp_header *oh,
|
||||
const struct ofputil_table_map *table_map)
|
||||
@@ -2030,8 +1729,8 @@ ofp_print_requestforward(struct ds *string, const struct ofp_header *oh,
|
||||
switch (rf.reason) {
|
||||
case OFPRFR_GROUP_MOD:
|
||||
ds_put_cstr(string, "group_mod");
|
||||
ofp_print_group_mod__(string, oh->version, rf.group_mod, port_map,
|
||||
table_map);
|
||||
ofputil_group_mod_format__(string, oh->version, rf.group_mod, port_map,
|
||||
table_map);
|
||||
break;
|
||||
|
||||
case OFPRFR_METER_MOD:
|
||||
@@ -2140,27 +1839,27 @@ ofp_to_string__(const struct ofp_header *oh,
|
||||
switch (type) {
|
||||
case OFPTYPE_GROUP_STATS_REQUEST:
|
||||
ofp_print_stats(string, oh);
|
||||
return ofp_print_ofpst_group_request(string, oh);
|
||||
return ofputil_group_stats_request_format(string, oh);
|
||||
|
||||
case OFPTYPE_GROUP_STATS_REPLY:
|
||||
return ofp_print_group_stats(string, oh);
|
||||
return ofputil_group_stats_format(string, oh);
|
||||
|
||||
case OFPTYPE_GROUP_DESC_STATS_REQUEST:
|
||||
ofp_print_stats(string, oh);
|
||||
return ofp_print_ofpst_group_desc_request(string, oh);
|
||||
return ofputil_group_desc_request_format(string, oh);
|
||||
|
||||
case OFPTYPE_GROUP_DESC_STATS_REPLY:
|
||||
return ofp_print_group_desc(string, oh, port_map, table_map);
|
||||
return ofputil_group_desc_format(string, oh, port_map, table_map);
|
||||
|
||||
case OFPTYPE_GROUP_FEATURES_STATS_REQUEST:
|
||||
ofp_print_stats(string, oh);
|
||||
break;
|
||||
|
||||
case OFPTYPE_GROUP_FEATURES_STATS_REPLY:
|
||||
return ofp_print_group_features(string, oh);
|
||||
return ofputil_group_features_format(string, oh);
|
||||
|
||||
case OFPTYPE_GROUP_MOD:
|
||||
return ofp_print_group_mod(string, oh, port_map, table_map);
|
||||
return ofputil_group_mod_format(string, oh, port_map, table_map);
|
||||
|
||||
case OFPTYPE_TABLE_FEATURES_STATS_REQUEST:
|
||||
case OFPTYPE_TABLE_FEATURES_STATS_REPLY:
|
||||
|
Reference in New Issue
Block a user