From: David Gibson <david@gibson.dropbear.id.au>
To: passt-dev@passt.top, Stefano Brivio <sbrivio@redhat.com>
Cc: David Gibson <david@gibson.dropbear.id.au>
Subject: [PATCH v2 4/7] udp: Share more logic between vu and non-vu reply socket paths
Date: Wed, 26 Mar 2025 14:44:04 +1100 [thread overview]
Message-ID: <20250326034407.2240846-5-david@gibson.dropbear.id.au> (raw)
In-Reply-To: <20250326034407.2240846-1-david@gibson.dropbear.id.au>
Share some additional miscellaneous logic between the vhost-user and "buf"
paths for data on udp reply sockets. The biggest piece is error handling
of cases where we can't forward between the two pifs of the flow. We also
make common some more simple logic locating the correct flow and its
parameters.
This adds some lines of code due to extra comment lines, but nonetheless
reduces logic duplication.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
udp.c | 41 ++++++++++++++++++++++++++---------------
udp_vu.c | 26 +++++++++++---------------
udp_vu.h | 3 ++-
3 files changed, 39 insertions(+), 31 deletions(-)
diff --git a/udp.c b/udp.c
index 55021ac4..4258812e 100644
--- a/udp.c
+++ b/udp.c
@@ -754,24 +754,25 @@ void udp_listen_sock_handler(const struct ctx *c,
/**
* udp_buf_reply_sock_data() - Handle new data from flow specific socket
* @c: Execution context
- * @ref: epoll reference
+ * @s: Socket to read data from
+ * @tosidx: Flow & side to forward data from @s to
* @now: Current timestamp
*
+ * Return: true on success, false if can't forward from socket to flow's pif
+ *
* #syscalls recvmmsg
*/
-static void udp_buf_reply_sock_data(const struct ctx *c, union epoll_ref ref,
+static bool udp_buf_reply_sock_data(const struct ctx *c,
+ int s, flow_sidx_t tosidx,
const struct timespec *now)
{
- flow_sidx_t tosidx = flow_sidx_opposite(ref.flowside);
const struct flowside *toside = flowside_at_sidx(tosidx);
- struct udp_flow *uflow = udp_at_sidx(ref.flowside);
+ struct udp_flow *uflow = udp_at_sidx(tosidx);
uint8_t topif = pif_at_sidx(tosidx);
- int n, i, from_s;
-
- from_s = uflow->s[ref.flowside.sidei];
+ int n, i;
- if ((n = udp_sock_recv(c, from_s, udp_mh_recv)) <= 0)
- return;
+ if ((n = udp_sock_recv(c, s, udp_mh_recv)) <= 0)
+ return true;
flow_trace(uflow, "Received %d datagrams on reply socket", n);
uflow->ts = now->tv_sec;
@@ -790,11 +791,10 @@ static void udp_buf_reply_sock_data(const struct ctx *c, union epoll_ref ref,
} else if (topif == PIF_TAP) {
tap_send_frames(c, &udp_l2_iov[0][0], UDP_NUM_IOVS, n);
} else {
- uint8_t frompif = pif_at_sidx(ref.flowside);
-
- flow_err(uflow, "No support for forwarding UDP from %s to %s",
- pif_name(frompif), pif_name(topif));
+ return false;
}
+
+ return true;
}
/**
@@ -821,10 +821,21 @@ void udp_reply_sock_handler(const struct ctx *c, union epoll_ref ref,
}
if (events & EPOLLIN) {
+ flow_sidx_t tosidx = flow_sidx_opposite(ref.flowside);
+ int s = ref.fd;
+ bool ret;
+
if (c->mode == MODE_VU)
- udp_vu_reply_sock_data(c, ref, now);
+ ret = udp_vu_reply_sock_data(c, s, tosidx, now);
else
- udp_buf_reply_sock_data(c, ref, now);
+ ret = udp_buf_reply_sock_data(c, s, tosidx, now);
+
+ if (!ret) {
+ flow_err(uflow,
+ "No support for forwarding UDP from %s to %s",
+ pif_name(pif_at_sidx(ref.flowside)),
+ pif_name(pif_at_sidx(tosidx)));
+ }
}
}
diff --git a/udp_vu.c b/udp_vu.c
index 6e1823a9..06bdeae6 100644
--- a/udp_vu.c
+++ b/udp_vu.c
@@ -273,38 +273,32 @@ void udp_vu_listen_sock_data(const struct ctx *c, union epoll_ref ref,
/**
* udp_vu_reply_sock_data() - Handle new data from flow specific socket
* @c: Execution context
- * @ref: epoll reference
+ * @s: Socket to read data from
+ * @tosidx: Flow & side to forward data from @s to
* @now: Current timestamp
+ *
+ * Return: true on success, false if can't forward from socket to flow's pif
*/
-void udp_vu_reply_sock_data(const struct ctx *c, union epoll_ref ref,
+bool udp_vu_reply_sock_data(const struct ctx *c, int s, flow_sidx_t tosidx,
const struct timespec *now)
{
- flow_sidx_t tosidx = flow_sidx_opposite(ref.flowside);
const struct flowside *toside = flowside_at_sidx(tosidx);
bool v6 = !(inany_v4(&toside->eaddr) && inany_v4(&toside->oaddr));
- struct udp_flow *uflow = udp_at_sidx(ref.flowside);
- int from_s = uflow->s[ref.flowside.sidei];
+ struct udp_flow *uflow = udp_at_sidx(tosidx);
struct vu_dev *vdev = c->vdev;
struct vu_virtq *vq = &vdev->vq[VHOST_USER_RX_QUEUE];
- uint8_t topif = pif_at_sidx(tosidx);
int i;
ASSERT(uflow);
- if (topif != PIF_TAP) {
- uint8_t frompif = pif_at_sidx(ref.flowside);
-
- flow_err(uflow,
- "No support for forwarding UDP from %s to %s",
- pif_name(frompif), pif_name(topif));
- return;
- }
+ if (pif_at_sidx(tosidx) != PIF_TAP)
+ return false;
for (i = 0; i < UDP_MAX_FRAMES; i++) {
ssize_t dlen;
int iov_used;
- iov_used = udp_vu_sock_recv(c, from_s, v6, &dlen);
+ iov_used = udp_vu_sock_recv(c, s, v6, &dlen);
if (iov_used <= 0)
break;
flow_trace(uflow, "Received 1 datagram on reply socket");
@@ -318,4 +312,6 @@ void udp_vu_reply_sock_data(const struct ctx *c, union epoll_ref ref,
}
vu_flush(vdev, vq, elem, iov_used);
}
+
+ return true;
}
diff --git a/udp_vu.h b/udp_vu.h
index 4f2262d0..2299b51f 100644
--- a/udp_vu.h
+++ b/udp_vu.h
@@ -8,6 +8,7 @@
void udp_vu_listen_sock_data(const struct ctx *c, union epoll_ref ref,
const struct timespec *now);
-void udp_vu_reply_sock_data(const struct ctx *c, union epoll_ref ref,
+bool udp_vu_reply_sock_data(const struct ctx *c, int s, flow_sidx_t tosidx,
const struct timespec *now);
+
#endif /* UDP_VU_H */
--
@@ -8,6 +8,7 @@
void udp_vu_listen_sock_data(const struct ctx *c, union epoll_ref ref,
const struct timespec *now);
-void udp_vu_reply_sock_data(const struct ctx *c, union epoll_ref ref,
+bool udp_vu_reply_sock_data(const struct ctx *c, int s, flow_sidx_t tosidx,
const struct timespec *now);
+
#endif /* UDP_VU_H */
--
2.49.0
next prev parent reply other threads:[~2025-03-26 3:44 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-26 3:44 [PATCH v2 0/7] UDP flow socket preliminaries David Gibson
2025-03-26 3:44 ` [PATCH v2 1/7] udp: Common invocation of udp_sock_errs() for vhost-user and "buf" paths David Gibson
2025-03-26 3:44 ` [PATCH v2 2/7] udp: Simplify checking of epoll event bits David Gibson
2025-03-26 3:44 ` [PATCH v2 3/7] udp_vu: Factor things out of udp_vu_reply_sock_data() loop David Gibson
2025-03-26 3:44 ` David Gibson [this message]
2025-03-26 22:14 ` [PATCH v2 4/7] udp: Share more logic between vu and non-vu reply socket paths Stefano Brivio
2025-03-26 23:11 ` David Gibson
2025-03-26 3:44 ` [PATCH v2 5/7] udp: Better handling of failure to forward from reply socket David Gibson
2025-03-26 3:44 ` [PATCH v2 6/7] udp: Always hash socket facing flowsides David Gibson
2025-03-26 3:44 ` [PATCH v2 7/7] udp: Add helper function for creating connected UDP socket David Gibson
2025-03-26 22:14 ` [PATCH v2 0/7] UDP flow socket preliminaries Stefano Brivio
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250326034407.2240846-5-david@gibson.dropbear.id.au \
--to=david@gibson.dropbear.id.au \
--cc=passt-dev@passt.top \
--cc=sbrivio@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://passt.top/passt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).