From: Alejandro Pacheco <[email protected]>
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
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to