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

Reply via email to