[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