Acked-by: Jarno Rajahalme <[email protected]>

> On Jul 2, 2015, at 8:41 PM, Ben Pfaff <[email protected]> wrote:
> 
> Signed-off-by: Ben Pfaff <[email protected]>
> Co-authored-by: Saloni Jain <[email protected]>
> Signed-off-by: Saloni Jain <[email protected]>
> Acked-by: Jarno Rajahalme <[email protected]>
> ---
> v1->v2: Use OFPROTO_EVICTION_FLAGS.  Fix documentation.  Fix style nits.
> 
> NEWS                            |   1 +
> include/openflow/openflow-1.4.h |  10 +++
> lib/learning-switch.c           |   2 +
> lib/ofp-msgs.h                  |  10 +++
> lib/ofp-print.c                 |  39 ++++++++++++
> lib/ofp-util.c                  | 135 ++++++++++++++++++++++++++++++++++++++++
> lib/ofp-util.h                  |  21 +++++++
> lib/rconn.c                     |   2 +
> ofproto/ofproto.c               |  45 ++++++++++++++
> ovn/controller/ofctrl.c         |   2 +
> tests/ofproto.at                |  22 +++++++
> utilities/ovs-ofctl.8.in        |   4 ++
> utilities/ovs-ofctl.c           |  19 ++++++
> 13 files changed, 312 insertions(+)
> 
> diff --git a/NEWS b/NEWS
> index 57e4f89..59f2552 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -8,6 +8,7 @@ Post-v2.4.0
>        now supported.
>      * OpenFlow 1.4+ "importance" is now considered for flow eviction.
>      * OpenFlow 1.4+ OFPTC_EVICTION is now implemented.
> +     * OpenFlow 1.4+ OFPMP_TABLE_DESC is now implemented.
>    - Support for matching and generating options with Geneve tunnels.
>    - Support Multicast Listener Discovery (MLDv1 and MLDv2).
> 
> diff --git a/include/openflow/openflow-1.4.h b/include/openflow/openflow-1.4.h
> index 7631e47..567aaae 100644
> --- a/include/openflow/openflow-1.4.h
> +++ b/include/openflow/openflow-1.4.h
> @@ -155,6 +155,16 @@ struct ofp14_table_mod {
> };
> OFP_ASSERT(sizeof(struct ofp14_table_mod) == 8);
> 
> +/* Body of reply to OFPMP_TABLE_DESC request. */
> +struct ofp14_table_desc {
> +    ovs_be16 length;       /* Length is padded to 64 bits. */
> +    uint8_t table_id;      /* Identifier of table. Lower numbered tables
> +                              are consulted first. */
> +    uint8_t pad[1];        /* Align to 32-bits. */
> +    ovs_be32 config;       /* Bitmap of OFPTC_* values. */
> +    /* Followed by 0 or more OFPTMPT14_* properties. */
> +};
> +OFP_ASSERT(sizeof(struct ofp14_table_desc) == 8);
> 
> /* ## ---------------- ## */
> /* ## ofp14_port_stats ## */
> diff --git a/lib/learning-switch.c b/lib/learning-switch.c
> index 2fe38a0..1753cea 100644
> --- a/lib/learning-switch.c
> +++ b/lib/learning-switch.c
> @@ -447,6 +447,8 @@ lswitch_process_packet(struct lswitch *sw, const struct 
> ofpbuf *msg)
>     case OFPTYPE_METER_FEATURES_STATS_REPLY:
>     case OFPTYPE_TABLE_FEATURES_STATS_REQUEST:
>     case OFPTYPE_TABLE_FEATURES_STATS_REPLY:
> +    case OFPTYPE_TABLE_DESC_REQUEST:
> +    case OFPTYPE_TABLE_DESC_REPLY:
>     case OFPTYPE_BUNDLE_CONTROL:
>     case OFPTYPE_BUNDLE_ADD_MESSAGE:
>     case OFPTYPE_NXT_GENEVE_TABLE_MOD:
> diff --git a/lib/ofp-msgs.h b/lib/ofp-msgs.h
> index e28bd50..29729c0 100644
> --- a/lib/ofp-msgs.h
> +++ b/lib/ofp-msgs.h
> @@ -369,6 +369,12 @@ enum ofpraw {
>     /* OFPST 1.3+ (12): struct ofp13_table_features, uint8_t[8][]. */
>     OFPRAW_OFPST13_TABLE_FEATURES_REPLY,
> 
> +    /* OFPST 1.4+ (15): void. */
> +    OFPRAW_OFPST14_TABLE_DESC_REQUEST,
> +
> +    /* OFPST 1.4+ (15): struct ofp14_table_desc, uint8_t[8][]. */
> +    OFPRAW_OFPST14_TABLE_DESC_REPLY,
> +
>     /* OFPST 1.0-1.4 (13): void. */
>     OFPRAW_OFPST10_PORT_DESC_REQUEST,
>     /* OFPST 1.5+ (13): ovs_be32. */
> @@ -611,6 +617,10 @@ enum ofptype {
> 
>     OFPTYPE_TABLE_FEATURES_STATS_REPLY, /* 
> OFPRAW_OFPST13_TABLE_FEATURES_REPLY. */
> 
> +    OFPTYPE_TABLE_DESC_REQUEST,      /* OFPRAW_OFPST14_TABLE_DESC_REQUEST. */
> +
> +    OFPTYPE_TABLE_DESC_REPLY,        /* OFPRAW_OFPST14_TABLE_DESC_REPLY. */
> +
>     OFPTYPE_PORT_DESC_STATS_REQUEST, /* OFPRAW_OFPST10_PORT_DESC_REQUEST.
>                                       * OFPRAW_OFPST15_PORT_DESC_REQUEST. */
> 
> diff --git a/lib/ofp-print.c b/lib/ofp-print.c
> index d76134f..4603bb7 100644
> --- a/lib/ofp-print.c
> +++ b/lib/ofp-print.c
> @@ -1025,6 +1025,18 @@ ofp_print_table_mod(struct ds *string, const struct 
> ofp_header *oh)
>     }
> }
> 
> +/* This function will print the Table description properties. */
> +static void
> +ofp_print_table_desc(struct ds *string, const struct ofputil_table_desc *td)
> +{
> +    ds_put_format(string, "\n  table %"PRIu8, td->table_id);
> +    ds_put_cstr(string, ":\n");
> +    ds_put_format(string, "   eviction=%s eviction_flags=",
> +                  ofputil_table_eviction_to_string(td->eviction));
> +    ofputil_put_eviction_flags(string, td->eviction_flags);
> +    ds_put_char(string, '\n');
> +}
> +
> static void
> ofp_print_queue_get_config_request(struct ds *string,
>                                    const struct ofp_header *oh)
> @@ -2607,6 +2619,28 @@ ofp_print_table_features_reply(struct ds *s, const 
> struct ofp_header *oh)
>     }
> }
> 
> +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));
> +
> +    for (;;) {
> +        struct ofputil_table_desc td;
> +        int retval;
> +
> +        retval = ofputil_decode_table_desc(&b, &td, oh->version);
> +        if (retval) {
> +            if (retval != EOF) {
> +                ofp_print_error(s, retval);
> +            }
> +            return;
> +        }
> +        ofp_print_table_desc(s, &td);
> +    }
> +}
> +
> static const char *
> bundle_flags_to_name(uint32_t bit)
> {
> @@ -2814,6 +2848,11 @@ ofp_to_string__(const struct ofp_header *oh, enum 
> ofpraw raw,
>         ofp_print_table_features_reply(string, oh);
>         break;
> 
> +    case OFPTYPE_TABLE_DESC_REQUEST:
> +    case OFPTYPE_TABLE_DESC_REPLY:
> +        ofp_print_table_desc_reply(string, oh);
> +        break;
> +
>     case OFPTYPE_HELLO:
>         ofp_print_hello(string, oh);
>         break;
> diff --git a/lib/ofp-util.c b/lib/ofp-util.c
> index 2e9ae47..f7dbdd5 100644
> --- a/lib/ofp-util.c
> +++ b/lib/ofp-util.c
> @@ -4887,6 +4887,139 @@ ofputil_append_table_features_reply(const struct 
> ofputil_table_features *tf,
> }
> 
> static enum ofperr
> +parse_table_desc_eviction_property(struct ofpbuf *property,
> +                                   struct ofputil_table_desc *td)
> +{
> +    struct ofp14_table_mod_prop_eviction *ote = property->data;
> +
> +    if (property->size != sizeof *ote) {
> +        return OFPERR_OFPBPC_BAD_LEN;
> +    }
> +
> +    td->eviction_flags = ntohl(ote->flags);
> +    return 0;
> +}
> +
> +/* Decodes the next OpenFlow "table desc" message (of possibly several) from
> + * 'msg' into an abstract form in '*td'.  Returns 0 if successful, EOF if the
> + * last "table desc" in 'msg' was already decoded, otherwise an OFPERR_*
> + * value. */
> +int
> +ofputil_decode_table_desc(struct ofpbuf *msg,
> +                          struct ofputil_table_desc *td,
> +                          enum ofp_version version)
> +{
> +    struct ofp14_table_desc *otd;
> +    struct ofpbuf properties;
> +    size_t length;
> +
> +    memset(td, 0, sizeof *td);
> +
> +    if (!msg->header) {
> +        ofpraw_pull_assert(msg);
> +    }
> +
> +    if (!msg->size) {
> +        return EOF;
> +    }
> +
> +    otd = ofpbuf_try_pull(msg, sizeof *otd);
> +    if (!otd) {
> +        VLOG_WARN_RL(&bad_ofmsg_rl, "OFP14_TABLE_DESC reply has %"PRIu32" "
> +                     "leftover bytes at end", msg->size);
> +        return OFPERR_OFPBRC_BAD_LEN;
> +    }
> +
> +    td->table_id = otd->table_id;
> +    length = ntohs(otd->length);
> +    if (length < sizeof *otd || length - sizeof *otd > msg->size) {
> +        VLOG_WARN_RL(&bad_ofmsg_rl, "OFP14_TABLE_DESC reply claims invalid "
> +                     "length %"PRIuSIZE, length);
> +        return OFPERR_OFPBRC_BAD_LEN;
> +    }
> +    length -= sizeof *otd;
> +    ofpbuf_use_const(&properties, ofpbuf_pull(msg, length), length);
> +
> +    td->eviction = ofputil_decode_table_eviction(otd->config, version);
> +    td->eviction_flags = UINT32_MAX;
> +
> +    while (properties.size > 0) {
> +        struct ofpbuf payload;
> +        enum ofperr error;
> +        uint16_t type;
> +
> +        error = ofputil_pull_property(&properties, &payload, &type);
> +        if (error) {
> +            return error;
> +        }
> +
> +        switch (type) {
> +        case OFPTMPT14_EVICTION:
> +            error = parse_table_desc_eviction_property(&payload, td);
> +            break;
> +
> +        default:
> +            log_property(true, "unknown table_desc property %"PRIu16, type);
> +            error = 0;
> +            break;
> +        }
> +
> +        if (error) {
> +            return error;
> +        }
> +    }
> +
> +    return 0;
> +}
> +
> +/* Encodes and returns a request to obtain description of tables of a switch.
> + * The message is encoded for OpenFlow version 'ofp_version'. */
> +struct ofpbuf *
> +ofputil_encode_table_desc_request(enum ofp_version ofp_version)
> +{
> +    struct ofpbuf *request = NULL;
> +
> +    if (ofp_version >= OFP14_VERSION) {
> +        request = ofpraw_alloc(OFPRAW_OFPST14_TABLE_DESC_REQUEST,
> +                               ofp_version, 0);
> +    } else {
> +        ovs_fatal(0, "dump-table-desc needs OpenFlow 1.4 or later "
> +                  "(\'-O OpenFlow14\')");
> +    }
> +
> +    return request;
> +}
> +
> +/* Function to append Table desc information in a reply list. */
> +void
> +ofputil_append_table_desc_reply(const struct ofputil_table_desc *td,
> +                                struct ovs_list *replies,
> +                                enum ofp_version version)
> +{
> +    struct ofpbuf *reply = ofpbuf_from_list(list_back(replies));
> +    size_t start_otd;
> +    struct ofp14_table_desc *otd;
> +
> +    start_otd = reply->size;
> +    ofpbuf_put_zeros(reply, sizeof *otd);
> +    if (td->eviction_flags != UINT32_MAX) {
> +        struct ofp14_table_mod_prop_eviction *ote;
> +
> +        ote = ofpbuf_put_zeros(reply, sizeof *ote);
> +        ote->type = htons(OFPTMPT14_EVICTION);
> +        ote->length = htons(sizeof *ote);
> +        ote->flags = htonl(td->eviction_flags);
> +    }
> +
> +    otd = ofpbuf_at_assert(reply, start_otd, sizeof *otd);
> +    otd->length = htons(reply->size - start_otd);
> +    otd->table_id = td->table_id;
> +    otd->config = ofputil_encode_table_config(OFPUTIL_TABLE_MISS_DEFAULT,
> +                                              td->eviction, version);
> +    ofpmp_postappend(replies, start_otd);
> +}
> +
> +static enum ofperr
> parse_table_mod_eviction_property(struct ofpbuf *property,
>                                   struct ofputil_table_mod *tm)
> {
> @@ -8890,6 +9023,7 @@ ofputil_is_bundlable(enum ofptype type)
>     case OFPTYPE_AGGREGATE_STATS_REQUEST:
>     case OFPTYPE_TABLE_STATS_REQUEST:
>     case OFPTYPE_TABLE_FEATURES_STATS_REQUEST:
> +    case OFPTYPE_TABLE_DESC_REQUEST:
>     case OFPTYPE_PORT_STATS_REQUEST:
>     case OFPTYPE_QUEUE_STATS_REQUEST:
>     case OFPTYPE_PORT_DESC_STATS_REQUEST:
> @@ -8931,6 +9065,7 @@ ofputil_is_bundlable(enum ofptype type)
>     case OFPTYPE_METER_CONFIG_STATS_REPLY:
>     case OFPTYPE_METER_FEATURES_STATS_REPLY:
>     case OFPTYPE_TABLE_FEATURES_STATS_REPLY:
> +    case OFPTYPE_TABLE_DESC_REPLY:
>     case OFPTYPE_ROLE_STATUS:
>     case OFPTYPE_NXT_GENEVE_TABLE_REQUEST:
>     case OFPTYPE_NXT_GENEVE_TABLE_REPLY:
> diff --git a/lib/ofp-util.h b/lib/ofp-util.h
> index fbc8abf..431f165 100644
> --- a/lib/ofp-util.h
> +++ b/lib/ofp-util.h
> @@ -638,6 +638,13 @@ struct ofputil_table_mod {
>     uint32_t eviction_flags;    /* OFPTMPEF14_*. */
> };
> 
> +/* Abstract ofp14_table_desc. */
> +struct ofputil_table_desc {
> +    uint8_t table_id;         /* ID of the table. */
> +    enum ofputil_table_eviction eviction;
> +    uint32_t eviction_flags;    /* UINT32_MAX if not present. */
> +};
> +
> enum ofperr ofputil_decode_table_mod(const struct ofp_header *,
>                                     struct ofputil_table_mod *);
> struct ofpbuf *ofputil_encode_table_mod(const struct ofputil_table_mod *,
> @@ -726,11 +733,22 @@ struct ofputil_table_features {
> 
> int ofputil_decode_table_features(struct ofpbuf *,
>                                   struct ofputil_table_features *, bool 
> loose);
> +
> +int ofputil_decode_table_desc(struct ofpbuf *,
> +                              struct ofputil_table_desc *,
> +                              enum ofp_version);
> +
> struct ofpbuf *ofputil_encode_table_features_request(enum ofp_version);
> 
> +struct ofpbuf *ofputil_encode_table_desc_request(enum ofp_version);
> +
> void ofputil_append_table_features_reply(
>     const struct ofputil_table_features *tf, struct ovs_list *replies);
> 
> +void ofputil_append_table_desc_reply(const struct ofputil_table_desc *td,
> +                                     struct ovs_list *replies,
> +                                     enum ofp_version);
> +
> /* Meter band configuration for all supported band types. */
> struct ofputil_meter_band {
>     uint16_t type;
> @@ -857,6 +875,9 @@ struct ofputil_table_stats {
> };
> 
> struct ofpbuf *ofputil_encode_table_stats_reply(const struct ofp_header *rq);
> +
> +struct ofpbuf *ofputil_encode_table_desc_reply(const struct ofp_header *rq);
> +
> void ofputil_append_table_stats_reply(struct ofpbuf *reply,
>                                       const struct ofputil_table_stats *,
>                                       const struct ofputil_table_features *);
> diff --git a/lib/rconn.c b/lib/rconn.c
> index 776ab9e..37adfa2 100644
> --- a/lib/rconn.c
> +++ b/lib/rconn.c
> @@ -1365,6 +1365,8 @@ is_admitted_msg(const struct ofpbuf *b)
>     case OFPTYPE_GROUP_FEATURES_STATS_REPLY:
>     case OFPTYPE_TABLE_FEATURES_STATS_REQUEST:
>     case OFPTYPE_TABLE_FEATURES_STATS_REPLY:
> +    case OFPTYPE_TABLE_DESC_REQUEST:
> +    case OFPTYPE_TABLE_DESC_REPLY:
>         return false;
> 
>     case OFPTYPE_PACKET_IN:
> diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
> index 970aca3..7ca6504 100644
> --- a/ofproto/ofproto.c
> +++ b/ofproto/ofproto.c
> @@ -3576,6 +3576,47 @@ handle_table_features_request(struct ofconn *ofconn,
>     return 0;
> }
> 
> +/* This function queries the database for dumping table-desc. */
> +static void
> +query_tables_desc(struct ofproto *ofproto, struct ofputil_table_desc **descp)
> +{
> +    struct ofputil_table_desc *table_desc;
> +    size_t i;
> +
> +    table_desc = *descp = xcalloc(ofproto->n_tables, sizeof *table_desc);
> +    for (i = 0; i < ofproto->n_tables; i++) {
> +        struct ofputil_table_desc *td = &table_desc[i];
> +        td->table_id = i;
> +        td->eviction = (ofproto->tables[i].eviction & EVICTION_OPENFLOW
> +                        ? OFPUTIL_TABLE_EVICTION_ON
> +                        : OFPUTIL_TABLE_EVICTION_OFF);
> +        td->eviction_flags = OFPROTO_EVICTION_FLAGS;
> +    }
> +}
> +
> +/* Function to handle dump-table-desc request. */
> +static enum ofperr
> +handle_table_desc_request(struct ofconn *ofconn,
> +                          const struct ofp_header *request)
> +{
> +    struct ofproto *ofproto = ofconn_get_ofproto(ofconn);
> +    struct ofputil_table_desc *table_desc;
> +    struct ovs_list replies;
> +    size_t i;
> +
> +    query_tables_desc(ofproto, &table_desc);
> +    ofpmp_init(&replies, request);
> +    for (i = 0; i < ofproto->n_tables; i++) {
> +        if (!(ofproto->tables[i].flags & OFTABLE_HIDDEN)) {
> +            ofputil_append_table_desc_reply(&table_desc[i], &replies,
> +                                            request->version);
> +        }
> +    }
> +    ofconn_send_replies(ofconn, &replies);
> +    free(table_desc);
> +    return 0;
> +}
> +
> static void
> append_port_stat(struct ofport *port, struct ovs_list *replies)
> {
> @@ -7105,6 +7146,9 @@ handle_openflow__(struct ofconn *ofconn, const struct 
> ofpbuf *msg)
>     case OFPTYPE_TABLE_FEATURES_STATS_REQUEST:
>         return handle_table_features_request(ofconn, oh);
> 
> +    case OFPTYPE_TABLE_DESC_REQUEST:
> +        return handle_table_desc_request(ofconn, oh);
> +
>     case OFPTYPE_PORT_STATS_REQUEST:
>         return handle_port_stats_request(ofconn, oh);
> 
> @@ -7176,6 +7220,7 @@ handle_openflow__(struct ofconn *ofconn, const struct 
> ofpbuf *msg)
>     case OFPTYPE_METER_CONFIG_STATS_REPLY:
>     case OFPTYPE_METER_FEATURES_STATS_REPLY:
>     case OFPTYPE_TABLE_FEATURES_STATS_REPLY:
> +    case OFPTYPE_TABLE_DESC_REPLY:
>     case OFPTYPE_ROLE_STATUS:
>     case OFPTYPE_NXT_GENEVE_TABLE_REPLY:
>     default:
> diff --git a/ovn/controller/ofctrl.c b/ovn/controller/ofctrl.c
> index 8405001..2c424a6 100644
> --- a/ovn/controller/ofctrl.c
> +++ b/ovn/controller/ofctrl.c
> @@ -225,6 +225,8 @@ ofctrl_recv(const struct ofpbuf *msg)
>     case OFPTYPE_METER_FEATURES_STATS_REPLY:
>     case OFPTYPE_TABLE_FEATURES_STATS_REQUEST:
>     case OFPTYPE_TABLE_FEATURES_STATS_REPLY:
> +    case OFPTYPE_TABLE_DESC_REQUEST:
> +    case OFPTYPE_TABLE_DESC_REPLY:
>     case OFPTYPE_BUNDLE_CONTROL:
>     case OFPTYPE_BUNDLE_ADD_MESSAGE:
>     case OFPTYPE_NXT_GENEVE_TABLE_MOD:
> diff --git a/tests/ofproto.at b/tests/ofproto.at
> index 54c077d..232dd2f 100644
> --- a/tests/ofproto.at
> +++ b/tests/ofproto.at
> @@ -1664,6 +1664,28 @@ AT_CHECK([ovs-ofctl -O OpenFlow13 dump-table-features 
> br0 | sed '/^$/d
> OVS_VSWITCHD_STOP
> AT_CLEANUP
> 
> +AT_SETUP([ofproto - table description (OpenFlow 1.4)])
> +OVS_VSWITCHD_START
> +(x=0
> + while test $x -lt 254; do
> +   y=`expr $x + 1`
> +   echo "  table $x:
> +   eviction=off eviction_flags=OTHER|IMPORTANCE|LIFETIME"
> +   x=$y
> + done) > expout
> +AT_CHECK([ovs-ofctl -O OpenFlow14 dump-table-desc br0 | sed '/^$/d
> +/^OFPST_TABLE_DESC/d'], [0], [expout])
> +
> +# Change the configuration.
> +AT_CHECK([ovs-ofctl -O Openflow14 mod-table br0 0 evict])
> +# Check that the configuration was updated.
> +mv expout orig-expout
> +sed -e '2s/eviction=off/eviction=on/' <orig-expout > expout
> +AT_CHECK([ovs-ofctl -O OpenFlow14 dump-table-desc br0 | sed '/^$/d
> +/^OFPST_TABLE_DESC/d'], [0], [expout])
> +OVS_VSWITCHD_STOP
> +AT_CLEANUP
> +
> AT_SETUP([ofproto - hard limits on flow table size (OpenFlow 1.0)])
> OVS_VSWITCHD_START
> # Configure a maximum of 4 flows.
> diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in
> index 058d205..0a40efa 100644
> --- a/utilities/ovs-ofctl.8.in
> +++ b/utilities/ovs-ofctl.8.in
> @@ -62,6 +62,10 @@ Prints to the console statistics for each of the flow 
> tables used by
> \fBdump\-table\-features \fIswitch\fR
> Prints to the console features for each of the flow tables used by
> \fIswitch\fR.
> +.TP
> +\fBdump\-table\-desc \fIswitch\fR
> +Prints to the console configuration for each of the flow tables used
> +by \fIswitch\fR for OpenFlow 1.4+.
> .IP "\fBmod\-table \fIswitch\fR \fItable_id\fR \fIsetting\fR"
> This command configures flow table settings for OpenFlow table
> \fItable_id\fR within \fIswitch\fR.  The available settings depend on
> diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
> index f16cc25..566a6b4 100644
> --- a/utilities/ovs-ofctl.c
> +++ b/utilities/ovs-ofctl.c
> @@ -338,6 +338,7 @@ usage(void)
>            "  dump-desc SWITCH            print switch description\n"
>            "  dump-tables SWITCH          print table stats\n"
>            "  dump-table-features SWITCH  print table features\n"
> +           "  dump-table-desc SWITCH      print table description (OF1.4+)\n"
>            "  mod-port SWITCH IFACE ACT   modify port behavior\n"
>            "  mod-table SWITCH MOD        modify flow table behavior\n"
>            "      OF1.1/1.2 MOD: controller, continue, drop\n"
> @@ -737,6 +738,22 @@ ofctl_dump_table_features(struct ovs_cmdl_context *ctx)
>     vconn_close(vconn);
> }
> 
> +static void
> +ofctl_dump_table_desc(struct ovs_cmdl_context *ctx)
> +{
> +    struct ofpbuf *request;
> +    struct vconn *vconn;
> +
> +    open_vconn(ctx->argv[1], &vconn);
> +    request = ofputil_encode_table_desc_request(vconn_get_version(vconn));
> +    if (request) {
> +        dump_stats_transaction(vconn, request);
> +    }
> +
> +    vconn_close(vconn);
> +}
> +
> +
> static bool fetch_port_by_stats(struct vconn *,
>                                 const char *port_name, ofp_port_t port_no,
>                                 struct ofputil_phy_port *);
> @@ -3612,6 +3629,8 @@ static const struct ovs_cmdl_command all_commands[] = {
>       1, 1, ofctl_dump_tables },
>     { "dump-table-features", "switch",
>       1, 1, ofctl_dump_table_features },
> +    { "dump-table-desc", "switch",
> +      1, 1, ofctl_dump_table_desc },
>     { "dump-flows", "switch",
>       1, 2, ofctl_dump_flows },
>     { "dump-aggregate", "switch",
> -- 
> 2.1.3
> 

_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev

Reply via email to