From: Muttamsetty surya <muttamsetty.su...@tcs.com> Signed-off-by: Muttamsetty Surya <muttamsetty.su...@tcs.com> Co-authored-by: Satya Valli <satyavalli.r...@tcs.com>
--- lib/ofp-util.c | 18 ++++++- lib/ox-stat.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/ox-stat.h | 3 ++ 3 files changed, 186 insertions(+), 1 deletion(-) diff --git a/lib/ofp-util.c b/lib/ofp-util.c index adb87eb..f0c96db 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -3289,6 +3289,12 @@ ofputil_encode_aggregate_stats_reply( enum ofpraw raw; ofpraw_decode(&raw, request); + if (raw == OFPRAW_OFPST15_OXS_AGGREGATE_REQUEST) { + enum ofp_version version = request->version; + + msg = ofpraw_alloc_stats_reply(request, 0); + oxs_put_agg_stat(msg, stats, version); + } else { if (raw == OFPRAW_OFPST10_AGGREGATE_REQUEST) { packet_count = unknown_to_zero(stats->packet_count); byte_count = unknown_to_zero(stats->byte_count); @@ -3302,6 +3308,7 @@ ofputil_encode_aggregate_stats_reply( put_32aligned_be64(&asr->packet_count, htonll(packet_count)); put_32aligned_be64(&asr->byte_count, htonll(byte_count)); asr->flow_count = htonl(stats->flow_count); + } return msg; } @@ -3311,12 +3318,21 @@ ofputil_decode_aggregate_stats_reply(struct ofputil_aggregate_stats *stats, const struct ofp_header *reply) { struct ofpbuf msg = ofpbuf_const_initializer(reply, ntohs(reply->length)); - ofpraw_pull_assert(&msg); + enum ofperr error; + enum ofpraw raw; + raw = ofpraw_pull_assert(&msg); + if (raw == OFPRAW_OFPST15_OXS_AGGREGATE_REPLY) { + memset(stats, 0, sizeof (*stats)); + error = oxs_pull_agg_stat(msg, stats); + if (error) + return error; + } else { struct ofp_aggregate_stats_reply *asr = msg.msg; stats->packet_count = ntohll(get_32aligned_be64(&asr->packet_count)); stats->byte_count = ntohll(get_32aligned_be64(&asr->byte_count)); stats->flow_count = ntohl(asr->flow_count); + } return 0; } diff --git a/lib/ox-stat.c b/lib/ox-stat.c index 8bea083..4cfcff7 100644 --- a/lib/ox-stat.c +++ b/lib/ox-stat.c @@ -148,11 +148,15 @@ static enum ofperr oxs_pull_match_entry(struct ofpbuf *b, static enum ofperr oxs_pull_raw(const uint8_t *, unsigned int , struct ofputil_flow_stats *fs, ovs_be64 * cookie, ovs_be64 * cookie_mask); +static enum ofperr oxs_pull_agg_raw(const uint8_t * p, unsigned int stat_len, + struct ofputil_aggregate_stats *fs); static void oxs_init(void); static void oxs_put_header__(struct ofpbuf *b, uint64_t header); static void oxs_put_header_len(struct ofpbuf *b, enum oxs_ofb_stat_fields field, enum ofp_version version); +static int ox_put_agg_raw(struct ofpbuf *b, enum ofp_version oxs, + const struct ofputil_aggregate_stats *fs); static bool is_experimenter_oxs(uint64_t header) @@ -400,6 +404,87 @@ oxs_pull_stat(struct ofpbuf *b, struct ofputil_flow_stats *fs, NULL); } +static enum ofperr +oxs_pull_agg_raw(const uint8_t * p, unsigned int stat_len, + struct ofputil_aggregate_stats *fs) +{ + struct ofpbuf b = ofpbuf_const_initializer(p, stat_len); + + while (b.size) { + + uint64_t header; + unsigned int payload_len; + const struct oxs_field *field; + const uint8_t *payload; + + oxs_pull_header__(&b, &header, &field); + payload_len = oxs_payload_len(header); + payload = ofpbuf_try_pull(&b, payload_len); + + if (fs && field) { + switch (field->id) { + case OFPXST_OFB_FLOW_COUNT: + { + uint32_t flow_count = 0; + + memcpy(&flow_count, payload, sizeof (flow_count)); + fs->flow_count = ntohl(flow_count); + } + break; + case OFPXST_OFB_PACKET_COUNT: + { + uint64_t packet_count; + + memcpy(&packet_count, payload, sizeof (packet_count)); + fs->packet_count = ntohll(packet_count); + } + break; + case OFPXST_OFB_BYTE_COUNT: + { + uint64_t byte_count; + + memcpy(&byte_count, payload, sizeof (byte_count)); + fs->byte_count = ntohll(byte_count); + } + break; + case OFPXST_OFB_DURATION: + case OFPXST_OFB_IDLE_TIME: + break; + } + + } + + } + return 0; +} + +/* Retrieve struct ofp_oxs_stat from 'b', followed by the aggregate flow entry + * statistics in OXS format. + * + * Returns error if message parsing fails, otherwise returns zero . */ +int +oxs_pull_agg_stat(struct ofpbuf b, struct ofputil_aggregate_stats *fs) +{ + struct ofp_oxs_stat *oxs = b.data; + uint8_t *p; + uint16_t stat_len; + + stat_len = ntohs(oxs->length); + + if (stat_len < sizeof *oxs) { + return OFPERR_OFPBMC_BAD_LEN; + } + + p = ofpbuf_try_pull(&b, ROUND_UP(stat_len, 8)); + if (!p) { + VLOG_DBG_RL(&rl, "oxs length %u, rounded up to a " + "multiple of 8, is longer than space in message (max " + "length %" PRIu32 ")", stat_len, b.size); + return OFPERR_OFPBMC_BAD_LEN; + } + + return oxs_pull_agg_raw(p + sizeof *oxs, stat_len - sizeof *oxs, fs); + } static struct hmap oxs_header_map; static struct hmap oxs_name_map; @@ -599,3 +684,84 @@ oxs_put_stat(struct ofpbuf *b, const struct ofputil_flow_stats *fs, return stat_len; } +/* Appends to 'b' the aggregate flow entry statistics in a flexible encoding, + * OXS format. + * + * OXS is a TLV format to express flow entry statistics. Specify the OpenFlow + * version in use as 'version'. + * + * Returns the number of bytes appended to 'b'. + * + * This function can cause 'b''s data to be reallocated. + * + * Returns zero or the number of bytes appended to 'b'. */ +static int +ox_put_agg_raw(struct ofpbuf *b, enum ofp_version oxs, + const struct ofputil_aggregate_stats *fs) +{ + const size_t start_len = b->size; + int stat_len; + + if (oxs_field_set & 1<<2) { + uint32_t flow_count = 0; + if(fs) { + flow_count=fs->flow_count; + flow_count=htonl(flow_count); + } + oxs_put__(b, OFPXST_OFB_FLOW_COUNT, oxs, &flow_count, + NULL, OXS_STATS_FLOW_COUNT_LEN); + } + + if (oxs_field_set & 1<<3) { + uint64_t pkt_count = 0; + if(fs) { + pkt_count = fs->packet_count; + pkt_count = htonll(pkt_count); + } + oxs_put__(b, OFPXST_OFB_PACKET_COUNT, oxs, &pkt_count, + NULL, OXS_STATS_PACKET_COUNT_LEN); + } + + if (oxs_field_set & 1<<4) { + uint64_t byte_count = 0; + if(fs) { + byte_count = fs->byte_count; + byte_count = htonll(byte_count); + } + oxs_put__(b, OFPXST_OFB_BYTE_COUNT, oxs, &byte_count, + NULL, OXS_STATS_BYTE_COUNT_LEN); + } + + stat_len = b->size - start_len; + return stat_len; +} + +/* Appends to 'b' an struct ofp_oxs_stat followed by the aggregate flow entry + * statistics in OXS format , plus enough zero bytes to pad the data appended + * out to a multiple of 8. + * + * Specify the OpenFlow version in use as 'version'. + * + * This function can cause 'b''s data to be reallocated. + * + * Returns the number of bytes appended to 'b', excluding the padding. Never + * returns zero. */ +int +oxs_put_agg_stat(struct ofpbuf *b, const struct ofputil_aggregate_stats *fs, + enum ofp_version version) +{ + int stat_len; + struct ofp_oxs_stat *oxs; + size_t start_len = b->size; + + ofpbuf_put_uninit(b, sizeof *oxs); + stat_len = (ox_put_agg_raw(b, version, fs) + + sizeof *oxs); + ofpbuf_put_zeros(b, PAD_SIZE(stat_len, 8)); + oxs = ofpbuf_at(b, start_len, sizeof *oxs); + oxs->reserved = htons(0); + oxs->length = htons(stat_len); + + return stat_len; +} + diff --git a/lib/ox-stat.h b/lib/ox-stat.h index 33c30ec..3ff7f07 100644 --- a/lib/ox-stat.h +++ b/lib/ox-stat.h @@ -30,4 +30,7 @@ int oxs_put_stat(struct ofpbuf *, const struct ofputil_flow_stats *, enum ofp_version ); int oxs_pull_stat(struct ofpbuf *,struct ofputil_flow_stats *, uint16_t *); +int oxs_put_agg_stat(struct ofpbuf *, const struct ofputil_aggregate_stats *, + enum ofp_version); +int oxs_pull_agg_stat(struct ofpbuf , struct ofputil_aggregate_stats *); #endif /* ox_stat.h */ -- 1.9.1 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev