This does a better job of putting related code together. Signed-off-by: Ben Pfaff <b...@ovn.org> --- include/openvswitch/ofp-group.h | 19 ++- lib/ofp-group.c | 306 ++++++++++++++++++++++++++++++++++++++ lib/ofp-print.c | 317 +--------------------------------------- 3 files changed, 332 insertions(+), 310 deletions(-)
diff --git a/include/openvswitch/ofp-group.h b/include/openvswitch/ofp-group.h index 8d893a53fcb2..10790eb020bd 100644 --- a/include/openvswitch/ofp-group.h +++ b/include/openvswitch/ofp-group.h @@ -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 } diff --git a/lib/ofp-group.c b/lib/ofp-group.c index a2755ee47fea..f5b0af8cec0f 100644 --- a/lib/ofp-group.c +++ b/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; +} diff --git a/lib/ofp-print.c b/lib/ofp-print.c index 0d1406873219..6e30312aef7c 100644 --- a/lib/ofp-print.c +++ b/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: -- 2.16.1 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev