From 1ec9daf950936c2a1c591596e83c09ce2eb12ade Mon Sep 17 00:00:00 2001 From: Matthew Wood Date: Sun, 4 Feb 2024 15:27:39 -0800 Subject: [PATCH] net: netconsole: append userdata to fragmented netconsole messages Regardless of whether the original message body or formatted userdata exceeds the MAX_PRINT_CHUNK, append userdata to the netconsole message starting with the first chunk that has available space after writing the body. Co-developed-by: Breno Leitao Signed-off-by: Breno Leitao Signed-off-by: Matthew Wood Signed-off-by: David S. Miller --- drivers/net/netconsole.c | 44 +++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index d53bb1172336..0de108a1c0c8 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -1085,24 +1085,48 @@ static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg, memcpy(buf + release_len, header, header_len); header_len += release_len; - while (offset < body_len) { + while (offset < body_len + userdata_len) { int this_header = header_len; - int this_chunk; + int this_offset = 0; + int this_chunk = 0; this_header += scnprintf(buf + this_header, sizeof(buf) - this_header, - ",ncfrag=%d/%d;", offset, body_len); + ",ncfrag=%d/%d;", offset, + body_len + userdata_len); - this_chunk = min(body_len - offset, - MAX_PRINT_CHUNK - this_header); - if (WARN_ON_ONCE(this_chunk <= 0)) - return; + /* Not all body data has been written yet */ + if (offset < body_len) { + this_chunk = min(body_len - offset, + MAX_PRINT_CHUNK - this_header); + if (WARN_ON_ONCE(this_chunk <= 0)) + return; + memcpy(buf + this_header, body + offset, this_chunk); + this_offset += this_chunk; + } + /* Body is fully written and there is pending userdata to write, + * append userdata in this chunk + */ + if (offset + this_offset >= body_len && + offset + this_offset < userdata_len + body_len) { + int sent_userdata = (offset + this_offset) - body_len; + int preceding_bytes = this_chunk + this_header; - memcpy(buf + this_header, body + offset, this_chunk); + if (WARN_ON_ONCE(sent_userdata < 0)) + return; - netpoll_send_udp(&nt->np, buf, this_header + this_chunk); + this_chunk = min(userdata_len - sent_userdata, + MAX_PRINT_CHUNK - preceding_bytes); + if (WARN_ON_ONCE(this_chunk <= 0)) + return; + memcpy(buf + this_header + this_offset, + userdata + sent_userdata, + this_chunk); + this_offset += this_chunk; + } - offset += this_chunk; + netpoll_send_udp(&nt->np, buf, this_header + this_offset); + offset += this_offset; } }