From 75fa58f844031e071dd828162344b493ecc561f0 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Mon, 8 Jul 2013 14:48:05 -0700 Subject: [PATCH] Add basic OpenFlow 1.1 protocol support. Signed-off-by: Ben Pfaff --- FAQ | 20 +++--- 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, 279 insertions(+), 30 deletions(-) diff --git a/FAQ b/FAQ index 7df4e90e9..0210477f7 100644 --- a/FAQ +++ b/FAQ @@ -934,22 +934,26 @@ 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 1.10 and later 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: ovs-vsctl set bridge br0 protocols=OpenFlow10,OpenFlow12,OpenFlow13 + Open vSwitch version 1.12 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,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 6ecf8b4a0..7d4d8ef32 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,8 @@ post-v1.11.0 --------------------- - OpenFlow: + * Experimental support for OpenFlow 1.1 (in addition to 1.2 and + 1.3, which had experimental support in 1.10). * New support for matching outer source and destination IP address of tunneled packets, for tunnel ports configured with the newly added "remote_ip=flow" and "local_ip=flow" options. diff --git a/lib/ofp-util.c b/lib/ofp-util.c index f1a6f2daa..892159260 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,14 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm, /* Translate the message. */ fm->priority = ntohs(ofm->priority); - if (ofm->command == OFPFC_ADD) { + if (ofm->command == OFPFC_ADD + || (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; @@ -1569,7 +1655,6 @@ 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); @@ -1601,7 +1686,6 @@ 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); @@ -1623,6 +1707,7 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm, : OFPERR_OFPFMFC_TABLE_FULL); } + fm->modify_cookie = fm->new_cookie != htonll(UINT64_MAX); if (protocol & OFPUTIL_P_TID) { fm->command = command & 0xff; fm->table_id = command >> 8; @@ -2020,15 +2105,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 +2135,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 +2214,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 +2337,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 +2346,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 +2829,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 +2849,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 85456a549..0385a578f 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 ce810b4e5..7e781c377 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 f8290a16c..d61c024c2 100644 --- a/tests/ofp-print.at +++ b/tests/ofp-print.at @@ -699,6 +699,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]) diff --git a/tests/ofproto-macros.at b/tests/ofproto-macros.at index d034105da..839d41ffe 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 5fc33d66e..df988637f 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 d51085121..c1c3ef467 100644 --- a/vswitchd/vswitch.ovsschema +++ b/vswitchd/vswitch.ovsschema @@ -1,6 +1,6 @@ {"name": "Open_vSwitch", - "version": "7.2.1", - "cksum": "707387125 19667", + "version": "7.3.0", + "cksum": "1081379034 19765", "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", -- 2.43.0