ofputil_decode_flow_monitor_request() pulls the OpenFlow header and
each decoded entry from the message buffer, so when an entry fails,
'b->data' no longer points to the request header. The error path of
handle_flow_monitor_request() still passes 'b->data' to
ofconn_send_error(), which reads the version, xid and length of the
message from that position and copies up to that many bytes into the
error reply.
Pass 'b->header', as the other callers of ofconn_send_error() do with
their request.
Fixes: af3c51aee409 ("ofproto: Handle flow monitor requests with
multiple parts.")
Assisted-by: claude-opus-5-5, Claude Code
Signed-off-by: Alejandro Pacheco <[email protected]>
---
ofproto/ofproto.c | 2 +-
tests/ofproto.at | 49 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index 8b636abef..6a2b21ddf 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -6799,7 +6799,7 @@ handle_flow_monitor_request(struct ofconn
*ofconn, const struct ovs_list *msgs)
continue;
error:
- ofconn_send_error(ofconn, b->data, error);
+ ofconn_send_error(ofconn, b->header, error);
for (size_t i = 0; i < n_monitors; i++) {
ofmonitor_destroy(monitors[i]);
diff --git a/tests/ofproto.at b/tests/ofproto.at
index 1277ba302..522c991d8 100644
--- a/tests/ofproto.at
+++ b/tests/ofproto.at
@@ -5096,6 +5096,55 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl])
OVS_VSWITCHD_STOP
AT_CLEANUP
+AT_SETUP([ofproto - OpenFlow14 flow monitor request with unknown monitor])
+AT_KEYWORDS([monitor])
+OVS_VSWITCHD_START
+
+ovs-ofctl -O OpenFlow14 monitor br0 --detach --no-chdir --pidfile
>monitor.log 2>&1
+AT_CAPTURE_FILE([monitor.log])
+
+# Add monitor 3, delete it, then delete the unknown monitor 4.
+ovs-appctl -t ovs-ofctl ofctl/send
0512005800000004001000000000000000000003ffffffffffffffff000fff00000100040000000000000003ffffffffffffffff0000ff02000100040000000000000004ffffffffffffffff0000ff020001000400000000
+# Add monitors 5 and 6, delete 5, then delete the unknown monitor 7.
+ovs-appctl -t ovs-ofctl ofctl/send
0512007000000005001000000000000000000005ffffffffffffffff000fff00000100040000000000000006ffffffffffffffff000fff00000100040000000000000005ffffffffffffffff0000ff02000100040000000000000007ffffffffffffffff0000ff020001000400000000
+# Monitor 6 was removed with the failed request.
+ovs-appctl -t ovs-ofctl ofctl/send
0512002800000006001000000000000000000006ffffffffffffffff0000ff020001000400000000
+ovs-appctl -t ovs-ofctl ofctl/barrier
+
+dnl Each error carries the whole request.
+AT_CHECK([sed 's/ (xid=0x[[1-9a-fA-F]][[0-9a-fA-F]]*)//'
monitor.log], [0], [dnl
+send: OFPST_FLOW_MONITOR request (OF1.4):
+ id=3 flags=initial,add,delete,modify
+ id=3 command=delete
+ id=4 command=delete
+OFPT_ERROR (OF1.4): OFPMOFC_UNKNOWN_MONITOR
+OFPST_FLOW_MONITOR request (OF1.4):
+ id=3 flags=initial,add,delete,modify
+ id=3 command=delete
+ id=4 command=delete
+send: OFPST_FLOW_MONITOR request (OF1.4):
+ id=5 flags=initial,add,delete,modify
+ id=6 flags=initial,add,delete,modify
+ id=5 command=delete
+ id=7 command=delete
+OFPT_ERROR (OF1.4): OFPMOFC_UNKNOWN_MONITOR
+OFPST_FLOW_MONITOR request (OF1.4):
+ id=5 flags=initial,add,delete,modify
+ id=6 flags=initial,add,delete,modify
+ id=5 command=delete
+ id=7 command=delete
+send: OFPST_FLOW_MONITOR request (OF1.4):
+ id=6 command=delete
+OFPT_ERROR (OF1.4): OFPMOFC_UNKNOWN_MONITOR
+OFPST_FLOW_MONITOR request (OF1.4):
+ id=6 command=delete
+OFPT_BARRIER_REPLY (OF1.4):
+])
+
+OVS_APP_EXIT_AND_WAIT([ovs-ofctl])
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
AT_SETUP([ofproto - event filtering (OpenFlow 1.3)])
AT_KEYWORDS([monitor])
OVS_VSWITCHD_START
--
2.53.0
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev