[ovs-dev] [of1.1 resend 7/7] Add basic OpenFlow 1.1 protocol support.

Ben Pfaff blp at nicira.com
Fri Jun 28 23:27:30 UTC 2013


Signed-off-by: Ben Pfaff <blp at nicira.com>
---
 FAQ                        |   16 +++---
 NEWS                       |    2 +
 lib/ofp-util.c             |  125 +++++++++++++++++++++++++++++++++++++++----
 lib/ofp-util.h             |   19 ++++++-
 tests/learn.at             |    2 +-
 tests/ofp-print.at         |   20 +++++++
 tests/ofproto-macros.at    |    2 +-
 tests/ofproto.at           |  110 ++++++++++++++++++++++++++++++++++++++
 vswitchd/vswitch.ovsschema |    9 ++-
 9 files changed, 276 insertions(+), 29 deletions(-)

diff --git a/FAQ b/FAQ
index 7df4e90..e131b92 100644
--- a/FAQ
+++ b/FAQ
@@ -934,22 +934,20 @@ A: Open vSwitch 1.9 and earlier support only OpenFlow 1.0 (plus
    extensions that bring in many of the features from later versions
    of OpenFlow).
 
-   Open vSwitch versions 1.10 and later will have experimental support
-   for OpenFlow 1.2 and 1.3.  On these versions of Open vSwitch, the
-   following command enables OpenFlow 1.0, 1.2, and 1.3 on bridge br0:
+   Open vSwitch versions 1.11 and later will have experimental support
+   for OpenFlow 1.1, 1.2, and 1.3.  On these versions of Open vSwitch,
+   the following command enables OpenFlow 1.0, 1.1, 1.2, and 1.3 on
+   bridge br0:
 
-       ovs-vsctl set bridge br0 protocols=OpenFlow10,OpenFlow12,OpenFlow13
+       ovs-vsctl set bridge br0 protocols=OpenFlow10,OpenFlow11,OpenFlow12,OpenFlow13
 
    Use the -O option to enable support for later versions of OpenFlow
    in ovs-ofctl.  For example:
 
        ovs-ofctl -O OpenFlow13 dump-flows br0
 
-   Support for OpenFlow 1.1 is incomplete enough that it cannot yet be
-   enabled, even experimentally.
-
-   Support for OpenFlow 1.2 and 1.3 is still incomplete.  Work to be
-   done is tracked in OPENFLOW-1.1+ in the Open vSwitch source tree
+   Support for OpenFlow 1.1, 1.2, and 1.3 is still incomplete.  Work
+   to be done is tracked in OPENFLOW-1.1+ in the Open vSwitch sources
    (also via http://openvswitch.org/development/openflow-1-x-plan/).
    When support for a given OpenFlow version is solidly implemented,
    Open vSwitch will enable that version by default.
diff --git a/NEWS b/NEWS
index b07a651..c2b37f0 100644
--- a/NEWS
+++ b/NEWS
@@ -26,6 +26,8 @@ v1.11.0 - xx xxx xxxx
       protocol (RFC 6830).  An external control plane or manual flow
       setup is required for EID-to-RLOC mapping.
     - OpenFlow:
+      * Experimental support for OpenFlow 1.1 (in addition to 1.2 and
+        1.3, which had experimental support in 1.10).
       * The "dec_mpls_ttl" and "set_mpls_ttl" actions from OpenFlow
         1.1 and later are now implemented.
       * New "stack" extension for use in actions, to push and pop from
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index f1a6f2d..0878e3f 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -547,6 +547,71 @@ ofputil_match_to_ofp11_match(const struct match *match,
     ofmatch->wildcards = htonl(wc);
 }
 
+/* Returns the "typical" length of a match for 'protocol', for use in
+ * estimating space to preallocate. */
+int
+ofputil_match_typical_len(enum ofputil_protocol protocol)
+{
+    switch (protocol) {
+    case OFPUTIL_P_OF10_STD:
+    case OFPUTIL_P_OF10_STD_TID:
+        return sizeof(struct ofp10_match);
+
+    case OFPUTIL_P_OF10_NXM:
+    case OFPUTIL_P_OF10_NXM_TID:
+        return NXM_TYPICAL_LEN;
+
+    case OFPUTIL_P_OF11_STD:
+        return sizeof(struct ofp11_match);
+
+    case OFPUTIL_P_OF12_OXM:
+    case OFPUTIL_P_OF13_OXM:
+        return NXM_TYPICAL_LEN;
+
+    default:
+        NOT_REACHED();
+    }
+}
+
+/* Appends to 'b' an struct ofp11_match_header followed by a match that
+ * expresses 'match' properly for 'protocol', plus enough zero bytes to pad the
+ * data appended out to a multiple of 8.  'protocol' must be one that is usable
+ * in OpenFlow 1.1 or later.
+ *
+ * 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
+ofputil_put_ofp11_match(struct ofpbuf *b, const struct match *match,
+                        enum ofputil_protocol protocol)
+{
+    switch (protocol) {
+    case OFPUTIL_P_OF10_STD:
+    case OFPUTIL_P_OF10_STD_TID:
+    case OFPUTIL_P_OF10_NXM:
+    case OFPUTIL_P_OF10_NXM_TID:
+        NOT_REACHED();
+
+    case OFPUTIL_P_OF11_STD: {
+        struct ofp11_match *om;
+
+        /* Make sure that no padding is needed. */
+        BUILD_ASSERT_DECL(sizeof *om % 8 == 0);
+
+        om = ofpbuf_put_uninit(b, sizeof *om);
+        ofputil_match_to_ofp11_match(match, om);
+        return sizeof *om;
+    }
+
+    case OFPUTIL_P_OF12_OXM:
+    case OFPUTIL_P_OF13_OXM:
+        return oxm_put_match(b, match);
+    }
+
+    NOT_REACHED();
+}
+
 /* Given a 'dl_type' value in the format used in struct flow, returns the
  * corresponding 'dl_type' value for use in an ofp10_match or ofp11_match
  * structure. */
@@ -589,6 +654,7 @@ static const struct proto_abbrev proto_abbrevs[] = {
 enum ofputil_protocol ofputil_flow_dump_protocols[] = {
     OFPUTIL_P_OF13_OXM,
     OFPUTIL_P_OF12_OXM,
+    OFPUTIL_P_OF11_STD,
     OFPUTIL_P_OF10_NXM,
     OFPUTIL_P_OF10_STD,
 };
@@ -604,11 +670,12 @@ ofputil_protocols_from_ofp_version(enum ofp_version version)
     switch (version) {
     case OFP10_VERSION:
         return OFPUTIL_P_OF10_STD_ANY | OFPUTIL_P_OF10_NXM_ANY;
+    case OFP11_VERSION:
+        return OFPUTIL_P_OF11_STD;
     case OFP12_VERSION:
         return OFPUTIL_P_OF12_OXM;
     case OFP13_VERSION:
         return OFPUTIL_P_OF13_OXM;
-    case OFP11_VERSION:
     default:
         return 0;
     }
@@ -636,6 +703,8 @@ ofputil_protocol_to_ofp_version(enum ofputil_protocol protocol)
     case OFPUTIL_P_OF10_NXM:
     case OFPUTIL_P_OF10_NXM_TID:
         return OFP10_VERSION;
+    case OFPUTIL_P_OF11_STD:
+        return OFP11_VERSION;
     case OFPUTIL_P_OF12_OXM:
         return OFP12_VERSION;
     case OFPUTIL_P_OF13_OXM:
@@ -707,6 +776,9 @@ ofputil_protocol_set_tid(enum ofputil_protocol protocol, bool enable)
     case OFPUTIL_P_OF10_NXM_TID:
         return enable ? OFPUTIL_P_OF10_NXM_TID : OFPUTIL_P_OF10_NXM;
 
+    case OFPUTIL_P_OF11_STD:
+        return OFPUTIL_P_OF11_STD;
+
     case OFPUTIL_P_OF12_OXM:
         return OFPUTIL_P_OF12_OXM;
 
@@ -744,6 +816,9 @@ ofputil_protocol_set_base(enum ofputil_protocol cur,
     case OFPUTIL_P_OF10_NXM_TID:
         return ofputil_protocol_set_tid(OFPUTIL_P_OF10_NXM, tid);
 
+    case OFPUTIL_P_OF11_STD:
+        return ofputil_protocol_set_tid(OFPUTIL_P_OF11_STD, tid);
+
     case OFPUTIL_P_OF12_OXM:
         return ofputil_protocol_set_tid(OFPUTIL_P_OF12_OXM, tid);
 
@@ -778,6 +853,9 @@ ofputil_protocol_to_string(enum ofputil_protocol protocol)
     case OFPUTIL_P_OF10_STD_TID:
         return "OpenFlow10+table_id";
 
+    case OFPUTIL_P_OF11_STD:
+        return "OpenFlow11";
+
     case OFPUTIL_P_OF12_OXM:
         return "OXM-OpenFlow12";
 
@@ -1364,9 +1442,10 @@ ofputil_encode_set_protocol(enum ofputil_protocol current,
         case OFPUTIL_P_OF10_STD:
             return ofputil_encode_nx_set_flow_format(NXFF_OPENFLOW10);
 
+        case OFPUTIL_P_OF11_STD:
         case OFPUTIL_P_OF12_OXM:
         case OFPUTIL_P_OF13_OXM:
-            /* There are only one of each OpenFlow 1.2+ protocols and we already
+            /* There is only one variant of each OpenFlow 1.1+ protocol, and we
              * verified above that we're not trying to change versions. */
             NOT_REACHED();
 
@@ -1514,7 +1593,17 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm,
 
         /* Translate the message. */
         fm->priority = ntohs(ofm->priority);
-        if (ofm->command == OFPFC_ADD) {
+        if (oh->version == OFP11_VERSION
+            && (ofm->command == OFPFC_MODIFY ||
+                ofm->command == OFPFC_MODIFY_STRICT)
+            && ofm->cookie_mask == htonll(0)) {
+            /* In OpenFlow 1.1 only, a "modify" or "modify-strict" that does
+             * not match on the cookie is treated as an "add" if there is no
+             * match. */
+            fm->cookie = htonll(0);
+            fm->cookie_mask = htonll(0);
+            fm->new_cookie = ofm->cookie;
+        } else if (ofm->command == OFPFC_ADD) {
             fm->cookie = htonll(0);
             fm->cookie_mask = htonll(0);
             fm->new_cookie = ofm->cookie;
@@ -2020,15 +2109,22 @@ ofputil_encode_flow_mod(const struct ofputil_flow_mod *fm,
     struct ofpbuf *msg;
 
     switch (protocol) {
+    case OFPUTIL_P_OF11_STD:
     case OFPUTIL_P_OF12_OXM:
     case OFPUTIL_P_OF13_OXM: {
         struct ofp11_flow_mod *ofm;
+        int tailroom;
 
+        tailroom = ofputil_match_typical_len(protocol) + fm->ofpacts_len;
         msg = ofpraw_alloc(OFPRAW_OFPT11_FLOW_MOD,
                            ofputil_protocol_to_ofp_version(protocol),
-                           NXM_TYPICAL_LEN + fm->ofpacts_len);
+                           tailroom);
         ofm = ofpbuf_put_zeros(msg, sizeof *ofm);
-        if (fm->command == OFPFC_ADD) {
+        if ((protocol == OFPUTIL_P_OF11_STD
+             && (fm->command == OFPFC_MODIFY ||
+                 fm->command == OFPFC_MODIFY_STRICT)
+             && fm->cookie_mask == htonll(0))
+            || fm->command == OFPFC_ADD) {
             ofm->cookie = fm->new_cookie;
         } else {
             ofm->cookie = fm->cookie;
@@ -2043,7 +2139,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(OFPG11_ANY);
         ofm->flags = htons(fm->flags);
-        oxm_put_match(msg, &fm->match);
+        ofputil_put_ofp11_match(msg, &fm->match, protocol);
         ofpacts_put_openflow11_instructions(fm->ofpacts, fm->ofpacts_len, msg);
         break;
     }
@@ -2122,8 +2218,10 @@ ofputil_flow_mod_usable_protocols(const struct ofputil_flow_mod *fms,
 
         /* Matching of the cookie is only supported through NXM or OF1.1+. */
         if (fm->cookie_mask != htonll(0)) {
-            usable_protocols &= OFPUTIL_P_OF10_NXM_ANY | OFPUTIL_P_OF12_OXM
-                | OFPUTIL_P_OF13_OXM;
+            usable_protocols &= (OFPUTIL_P_OF10_NXM_ANY
+                                 | OFPUTIL_P_OF11_STD
+                                 | OFPUTIL_P_OF12_OXM
+                                 | OFPUTIL_P_OF13_OXM);
         }
     }
 
@@ -2243,6 +2341,7 @@ ofputil_encode_flow_stats_request(const struct ofputil_flow_stats_request *fsr,
     enum ofpraw raw;
 
     switch (protocol) {
+    case OFPUTIL_P_OF11_STD:
     case OFPUTIL_P_OF12_OXM:
     case OFPUTIL_P_OF13_OXM: {
         struct ofp11_flow_stats_request *ofsr;
@@ -2251,14 +2350,14 @@ ofputil_encode_flow_stats_request(const struct ofputil_flow_stats_request *fsr,
                ? OFPRAW_OFPST11_AGGREGATE_REQUEST
                : OFPRAW_OFPST11_FLOW_REQUEST);
         msg = ofpraw_alloc(raw, ofputil_protocol_to_ofp_version(protocol),
-			   NXM_TYPICAL_LEN);
+                           ofputil_match_typical_len(protocol));
         ofsr = ofpbuf_put_zeros(msg, sizeof *ofsr);
         ofsr->table_id = fsr->table_id;
         ofsr->out_port = ofputil_port_to_ofp11(fsr->out_port);
         ofsr->out_group = htonl(OFPG11_ANY);
         ofsr->cookie = fsr->cookie;
         ofsr->cookie_mask = fsr->cookie_mask;
-        oxm_put_match(msg, &fsr->match);
+        ofputil_put_ofp11_match(msg, &fsr->match, protocol);
         break;
     }
 
@@ -2734,13 +2833,15 @@ ofputil_encode_flow_removed(const struct ofputil_flow_removed *fr,
     struct ofpbuf *msg;
 
     switch (protocol) {
+    case OFPUTIL_P_OF11_STD:
     case OFPUTIL_P_OF12_OXM:
     case OFPUTIL_P_OF13_OXM: {
         struct ofp12_flow_removed *ofr;
 
         msg = ofpraw_alloc_xid(OFPRAW_OFPT11_FLOW_REMOVED,
                                ofputil_protocol_to_ofp_version(protocol),
-                               htonl(0), NXM_TYPICAL_LEN);
+                               htonl(0),
+                               ofputil_match_typical_len(protocol));
         ofr = ofpbuf_put_zeros(msg, sizeof *ofr);
         ofr->cookie = fr->cookie;
         ofr->priority = htons(fr->priority);
@@ -2752,7 +2853,7 @@ ofputil_encode_flow_removed(const struct ofputil_flow_removed *fr,
         ofr->hard_timeout = htons(fr->hard_timeout);
         ofr->packet_count = htonll(fr->packet_count);
         ofr->byte_count = htonll(fr->byte_count);
-        oxm_put_match(msg, &fr->match);
+        ofputil_put_ofp11_match(msg, &fr->match, protocol);
         break;
     }
 
diff --git a/lib/ofp-util.h b/lib/ofp-util.h
index 85456a5..0385a57 100644
--- a/lib/ofp-util.h
+++ b/lib/ofp-util.h
@@ -81,6 +81,15 @@ enum ofputil_protocol {
 #define OFPUTIL_P_OF10_STD_ANY (OFPUTIL_P_OF10_STD | OFPUTIL_P_OF10_STD_TID)
 #define OFPUTIL_P_OF10_NXM_ANY (OFPUTIL_P_OF10_NXM | OFPUTIL_P_OF10_NXM_TID)
 
+    /* OpenFlow 1.1 protocol.
+     *
+     * We only support the standard OpenFlow 1.1 flow format.
+     *
+     * OpenFlow 1.1 always operates with an equivalent of the
+     * nx_flow_mod_table_id Nicira extension enabled, so there is no "TID"
+     * variant. */
+    OFPUTIL_P_OF11_STD     = 1 << 4,
+
     /* OpenFlow 1.2+ protocols (only one variant each).
      *
      * These use the standard OpenFlow Extensible Match (OXM) flow format.
@@ -88,16 +97,17 @@ enum ofputil_protocol {
      * OpenFlow 1.2+ always operates with an equivalent of the
      * nx_flow_mod_table_id Nicira extension enabled, so there is no "TID"
      * variant. */
-    OFPUTIL_P_OF12_OXM      = 1 << 4,
-    OFPUTIL_P_OF13_OXM      = 1 << 5,
+    OFPUTIL_P_OF12_OXM      = 1 << 5,
+    OFPUTIL_P_OF13_OXM      = 1 << 6,
 #define OFPUTIL_P_ANY_OXM (OFPUTIL_P_OF12_OXM | OFPUTIL_P_OF13_OXM)
 
     /* All protocols. */
-#define OFPUTIL_P_ANY ((1 << 6) - 1)
+#define OFPUTIL_P_ANY ((1 << 7) - 1)
 
     /* Protocols in which a specific table may be specified in flow_mods. */
 #define OFPUTIL_P_TID (OFPUTIL_P_OF10_STD_TID | \
                        OFPUTIL_P_OF10_NXM_TID | \
+                       OFPUTIL_P_OF11_STD |     \
                        OFPUTIL_P_ANY_OXM)
 };
 
@@ -178,7 +188,10 @@ enum ofperr ofputil_pull_ofp11_match(struct ofpbuf *, struct match *,
                                      uint16_t *padded_match_len);
 enum ofperr ofputil_match_from_ofp11_match(const struct ofp11_match *,
                                            struct match *);
+int ofputil_put_ofp11_match(struct ofpbuf *, const struct match *,
+                            enum ofputil_protocol);
 void ofputil_match_to_ofp11_match(const struct match *, struct ofp11_match *);
+int ofputil_match_typical_len(enum ofputil_protocol);
 
 /* dl_type translation between OpenFlow and 'struct flow' format. */
 ovs_be16 ofputil_dl_type_to_openflow(ovs_be16 flow_dl_type);
diff --git a/tests/learn.at b/tests/learn.at
index ec1c347..89adf2b 100644
--- a/tests/learn.at
+++ b/tests/learn.at
@@ -46,7 +46,7 @@ table=0 actions=learn(table=1,hard_timeout=10, NXM_OF_VLAN_TCI[0..11],output:NXM
 table=1 priority=0 actions=flood
 ]])
 AT_CHECK([ovs-ofctl parse-flows flows.txt], [0],
-[[usable protocols: OXM,OpenFlow10+table_id,NXM+table_id
+[[usable protocols: OXM,OpenFlow10+table_id,NXM+table_id,OpenFlow11
 chosen protocol: OpenFlow10+table_id
 OFPT_FLOW_MOD (xid=0x1): ADD table:255 actions=learn(table=1,in_port=99,NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:NXM_OF_IN_PORT[]->NXM_NX_REG1[16..31])
 OFPT_FLOW_MOD (xid=0x2): ADD table:255 actions=learn(table=1,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],output:NXM_OF_IN_PORT[])
diff --git a/tests/ofp-print.at b/tests/ofp-print.at
index f8290a1..d61c024 100644
--- a/tests/ofp-print.at
+++ b/tests/ofp-print.at
@@ -700,6 +700,26 @@ ofp_util|INFO|post: arp,in_port=1,vlan_tci=0x0000,dl_src=50:54:00:00:00:06,dl_ds
 AT_CLEANUP
 
 # The flow is formatted with cls_rule_format() for the low-verbosity case.
+AT_SETUP([OFPT_FLOW_MOD - OF1.1 - low verbosity])
+AT_KEYWORDS([ofp-print])
+AT_CHECK([ovs-ofctl '-vPATTERN:console:%c|%p|%m' ofp-print "\
+020e 0090 01020304 \
+da1aa3e035d87158 ffffffffffffffff \
+02 01 003c 0078 9c40 ffffffff ffffffff ffffffff 0003 \
+0000 \
+\
+0000 0058 00000000 000003f7 \
+000000000000ffffffffffff 000000000000ffffffffffff \
+0000 00 00 0806 00 00 c0a88000000000ff 00000000ffffffff 0000 0000 \
+00000000 00 000000 0000000000000000ffffffffffffffff \
+\
+0001 0008 03 000000 \
+" 2], [0], [dnl
+OFPT_FLOW_MOD (OF1.1) (xid=0x1020304): MOD table:2 priority=40000,arp,arp_spa=192.168.128.0/24 cookie:0xda1aa3e035d87158/0xffffffffffffffff idle:60 hard:120 send_flow_rem check_overlap actions=goto_table:3
+])
+AT_CLEANUP
+
+# The flow is formatted with cls_rule_format() for the low-verbosity case.
 AT_SETUP([OFPT_FLOW_MOD - OF1.2 - low verbosity])
 AT_KEYWORDS([ofp-print])
 AT_CHECK([ovs-ofctl '-vPATTERN:console:%c|%p|%m' ofp-print "\
diff --git a/tests/ofproto-macros.at b/tests/ofproto-macros.at
index d034105..839d41f 100644
--- a/tests/ofproto-macros.at
+++ b/tests/ofproto-macros.at
@@ -83,7 +83,7 @@ m4_define([OVS_VSWITCHD_START],
 /ofproto|INFO|datapath ID changed to fedcba9876543210/d']])
 
    dnl Add bridges, ports, etc.
-   AT_CHECK([ovs-vsctl -- add-br br0 -- set bridge br0 datapath-type=dummy other-config:datapath-id=fedcba9876543210 other-config:hwaddr=aa:55:aa:55:00:00 protocols=[[OpenFlow10,OpenFlow12,OpenFlow13]] fail-mode=secure -- $1 m4_if([$2], [], [], [| ${PERL} $srcdir/uuidfilt.pl])], [0], [$2])
+   AT_CHECK([ovs-vsctl -- add-br br0 -- set bridge br0 datapath-type=dummy other-config:datapath-id=fedcba9876543210 other-config:hwaddr=aa:55:aa:55:00:00 protocols=[[OpenFlow10,OpenFlow11,OpenFlow12,OpenFlow13]] fail-mode=secure -- $1 m4_if([$2], [], [], [| ${PERL} $srcdir/uuidfilt.pl])], [0], [$2])
 ])
 
 m4_divert_push([PREPARE_TESTS])
diff --git a/tests/ofproto.at b/tests/ofproto.at
index 5fc33d6..df98863 100644
--- a/tests/ofproto.at
+++ b/tests/ofproto.at
@@ -253,6 +253,28 @@ AT_CHECK([ovs-ofctl -F openflow10 dump-flows br0 | ofctl_strip], [0], [OFPST_FLO
 OVS_VSWITCHD_STOP
 AT_CLEANUP
 
+AT_SETUP([ofproto - basic flow_mod commands (OpenFlow 1.1)])
+OVS_VSWITCHD_START
+AT_CHECK([ovs-ofctl -O OpenFlow11 dump-flows br0 | ofctl_strip], [0], [OFPST_FLOW reply (OF1.1):
+])
+AT_CHECK([echo 'in_port=2,actions=1' | ovs-ofctl -O OpenFlow11 add-flows br0 -])
+AT_CHECK([ovs-ofctl -O OpenFlow11 add-flow br0 in_port=1,actions=2])
+AT_CHECK([ovs-ofctl -O OpenFlow11 add-flow br0 table=1,in_port=4,actions=3])
+AT_CHECK([ovs-ofctl -O OpenFlow11 dump-flows br0 | ofctl_strip | sort], [0], [dnl
+ in_port=1 actions=output:2
+ in_port=2 actions=output:1
+ table=1, in_port=4 actions=output:3
+OFPST_FLOW reply (OF1.1):
+])
+AT_CHECK([ovs-ofctl -O OpenFlow11 dump-aggregate br0 table=0 | STRIP_XIDS], [0], [dnl
+OFPST_AGGREGATE reply (OF1.1): packet_count=0 byte_count=0 flow_count=2
+])
+AT_CHECK([ovs-ofctl -O OpenFlow11 del-flows br0])
+AT_CHECK([ovs-ofctl -O OpenFlow11 dump-flows br0 | ofctl_strip], [0], [OFPST_FLOW reply (OF1.1):
+])
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
 AT_SETUP([ofproto - set-field flow_mod commands (NXM)])
 OVS_VSWITCHD_START
 AT_CHECK([ovs-ofctl add-flow br0 ipv6,table=1,in_port=3,actions=drop])
@@ -339,6 +361,21 @@ NXST_FLOW reply:
 OVS_VSWITCHD_STOP
 AT_CLEANUP
 
+AT_SETUP([ofproto - no mod flow with cookie change (OpenFlow 1.1)])
+OVS_VSWITCHD_START
+AT_CHECK([ovs-ofctl -O OpenFlow11 add-flow br0 cookie=0x1,in_port=1,actions=1])
+AT_CHECK([ovs-ofctl -O OpenFlow11 dump-flows br0 | ofctl_strip | sort], [0], [dnl
+ cookie=0x1, in_port=1 actions=output:1
+OFPST_FLOW reply (OF1.1):
+])
+AT_CHECK([ovs-ofctl -O OpenFlow11 mod-flows br0 cookie=0x2,in_port=1,actions=1])
+AT_CHECK([ovs-ofctl -O OpenFlow11 dump-flows br0 | ofctl_strip | sort], [0], [dnl
+ cookie=0x1, in_port=1 actions=output:1
+OFPST_FLOW reply (OF1.1):
+])
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
 dnl The OpenFlow 1.2 spec states that the cookie may not be modified
 AT_SETUP([ofproto - no mod flow with cookie change (OpenFlow 1.2)])
 OVS_VSWITCHD_START
@@ -378,6 +415,28 @@ NXST_FLOW reply:
 OVS_VSWITCHD_STOP
 AT_CLEANUP
 
+AT_SETUP([ofproto - mod flows based on cookie mask (OpenFlow 1.1)])
+OVS_VSWITCHD_START
+AT_CHECK([ovs-ofctl -O OpenFlow11 add-flow br0 cookie=0x1,in_port=1,actions=1])
+AT_CHECK([ovs-ofctl -O OpenFlow11 add-flow br0 cookie=0x1,in_port=2,actions=1])
+AT_CHECK([ovs-ofctl -O OpenFlow11 add-flow br0 cookie=0x2,in_port=3,actions=1])
+AT_CHECK([ovs-ofctl -O OpenFlow11 dump-flows br0 | ofctl_strip | sort], [0], [dnl
+ cookie=0x1, in_port=1 actions=output:1
+ cookie=0x1, in_port=2 actions=output:1
+ cookie=0x2, in_port=3 actions=output:1
+OFPST_FLOW reply (OF1.1):
+])
+
+AT_CHECK([ovs-ofctl -O OpenFlow11 mod-flows br0 cookie=0x1/0xff,actions=4])
+AT_CHECK([ovs-ofctl -O OpenFlow11 dump-flows br0 | ofctl_strip | sort], [0], [dnl
+ cookie=0x1, in_port=1 actions=output:4
+ cookie=0x1, in_port=2 actions=output:4
+ cookie=0x2, in_port=3 actions=output:1
+OFPST_FLOW reply (OF1.1):
+])
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
 AT_SETUP([ofproto - mod flows based on cookie mask (OpenFlow 1.2)])
 OVS_VSWITCHD_START
 AT_CHECK([ovs-ofctl -O OpenFlow12 add-flow br0 cookie=0x1,in_port=1,actions=1])
@@ -433,6 +492,16 @@ NXST_FLOW reply:
 OVS_VSWITCHD_STOP
 AT_CLEANUP
 
+AT_SETUP([ofproto - mod flow with cookie miss (mask==0) - OF1.1])
+OVS_VSWITCHD_START
+AT_CHECK([ovs-ofctl -O openflow11 mod-flows br0 in_port=1,actions=1])
+AT_CHECK([ovs-ofctl -O openflow11 dump-flows br0 | ofctl_strip | sort], [0], [dnl
+ in_port=1 actions=output:1
+OFPST_FLOW reply (OF1.1):
+])
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
 AT_SETUP([ofproto - mod flow with cookie miss (mask==0) - OF1.2])
 OVS_VSWITCHD_START
 AT_CHECK([ovs-ofctl -O openflow12 mod-flows br0 in_port=1,actions=1])
@@ -451,6 +520,15 @@ NXST_FLOW reply:
 OVS_VSWITCHD_STOP
 AT_CLEANUP
 
+AT_SETUP([ofproto - mod flow with cookie miss (mask!=0) - OF1.1])
+OVS_VSWITCHD_START
+AT_CHECK([ovs-ofctl -O openflow11 mod-flows br0 cookie=1/1,in_port=1,actions=1])
+AT_CHECK([ovs-ofctl -O openflow11 dump-flows br0 | ofctl_strip | sort], [0], [dnl
+OFPST_FLOW reply (OF1.1):
+])
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
 AT_SETUP([ofproto - mod flow with cookie miss (mask!=0) - OF1.2])
 OVS_VSWITCHD_START
 AT_CHECK([ovs-ofctl -O openflow12 mod-flows br0 cookie=1/1,in_port=1,actions=1])
@@ -551,6 +629,38 @@ NXST_FLOW reply:
 OVS_VSWITCHD_STOP
 AT_CLEANUP
 
+AT_SETUP([ofproto - del flows based on table id (OpenFlow 1.1)])
+OVS_VSWITCHD_START
+AT_CHECK([ovs-ofctl -O OpenFlow11 add-flow br0 cookie=0x1,in_port=1,actions=1])
+AT_CHECK([ovs-ofctl -O OpenFlow11 add-flow br0 cookie=0x2,in_port=2,table=1,actions=1])
+AT_CHECK([ovs-ofctl -O OpenFlow11 dump-flows br0 | ofctl_strip | sort], [0], [dnl
+ cookie=0x1, in_port=1 actions=output:1
+ cookie=0x2, table=1, in_port=2 actions=output:1
+OFPST_FLOW reply (OF1.1):
+])
+AT_CHECK([ovs-ofctl -O OpenFlow11 del-flows br0 table=0])
+AT_CHECK([ovs-ofctl -O OpenFlow11 dump-flows br0 | ofctl_strip | sort], [0], [dnl
+ cookie=0x2, table=1, in_port=2 actions=output:1
+OFPST_FLOW reply (OF1.1):
+])
+AT_CHECK([ovs-ofctl -O OpenFlow11 del-flows br0 table=1])
+AT_CHECK([ovs-ofctl -O OpenFlow11 dump-flows br0 | ofctl_strip | sort], [0], [dnl
+OFPST_FLOW reply (OF1.1):
+])
+AT_CHECK([ovs-ofctl -O OpenFlow11 add-flow br0 cookie=0x1,in_port=1,actions=1])
+AT_CHECK([ovs-ofctl -O OpenFlow11 add-flow br0 cookie=0x2,in_port=2,table=1,actions=1])
+AT_CHECK([ovs-ofctl -O OpenFlow11 dump-flows br0 | ofctl_strip | sort], [0], [dnl
+ cookie=0x1, in_port=1 actions=output:1
+ cookie=0x2, table=1, in_port=2 actions=output:1
+OFPST_FLOW reply (OF1.1):
+])
+AT_CHECK([ovs-ofctl -O OpenFlow11 del-flows br0])
+AT_CHECK([ovs-ofctl -O OpenFlow11 dump-flows br0 | ofctl_strip | sort], [0], [dnl
+OFPST_FLOW reply (OF1.1):
+])
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
 AT_SETUP([ofproto - del flows based on table id (OpenFlow 1.2)])
 OVS_VSWITCHD_START
 AT_CHECK([ovs-ofctl -O OpenFlow12 add-flow br0 cookie=0x1,in_port=1,actions=1])
diff --git a/vswitchd/vswitch.ovsschema b/vswitchd/vswitch.ovsschema
index bb3ca48..088bfd3 100644
--- a/vswitchd/vswitch.ovsschema
+++ b/vswitchd/vswitch.ovsschema
@@ -1,6 +1,6 @@
 {"name": "Open_vSwitch",
- "version": "7.2.0",
- "cksum": "543912409 19436",
+ "version": "7.3.0",
+ "cksum": "988505276 19534",
  "tables": {
    "Open_vSwitch": {
      "columns": {
@@ -80,7 +80,10 @@
                   "min": 0, "max": "unlimited"}},
        "protocols": {
          "type": {"key": {"type": "string",
-           "enum": ["set", ["OpenFlow10", "OpenFlow12", "OpenFlow13"]]},
+           "enum": ["set", ["OpenFlow10",
+                            "OpenFlow11",
+                            "OpenFlow12",
+                            "OpenFlow13"]]},
 	   "min": 0, "max": "unlimited"}},
        "fail_mode": {
          "type": {"key": {"type": "string",
-- 
1.7.2.5




More information about the dev mailing list