Signed-off-by: Simon Horman <[email protected]>
---
lib/ofp-msgs.c | 3 +-
ofproto/ofproto.c | 63 +++++++++++++++++++---------
tests/ofproto.at | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 167 insertions(+), 21 deletions(-)
diff --git a/lib/ofp-msgs.c b/lib/ofp-msgs.c
index 29f9770..91650b9 100644
--- a/lib/ofp-msgs.c
+++ b/lib/ofp-msgs.c
@@ -915,8 +915,7 @@ ofpmsg_is_mp_request(const struct ofp_header *oh)
bool
ofpmsg_may_buffer_mp_request(enum ofptype type OVS_UNUSED)
{
- /* Currently no types are allowed to be buffered. */
- return false;
+ return type == OFPTYPE_FLOW_MONITOR_STATS_REQUEST;
}
static ovs_be16 *ofpmp_flags__(const struct ofp_header *);
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index f8d2690..c930243 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -4906,21 +4906,17 @@ flow_monitor_delete(struct ofconn *ofconn, uint32_t id)
}
static enum ofperr
-handle_flow_monitor_request(struct ofconn *ofconn, const struct ofp_header *oh)
- OVS_EXCLUDED(ofproto_mutex)
+handle_one_flow_monitor_request(struct ofconn *ofconn,
+ const struct ofp_header *oh,
+ struct list *monitor_list)
+ OVS_REQUIRES(ofproto_mutex)
{
- struct list monitor_list = LIST_INITIALIZER(&monitor_list);
struct ofproto *ofproto = ofconn_get_ofproto(ofconn);
- struct rule_collection rules;
- struct list replies;
- struct ofmonitor *m, *next;
- enum ofperr error;
+ struct ofmonitor *m;
struct ofpbuf b;
- error = 0;
ofpbuf_use_const(&b, oh, ntohs(oh->length));
- ovs_mutex_lock(&ofproto_mutex);
for (;;) {
struct ofputil_flow_monitor_request request;
int retval;
@@ -4929,32 +4925,61 @@ handle_flow_monitor_request(struct ofconn *ofconn,
const struct ofp_header *oh)
if (retval == EOF) {
break;
} else if (retval) {
- error = retval;
- goto error;
+ return retval;
}
if (request.table_id != 0xff
&& request.table_id >= ofproto->n_tables) {
- error = OFPERR_OFPBRC_BAD_TABLE_ID;
- goto error;
+ return OFPERR_OFPBRC_BAD_TABLE_ID;
}
if (request.command == OFPFMC14_DELETE ||
request.command == OFPFMC14_MODIFY) {
- error = flow_monitor_delete(ofconn, request.id);
+ enum ofperr error = flow_monitor_delete(ofconn, request.id);
if (error) {
- goto error;
+ return error;
}
}
if (request.command == OFPFMC14_ADD ||
request.command == OFPFMC14_MODIFY) {
- error = ofmonitor_create(&request, ofconn, &m);
+ enum ofperr error = ofmonitor_create(&request, ofconn, &m);
if (error) {
- goto error;
+ return error;
}
- list_insert(&monitor_list, &m->list_node);
+ list_insert(monitor_list, &m->list_node);
+ }
+ }
+
+ return 0;
+}
+
+static enum ofperr
+handle_flow_monitor_request(struct ofconn *ofconn, const struct ofpbuf *msg)
+ OVS_EXCLUDED(ofproto_mutex)
+{
+ struct list monitor_list = LIST_INITIALIZER(&monitor_list);
+ const struct ofp_header *oh = ofpbuf_data(msg);
+ struct rule_collection rules;
+ struct list replies;
+ struct ofmonitor *m, *next;
+ enum ofperr error;
+ struct ofpbuf *b;
+
+ error = 0;
+
+ ovs_mutex_lock(&ofproto_mutex);
+
+ /* First part of multi-part request */
+ handle_one_flow_monitor_request(ofconn, oh, &monitor_list);
+
+ /* Any subsequent parts */
+ LIST_FOR_EACH (b, list_node, &msg->list_node) {
+ error = handle_one_flow_monitor_request(ofconn, ofpbuf_data(b),
+ &monitor_list);
+ if (error) {
+ goto error;
}
}
@@ -6025,7 +6050,7 @@ handle_openflow__(struct ofconn *ofconn, const struct
ofpbuf *msg)
return handle_port_desc_stats_request(ofconn, oh);
case OFPTYPE_FLOW_MONITOR_STATS_REQUEST:
- return handle_flow_monitor_request(ofconn, oh);
+ return handle_flow_monitor_request(ofconn, msg);
case OFPTYPE_METER_STATS_REQUEST:
case OFPTYPE_METER_CONFIG_STATS_REQUEST:
diff --git a/tests/ofproto.at b/tests/ofproto.at
index af48809..18fe0e7 100644
--- a/tests/ofproto.at
+++ b/tests/ofproto.at
@@ -3583,3 +3583,125 @@ OFPT_BARRIER_REPLY (OF1.4):
OVS_VSWITCHD_STOP
AT_CLEANUP
+
+AT_SETUP([ofproto - multipart flow monitor request (OpenFlow 1.3)])
+AT_KEYWORDS([monitor])
+OVS_VSWITCHD_START
+ADD_OF_PORTS([br0], [1], [2], [3])
+
+# Start a monitor, use the required protocol version
+ovs-ofctl -O OpenFlow13 monitor br0 --detach --no-chdir --pidfile >monitor.log
2>&1
+AT_CAPTURE_FILE([monitor.log])
+
+# Send first part: monitor actions with dl_vlan=7
+ovs-appctl -t ovs-ofctl ofctl/send "\
+04 12 00 30 00 00 00 01 ff ff 00 01 00 00 00 00 \
+4f 4e 46 00 00 00 07 4e 00 00 00 07 00 1f 00 06 \
+ff ff ff ff 00 00 00 00 80 00 0c 02 10 07 00 00 \
+"
+
+# Send second part: monitor actions with dl_vlan=8
+ovs-appctl -t ovs-ofctl ofctl/send "\
+04 12 00 30 00 00 00 01 ff ff 00 01 00 00 00 00 \
+4f 4e 46 00 00 00 07 4e 00 00 00 08 00 1f 00 06 \
+ff ff ff ff 00 00 00 00 80 00 0c 02 10 08 00 00 \
+"
+
+# Send third part: monitor actions with dl_vlan=9
+ovs-appctl -t ovs-ofctl ofctl/send "\
+04 12 00 30 00 00 00 01 ff ff 00 00 00 00 00 00 \
+4f 4e 46 00 00 00 07 4e 00 00 00 09 00 1f 00 06 \
+ff ff ff ff 00 00 00 00 80 00 0c 02 10 09 00 00 \
+"
+
+ovs-appctl -t ovs-ofctl ofctl/barrier
+
+# Create some evnents that should be monitored
+ovs-ofctl -O OpenFlow13 add-flow br0 in_port=0,dl_vlan=7,actions=output:2
+ovs-ofctl -O OpenFlow13 add-flow br0 in_port=0,dl_vlan=8,actions=output:2
+ovs-ofctl -O OpenFlow13 add-flow br0 in_port=0,dl_vlan=9,actions=output:2
+
+# Check default setting
+read -r -d '' expected <<'EOF'
+EOF
+
+AT_CHECK([ofctl_strip < monitor.log ], [], [dnl
+send: ONFST_FLOW_MONITOR request (OF1.3):
+ id=7 flags=initial,add,delete,modify,actions table=0 dl_vlan=7
+send: ONFST_FLOW_MONITOR request (OF1.3):
+ id=8 flags=initial,add,delete,modify,actions table=0 dl_vlan=8
+send: ONFST_FLOW_MONITOR request (OF1.3):
+ id=9 flags=initial,add,delete,modify,actions table=0 dl_vlan=9
+ONFST_FLOW_MONITOR reply (OF1.3):
+OFPT_BARRIER_REPLY (OF1.3):
+ONFST_FLOW_MONITOR reply (OF1.3):
+ event=ADDED table=0 cookie=0 in_port=0,dl_vlan=7 actions=output:2
+ONFST_FLOW_MONITOR reply (OF1.3):
+ event=ADDED table=0 cookie=0 in_port=0,dl_vlan=8 actions=output:2
+ONFST_FLOW_MONITOR reply (OF1.3):
+ event=ADDED table=0 cookie=0 in_port=0,dl_vlan=9 actions=output:2
+])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([ofproto - multipart flow monitor request (OpenFlow 1.4)])
+AT_KEYWORDS([monitor])
+OVS_VSWITCHD_START
+ADD_OF_PORTS([br0], [1], [2], [3])
+
+# Start a monitor, use the required protocol version
+ovs-ofctl -O OpenFlow14 monitor br0 --detach --no-chdir --pidfile >monitor.log
2>&1
+AT_CAPTURE_FILE([monitor.log])
+
+# Send first part: monitor actions with dl_vlan=7
+ovs-appctl -t ovs-ofctl ofctl/send "\
+05 12 00 30 00 00 00 02 00 10 00 01 00 00 00 00 \
+00 00 00 01 ff ff ff ff ff ff ff ff 00 1f 00 00 \
+00 01 00 0a 80 00 0c 02 10 07 00 00 00 00 00 00 \
+"
+
+# Send second part: monitor actions with dl_vlan=8
+ovs-appctl -t ovs-ofctl ofctl/send "\
+05 12 00 30 00 00 00 02 00 10 00 01 00 00 00 00 \
+00 00 00 02 ff ff ff ff ff ff ff ff 00 1f 00 00 \
+00 01 00 0a 80 00 0c 02 10 08 00 00 00 00 00 00 \
+"
+
+# Send third part: monitor actions with dl_vlan=9
+ovs-appctl -t ovs-ofctl ofctl/send "\
+05 12 00 30 00 00 00 02 00 10 00 00 00 00 00 00 \
+00 00 00 03 ff ff ff ff ff ff ff ff 00 1f 00 00 \
+00 01 00 0a 80 00 0c 02 10 09 00 00 00 00 00 00 \
+"
+
+ovs-appctl -t ovs-ofctl ofctl/barrier
+
+# Create some evnents that should be monitored
+ovs-ofctl -O OpenFlow14 add-flow br0 in_port=0,dl_vlan=7,actions=output:2
+ovs-ofctl -O OpenFlow14 add-flow br0 in_port=0,dl_vlan=8,actions=output:2
+ovs-ofctl -O OpenFlow14 add-flow br0 in_port=0,dl_vlan=9,actions=output:2
+
+# Check default setting
+read -r -d '' expected <<'EOF'
+EOF
+
+AT_CHECK([ofctl_strip < monitor.log ], [], [dnl
+send: OFPST_FLOW_MONITOR request (OF1.4):
+ command=ADD id=1 flags=initial,add,delete,modify,instructions table=0
dl_vlan=7
+send: OFPST_FLOW_MONITOR request (OF1.4):
+ command=ADD id=2 flags=initial,add,delete,modify,instructions table=0
dl_vlan=8
+send: OFPST_FLOW_MONITOR request (OF1.4):
+ command=ADD id=3 flags=initial,add,delete,modify,instructions table=0
dl_vlan=9
+OFPST_FLOW_MONITOR reply (OF1.4):
+OFPT_BARRIER_REPLY (OF1.4):
+OFPST_FLOW_MONITOR reply (OF1.4):
+ event=ADDED table=0 cookie=0 in_port=0,dl_vlan=7 actions=output:2
+OFPST_FLOW_MONITOR reply (OF1.4):
+ event=ADDED table=0 cookie=0 in_port=0,dl_vlan=8 actions=output:2
+OFPST_FLOW_MONITOR reply (OF1.4):
+ event=ADDED table=0 cookie=0 in_port=0,dl_vlan=9 actions=output:2
+])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
--
2.0.0.rc2
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev