ofp-util: Add 'modify_cookie' to struct ofputil_flow_mod, to support OF1.1.
authorBen Pfaff <blp@nicira.com>
Wed, 17 Apr 2013 20:02:15 +0000 (13:02 -0700)
committerBen Pfaff <blp@nicira.com>
Mon, 8 Jul 2013 21:52:43 +0000 (14:52 -0700)
Signed-off-by: Ben Pfaff <blp@nicira.com>
lib/learn.c
lib/ofp-parse.c
lib/ofp-util.c
lib/ofp-util.h
ofproto/ofproto-dpif.c
ofproto/ofproto.c
utilities/ovs-ofctl.c

index d0a4796..49d9efd 100644 (file)
@@ -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;
index 609166c..618290b 100644 (file)
@@ -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);
index aa4009d..f1a6f2d 100644 (file)
@@ -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);
index 39c81be..85456a5 100644 (file)
@@ -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.  "<used>" and "-" indicate a value
- * that may be populated and an ignored field, respectively.
- *
- *               cookie  cookie_mask  new_cookie
- *               ======  ===========  ==========
- * OF10 Add        -          0         <used>
- * OF10 Modify     -          0         <used>
- * OF10 Delete     -          0           -
- * NXM Add         -          0         <used>
- * NXM Modify    <used>     <used>      <used>
- * NXM Delete    <used>     <used>        -
- */
+ * 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;
index a45ad36..4f9a90a 100644 (file)
@@ -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;
index 522c839..114c0cd 100644 (file)
@@ -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) {
index 6453167..4d5a84e 100644 (file)
@@ -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;