Backported OFPT14_REQUESTFORWARD to OF1.0-1.3 as a Nicira extension. VMware-BZ: 2136594 Signed-off-by: Zak Whittington <zwhitt.vmw...@gmail.com> --- include/openvswitch/ofp-monitor.h | 1 + include/openvswitch/ofp-msgs.h | 5 +- lib/ofp-monitor.c | 11 +++-- ofproto/connmgr.c | 6 ++- tests/ofp-print.at | 76 ++++++++++++++++++++++++++++++ tests/ofproto.at | 98 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 191 insertions(+), 6 deletions(-)
diff --git a/include/openvswitch/ofp-monitor.h b/include/openvswitch/ofp-monitor.h index 1bfcf92..7015200 100644 --- a/include/openvswitch/ofp-monitor.h +++ b/include/openvswitch/ofp-monitor.h @@ -116,6 +116,7 @@ struct ofpbuf *ofputil_encode_flow_monitor_cancel(uint32_t id); struct ofputil_requestforward { ovs_be32 xid; + /* Also used for OF 1.0-1.3 when using Nicera Extension: */ enum ofp14_requestforward_reason reason; union { /* reason == OFPRFR_METER_MOD. */ diff --git a/include/openvswitch/ofp-msgs.h b/include/openvswitch/ofp-msgs.h index 8a32a3d..012aa06 100644 --- a/include/openvswitch/ofp-msgs.h +++ b/include/openvswitch/ofp-msgs.h @@ -274,6 +274,8 @@ enum ofpraw { /* OFPT 1.4+ (31): struct ofp14_table_status, uint8_t[8][]. */ OFPRAW_OFPT14_TABLE_STATUS, + /* NXT 1.0-1.3 (132): struct ofp14_requestforward, uint8_t[8][]. */ + OFPRAW_NXT_REQUESTFORWARD, /* OFPT 1.4+ (32): struct ofp14_requestforward, uint8_t[8][]. */ OFPRAW_OFPT14_REQUESTFORWARD, @@ -645,7 +647,8 @@ enum ofptype { * OFPRAW_OFPT14_ROLE_STATUS. */ /* Request forwarding by the switch. */ - OFPTYPE_REQUESTFORWARD, /* OFPRAW_OFPT14_REQUESTFORWARD. */ + OFPTYPE_REQUESTFORWARD, /* OFPRAW_NXT_REQUESTFORWARD. + * OFPRAW_OFPT14_REQUESTFORWARD. */ /* Asynchronous messages. */ OFPTYPE_TABLE_STATUS, /* OFPRAW_OFPT14_TABLE_STATUS. */ diff --git a/lib/ofp-monitor.c b/lib/ofp-monitor.c index d1853d9..4a9a650 100644 --- a/lib/ofp-monitor.c +++ b/lib/ofp-monitor.c @@ -785,8 +785,7 @@ ofputil_flow_update_format(struct ds *s, } } -/* Encodes 'rf' according to 'protocol', and returns the encoded message. - * 'protocol' must be for OpenFlow 1.4 or later. */ +/* Encodes 'rf' according to 'protocol', and returns the encoded message. */ struct ofpbuf * ofputil_encode_requestforward(const struct ofputil_requestforward *rf, enum ofputil_protocol protocol) @@ -813,7 +812,9 @@ ofputil_encode_requestforward(const struct ofputil_requestforward *rf, inner_oh->xid = rf->xid; inner_oh->length = htons(inner->size); - struct ofpbuf *outer = ofpraw_alloc_xid(OFPRAW_OFPT14_REQUESTFORWARD, + struct ofpbuf *outer = ofpraw_alloc_xid((ofp_version < OFP14_VERSION) ? + OFPRAW_NXT_REQUESTFORWARD : + OFPRAW_OFPT14_REQUESTFORWARD, ofp_version, htonl(0), inner->size); ofpbuf_put(outer, inner->data, inner->size); @@ -836,7 +837,9 @@ ofputil_decode_requestforward(const struct ofp_header *outer, struct ofpbuf b = ofpbuf_const_initializer(outer, ntohs(outer->length)); /* Skip past outer message. */ - ovs_assert(ofpraw_pull_assert(&b) == OFPRAW_OFPT14_REQUESTFORWARD); + enum ofpraw raw_msg_type = ofpraw_pull_assert(&b); + ovs_assert(raw_msg_type == OFPRAW_OFPT14_REQUESTFORWARD || + raw_msg_type == OFPRAW_NXT_REQUESTFORWARD); /* Validate inner message. */ if (b.size < sizeof(struct ofp_header)) { diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c index 9431200..a9b52f9 100644 --- a/ofproto/connmgr.c +++ b/ofproto/connmgr.c @@ -1691,8 +1691,12 @@ connmgr_send_requestforward(struct connmgr *mgr, const struct ofconn *source, struct ofconn *ofconn; LIST_FOR_EACH (ofconn, node, &mgr->all_conns) { + /* METER_MOD only supported in OF13 and up. */ + if (rf->reason == OFPRFR_METER_MOD && + rconn_get_version(ofconn->rconn) < OFP13_VERSION) + continue; + if (ofconn_receives_async_msg(ofconn, OAM_REQUESTFORWARD, rf->reason) - && rconn_get_version(ofconn->rconn) >= OFP14_VERSION && ofconn != source) { enum ofputil_protocol protocol = ofconn_get_protocol(ofconn); ofconn_send(ofconn, ofputil_encode_requestforward(rf, protocol), diff --git a/tests/ofp-print.at b/tests/ofp-print.at index e38ca4a..966061a 100644 --- a/tests/ofp-print.at +++ b/tests/ofp-print.at @@ -3138,6 +3138,82 @@ OFPT_REQUESTFORWARD (OF1.4) (xid=0x2): reason=meter_mod MOD meter=1 flags:0x100 ]) AT_CLEANUP +AT_SETUP([NXT_REQUESTFORWARD - inner NXT_GROUP_MOD]) +AT_KEYWORDS([ofp-print]) +AT_CHECK([ovs-ofctl ofp-print "\ +dnl OF version 1.0; type=extension: +01 04 \ +dnl size in bytes: +00 b8 \ +dnl xid: +00 00 00 02 \ +dnl Nicira vendor number: +00 00 23 20 \ +dnl subtype (message id number = 132 in this case) +00 00 00 84 \ +dnl inner msg copied and pasted from NXT_GROUP_MOD test above: +01 04 00 a8 00 00 00 02 00 00 23 20 00 00 00 1f 00 00 01 00 87 65 43 21 \ +00 60 00 00 ff ff ff ff 00 20 00 08 00 00 00 00 00 00 00 08 00 01 00 00 \ +00 00 00 08 00 64 00 00 00 01 00 08 00 00 00 01 00 20 00 08 00 00 00 01 \ +00 00 00 08 00 02 00 00 00 00 00 08 00 c8 00 00 00 01 00 08 00 00 00 02 \ +00 20 00 08 00 00 00 02 00 00 00 08 00 03 00 00 00 00 00 08 00 c8 00 00 \ +00 01 00 08 00 00 00 03 ff ff 00 28 00 00 15 40 00 00 00 01 00 00 00 00 \ +68 61 73 68 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 07 \ +"], [0], [dnl +NXT_REQUESTFORWARD (xid=0x2): reason=group_mod + ADD group_id=2271560481,type=select,selection_method=hash,selection_method_param=7,bucket=bucket_id:0,weight:100,watch_port:1,actions=output:1,bucket=bucket_id:1,weight:200,watch_port:2,actions=output:2,bucket=bucket_id:2,weight:200,watch_port:3,actions=output:3 +]) +AT_CLEANUP + +AT_SETUP([NXT_REQUESTFORWARD - inner OFPT_GROUP_MOD - OF1.1]) +AT_KEYWORDS([ofp-print]) +AT_CHECK([ovs-ofctl ofp-print "\ +dnl OF Version 1.1; type=extension: +02 04 \ +dnl size in bytes: +00 80 \ +dnl xid: +00 00 00 02 \ +dnl Nicira vendor number: +00 00 23 20 \ +dnl subtype (message id number = 132 in this case) +00 00 00 84 \ +dnl inner msg copied and pasted from OFPT_GROUP_MOD OF1.1 test above: +02 0f 00 70 11 22 33 44 00 00 01 00 87 65 43 21 \ +00 20 00 64 00 00 00 01 ff ff ff ff 00 00 00 00 \ +00 00 00 10 00 00 00 01 00 00 00 00 00 00 00 00 \ +00 20 00 c8 00 00 00 02 ff ff ff ff 00 00 00 00 \ +00 00 00 10 00 00 00 02 00 00 00 00 00 00 00 00 \ +00 20 00 c8 00 00 00 03 ff ff ff ff 00 00 00 00 \ +00 00 00 10 00 00 00 03 00 00 00 00 00 00 00 00 \ +"], [0], [dnl +NXT_REQUESTFORWARD (OF1.1) (xid=0x2): reason=group_mod + ADD group_id=2271560481,type=select,bucket=weight:100,watch_port:1,actions=output:1,bucket=weight:200,watch_port:2,actions=output:2,bucket=weight:200,watch_port:3,actions=output:3 +]) +AT_CLEANUP + +AT_SETUP([NXT_REQUESTFORWARD - inner OFPT_METER_MOD - OF1.3]) +AT_KEYWORDS([ofp-print]) +AT_CHECK([ovs-ofctl ofp-print "\ +dnl OF Version 1.3; type=extension: +04 04 \ +dnl size in bytes: +00 30 \ +dnl xid: +00 00 00 02 \ +dnl Nicira vendor number: +00 00 23 20 \ +dnl subtype (message id number = 132 in this case) +00 00 00 84 \ +dnl inner msg copied and pasted from the valid OFPT_METER_MOD OF1.3 test: +04 1d 00 20 00 00 00 02 00 00 00 0d 00 00 00 05 \ +00 01 00 10 00 00 04 00 00 00 00 80 00 00 00 00 \ +"], [0], [dnl +NXT_REQUESTFORWARD (OF1.3) (xid=0x2): reason=meter_mod ADD meter=5 kbps burst stats bands= +type=drop rate=1024 burst_size=128 +]) +AT_CLEANUP + AT_SETUP([NXT_SET_PACKET_IN]) AT_KEYWORDS([ofp-print]) AT_CHECK([ovs-ofctl ofp-print "\ diff --git a/tests/ofproto.at b/tests/ofproto.at index c92339a3..b6c24b6 100644 --- a/tests/ofproto.at +++ b/tests/ofproto.at @@ -4186,6 +4186,104 @@ check_async 1 OFPGC_ADD OFPGC_MODIFY OVS_VSWITCHD_STOP AT_CLEANUP +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 other controllers, using the NXT Nicira Extension for OF 1.3. +AT_SETUP([ofproto - NXT requestforward (OpenFlow 1.3)]) +OVS_VSWITCHD_START +on_exit 'kill `cat c1.pid c2.pid c3.pid`' + +# Start two ovs-ofctl controller processes. +AT_CAPTURE_FILE([monitor1.log]) +AT_CAPTURE_FILE([expout1]) +AT_CAPTURE_FILE([monitor2.log]) +AT_CAPTURE_FILE([expout2]) +AT_CAPTURE_FILE([monitor3.log]) +AT_CAPTURE_FILE([expout3]) + +ovs-ofctl -O OpenFlow13 monitor br0 --detach --no-chdir --pidfile=c1.pid --unixctl=c1 +ovs-ofctl -O OpenFlow13 monitor br0 --detach --no-chdir --pidfile=c2.pid --unixctl=c2 +ovs-ofctl -O OpenFlow13 monitor br0 --detach --no-chdir --pidfile=c3.pid --unixctl=c3 + +check_async () { + for i in 1 3; do + ovs-appctl -t `pwd`/c$i ofctl/barrier + ovs-appctl -t `pwd`/c$i ofctl/set-output-file monitor$i.log + : > expout$i + done + + printf '\n\n--- check_async %d ---\n\n\n' $1 + INDEX=$1 + shift + + # OFPGC_ADD + # OFPT_GROUP_MOD (OF1.3) (xid=0x2): + # ADD group_id=1,type=all,bucket=actions=drop + ovs-appctl -t `pwd`/c2 ofctl/send "040f0020000000020000000000000001 00100000 ffffffffffffffff 00000000" + if test X"$1" = X"OFPGC_ADD"; then shift; + echo >>expout2 "send: OFPT_GROUP_MOD (OF1.3): + ADD group_id=1,type=all,bucket=actions=drop" + echo >>expout1 "NXT_REQUESTFORWARD (OF1.3): reason=group_mod + ADD group_id=1,type=all,bucket=actions=drop" + echo >>expout3 "NXT_REQUESTFORWARD (OF1.3): reason=group_mod + ADD group_id=1,type=all,bucket=actions=drop" + fi + + # OFPGC_MODIFY + # OFPT_GROUP_MOD (OF1.3) (xid=0x2): + # MOD group_id=1,type=select,bucket=weight:0,actions=drop + ovs-appctl -t `pwd`/c2 ofctl/send "040f0020000000020001010000000001 00100000 ffffffffffffffff 00000000" + if test X"$1" = X"OFPGC_MODIFY"; then shift; + echo >>expout2 "send: OFPT_GROUP_MOD (OF1.3): + MOD group_id=1,type=select,bucket=weight:0,actions=drop" + echo >>expout1 "NXT_REQUESTFORWARD (OF1.3): reason=group_mod + MOD group_id=1,type=select,bucket=weight:0,actions=drop" + echo >>expout3 "NXT_REQUESTFORWARD (OF1.3): reason=group_mod + MOD group_id=1,type=select,bucket=weight:0,actions=drop" + fi + + ovs-appctl -t `pwd`/c1 ofctl/barrier + echo >>expout1 "OFPT_BARRIER_REPLY (OF1.3):" + ovs-appctl -t `pwd`/c2 ofctl/barrier + echo >>expout2 "OFPT_BARRIER_REPLY (OF1.3):" + ovs-appctl -t `pwd`/c3 ofctl/barrier + echo >>expout3 "OFPT_BARRIER_REPLY (OF1.3):" + + # Check output. + for i in 1 3; do + cp expout$i expout + AT_CHECK( + [[sed ' +s/ (xid=0x[0-9a-fA-F]*)//'< monitor$i.log]], + [0], [expout]) + done +} + +# controller 1: Become slave +# OFPT_ROLE_REQUEST (OF1.3) (xid=0x3): role=slave +ovs-appctl -t `pwd`/c1 ofctl/send 041800180000000300000003000000008000000000000002 + +# controller 2: Become master +# OFPT_ROLE_REQUEST (OF1.3) (xid=0x3): role=master +ovs-appctl -t `pwd`/c2 ofctl/send 041800180000000300000002000000008000000000000003 + +# controller 1: Become slave +# OFPT_ROLE_REQUEST (OF1.3) (xid=0x3): role=slave +ovs-appctl -t `pwd`/c3 ofctl/send 041800180000000300000003000000008000000000000004 + +# controller 1: Enabled requestforward using OFPRAW_NXT_SET_ASYNC_CONFIG2 (necessary for OF1.3) +ovs-appctl -t `pwd`/c1 ofctl/send 0404003000000002000023200000001b00000008000000050002000800000002000400080000001a000a000800000003 + +# controller 2: Enabled requestforward using OFPRAW_NXT_SET_ASYNC_CONFIG2 (necessary for OF1.3) +ovs-appctl -t `pwd`/c2 ofctl/send 0404003000000002000023200000001b000100080000000200030008000000050005000800000005000b000800000003 + +# controller 1: Enabled requestforward using OFPRAW_NXT_SET_ASYNC_CONFIG2 (necessary for OF1.3) +ovs-appctl -t `pwd`/c3 ofctl/send 0404003000000002000023200000001b00000008000000050002000800000002000400080000001a000a000800000003 +check_async 1 OFPGC_ADD OFPGC_MODIFY + +OVS_VSWITCHD_STOP +AT_CLEANUP + dnl This test checks that OFPT_PACKET_OUT accepts both OFPP_NONE (as dnl specified by OpenFlow 1.0) and OFPP_CONTROLLER (used by some dnl controllers despite the spec) as meaning a packet that was generated -- 2.7.4 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev