From 2334285719dffc1f193a2fdf0e5f7f54062348da Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Wed, 17 Apr 2013 13:02:15 -0700 Subject: [PATCH] ofp-util: Add 'modify_cookie' to struct ofputil_flow_mod, to support OF1.1. Signed-off-by: Ben Pfaff --- lib/learn.c | 1 + lib/ofp-parse.c | 2 ++ lib/ofp-util.c | 3 +++ lib/ofp-util.h | 41 +++++++++++++++++++++++++---------------- ofproto/ofproto-dpif.c | 1 + ofproto/ofproto.c | 2 +- utilities/ovs-ofctl.c | 1 + 7 files changed, 34 insertions(+), 17 deletions(-) diff --git a/lib/learn.c b/lib/learn.c index d0a4796c9..49d9efdba 100644 --- a/lib/learn.c +++ b/lib/learn.c @@ -303,6 +303,7 @@ learn_execute(const struct ofpact_learn *learn, const struct flow *flow, fm->cookie = htonll(0); fm->cookie_mask = htonll(0); fm->new_cookie = htonll(learn->cookie); + fm->modify_cookie = fm->new_cookie != htonll(UINT64_MAX); fm->table_id = learn->table_id; fm->command = OFPFC_MODIFY_STRICT; fm->idle_timeout = learn->idle_timeout; diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c index 609166cb4..618290b7a 100644 --- a/lib/ofp-parse.c +++ b/lib/ofp-parse.c @@ -1125,6 +1125,7 @@ parse_ofp_str__(struct ofputil_flow_mod *fm, int command, char *string) } else{ fm->new_cookie = htonll(0); } + fm->modify_cookie = false; fm->table_id = 0xff; fm->command = command; fm->idle_timeout = OFP_FLOW_PERMANENT; @@ -1212,6 +1213,7 @@ parse_ofp_str__(struct ofputil_flow_mod *fm, int command, char *string) return xstrdup("cannot set cookie"); } error = str_to_be64(value, &fm->new_cookie); + fm->modify_cookie = true; } } else if (mf_from_name(name)) { error = parse_field(mf_from_name(name), value, &fm->match); diff --git a/lib/ofp-util.c b/lib/ofp-util.c index aa4009d84..f1a6f2daa 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -1523,6 +1523,7 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm, fm->cookie_mask = ofm->cookie_mask; fm->new_cookie = htonll(UINT64_MAX); } + fm->modify_cookie = false; fm->command = ofm->command; fm->table_id = ofm->table_id; fm->idle_timeout = ntohs(ofm->idle_timeout); @@ -1568,6 +1569,7 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm, fm->cookie = htonll(0); fm->cookie_mask = htonll(0); fm->new_cookie = ofm->cookie; + fm->modify_cookie = fm->new_cookie != htonll(UINT64_MAX); fm->idle_timeout = ntohs(ofm->idle_timeout); fm->hard_timeout = ntohs(ofm->hard_timeout); fm->buffer_id = ntohl(ofm->buffer_id); @@ -1599,6 +1601,7 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm, } fm->priority = ntohs(nfm->priority); fm->new_cookie = nfm->cookie; + fm->modify_cookie = fm->new_cookie != htonll(UINT64_MAX); fm->idle_timeout = ntohs(nfm->idle_timeout); fm->hard_timeout = ntohs(nfm->hard_timeout); fm->buffer_id = ntohl(nfm->buffer_id); diff --git a/lib/ofp-util.h b/lib/ofp-util.h index 39c81be5a..85456a549 100644 --- a/lib/ofp-util.h +++ b/lib/ofp-util.h @@ -197,27 +197,36 @@ struct ofpbuf *ofputil_make_flow_mod_table_id(bool flow_mod_table_id); /* Protocol-independent flow_mod. * * The handling of cookies across multiple versions of OpenFlow is a bit - * confusing. A full description of Open vSwitch's cookie handling is - * in the DESIGN file. The following table shows the expected values of - * the cookie-related fields for the different flow_mod commands in - * OpenFlow 1.0 ("OF10") and NXM. "" and "-" indicate a value - * that may be populated and an ignored field, respectively. - * - * cookie cookie_mask new_cookie - * ====== =========== ========== - * OF10 Add - 0 - * OF10 Modify - 0 - * OF10 Delete - 0 - - * NXM Add - 0 - * NXM Modify - * NXM Delete - - */ + * confusing. See DESIGN for the details. */ struct ofputil_flow_mod { struct match match; unsigned int priority; + + /* Cookie matching. The flow_mod affects only flows that have cookies that + * bitwise match 'cookie' bits in positions where 'cookie_mask has 1-bits. + * + * 'cookie_mask' should be zero for OFPFC_ADD flow_mods. */ ovs_be64 cookie; /* Cookie bits to match. */ ovs_be64 cookie_mask; /* 1-bit in each 'cookie' bit to match. */ - ovs_be64 new_cookie; /* New cookie to install or -1. */ + + /* Cookie changes. + * + * OFPFC_ADD uses 'new_cookie' as the new flow's cookie. 'new_cookie' + * should not be UINT64_MAX. + * + * OFPFC_MODIFY and OFPFC_MODIFY_STRICT have two cases: + * + * - If one or more matching flows exist and 'modify_cookie' is true, + * then the flow_mod changes the existing flows' cookies to + * 'new_cookie'. 'new_cookie' should not be UINT64_MAX. + * + * - If no matching flow exists, 'new_cookie' is not UINT64_MAX, and + * 'cookie_mask' is 0, then the flow_mod adds a new flow with + * 'new_cookie' as its cookie. + */ + ovs_be64 new_cookie; /* New cookie to install or UINT64_MAX. */ + bool modify_cookie; /* Set cookie of existing flow to 'new_cookie'? */ + uint8_t table_id; uint16_t command; uint16_t idle_timeout; diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index a45ad36f3..4f9a90a48 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -1093,6 +1093,7 @@ add_internal_flow(struct ofproto_dpif *ofproto, int id, fm.new_cookie = htonll(0); fm.cookie = htonll(0); fm.cookie_mask = htonll(0); + fm.modify_cookie = false; fm.table_id = TBL_INTERNAL; fm.command = OFPFC_ADD; fm.idle_timeout = 0; diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 522c8398f..114c0cd3f 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -3475,7 +3475,7 @@ modify_flows__(struct ofproto *ofproto, struct ofconn *ofconn, op = ofoperation_create(group, rule, OFOPERATION_MODIFY, 0); - if (fm->new_cookie != htonll(UINT64_MAX)) { + if (fm->modify_cookie && fm->new_cookie != htonll(UINT64_MAX)) { ofproto_rule_change_cookie(ofproto, rule, fm->new_cookie); } if (actions_changed) { diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index 645316721..4d5a84ea2 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -2079,6 +2079,7 @@ fte_make_flow_mod(const struct fte *fte, int index, uint16_t command, fm.cookie = htonll(0); fm.cookie_mask = htonll(0); fm.new_cookie = version->cookie; + fm.modify_cookie = true; fm.table_id = 0xff; fm.command = command; fm.idle_timeout = version->idle_timeout; -- 2.20.1