From: rishibamba <rishiba...@users.noreply.github.com> This patch enables a user to set importance for a new rule via add-flow OF1.1+ in the OVS and display the same via dump-flows command OF1.1+ . The changes are made in accordance with OpenFlow 1.4 specs to implement Eviction on the basis of "importance".
Signed-off-by: Rishi Bamba <rishi.ba...@tcs.com> --- include/openflow/openflow-1.1.h | 5 +++-- lib/ofp-parse.c | 6 +++++- lib/ofp-print.c | 3 +++ lib/ofp-util.c | 8 ++++++++ lib/ofp-util.h | 3 +++ ofproto/ofproto-provider.h | 3 +++ ofproto/ofproto.c | 5 ++++- 7 files changed, 29 insertions(+), 4 deletions(-) diff --git a/include/openflow/openflow-1.1.h b/include/openflow/openflow-1.1.h index f87c5cf..d881192 100644 --- a/include/openflow/openflow-1.1.h +++ b/include/openflow/openflow-1.1.h @@ -340,7 +340,7 @@ struct ofp11_flow_mod { output group. A value of OFPG11_ANY indicates no restriction. */ ovs_be16 flags; /* One of OFPFF_*. */ - uint8_t pad[2]; + ovs_be16 importance; /* Eviction Precedence */ /* Followed by an ofp11_match structure. */ /* Followed by an instruction set. */ }; @@ -451,7 +451,8 @@ struct ofp11_flow_stats { ovs_be16 idle_timeout; /* Number of seconds idle before expiration. */ ovs_be16 hard_timeout; /* Number of seconds before expiration. */ ovs_be16 flags; /* OF 1.3: Set of OFPFF*. */ - uint8_t pad2[4]; /* Align to 64-bits. */ + ovs_be16 importance; /* Eviction Precedence */ + uint8_t pad2[2]; /* Align to 64-bits. */ ovs_be64 cookie; /* Opaque controller-issued identifier. */ ovs_be64 packet_count; /* Number of packets in flow. */ ovs_be64 byte_count; /* Number of bytes in flow. */ diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c index 729139f..e82485b 100644 --- a/lib/ofp-parse.c +++ b/lib/ofp-parse.c @@ -248,6 +248,7 @@ parse_ofp_str__(struct ofputil_flow_mod *fm, int command, char *string, enum { F_OUT_PORT = 1 << 0, F_ACTIONS = 1 << 1, + F_IMPORTANCE=1 << 2, F_TIMEOUT = 1 << 3, F_PRIORITY = 1 << 4, F_FLAGS = 1 << 5, @@ -264,7 +265,7 @@ parse_ofp_str__(struct ofputil_flow_mod *fm, int command, char *string, break; case OFPFC_ADD: - fields = F_ACTIONS | F_TIMEOUT | F_PRIORITY | F_FLAGS; + fields = F_ACTIONS | F_TIMEOUT | F_PRIORITY | F_FLAGS | F_IMPORTANCE; break; case OFPFC_DELETE: @@ -305,6 +306,7 @@ parse_ofp_str__(struct ofputil_flow_mod *fm, int command, char *string, fm->buffer_id = UINT32_MAX; fm->out_port = OFPP_ANY; fm->flags = 0; + fm->importance = OFP_FLOW_PERMANENT; fm->out_group = OFPG11_ANY; fm->delete_reason = OFPRR_DELETE; if (fields & F_ACTIONS) { @@ -366,6 +368,8 @@ parse_ofp_str__(struct ofputil_flow_mod *fm, int command, char *string, error = str_to_u16(value, name, &fm->idle_timeout); } else if (fields & F_TIMEOUT && !strcmp(name, "hard_timeout")) { error = str_to_u16(value, name, &fm->hard_timeout); + } else if (fields & F_IMPORTANCE && !strcmp(name, "importance")) { + error = str_to_u16(value, name, &fm->importance); } else if (!strcmp(name, "cookie")) { char *mask = strchr(value, '/'); diff --git a/lib/ofp-print.c b/lib/ofp-print.c index 43bfa17..7f45858 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -1431,6 +1431,9 @@ ofp_print_flow_stats(struct ds *string, struct ofputil_flow_stats *fs) if (fs->flags) { ofp_print_flow_flags(string, fs->flags); } + if (fs->importance != OFP_FLOW_PERMANENT) { + ds_put_format(string, "importance=%"PRIu16", ", fs->importance); + } if (fs->idle_age >= 0) { ds_put_format(string, "idle_age=%d, ", fs->idle_age); } diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 573f38a..02d102d 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -1700,6 +1700,7 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm, fm->idle_timeout = ntohs(ofm->idle_timeout); fm->hard_timeout = ntohs(ofm->hard_timeout); + fm->importance = ntohs(ofm->importance); fm->buffer_id = ntohl(ofm->buffer_id); error = ofputil_port_from_ofp11(ofm->out_port, &fm->out_port); if (error) { @@ -1738,6 +1739,7 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm, fm->new_cookie = ofm->cookie; fm->idle_timeout = ntohs(ofm->idle_timeout); fm->hard_timeout = ntohs(ofm->hard_timeout); + fm->importance = 0; fm->buffer_id = ntohl(ofm->buffer_id); fm->out_port = u16_to_ofp(ntohs(ofm->out_port)); fm->out_group = OFPG11_ANY; @@ -1765,6 +1767,7 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm, fm->new_cookie = nfm->cookie; fm->idle_timeout = ntohs(nfm->idle_timeout); fm->hard_timeout = ntohs(nfm->hard_timeout); + fm->importance = 0; fm->buffer_id = ntohl(nfm->buffer_id); fm->out_port = u16_to_ofp(ntohs(nfm->out_port)); fm->out_group = OFPG11_ANY; @@ -2248,6 +2251,7 @@ ofputil_encode_flow_mod(const struct ofputil_flow_mod *fm, ofm->out_port = ofputil_port_to_ofp11(fm->out_port); ofm->out_group = htonl(fm->out_group); ofm->flags = raw_flags; + ofm->importance = htons(fm->importance); ofputil_put_ofp11_match(msg, &fm->match, protocol); ofpacts_put_openflow_instructions(fm->ofpacts, fm->ofpacts_len, msg, version); @@ -2834,6 +2838,7 @@ ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *fs, fs->duration_nsec = ntohl(ofs->duration_nsec); fs->idle_timeout = ntohs(ofs->idle_timeout); fs->hard_timeout = ntohs(ofs->hard_timeout); + fs->importance = ntohs(ofs->importance); if (raw == OFPRAW_OFPST13_FLOW_REPLY) { error = ofputil_decode_flow_mod_flags(ofs->flags, -1, oh->version, &fs->flags); @@ -2875,6 +2880,7 @@ ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *fs, fs->duration_nsec = ntohl(ofs->duration_nsec); fs->idle_timeout = ntohs(ofs->idle_timeout); fs->hard_timeout = ntohs(ofs->hard_timeout); + fs->importance = 0; fs->idle_age = -1; fs->hard_age = -1; fs->packet_count = ntohll(get_32aligned_be64(&ofs->packet_count)); @@ -2910,6 +2916,7 @@ ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *fs, fs->priority = ntohs(nfs->priority); fs->idle_timeout = ntohs(nfs->idle_timeout); fs->hard_timeout = ntohs(nfs->hard_timeout); + fs->importance = 0; fs->idle_age = -1; fs->hard_age = -1; if (flow_age_extension) { @@ -2977,6 +2984,7 @@ ofputil_append_flow_stats_reply(const struct ofputil_flow_stats *fs, ofs->priority = htons(fs->priority); ofs->idle_timeout = htons(fs->idle_timeout); ofs->hard_timeout = htons(fs->hard_timeout); + ofs->importance = htons(fs->importance); if (raw == OFPRAW_OFPST13_FLOW_REPLY) { ofs->flags = ofputil_encode_flow_mod_flags(fs->flags, version); } else { diff --git a/lib/ofp-util.h b/lib/ofp-util.h index c9900d8..e3e11b4 100644 --- a/lib/ofp-util.h +++ b/lib/ofp-util.h @@ -306,6 +306,7 @@ struct ofputil_flow_mod { ofp_port_t out_port; uint32_t out_group; enum ofputil_flow_mod_flags flags; + uint16_t importance; /* Eviction Precedence */ struct ofpact *ofpacts; /* Series of "struct ofpact"s. */ size_t ofpacts_len; /* Length of ofpacts, in bytes. */ @@ -355,6 +356,7 @@ struct ofputil_flow_stats { const struct ofpact *ofpacts; size_t ofpacts_len; enum ofputil_flow_mod_flags flags; + uint16_t importance; /* Eviction Precedence */ }; int ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *, @@ -391,6 +393,7 @@ struct ofputil_flow_removed { uint16_t hard_timeout; uint64_t packet_count; /* Packet count, UINT64_MAX if unknown. */ uint64_t byte_count; /* Byte count, UINT64_MAX if unknown. */ + uint16_t importance; /* Eviction Precedence */ }; enum ofperr ofputil_decode_flow_removed(struct ofputil_flow_removed *, diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h index 14f1cba..8204862 100644 --- a/ofproto/ofproto-provider.h +++ b/ofproto/ofproto-provider.h @@ -346,6 +346,9 @@ struct rule { uint16_t hard_timeout OVS_GUARDED; /* In seconds from ->modified. */ uint16_t idle_timeout OVS_GUARDED; /* In seconds from ->used. */ + /* "Importance" is the eviction precedence of a flow */ + uint16_t importance OVS_GUARDED; + /* Eviction groups (see comment on struct eviction_group for explanation) . * * 'eviction_group' is this rule's eviction group, or NULL if it is not in diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 1233164..fd9822b 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -3809,6 +3809,7 @@ handle_flow_stats_request(struct ofconn *ofconn, fs.cookie = rule->flow_cookie; fs.idle_timeout = rule->idle_timeout; fs.hard_timeout = rule->hard_timeout; + fs.importance = rule->importance; created = rule->created; modified = rule->modified; actions = rule_get_actions(rule); @@ -4238,6 +4239,7 @@ add_flow(struct ofproto *ofproto, struct ofputil_flow_mod *fm, ovs_mutex_lock(&rule->mutex); rule->idle_timeout = fm->idle_timeout; rule->hard_timeout = fm->hard_timeout; + rule->importance = fm->importance; ovs_mutex_unlock(&rule->mutex); *CONST_CAST(uint8_t *, &rule->table_id) = table - ofproto->tables; @@ -4353,6 +4355,7 @@ modify_flows__(struct ofproto *ofproto, struct ofputil_flow_mod *fm, if (fm->command == OFPFC_ADD) { rule->idle_timeout = fm->idle_timeout; rule->hard_timeout = fm->hard_timeout; + rule->importance = fm->importance; rule->flags = fm->flags & OFPUTIL_FF_STATE; rule->created = now; } @@ -4366,7 +4369,7 @@ modify_flows__(struct ofproto *ofproto, struct ofputil_flow_mod *fm, cookies_insert(ofproto, rule); } if (fm->command == OFPFC_ADD) { - if (fm->idle_timeout || fm->hard_timeout) { + if (fm->idle_timeout || fm->hard_timeout || fm->importance) { if (!rule->eviction_group) { eviction_group_add_rule(rule); } -- 2.1.1 =====-----=====-----===== 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