2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-22 01:51:26 +00:00

Implement OF1.3 extension for OF1.4 role status feature.

ONF extension pack 1 for OpenFlow 1.3 defines how to implement the OpenFlow
1.4 "role status" message in OpenFlow 1.3.  This commit implements that
feature.

ONF-JIRA: EXT-191
Signed-off-by: Ben Pfaff <blp@ovn.org>
Acked-by: William Tu <u9012063@gmail.com>
This commit is contained in:
Ben Pfaff 2018-02-08 13:25:39 -08:00
parent 0d71302e36
commit b0e07d5078
6 changed files with 118 additions and 26 deletions

View File

@ -159,14 +159,6 @@ in OVS.
(EXT-187) (EXT-187)
(optional for OF1.4+) (optional for OF1.4+)
* Role Status
Already implemented as a 1.4 feature.
(EXT-191)
(required for OF1.4+)
* Flow entry eviction * Flow entry eviction
OVS has flow eviction functionality. ``table_mod OFPTC_EVICTION``, OVS has flow eviction functionality. ``table_mod OFPTC_EVICTION``,

2
NEWS
View File

@ -10,6 +10,8 @@ Post-v2.9.0
default it always accepts names and in interactive use it displays them; default it always accepts names and in interactive use it displays them;
use --names or --no-names to override. See ovs-ofctl(8) for details. use --names or --no-names to override. See ovs-ofctl(8) for details.
- ovs-vsctl: New commands "add-bond-iface" and "del-bond-iface". - ovs-vsctl: New commands "add-bond-iface" and "del-bond-iface".
- OpenFlow:
* OFPT_ROLE_STATUS is now available in OpenFlow 1.3.
v2.9.0 - xx xxx xxxx v2.9.0 - xx xxx xxxx

View File

@ -262,6 +262,8 @@ enum ofpraw {
/* OFPT 1.3+ (29): struct ofp13_meter_mod, uint8_t[8][]. */ /* OFPT 1.3+ (29): struct ofp13_meter_mod, uint8_t[8][]. */
OFPRAW_OFPT13_METER_MOD, OFPRAW_OFPT13_METER_MOD,
/* ONFT 1.3 (1911): struct ofp14_role_status, uint8_t[8][]. */
OFPRAW_ONFT13_ROLE_STATUS,
/* OFPT 1.4+ (30): struct ofp14_role_status, uint8_t[8][]. */ /* OFPT 1.4+ (30): struct ofp14_role_status, uint8_t[8][]. */
OFPRAW_OFPT14_ROLE_STATUS, OFPRAW_OFPT14_ROLE_STATUS,
@ -615,7 +617,8 @@ enum ofptype {
OFPTYPE_METER_MOD, /* OFPRAW_OFPT13_METER_MOD. */ OFPTYPE_METER_MOD, /* OFPRAW_OFPT13_METER_MOD. */
/* Controller role change event messages. */ /* Controller role change event messages. */
OFPTYPE_ROLE_STATUS, /* OFPRAW_OFPT14_ROLE_STATUS. */ OFPTYPE_ROLE_STATUS, /* OFPRAW_ONFT13_ROLE_STATUS.
* OFPRAW_OFPT14_ROLE_STATUS. */
/* Request forwarding by the switch. */ /* Request forwarding by the switch. */
OFPTYPE_REQUESTFORWARD, /* OFPRAW_OFPT14_REQUESTFORWARD. */ OFPTYPE_REQUESTFORWARD, /* OFPRAW_OFPT14_REQUESTFORWARD. */

View File

@ -127,24 +127,21 @@ struct ofpbuf *
ofputil_encode_role_status(const struct ofputil_role_status *status, ofputil_encode_role_status(const struct ofputil_role_status *status,
enum ofputil_protocol protocol) enum ofputil_protocol protocol)
{ {
enum ofp_version version; enum ofp_version version = ofputil_protocol_to_ofp_version(protocol);
if (version < OFP13_VERSION) {
version = ofputil_protocol_to_ofp_version(protocol);
if (version >= OFP14_VERSION) {
struct ofp14_role_status *rstatus;
struct ofpbuf *buf;
buf = ofpraw_alloc_xid(OFPRAW_OFPT14_ROLE_STATUS, version, htonl(0),
0);
rstatus = ofpbuf_put_zeros(buf, sizeof *rstatus);
rstatus->role = htonl(status->role);
rstatus->reason = status->reason;
rstatus->generation_id = htonll(status->generation_id);
return buf;
} else {
return NULL; return NULL;
} }
enum ofpraw raw = (version >= OFP14_VERSION
? OFPRAW_OFPT14_ROLE_STATUS
: OFPRAW_ONFT13_ROLE_STATUS);
struct ofpbuf *buf = ofpraw_alloc_xid(raw, version, htonl(0), 0);
struct ofp14_role_status *rstatus = ofpbuf_put_zeros(buf, sizeof *rstatus);
rstatus->role = htonl(status->role);
rstatus->reason = status->reason;
rstatus->generation_id = htonll(status->generation_id);
return buf;
} }
enum ofperr enum ofperr
@ -152,7 +149,9 @@ ofputil_decode_role_status(const struct ofp_header *oh,
struct ofputil_role_status *rs) struct ofputil_role_status *rs)
{ {
struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length)); struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
ovs_assert(ofpraw_pull_assert(&b) == OFPRAW_OFPT14_ROLE_STATUS); enum ofpraw raw = ofpraw_pull_assert(&b);
ovs_assert(raw == OFPRAW_OFPT14_ROLE_STATUS ||
raw == OFPRAW_ONFT13_ROLE_STATUS);
const struct ofp14_role_status *r = b.msg; const struct ofp14_role_status *r = b.msg;
if (r->role != htonl(OFPCR12_ROLE_NOCHANGE) && if (r->role != htonl(OFPCR12_ROLE_NOCHANGE) &&

View File

@ -2852,6 +2852,36 @@ NXT_ROLE_REPLY (xid=0x2): role=slave
]) ])
AT_CLEANUP AT_CLEANUP
AT_SETUP([OFP_ROLE_STATUS - master, experimenter - OF1.3])
AT_KEYWORDS([ofp-print])
AT_CHECK([ovs-ofctl ofp-print "\
04 04 00 20 00 00 00 0a 4f 4e 46 00 00 00 07 77 \
00 00 00 02 02 00 00 00 ff ff ff ff ff ff ff ff \
"], [0], [dnl
ONFT_ROLE_STATUS (OF1.3) (xid=0xa): role=master reason=experimenter_data_changed
])
AT_CLEANUP
AT_SETUP([OFP_ROLE_STATUS - master, config - OF1.3])
AT_KEYWORDS([ofp-print])
AT_CHECK([ovs-ofctl ofp-print "\
04 04 00 20 00 00 00 0a 4f 4e 46 00 00 00 07 77 \
00 00 00 02 01 00 00 00 ff ff ff ff ff ff ff ff \
"], [0], [dnl
ONFT_ROLE_STATUS (OF1.3) (xid=0xa): role=master reason=configuration_changed
])
AT_CLEANUP
AT_SETUP([OFP_ROLE_STATUS - master, config,generation - OF1.3])
AT_KEYWORDS([ofp-print])
AT_CHECK([ovs-ofctl ofp-print "\
04 04 00 20 00 00 00 0a 4f 4e 46 00 00 00 07 77 \
00 00 00 02 01 00 00 00 00 00 00 00 00 00 00 10 \
"], [0], [dnl
ONFT_ROLE_STATUS (OF1.3) (xid=0xa): role=master generation_id=16 reason=configuration_changed
])
AT_CLEANUP
AT_SETUP([OFP_ROLE_STATUS - master, experimenter - OF1.4]) AT_SETUP([OFP_ROLE_STATUS - master, experimenter - OF1.4])
AT_KEYWORDS([ofp-print]) AT_KEYWORDS([ofp-print])
AT_CHECK([ovs-ofctl ofp-print "\ AT_CHECK([ovs-ofctl ofp-print "\

View File

@ -3945,6 +3945,72 @@ done
OVS_VSWITCHD_STOP OVS_VSWITCHD_STOP
AT_CLEANUP AT_CLEANUP
dnl This test checks that the role request/response messaging works,
dnl that generation_id is handled properly, and that role status update
dnl messages are sent when a controller's role gets changed from master
dnl to slave.
AT_SETUP([ofproto - controller role (OpenFlow 1.3)])
OVS_VSWITCHD_START
on_exit 'kill `cat c1.pid c2.pid`'
# Start two ovs-ofctl controller processes.
AT_CAPTURE_FILE([monitor1.log])
AT_CAPTURE_FILE([expout1])
AT_CAPTURE_FILE([experr1])
AT_CAPTURE_FILE([monitor2.log])
AT_CAPTURE_FILE([expout2])
AT_CAPTURE_FILE([experr2])
for i in 1 2; do
AT_CHECK([ovs-ofctl -O OpenFlow13 monitor br0 --detach --no-chdir --pidfile=c$i.pid --unixctl=c$i])
ovs-appctl -t `pwd`/c$i ofctl/barrier
ovs-appctl -t `pwd`/c$i ofctl/set-output-file monitor$i.log
: > expout$i
: > experr$i
# find out current role
ovs-appctl -t `pwd`/c$i ofctl/send 041800180000000200000000000000000000000000000000
echo >>experr$i "send: OFPT_ROLE_REQUEST (OF1.3): role=nochange"
echo >>expout$i "OFPT_ROLE_REPLY (OF1.3): role=equal"
done
# controller 1: Become slave (generation_id is initially undefined, so
# 2^63+2 should not be stale)
ovs-appctl -t `pwd`/c1 ofctl/send 041800180000000300000003000000008000000000000002
echo >>experr1 "send: OFPT_ROLE_REQUEST (OF1.3): role=slave generation_id=9223372036854775810"
echo >>expout1 "OFPT_ROLE_REPLY (OF1.3): role=slave generation_id=9223372036854775810"
# controller 2: Become master.
ovs-appctl -t `pwd`/c2 ofctl/send 041800180000000300000002000000008000000000000003
echo >>experr2 "send: OFPT_ROLE_REQUEST (OF1.3): role=master generation_id=9223372036854775811"
echo >>expout2 "OFPT_ROLE_REPLY (OF1.3): role=master generation_id=9223372036854775811"
# controller 1: Try to become the master using a stale generation ID
ovs-appctl -t `pwd`/c1 ofctl/send 041800180000000400000002000000000000000000000003
echo >>experr1 "send: OFPT_ROLE_REQUEST (OF1.3): role=master generation_id=3"
echo >>expout1 "OFPT_ERROR (OF1.3): OFPRRFC_STALE"
echo >>expout1 "OFPT_ROLE_REQUEST (OF1.3): role=master generation_id=3"
# controller 1: Become master using a valid generation ID
ovs-appctl -t `pwd`/c1 ofctl/send 041800180000000500000002000000000000000000000001
echo >>experr1 "send: OFPT_ROLE_REQUEST (OF1.3): role=master generation_id=1"
echo >>expout1 "OFPT_ROLE_REPLY (OF1.3): role=master generation_id=1"
echo >>expout2 "ONFT_ROLE_STATUS (OF1.3): role=slave generation_id=1 reason=master_request"
for i in 1 2; do
ovs-appctl -t `pwd`/c$i ofctl/barrier
echo >>expout$i "OFPT_BARRIER_REPLY (OF1.3):"
done
# Check output.
for i in 1 2; do
cp expout$i expout
AT_CHECK([grep -v '^send:' monitor$i.log | strip_xids], [0], [expout])
cp experr$i expout
AT_CHECK([grep '^send:' monitor$i.log | strip_xids], [0], [expout])
done
OVS_VSWITCHD_STOP
AT_CLEANUP
dnl This test checks the Group and meter notifications when a group mod dnl This test checks the Group and meter notifications when a group mod
dnl command is sent from one controller and the reply is received by dnl command is sent from one controller and the reply is received by
dnl other controllers. dnl other controllers.