Hi Team,

Kindly ignore previous Patch because that contains some garbage value due to 
text editor. Please use 
latest mail for the patch.

Thanks & Regards,
Hiteshi Madan


-----"dev" <dev-boun...@openvswitch.org> wrote: -----
To: dev@openvswitch.org
From: hiteshi.ma...@tcs.com
Sent by: "dev" 
Date: 11/03/2014 05:03PM
Cc: deepankar.gu...@tcs.com, partha.da...@tcs.com
Subject: Re: [ovs-dev] [PATCH] ovs-ofctl: Implementation of eviction on the 
basis of Importance

Hi Team,

Kindly apply following 5 patches before applying patch for eviction:
[PATCH 1/5] ovs-ofctl:To set importance of a rule for eviction(OF14)
[PATCH 2/5] ovs-ofctl:Changes made to DESIGN and added  test cases(OF14)
[PATCH 3/5] ovs-ofctl:Enhanced diff-flows &     replace-flows(OF14)
[PATCH 4/5] ovs-ofctl:Test Case for replace-flows(OF14)
[PATCH 5/5] ovs-ofctl : Setting of importance parameter
Thanks & Regards,
HIteshi Madan

-----Hiteshi Madan/DEL/TCS wrote: -----
To: dev@openvswitch.org, "Ben Pfaff" <b...@nicira.com>
From: Hiteshi Madan/DEL/TCS
Date: 11/03/2014 04:54PM
Cc: Partha Datta/DEL/TCS@TCS, Deepankar Gupta/DEL/TCS@TCS
Subject: [PATCH] ovs-ofctl: Implementation of eviction on the basis of 
Importance

From: root <root@TCS.(none)>

This commit enables the eviction mechanism on the basis of importance as
per the openflow specification 1.4.

ovs-ofctl mod-table <bridge> <table> evict
Enable eviction on <table> of <bridge>. Eviction adds a mechanism
enabling the switch to automatically eliminate entries of lower
importance to make space for newer entries. This enables to smoother
degradation of behaviour when the table is full. If want to enable eviction
on all tables, user can set the <table> as 'all'.

ovs-ofctl dump-tables-desc <bridge>
This command provides a way to list the current configuration
(eviction for importance) of the tables on a <bridge>, which is set
using the mod-table command.

Signed-off-by:saloni.j...@tcs.com
---
 include/openflow/openflow-1.4.h |   10 ++
 lib/learning-switch.c           |    2 +
 lib/ofp-msgs.h                  |   10 ++
 lib/ofp-parse.c                 |    4 +
 lib/ofp-print.c                 |   59 +++++++++
 lib/ofp-util.c                  |  275 ++++++++++++++++++++++++++++++++++++++-
 lib/ofp-util.h                  |   47 +++++++
 lib/rconn.c                     |    2 +
 ofproto/ofproto-provider.h      |    1 +
 ofproto/ofproto.c               |  134 +++++++++++++++++--
 tests/ofproto.at                |  105 +++++++++++++++
 utilities/ovs-ofctl.c           |   20 +++
 12 files changed, 655 insertions(+), 14 deletions(-)

diff --git a/include/openflow/openflow-1.4.h b/include/openflow/openflow-1.4.h
index 2a765cf..dcb4439 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 e3b48d5..5b8ac07 100644
--- a/lib/learning-switch.c
+++ b/lib/learning-switch.c
@@ -438,6 +438,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:
     default:
diff --git a/lib/ofp-msgs.h b/lib/ofp-msgs.h
index a78747e..18a6f32 100644
--- a/lib/ofp-msgs.h
+++ b/lib/ofp-msgs.h
@@ -367,6 +367,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. */
@@ -598,6 +604,10 @@ enum ofptype {
     OFPTYPE_TABLE_FEATURES_STATS_REQUEST, /* 
OFPRAW_OFPST13_TABLE_FEATURES_REQUEST. */
 
     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-parse.c b/lib/ofp-parse.c
index f7cf10d..d99069f 100644
--- a/lib/ofp-parse.c
+++ b/lib/ofp-parse.c
@@ -867,6 +867,10 @@ parse_ofp_table_mod(struct ofputil_table_mod *tm, const 
char *table_id,
         tm->miss_config = OFPUTIL_TABLE_MISS_CONTINUE;
     } else if (strcmp(flow_miss_handling, "drop") == 0) {
         tm->miss_config = OFPUTIL_TABLE_MISS_DROP;
+    } else if (strcmp(flow_miss_handling, "evict") == 0) {
+        tm->config = OFPUTIL_TABLE_CONFIG_EVICTION;ÿ 
+ÿÿÿ } else if (strcmp(flow_miss_handling, "noevict") == 0) {ÿ 
+ÿÿÿÿÿÿÿ tm->config = OFPUTIL_TABLE_CONFIG_NO_EVICTION;ÿ 
ÿÿÿÿ } else {
ÿÿÿÿÿÿÿÿ return xasprintf("invalid flow_miss_handling %s", flow_miss_handling);
ÿÿÿÿ }
diff --git a/lib/ofp-print.c b/lib/ofp-print.c
index 90df745..3559486 100644
--- a/lib/ofp-print.c
+++ b/lib/ofp-print.c
@@ -978,6 +978,27 @@ ofp_print_table_miss_config(struct ds *string, enum 
ofputil_table_miss miss)
&#732;&#732;&#732;&#732; }
&#732;}
&#732;
+/* This Function will print the config properties of table set through 
mod-table command */
+static void
+ofp_print_table_config(struct ds *string, const struct ofputil_table_desc *td)
+{
+&#732;&#732;&#732; switch (td->config) {
+&#732;&#732;&#732; case OFPUTIL_TABLE_CONFIG_EVICTION:
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; ds_put_cstr(string, "Eviction");
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; if (td->evict.flags & 
OFPUTIL_TABLE_EVICTION_IMPORTANCE) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; 
ds_put_cstr(string, "&#732;&#732;&#732; flag: Importance\n");
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; }&#732; 
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; break;
+&#732;&#732;&#732; case OFPUTIL_TABLE_CONFIG_NO_EVICTION:
+&#732;&#732;&#732; case OFPUTIL_TABLE_CONFIG_DEFAULT:
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; ds_put_cstr(string, "No 
Eviction\n");
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; break;
+&#732;&#732;&#732; default:
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; ds_put_format(string, "Unknown 
(%d)\n", td->config);
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; break;
+&#732;&#732;&#732; }
+}
+
&#732;static void
&#732;ofp_print_table_mod(struct ds *string, const struct ofp_header *oh)
&#732;{
@@ -1002,6 +1023,17 @@ ofp_print_table_mod(struct ds *string, const struct 
ofp_header *oh)
&#732;&#732;&#732;&#732; }
&#732;}
&#732;
+/* This function will print the Table description properties */
+static void
+ofp_print_table_desc(struct ds *string, const struct ofputil_table_desc *td)
+{
+&#732;&#732;&#732; ds_put_format(string, "\n&#732; table %"PRIu8, 
td->table_id);
+&#732;&#732;&#732; ds_put_cstr(string, ":\n");
+
+&#732;&#732;&#732; ds_put_cstr(string, "&#732;&#732; config= ");
+&#732;&#732;&#732; ofp_print_table_config(string, td);
+}
+
&#732;static void
&#732;ofp_print_queue_get_config_request(struct ds *string,
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 const struct ofp_header *oh)
@@ -2496,6 +2528,28 @@ ofp_print_table_features_reply(struct ds *s, const 
struct ofp_header *oh)
&#732;&#732;&#732;&#732; }
&#732;}
&#732;
+static void
+ofp_print_table_desc_reply(struct ds *s, const struct ofp_header *oh)
+{
+&#732;&#732;&#732; struct ofpbuf b;
+
+&#732;&#732;&#732; ofpbuf_use_const(&b, oh, ntohs(oh->length));
+
+&#732;&#732;&#732; for (;;) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; struct ofputil_table_desc td;
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; int retval;
+
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; retval = 
ofputil_decode_table_desc(&b, &td);
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; if (retval) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; if (retval 
!= EOF) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 ofp_print_error(s, retval);
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; }
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; return;
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; }
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; ofp_print_table_desc(s, &td);
+&#732;&#732;&#732; }
+}
+
&#732;static const char *
&#732;bundle_flags_to_name(uint32_t bit)
&#732;{
@@ -2624,6 +2678,11 @@ ofp_to_string__(const struct ofp_header *oh, enum ofpraw 
raw,
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; 
ofp_print_table_features_reply(string, oh);
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; break;
&#732;
+&#732;&#732;&#732; case OFPTYPE_TABLE_DESC_REQUEST:
+&#732;&#732;&#732; case OFPTYPE_TABLE_DESC_REPLY:
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; 
ofp_print_table_desc_reply(string, oh);
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; break;
+
&#732;&#732;&#732;&#732; case OFPTYPE_HELLO:
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; ofp_print_hello(string, oh);
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; break;
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index 02d102d..a7e5f9b 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -53,11 +53,54 @@ static struct vlog_rate_limit bad_ofmsg_rl = 
VLOG_RATE_LIMIT_INIT(1, 5);
&#732;static enum ofputil_table_miss ofputil_table_miss_from_config(
&#732;&#732;&#732;&#732; ovs_be32 config_, enum ofp_version);
&#732;
+static enum ofputil_table_config ofputil_table_utilconfig_from_config(
+&#732;&#732;&#732; ovs_be32 config_, enum ofp_version version);
+
+static const struct ovstableprop_map *get_ovsprop_map(void);
+
+ovs_be32 ovsprop_bitmap_to_openflow(uint32_t ovsprop_bitmap);
+
&#732;struct ofp_prop_header {
&#732;&#732;&#732;&#732; ovs_be16 type;
&#732;&#732;&#732;&#732; ovs_be16 len;
&#732;};
&#732;
+/* Two-way translation between OFPUTIL eviction flag and representation of
+ * eviction flags "OFPTMPEF_*" used in OpenFlow specification. */
+struct ovstableprop_map {
+&#732;&#732;&#732; enum ofputil_table_mod_prop_eviction_flag flag; /* Internal 
name for eviction flag. */
+&#732;&#732;&#732; int 
ofp_flag;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 /* OFPTMPEF_* number from OpenFlow spec. */
+};
+
+static const struct ovstableprop_map *
+get_ovsprop_map()
+{
+&#732;&#732;&#732; /* OpenFlow 1.4 eviction flags. */
+&#732;&#732;&#732; static const struct ovstableprop_map of14[] = {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; { OFPUTIL_TABLE_EVICTION_OTHER, 1 },
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; { 
OFPUTIL_TABLE_EVICTION_IMPORTANCE, 2 },
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; { OFPUTIL_TABLE_EVICTION_LIFETIME, 
4 },
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; { 0, -1 },
+&#732;&#732;&#732; };
+&#732;&#732;&#732; return of14;
+}
+
+/* Converts 'ovstableprop_bitmap', a bitmap whose bits correspond to OFPUTIL_*
+ * values, into a bitmap of eviction flags. */
+ovs_be32
+ovsprop_bitmap_to_openflow(uint32_t ovsprop_bitmap)
+{
+&#732;&#732;&#732; uint32_t ofpevict_bitmap = 0;
+&#732;&#732;&#732; const struct ovstableprop_map *x;
+
+&#732;&#732;&#732; for (x = get_ovsprop_map(); x->ofp_flag >= 0; x++) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; if (ovsprop_bitmap & (1u << 
x->flag)) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; 
ofpevict_bitmap |= 1u << x->ofp_flag;
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; }
+&#732;&#732;&#732; }
+&#732;&#732;&#732; return htonl(ofpevict_bitmap);
+}
+
&#732;/* Pulls a property, beginning with struct ofp_prop_header, from the 
beginning
&#732; * of 'msg'.&#732; Stores the type of the property in '*typep' and, if 
'property' is
&#732; * nonnull, the entire property, including the header, in 
'*property'.&#732; Returns
@@ -4552,6 +4595,25 @@ parse_instruction_ids(struct ofpbuf *payload, bool 
loose, uint32_t *insts)
&#732;}
&#732;
&#732;static enum ofperr
+parse_table_property(struct ofpbuf *payload, uint32_t *flags)
+{
+&#732;&#732;&#732; *flags = 0;
+&#732;&#732;&#732; while (ofpbuf_size(payload) > 0) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; enum ofperr error;
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; uint16_t ofp_flags = 0;
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; error = 
ofputil_pull_property__(payload, NULL, 1, &ofp_flags);
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; if (error) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; return 
error;
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; }
+&#732;&#732;&#732;&#732;&#732;&#732; /* ofp_flags contains the bitmap sent 
from vswitchd containing value of type eviction flags OFPTMPEF_*
+ * flags are calculated from this value of ofp_flags.
+ */&#732;&#732;&#732; 
+&#732;&#732;&#732;&#732;&#732;&#732; *flags |= 1u << ofp_flags;
+&#732;&#732;&#732; }
+&#732;&#732;&#732; return 0;
+}
+
+static enum ofperr
&#732;parse_table_features_next_table(struct ofpbuf *payload,
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 unsigned long int *next_tables)
&#732;{
@@ -4785,6 +4847,32 @@ ofputil_encode_table_features_request(enum ofp_version 
ofp_version)
&#732;&#732;&#732;&#732; return request;
&#732;}
&#732;
+/* Encodes and returns a request to obtain the table desc feature of a switch.
+ * The message is encoded for OpenFlow version 'ofp_version'.*/
+struct ofpbuf *
+ofputil_encode_table_desc_request(enum ofp_version ofp_version)
+{
+&#732;&#732;&#732; struct ofpbuf *request = NULL;
+
+&#732;&#732;&#732; switch (ofp_version) {
+&#732;&#732;&#732; case OFP10_VERSION:
+&#732;&#732;&#732; case OFP11_VERSION:
+&#732;&#732;&#732; case OFP12_VERSION:
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; ovs_fatal(0, "dump-table-desc needs 
OpenFlow 1.3 or later "
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 "(\'-O OpenFlow13\')");
+&#732;&#732;&#732; case OFP13_VERSION:
+&#732;&#732;&#732; case OFP14_VERSION:
+&#732;&#732;&#732; case OFP15_VERSION:
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; request = 
ofpraw_alloc(OFPRAW_OFPST14_TABLE_DESC_REQUEST,
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 ofp_version, 0);
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; break;
+&#732;&#732;&#732; default:
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; OVS_NOT_REACHED();
+&#732;&#732;&#732; }
+
+&#732;&#732;&#732; return request;
+}
+
&#732;static void
&#732;put_fields_property(struct ofpbuf *reply,
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 const struct mf_bitmap *fields,
@@ -4850,6 +4938,17 @@ put_table_instruction_features(
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 OFPTFPT13_APPLY_SETFIELD, miss_offset, version);
&#732;}
&#732;
+static void
+put_table_mod_eviction_property(struct ofpbuf *reply,
+ const struct ofputil_table_mod_prop_eviction *tme)
+{
+&#732;&#732;&#732; size_t start_ofs;
+&#732;&#732;&#732; start_ofs = start_property(reply, OFPTMPT14_EVICTION);
+&#732;&#732;&#732; put_bitmap_properties(reply,
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 ntohl(ovsprop_bitmap_to_openflow(tme->flags)));
+&#732;&#732;&#732; end_property(reply, start_ofs);
+}
+
&#732;void
&#732;ofputil_append_table_features_reply(const struct ofputil_table_features 
*tf,
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 struct list *replies)
@@ -4880,6 +4979,29 @@ ofputil_append_table_features_reply(const struct 
ofputil_table_features *tf,
&#732;&#732;&#732;&#732; ofpmp_postappend(replies, start_ofs);
&#732;}
&#732;
+/* Function to append Table desc information in a reply list. */
+void
+ofputil_append_table_desc_reply(const struct ofputil_table_desc *td,
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 struct list *replies)
+{
+&#732;&#732;&#732; struct ofpbuf *reply = ofpbuf_from_list(list_back(replies));
+&#732;&#732;&#732; enum ofp_version version = ofpmp_version(replies);
+&#732;&#732;&#732; size_t start_ofs = ofpbuf_size(reply);
+&#732;&#732;&#732; struct ofp14_table_desc *otd;
+&#732;&#732;&#732; enum ofputil_table_config config;
+
+&#732;&#732;&#732; otd = ofpbuf_put_zeros(reply, sizeof *otd);
+&#732;&#732;&#732; otd->table_id = td->table_id;
+&#732;&#732;&#732; config = ofputil_table_utilconfig_to_config(td->config, 
version);
+&#732;&#732;&#732; otd->config = config;
+&#732;&#732;&#732; if (td->config == OFPUTIL_TABLE_CONFIG_EVICTION) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; 
put_table_mod_eviction_property(reply, &td->evict);
+&#732;&#732;&#732; }
+&#732;&#732;&#732; otd = ofpbuf_at_assert(reply, start_ofs, sizeof *otd);
+&#732;&#732;&#732; otd->length = htons(ofpbuf_size(reply) - start_ofs);
+&#732;&#732;&#732; ofpmp_postappend(replies, start_ofs);
+}
+
&#732;/* ofputil_table_mod */
&#732;
&#732;/* Given 'config', taken from an OpenFlow 'version' message that specifies
@@ -4910,6 +5032,32 @@ ofputil_table_miss_from_config(ovs_be32 config_, enum 
ofp_version version)
&#732;&#732;&#732;&#732; }
&#732;}
&#732;
+
+/* Given 'config', taken from an OpenFlow 'version' message that specifies
+ * table configuration (a table mod message),
+ * returns the table configuration that it specifies.&#732; */
+static enum ofputil_table_config
+ofputil_table_utilconfig_from_config(ovs_be32 config_, enum ofp_version 
version)
+{
+&#732;&#732;&#732; uint32_t config = ntohl(config_);
+
+&#732;&#732;&#732; if (version >= OFP14_VERSION) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; switch (config) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; case OFPTC14_EVICTION:
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; return 
OFPUTIL_TABLE_CONFIG_EVICTION;
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; case OFPTC11_TABLE_MISS_MASK:
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; return 
OFPUTIL_TABLE_CONFIG_NO_EVICTION;
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; case 
OFPTC11_TABLE_MISS_CONTROLLER:&#732; /* for handling Default Value 0 */
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; return 
OFPUTIL_TABLE_CONFIG_DEFAULT;
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; default:
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; 
VLOG_WARN_RL(&bad_ofmsg_rl, "bad table config %d", config);
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; return 
OFPUTIL_TABLE_CONFIG_DEFAULT;
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; }
+&#732;&#732;&#732; } else {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; return OFPUTIL_TABLE_CONFIG_DEFAULT;
+&#732;&#732;&#732; }
+}
+
&#732;/* Given a table miss configuration, returns the corresponding OpenFlow 
table
&#732; * configuration for use in an OpenFlow message of the given 'version'. */
&#732;ovs_be32
@@ -4936,6 +5084,33 @@ ofputil_table_miss_to_config(enum ofputil_table_miss 
miss,
&#732;&#732;&#732;&#732; }
&#732;}
&#732;
+/* Given a table configuration, returns the corresponding OpenFlow table
+ * configuration for use in an OpenFlow message of the given 'version'.
+&#732;&#732; Point for using Miss Mask as return value of No Eviction
+ * OFPTC11_TABLE_MISS_MASK is using same value as OFPTC14_DEPRECATED_MASK
+ * as defined in Openflow 1.4. In openflow-common.h, OFPTC14_DEPRECATED_MASK
+ * is not defined. Hence using MISS_MASK value*/
+ovs_be32
+ofputil_table_utilconfig_to_config(enum ofputil_table_config config,
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 enum ofp_version version)
+{
+&#732;&#732;&#732; if (version >= OFP14_VERSION) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; switch (config) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; case OFPUTIL_TABLE_CONFIG_EVICTION:
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; return 
htonl(OFPTC14_EVICTION);
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; case 
OFPUTIL_TABLE_CONFIG_NO_EVICTION:
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; return 
htonl(OFPTC11_TABLE_MISS_MASK);&#732; 
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; case OFPUTIL_TABLE_CONFIG_DEFAULT:
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; return 
htonl(0);
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; default:
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; 
OVS_NOT_REACHED();
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; }
+&#732;&#732;&#732; } else {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; return htonl(0);
+&#732;&#732;&#732; }
+}
+
+
&#732;/* Decodes the OpenFlow "table mod" message in '*oh' into an abstract 
form in
&#732; * '*pm'.&#732; Returns 0 if successful, otherwise an OFPERR_* value. */
&#732;enum ofperr
@@ -4960,8 +5135,8 @@ ofputil_decode_table_mod(const struct ofp_header *oh,
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; pm->table_id = otm->table_id;
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; pm->miss_config = 
ofputil_table_miss_from_config(otm->config,
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 oh->version);
-&#732;&#732;&#732;&#732;&#732;&#732;&#732; /* We do not understand any 
properties yet, so we do not bother
-&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; * parsing them. */
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; pm->config = 
ofputil_table_utilconfig_from_config(otm->config,
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 oh->version);
&#732;&#732;&#732;&#732; } else {
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; return OFPERR_OFPBRC_BAD_TYPE;
&#732;&#732;&#732;&#732; }
@@ -4969,6 +5144,75 @@ ofputil_decode_table_mod(const struct ofp_header *oh,
&#732;&#732;&#732;&#732; return 0;
&#732;}
&#732;
+
+/* Decodes the OpenFlow "table desc" message in '*oh' into an abstract form in
+ * '*pd'.&#732; Returns 0 if successful, otherwise an OFPERR_* value. */
+int
+ofputil_decode_table_desc(struct ofpbuf *msg,
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 struct ofputil_table_desc *td)
+{
+&#732;&#732;&#732; const struct ofp_header *oh;
+&#732;&#732;&#732; struct ofp14_table_desc *otd;
+&#732;&#732;&#732; struct ofpbuf properties;
+&#732;&#732;&#732; unsigned int len;
+
+&#732;&#732;&#732; memset(td, 0, sizeof *td);
+
+&#732;&#732;&#732; if (!msg->frame) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; ofpraw_pull_assert(msg);
+&#732;&#732;&#732; }
+&#732;&#732;&#732; oh = ofpbuf_l2(msg);
+
+&#732;&#732;&#732; if (!ofpbuf_size(msg)) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; return EOF;
+&#732;&#732;&#732; }
+
+&#732;&#732;&#732; if (ofpbuf_size(msg) < sizeof *otd) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; return OFPERR_OFPBPC_BAD_LEN;
+&#732;&#732;&#732; }
+
+&#732;&#732;&#732; otd = ofpbuf_data(msg);
+&#732;&#732;&#732; len = ntohs(otd->length);
+&#732;&#732;&#732; if (len < sizeof *otd || len % 8 || len > ofpbuf_size(msg)) 
{
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; return OFPERR_OFPBPC_BAD_LEN;
+&#732;&#732;&#732; }
+&#732;&#732;&#732; ofpbuf_use_const(&properties, ofpbuf_pull(msg, len), len);
+&#732;&#732;&#732; ofpbuf_pull(&properties, sizeof *otd);
+
+&#732;&#732;&#732; td->table_id = otd->table_id;
+&#732;&#732;&#732; if (td->table_id == OFPTT_ALL) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; return OFPERR_OFPTFFC_BAD_TABLE;
+&#732;&#732;&#732; }
+
+&#732;&#732;&#732; td->config = 
ofputil_table_utilconfig_from_config(otd->config,
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 oh->version);
+&#732;&#732;&#732;&#732; while (ofpbuf_size(&properties) > 0) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; struct ofpbuf payload;
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; enum ofperr error;
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; uint16_t type;
+
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; error = 
pull_table_feature_property(&properties, &payload, &type);
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; if (error) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; return 
error;
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; }
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; switch ((enum 
ofp14_table_mod_prop_type) type) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; case OFPTMPT14_EVICTION:
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; error = 
parse_table_property(&payload, &td->evict.flags);
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; break;
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; case OFPTMPT14_VACANCY:
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; case OFPTMPT14_EXPERIMENTER:
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; default:
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; 
log_property(true, "unknown table features property %"PRIu16,
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 type);
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; break;
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; }
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; if (error) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; return 
error;
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; }
+&#732;&#732;&#732; }
+&#732;&#732;&#732; return 0;
+}
+
&#732;/* Converts the abstract form of a "table mod" message in '*pm' into an 
OpenFlow
&#732; * message suitable for 'protocol', and returns that encoded form in a 
buffer
&#732; * owned by the caller. */
@@ -5000,12 +5244,25 @@ ofputil_encode_table_mod(const struct ofputil_table_mod 
*pm,
&#732;&#732;&#732;&#732; case OFP14_VERSION:
&#732;&#732;&#732;&#732; case OFP15_VERSION: {
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; struct ofp14_table_mod *otm;
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; enum ofputil_table_config config ;
&#732;
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; b = 
ofpraw_alloc(OFPRAW_OFPT14_TABLE_MOD, ofp_version, 0);
-&#732;&#732;&#732;&#732;&#732;&#732;&#732; otm = ofpbuf_put_zeros(b, sizeof 
*otm);
-&#732;&#732;&#732;&#732;&#732;&#732;&#732; otm->table_id = pm->table_id;
-&#732;&#732;&#732;&#732;&#732;&#732;&#732; otm->config = 
ofputil_table_miss_to_config(pm->miss_config,
-&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 ofp_version);
+ otm = ofpbuf_put_zeros(b, sizeof *otm);
+ otm->table_id = pm->table_id;
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; /* As per the openflow 
specification miss_config is handled only for
+ * versions less&#732; than OFP13_VERSION so this handling is not required 
here.
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; 
+ miss_config = ofputil_table_miss_to_config(pm->miss_config,
+ ofp_version);*/
+
+ config = ofputil_table_utilconfig_to_config(pm->config,
+ ofp_version);
+
+&#732;&#732;&#732;&#732;&#732;&#732; /* Mod -table arguments are miss-config 
and config fields.
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; for handling both in 
Standard structure, we are doing following */
+ //otm->config = (miss_config | config);
+
+ otm->config = config;
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; break;
&#732;&#732;&#732;&#732; }
&#732;&#732;&#732;&#732; default:
@@ -5378,6 +5635,12 @@ ofputil_encode_table_stats_reply(const struct ofp_header 
*request)
&#732;&#732;&#732;&#732; return ofpraw_alloc_stats_reply(request, 0);
&#732;}
&#732;
+struct ofpbuf *
+ofputil_encode_table_desc_reply(const struct ofp_header *request)
+{
+&#732;&#732;&#732; return ofpraw_alloc_stats_reply(request, 0);
+}
+
&#732;void
&#732;ofputil_append_table_stats_reply(struct ofpbuf *reply,
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 const struct ofputil_table_stats *stats,
diff --git a/lib/ofp-util.h b/lib/ofp-util.h
index e3e11b4..cfe5de5 100644
--- a/lib/ofp-util.h
+++ b/lib/ofp-util.h
@@ -607,15 +607,43 @@ enum ofputil_table_miss {
&#732;&#732;&#732;&#732; 
OFPUTIL_TABLE_MISS_DROP,&#732;&#732;&#732;&#732;&#732;&#732; /* Drop the 
packet. */
&#732;};
&#732;
+/* Abstract version of OFPTC14_TABLE_CONFIG*.*/
+enum ofputil_table_config {
+&#732;&#732;&#732; OFPUTIL_TABLE_CONFIG_DEFAULT,&#732;&#732;&#732;&#732;&#732; 
/*&#732; Table Config default behaviour*/
+&#732;&#732;&#732; OFPUTIL_TABLE_CONFIG_EVICTION,&#732;&#732;&#732;&#732; 
/*&#732; Eviction for importance Configured */
+&#732;&#732;&#732; OFPUTIL_TABLE_CONFIG_NO_EVICTION,&#732; /*&#732; No 
Eviction for Table*/
+};
+
+/* Abstract version of OFPTMPEF_* */&#732; 
+enum ofputil_table_mod_prop_eviction_flag{
+&#732;&#732;&#732; OFPUTIL_TABLE_EVICTION_OTHER =&#732; 
1,&#732;&#732;&#732;&#732;&#732;&#732; /*&#732; Eviction Enabled Using other 
Factors */
+&#732;&#732;&#732; OFPUTIL_TABLE_EVICTION_IMPORTANCE = 2,&#732; /*&#732; 
Eviction Enabled Using flow entry importance */
+&#732;&#732;&#732; OFPUTIL_TABLE_EVICTION_LIFETIME = 4,&#732;&#732;&#732; 
/*&#732; Eviction Enabled Using flow entry lifetime */
+};
+
&#732;ovs_be32 ofputil_table_miss_to_config(enum ofputil_table_miss,
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 enum ofp_version);
&#732;
+ovs_be32 ofputil_table_utilconfig_to_config(enum ofputil_table_config config,
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 enum ofp_version version);
+
+
&#732;/* Abstract ofp_table_mod. */
&#732;struct ofputil_table_mod {
&#732;&#732;&#732;&#732; uint8_t 
table_id;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; /* ID of the table, 
0xff indicates all tables. */
+&#732;&#732;&#732; enum ofputil_table_config config;
&#732;&#732;&#732;&#732; enum ofputil_table_miss miss_config;
&#732;};
&#732;
+/* Abstract ofp14_table_desc. */
+struct ofputil_table_desc{
+&#732;&#732;&#732; uint8_t 
table_id;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; /* ID of the table, 
0xff indicates all tables. */
+&#732;&#732;&#732; enum ofputil_table_config config;
+&#732;&#732;&#732; struct ofputil_table_mod_prop_eviction{
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; uint32_t flags;
+&#732;&#732;&#732; }evict;
+};
+
&#732;enum ofperr ofputil_decode_table_mod(const struct ofp_header *,
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 struct ofputil_table_mod *);
&#732;struct ofpbuf *ofputil_encode_table_mod(const struct ofputil_table_mod *,
@@ -682,11 +710,27 @@ struct ofputil_table_features {
&#732;
&#732;int ofputil_decode_table_features(struct ofpbuf *,
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 struct ofputil_table_features *, bool loose);
+
+/* Eviction_Changes_1.4*/
+int ofputil_decode_table_desc(struct ofpbuf *,
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 struct ofputil_table_desc *);
&#732;struct ofpbuf *ofputil_encode_table_features_request(enum ofp_version);
+struct ofpbuf *ofputil_encode_table_desc_request(enum ofp_version);
&#732;
&#732;void ofputil_append_table_features_reply(
&#732;&#732;&#732;&#732; const struct ofputil_table_features *tf, struct list 
*replies);
&#732;
+/* Eviction_Changes_1.4*/
+void
+ofputil_append_table_desc_reply(const struct ofputil_table_desc *td,
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 struct list *replies);
+
+/* Eviction_Changes_1.4
+void
+ofputil_append_table_desc_reply(struct ofpbuf *buf,
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 const struct ofputil_table_desc *td);*/
+
+
&#732;/* Meter band configuration for all supported band types. */
&#732;struct ofputil_meter_band {
&#732;&#732;&#732;&#732; uint16_t type;
@@ -813,6 +857,9 @@ struct ofputil_table_stats {
&#732;};
&#732;
&#732;struct ofpbuf *ofputil_encode_table_stats_reply(const struct ofp_header 
*rq);
+
+struct ofpbuf *ofputil_encode_table_desc_reply(const struct ofp_header *rq);
+
&#732;void ofputil_append_table_stats_reply(struct ofpbuf *reply,
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 const struct ofputil_table_stats *,
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 const struct ofputil_table_features *);
diff --git a/lib/rconn.c b/lib/rconn.c
index 5c28806..46f08ff 100644
--- a/lib/rconn.c
+++ b/lib/rconn.c
@@ -1389,6 +1389,8 @@ is_admitted_msg(const struct ofpbuf *b)
&#732;&#732;&#732;&#732; case OFPTYPE_GROUP_FEATURES_STATS_REPLY:
&#732;&#732;&#732;&#732; case OFPTYPE_TABLE_FEATURES_STATS_REQUEST:
&#732;&#732;&#732;&#732; case OFPTYPE_TABLE_FEATURES_STATS_REPLY:
+&#732;&#732;&#732; case OFPTYPE_TABLE_DESC_REQUEST:
+&#732;&#732;&#732; case OFPTYPE_TABLE_DESC_REPLY:
&#732;&#732;&#732;&#732; case OFPTYPE_BUNDLE_CONTROL:
&#732;&#732;&#732;&#732; case OFPTYPE_BUNDLE_ADD_MESSAGE:
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; return false;
diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
index 8204862..69f878b 100644
--- a/ofproto/ofproto-provider.h
+++ b/ofproto/ofproto-provider.h
@@ -243,6 +243,7 @@ struct oftable {
&#732;
&#732;&#732;&#732;&#732; /* Table configuration. */
&#732;&#732;&#732;&#732; ATOMIC(enum ofputil_table_miss) miss_config;
+&#732;&#732;&#732; ATOMIC(enum ofputil_table_config) config;
&#732;
&#732;&#732;&#732;&#732; atomic_ulong n_matched;
&#732;&#732;&#732;&#732; atomic_ulong n_missed;
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index fd9822b..fa35a31 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -88,6 +88,8 @@ static void oftable_enable_eviction(struct oftable *,
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 const struct mf_subfield *fields,
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 size_t n_fields);
&#732;
+static void enable_eviction_for_importance(struct oftable *);
+
&#732;static void oftable_remove_rule(struct rule *rule) 
OVS_REQUIRES(ofproto_mutex);
&#732;static void oftable_remove_rule__(struct ofproto *, struct rule *)
&#732;&#732;&#732;&#732; OVS_REQUIRES(ofproto_mutex);
@@ -1286,7 +1288,7 @@ ofproto_configure_table(struct ofproto *ofproto, int 
table_id,
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; return;
&#732;&#732;&#732;&#732; }
&#732;
-&#732;&#732;&#732; if (s->groups) {
+&#732;&#732;&#732; if (s->groups || table->config == 
OFPUTIL_TABLE_CONFIG_EVICTION) {
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; oftable_enable_eviction(table, 
s->groups, s->n_groups);
&#732;&#732;&#732;&#732; } else {
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; 
oftable_disable_eviction(table);
@@ -3329,6 +3331,54 @@ handle_table_features_request(struct ofconn *ofconn,
&#732;&#732;&#732;&#732; return 0;
&#732;}
&#732;
+/* This function queries the database for dumping table-desc*/
+static void
+query_tables_desc(struct ofproto *ofproto,
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; 
struct ofputil_table_desc **descp)
+{
+&#732;&#732;&#732; struct&#732; ofputil_table_desc *table_desc;&#732; 
+&#732;&#732;&#732; size_t i;
+&#732;&#732;&#732; table_desc = *descp =&#732; xcalloc(ofproto->n_tables, 
sizeof *table_desc);
+&#732;&#732;&#732; for (i = 0; i < ofproto->n_tables; i++) {
+ struct ofputil_table_desc *td = &table_desc[i];
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; td->table_id = i;
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; 
atomic_read_relaxed(&ofproto->tables[i].config, &td->config);
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; if (td->config == 
OFPUTIL_TABLE_CONFIG_EVICTION) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; 
td->evict.flags = OFPUTIL_TABLE_EVICTION_IMPORTANCE;
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; }
+&#732;&#732;&#732; }
+}
+
+/* Function to handle dump-table-desc request */
+static enum ofperr
+handle_table_desc_request(struct ofconn *ofconn,
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 const struct ofp_header *request)
+{
+&#732;&#732;&#732; struct ofproto *ofproto = ofconn_get_ofproto(ofconn);
+&#732;&#732;&#732; struct&#732; ofputil_table_desc *table_desc;&#732; 
+&#732;&#732;&#732; struct list replies;
+&#732;&#732;&#732; struct ofpbuf msg;
+&#732;&#732;&#732; size_t i;
+
+&#732;&#732;&#732; ofpbuf_use_const(&msg, request, ntohs(request->length));
+&#732;&#732;&#732; ofpraw_pull_assert(&msg);
+&#732;&#732;&#732; if (ofpbuf_size(&msg) || ofpmp_more(request)) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; return OFPERR_OFPTFFC_EPERM;
+&#732;&#732;&#732; }
+&#732;&#732;&#732; query_tables_desc(ofproto, &table_desc);
+&#732;&#732;&#732; 
+&#732;&#732;&#732; ofpmp_init(&replies, request);
+&#732;&#732;&#732; for (i = 0; i < ofproto->n_tables; i++) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; if (!(ofproto->tables[i].flags & 
OFTABLE_HIDDEN)) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; 
ofputil_append_table_desc_reply(&table_desc[i], &replies);
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; }
+&#732;&#732;&#732; }
+&#732;&#732;&#732; ofconn_send_replies(ofconn, &replies);
+&#732;&#732;&#732; free(table_desc);
+
+&#732;&#732;&#732; return 0;
+}
+
&#732;static void
&#732;append_port_stat(struct ofport *port, struct list *replies)
&#732;{
@@ -5932,26 +5982,69 @@ ofproto_table_get_miss_config(const struct ofproto 
*ofproto, uint8_t table_id)
&#732;&#732;&#732;&#732; return value;
&#732;}
&#732;
+/* OFPUTIL_TABLE_CONFIG_NO_EVICTION and OFPUTIL_TABLE_CONFIG_DEFAULT
+ * these two values are considered different because we have to understand in 
switch
+ * that user wants to disable Eviction by explicitely giving Noevict or no 
value is passed
+ * at all which is default case */
&#732;static enum ofperr
&#732;table_mod(struct ofproto *ofproto, const struct ofputil_table_mod *tm)
&#732;{
&#732;&#732;&#732;&#732; if (!check_table_id(ofproto, tm->table_id)) {
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; return 
OFPERR_OFPTMFC_BAD_TABLE;
-&#732;&#732;&#732; } else if (tm->miss_config != OFPUTIL_TABLE_MISS_DEFAULT) {
+&#732;&#732;&#732; } else if (tm->config == OFPUTIL_TABLE_CONFIG_EVICTION) {
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; if (tm->table_id == OFPTT_ALL) 
{
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; int i;
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; for (i 
= 0; i < ofproto->n_tables; i++) {
-&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 atomic_store_relaxed(&ofproto->tables[i].miss_config,
-&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 tm->miss_config);
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 atomic_store_relaxed(&ofproto->tables[i].config,
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 tm->config);
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; 
enable_eviction_for_importance(&ofproto->tables[i]);
+&#732;&#732;&#732; }
+ } else {
+&#732;&#732;&#732; atomic_store_relaxed(&ofproto->tables[tm->table_id].config,
+ tm->config);
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; 
enable_eviction_for_importance(&ofproto->tables[tm->table_id]);
+ }
+&#732;&#732;&#732; } else if (tm->config == OFPUTIL_TABLE_CONFIG_NO_EVICTION) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; if (tm->table_id == OFPTT_ALL) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; int i;
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; for (i = 0; 
i < ofproto->n_tables; i++) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 atomic_store_relaxed(&ofproto->tables[i].config,
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 tm->config);
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 oftable_disable_eviction(&ofproto->tables[i]);
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; }
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; } else {
-&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; 
atomic_store_relaxed(&ofproto->tables[tm->table_id].miss_config,
-&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 tm->miss_config);
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; 
atomic_store_relaxed(&ofproto->tables[tm->table_id].config,
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 tm->config);
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; 
oftable_disable_eviction(&ofproto->tables[tm->table_id]);
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; }
&#732;&#732;&#732;&#732; }
+&#732;&#732;&#732; if (tm->miss_config != OFPUTIL_TABLE_MISS_DEFAULT) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; if (tm->table_id == OFPTT_ALL) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; int i;
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; for (i = 0; 
i < ofproto->n_tables; i++) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 atomic_store_relaxed(&ofproto->tables[i].miss_config,
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 tm->miss_config);
+&#732;&#732;&#732; }
+ } else {
+&#732;&#732;&#732; 
atomic_store_relaxed(&ofproto->tables[tm->table_id].miss_config,
+ tm->miss_config);
+&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; }
+&#732;&#732;&#732; }
&#732;&#732;&#732;&#732; return 0;
&#732;}
&#732;
+/* This function is only used when eviction is performed on the
+&#732;&#732; basis of importance. This function enables eviction on a 
particular table given */
+static void
+enable_eviction_for_importance(struct oftable *tables)
+{
+&#732;&#732;&#732; struct mf_subfield *field = NULL;
+&#732;&#732;&#732; size_t n_field = 0;
+&#732; 
+&#732;&#732; field = xmalloc(n_field* sizeof *field);
+&#732;&#732; oftable_enable_eviction(tables, field, n_field);
+}
+
&#732;static enum ofperr
&#732;handle_table_mod(struct ofconn *ofconn, const struct ofp_header *oh)
&#732;{
@@ -6139,6 +6232,9 @@ handle_openflow__(struct ofconn *ofconn, const struct 
ofpbuf *msg)
&#732;&#732;&#732;&#732; case OFPTYPE_TABLE_FEATURES_STATS_REQUEST:
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; return 
handle_table_features_request(ofconn, oh);
&#732;
+&#732;&#732;&#732; case OFPTYPE_TABLE_DESC_REQUEST:
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; return 
handle_table_desc_request(ofconn, oh);
+
&#732;&#732;&#732;&#732; case OFPTYPE_PORT_STATS_REQUEST:
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; return 
handle_port_stats_request(ofconn, oh);
&#732;
@@ -6204,6 +6300,7 @@ handle_openflow__(struct ofconn *ofconn, const struct 
ofpbuf *msg)
&#732;&#732;&#732;&#732; case OFPTYPE_METER_CONFIG_STATS_REPLY:
&#732;&#732;&#732;&#732; case OFPTYPE_METER_FEATURES_STATS_REPLY:
&#732;&#732;&#732;&#732; case OFPTYPE_TABLE_FEATURES_STATS_REPLY:
+&#732;&#732;&#732; case OFPTYPE_TABLE_DESC_REPLY:
&#732;&#732;&#732;&#732; case OFPTYPE_ROLE_STATUS:
&#732;&#732;&#732;&#732; default:
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; if 
(ofpmsg_is_stat_request(oh)) {
@@ -6457,7 +6554,7 @@ eviction_group_find(struct oftable *table, uint32_t id)
&#732;/* Returns an eviction priority for 'rule'.&#732; The return value should 
be
&#732; * interpreted so that higher priorities make a rule more attractive 
candidates
&#732; * for eviction.
- * Called only if have a timeout. */
+ * Called only if have a timeout and for eviction on basis of importance */
&#732;static uint32_t
&#732;rule_eviction_priority(struct ofproto *ofproto, struct rule *rule)
&#732;&#732;&#732;&#732; OVS_REQUIRES(ofproto_mutex)
@@ -6465,12 +6562,26 @@ rule_eviction_priority(struct ofproto *ofproto, struct 
rule *rule)
&#732;&#732;&#732;&#732; long long int expiration = LLONG_MAX;
&#732;&#732;&#732;&#732; long long int modified;
&#732;&#732;&#732;&#732; uint32_t expiration_offset;
+&#732;&#732;&#732; struct oftable *table = &ofproto->tables[rule->table_id];
+&#732;&#732;&#732; bool has_eviction_by_importance;&#732; 
&#732;
&#732;&#732;&#732;&#732; /* 'modified' needs protection even when we hold 
'ofproto_mutex'. */
&#732;&#732;&#732;&#732; ovs_mutex_lock(&rule->mutex);
&#732;&#732;&#732;&#732; modified = rule->modified;
&#732;&#732;&#732;&#732; ovs_mutex_unlock(&rule->mutex);
&#732;
+&#732;&#732; /* For eviction on basis of importance only those entries will be 
added which have
+&#732;&#732;&#732; * eviction fields set, importance parameter given in flow 
entry and table config parameter for eviction is set. */
+&#732;&#732;&#732; has_eviction_by_importance = (table->eviction_fields && 
rule->importance && table->config == OFPUTIL_TABLE_CONFIG_EVICTION);
+
+
+&#732;&#732; /* As per the openflow specification 1.4, flow entries with 
lesser importance will be evicted before flow entries with higher importance.
+&#732;&#732;&#732; * So invert the value of importance for calculating the 
rule eviction priority as higher priorities make a rule more
+&#732;&#732;&#732; * attractive candidates for eviction */
+&#732;&#732;&#732; if (has_eviction_by_importance) {
+&#732;&#732;&#732;&#732;&#732;&#732; return UINT32_MAX - 
(rule->importance);&#732; 
+&#732;&#732;&#732; }
+&#732;&#732;&#732; 
&#732;&#732;&#732;&#732; if (rule->hard_timeout) {
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; expiration = modified + 
rule->hard_timeout * 1000;
&#732;&#732;&#732;&#732; }
@@ -6512,12 +6623,18 @@ eviction_group_add_rule(struct rule *rule)
&#732;&#732;&#732;&#732; struct ofproto *ofproto = rule->ofproto;
&#732;&#732;&#732;&#732; struct oftable *table = 
&ofproto->tables[rule->table_id];
&#732;&#732;&#732;&#732; bool has_timeout;
+&#732;&#732;&#732; bool 
has_eviction_by_importance;&#732;&#732;&#732;&#732;&#732; 
&#732;
&#732;&#732;&#732;&#732; /* Timeouts may be modified only when holding 
'ofproto_mutex'.&#732; We have it
&#732;&#732;&#732;&#732;&#732; * so no additional protection is needed. */
&#732;&#732;&#732;&#732; has_timeout = rule->hard_timeout || rule->idle_timeout;
&#732;
-&#732;&#732;&#732; if (table->eviction_fields && has_timeout) {
+&#732;&#732; /* For eviction on basis of importance only those entries will be 
added which have
+&#732;&#732;&#732; * eviction fields set, importance parameter is not zero in 
flow entry and table config parameter for eviction is set.
+&#732;&#732;&#732; * All rules are added in a single group when eviction is 
done on basis of importance */
+&#732;&#732;&#732; has_eviction_by_importance = (table->eviction_fields && 
rule->importance && table->config == OFPUTIL_TABLE_CONFIG_EVICTION);
+
+&#732;&#732;&#732; if ((table->eviction_fields && has_timeout) || 
has_eviction_by_importance) {
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; struct eviction_group *evg;
&#732;
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732; evg = 
eviction_group_find(table, eviction_group_hash_rule(rule));
@@ -6539,6 +6656,7 @@ oftable_init(struct oftable *table)
&#732;&#732;&#732;&#732; classifier_init(&table->cls, flow_segment_u32s);
&#732;&#732;&#732;&#732; table->max_flows = UINT_MAX;
&#732;&#732;&#732;&#732; atomic_init(&table->miss_config, 
OFPUTIL_TABLE_MISS_DEFAULT);
+&#732;&#732;&#732; atomic_init(&table->config, OFPUTIL_TABLE_CONFIG_DEFAULT);
&#732;
&#732;&#732;&#732;&#732; classifier_set_prefix_fields(&table->cls, 
default_prefix_fields,
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 ARRAY_SIZE(default_prefix_fields));
diff --git a/tests/ofproto.at b/tests/ofproto.at
index 69f8dc9..6879e74 100644
--- a/tests/ofproto.at
+++ b/tests/ofproto.at
@@ -1269,6 +1269,111 @@ AT_CHECK([ovs-ofctl -O OpenFlow13 dump-table-features 
br0 | sed '/^$/d
&#732;OVS_VSWITCHD_STOP
&#732;AT_CLEANUP
&#732;
+AT_SETUP([ofproto - table description (OpenFlow 1.4)])
+OVS_VSWITCHD_START
+(x=0
+ while test $x -lt 254; do
+&#732;&#732; y=`expr $x + 1`
+&#732;&#732; echo "&#732; table $x:
+&#732;&#732; config= No Eviction"
+&#732;&#732; 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
+FLAG_STRING="&#732;&#732;&#732; flag: Importance"
+sed -e "2s/No Eviction/Eviction/
+2s/$/$FLAG_STRING/" <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 - eviction using importance upon table overflow (OpenFlow 
1.4)])
+OVS_VSWITCHD_START
+# Configure a maximum of 4 flows.
+AT_CHECK(
+&#732; [ovs-vsctl \
+&#732;&#732;&#732;&#732; -- --id=@t0 create Flow_Table flow-limit=4 \
+&#732;&#732;&#732;&#732; -- set bridge br0 flow_tables:0=@t0 \
+&#732;&#732; | ${PERL} $srcdir/uuidfilt.pl],
+&#732; [0], [<0>
+])
+# set the Eviction configuration.
+AT_CHECK([ovs-ofctl -O Openflow14 mod-table br0 0 evict])
+# Add 4 flows.
+for in_port in 4 3 2 1; do
+&#732;&#732;&#732; ovs-ofctl -O Openflow14 add-flow br0 importance=$((in_port 
+ 30)),priority=$((in_port + 5)),hard_timeout=$((in_port + 500)),actions=drop
+done
+AT_CHECK([ovs-ofctl -O Openflow14 dump-flows br0 | ofctl_strip | sort], [0], 
[dnl
+ hard_timeout=501, importance=31, priority=6 actions=drop
+ hard_timeout=502, importance=32, priority=7 actions=drop
+ hard_timeout=503, importance=33, priority=8 actions=drop
+ hard_timeout=504, importance=34, priority=9 actions=drop
+OFPST_FLOW reply (OF1.4):
+])
+# Adding another flow will cause the one with lowest importance to be evicted.
+AT_CHECK([ovs-ofctl -O Openflow14 add-flow br0 
hard_timeout=505,importance=35,priority=10,in_port=2,actions=drop])
+AT_CHECK([ovs-ofctl -O Openflow14 dump-flows br0 | ofctl_strip | sort], [0], 
[dnl
+ hard_timeout=502, importance=32, priority=7 actions=drop
+ hard_timeout=503, importance=33, priority=8 actions=drop
+ hard_timeout=504, importance=34, priority=9 actions=drop
+ hard_timeout=505, importance=35, priority=10,in_port=2 actions=drop
+OFPST_FLOW reply (OF1.4):
+])
+# Disable the Eviction configuration.
+AT_CHECK([ovs-ofctl -O Openflow14 mod-table br0 0 noevict])
+# Adding another flow will cause the system to give error for FULL TABLE.
+AT_CHECK([ovs-ofctl -O Openflow14 add-flow br0 
hard_timeout=506,importance=36,priority=11,actions=drop],[1], [], [stderr])
+AT_CHECK([head -n 1 stderr | ofctl_strip], [0],
+ [OFPT_ERROR (OF1.4): OFPFMFC_TABLE_FULL
+])
+#Dump flows. It should show only the old values
+AT_CHECK([ovs-ofctl -O Openflow14 dump-flows br0 | ofctl_strip | sort], [0], 
[dnl
+ hard_timeout=502, importance=32, priority=7 actions=drop
+ hard_timeout=503, importance=33, priority=8 actions=drop
+ hard_timeout=504, importance=34, priority=9 actions=drop
+ hard_timeout=505, importance=35, priority=10,in_port=2 actions=drop
+OFPST_FLOW reply (OF1.4):
+])
+# mod-flow that would modify a flow will be done successfully.
+AT_CHECK([ovs-ofctl -O Openflow14 mod-flows br0 in_port=2,actions=NORMAL])
+AT_CHECK([ovs-ofctl -O Openflow14 dump-flows br0 | ofctl_strip | sort], [0], 
[dnl
+ hard_timeout=502, importance=32, priority=7 actions=drop
+ hard_timeout=503, importance=33, priority=8 actions=drop
+ hard_timeout=504, importance=34, priority=9 actions=drop
+ hard_timeout=505, importance=35, priority=10,in_port=2 actions=NORMAL
+OFPST_FLOW reply (OF1.4):
+])
+# Also a mod-flow that would add a flow will be refused.
+AT_CHECK([ovs-ofctl mod-flows br0 in_port=5,actions=drop], [1], [], [stderr])
+AT_CHECK([head -n 1 stderr | ofctl_strip], [0],
+&#732; [OFPT_ERROR: OFPFMFC_TABLE_FULL
+])
+# Now set the eviction on timeout basis.
+AT_CHECK(
+&#732; [ovs-vsctl \
+&#732;&#732;&#732;&#732; -- --id=@t0 create Flow_Table flow-limit=4 
overflow-policy=evict \
+&#732;&#732;&#732;&#732; -- set bridge br0 flow_tables:0=@t0 \
+&#732;&#732; | ${PERL} $srcdir/uuidfilt.pl],
+&#732; [0], [<0>
+])
+#Now add a new flow
+AT_CHECK([ovs-ofctl -O Openflow14 add-flow br0 
importance=37,hard_timeout=507,priority=11,in_port=6,actions=drop])
+AT_CHECK([ovs-ofctl -O Openflow14 dump-flows br0 | ofctl_strip | sort], [0], 
[dnl
+ hard_timeout=503, importance=33, priority=8 actions=drop
+ hard_timeout=504, importance=34, priority=9 actions=drop
+ hard_timeout=505, importance=35, priority=10,in_port=2 actions=NORMAL
+ hard_timeout=507, importance=37, priority=11,in_port=6 actions=drop
+OFPST_FLOW reply (OF1.4):
+])
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
&#732;AT_SETUP([ofproto - hard limits on flow table size (OpenFlow 1.0)])
&#732;OVS_VSWITCHD_START
&#732;# Configure a maximum of 4 flows.
diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
index 67465ce..95d0616 100644
--- a/utilities/ovs-ofctl.c
+++ b/utilities/ovs-ofctl.c
@@ -699,6 +699,24 @@ ofctl_dump_table_features(int argc OVS_UNUSED, char 
*argv[])
&#732;&#732;&#732;&#732; vconn_close(vconn);
&#732;}
&#732;
+/* ovs-ofctl dump-table-desc provides a way to list the current configuration 
of
+ * the tables on a switch, which is set using the ovs-ofctl table-mod command. 
*/
+static void
+ofctl_dump_table_desc(int argc OVS_UNUSED, char *argv[])
+{
+&#732;&#732;&#732; struct ofpbuf *request;
+&#732;&#732;&#732; struct vconn *vconn;
+
+&#732;&#732;&#732; open_vconn(argv[1], &vconn);
+&#732;&#732;&#732; request = 
ofputil_encode_table_desc_request(vconn_get_version(vconn));
+&#732;&#732;&#732; if (request) {
+&#732;&#732;&#732;&#732;&#732;&#732;&#732; dump_stats_transaction(vconn, 
request);
+&#732;&#732;&#732; }
+
+&#732;&#732;&#732; vconn_close(vconn);
+}
+
+
&#732;static bool fetch_port_by_stats(struct vconn *,
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 const char *port_name, ofp_port_t port_no,
&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;&#732;
 struct ofputil_phy_port *);
@@ -3474,6 +3492,8 @@ static const struct command all_commands[] = {
&#732;&#732;&#732;&#732;&#732;&#732; 1, 1, ofctl_dump_tables },
&#732;&#732;&#732;&#732; { "dump-table-features", "switch",
&#732;&#732;&#732;&#732;&#732;&#732; 1, 1, ofctl_dump_table_features },
+&#732;&#732;&#732; { "dump-table-desc", "switch",
+&#732;&#732;&#732;&#732;&#732; 1, 1, ofctl_dump_table_desc},
&#732;&#732;&#732;&#732; { "dump-flows", "switch",
&#732;&#732;&#732;&#732;&#732;&#732; 1, 2, ofctl_dump_flows },
&#732;&#732;&#732;&#732; { "dump-aggregate", "switch",
-- 
1.7.9.5
ÿ
=====-----=====-----=====
Notice: The information contained in this e-mail
message and/or attachments to it may contain 
confidential or privileged information. If you are 
not the intended recipient, any dissemination, use, 
review, distribution, printing or copying of the 
information contained in this e-mail message 
and/or attachments to it are strictly prohibited. If 
you have received this communication in error, 
please notify us by reply e-mail or telephone and 
immediately and permanently delete the message 
and any attachments. Thank you


_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to