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:
parent
0d71302e36
commit
b0e07d5078
@ -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
2
NEWS
@ -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
|
||||||
|
@ -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. */
|
||||||
|
@ -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) &&
|
||||||
|
@ -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 "\
|
||||||
|
@ -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.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user