1
0
Fork 0
mirror of https://passt.top/passt synced 2025-06-06 16:06:19 +02:00

udp: Share more logic between vu and non-vu reply socket paths

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>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
David Gibson 2025-03-26 14:44:04 +11:00 committed by Stefano Brivio
parent d924b7dfc4
commit 269cf6a12a
3 changed files with 39 additions and 31 deletions

41
udp.c
View file

@ -752,24 +752,25 @@ void udp_listen_sock_handler(const struct ctx *c,
/** /**
* udp_buf_reply_sock_data() - Handle new data from flow specific socket * udp_buf_reply_sock_data() - Handle new data from flow specific socket
* @c: Execution context * @c: Execution context
* @ref: epoll reference * @s: Socket to read data from
* @tosidx: Flow & side to forward data from @s to
* @now: Current timestamp * @now: Current timestamp
* *
* Return: true on success, false if can't forward from socket to flow's pif
*
* #syscalls recvmmsg * #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) const struct timespec *now)
{ {
flow_sidx_t tosidx = flow_sidx_opposite(ref.flowside);
const struct flowside *toside = flowside_at_sidx(tosidx); 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); uint8_t topif = pif_at_sidx(tosidx);
int n, i, from_s; int n, i;
from_s = uflow->s[ref.flowside.sidei]; if ((n = udp_sock_recv(c, s, udp_mh_recv)) <= 0)
return true;
if ((n = udp_sock_recv(c, from_s, udp_mh_recv)) <= 0)
return;
flow_trace(uflow, "Received %d datagrams on reply socket", n); flow_trace(uflow, "Received %d datagrams on reply socket", n);
uflow->ts = now->tv_sec; uflow->ts = now->tv_sec;
@ -788,11 +789,10 @@ static void udp_buf_reply_sock_data(const struct ctx *c, union epoll_ref ref,
} else if (topif == PIF_TAP) { } else if (topif == PIF_TAP) {
tap_send_frames(c, &udp_l2_iov[0][0], UDP_NUM_IOVS, n); tap_send_frames(c, &udp_l2_iov[0][0], UDP_NUM_IOVS, n);
} else { } else {
uint8_t frompif = pif_at_sidx(ref.flowside); return false;
flow_err(uflow, "No support for forwarding UDP from %s to %s",
pif_name(frompif), pif_name(topif));
} }
return true;
} }
/** /**
@ -819,10 +819,21 @@ void udp_reply_sock_handler(const struct ctx *c, union epoll_ref ref,
} }
if (events & EPOLLIN) { if (events & EPOLLIN) {
flow_sidx_t tosidx = flow_sidx_opposite(ref.flowside);
int s = ref.fd;
bool ret;
if (c->mode == MODE_VU) if (c->mode == MODE_VU)
udp_vu_reply_sock_data(c, ref, now); ret = udp_vu_reply_sock_data(c, s, tosidx, now);
else 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)));
}
} }
} }

View file

@ -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 * udp_vu_reply_sock_data() - Handle new data from flow specific socket
* @c: Execution context * @c: Execution context
* @ref: epoll reference * @s: Socket to read data from
* @tosidx: Flow & side to forward data from @s to
* @now: Current timestamp * @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) const struct timespec *now)
{ {
flow_sidx_t tosidx = flow_sidx_opposite(ref.flowside);
const struct flowside *toside = flowside_at_sidx(tosidx); const struct flowside *toside = flowside_at_sidx(tosidx);
bool v6 = !(inany_v4(&toside->eaddr) && inany_v4(&toside->oaddr)); bool v6 = !(inany_v4(&toside->eaddr) && inany_v4(&toside->oaddr));
struct udp_flow *uflow = udp_at_sidx(ref.flowside); struct udp_flow *uflow = udp_at_sidx(tosidx);
int from_s = uflow->s[ref.flowside.sidei];
struct vu_dev *vdev = c->vdev; struct vu_dev *vdev = c->vdev;
struct vu_virtq *vq = &vdev->vq[VHOST_USER_RX_QUEUE]; struct vu_virtq *vq = &vdev->vq[VHOST_USER_RX_QUEUE];
uint8_t topif = pif_at_sidx(tosidx);
int i; int i;
ASSERT(uflow); ASSERT(uflow);
if (topif != PIF_TAP) { if (pif_at_sidx(tosidx) != PIF_TAP)
uint8_t frompif = pif_at_sidx(ref.flowside); return false;
flow_err(uflow,
"No support for forwarding UDP from %s to %s",
pif_name(frompif), pif_name(topif));
return;
}
for (i = 0; i < UDP_MAX_FRAMES; i++) { for (i = 0; i < UDP_MAX_FRAMES; i++) {
ssize_t dlen; ssize_t dlen;
int iov_used; 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) if (iov_used <= 0)
break; break;
flow_trace(uflow, "Received 1 datagram on reply socket"); 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); vu_flush(vdev, vq, elem, iov_used);
} }
return true;
} }

View file

@ -8,6 +8,7 @@
void udp_vu_listen_sock_data(const struct ctx *c, union epoll_ref ref, void udp_vu_listen_sock_data(const struct ctx *c, union epoll_ref ref,
const struct timespec *now); 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); const struct timespec *now);
#endif /* UDP_VU_H */ #endif /* UDP_VU_H */