Signed-off-by: Simon Horman <ho...@verge.net.au> --- 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 dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev