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
