[ovs-dev] [PATCH 4/6] OF1.5/EXT-334 OXS/Aggregate Flow Statistics -2
muttamsetty.surya at gmail.com
muttamsetty.surya at gmail.com
Wed May 17 17:05:48 UTC 2017
From: Muttamsetty surya <muttamsetty.surya at tcs.com>
Signed-off-by: Muttamsetty Surya <muttamsetty.surya at tcs.com>
Co-authored-by: Satya Valli <satyavalli.rama at 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
More information about the dev
mailing list