mirror of
https://passt.top/passt
synced 2025-05-20 16:35:33 +02:00
udp: Simplify updates to UDP flow timestamp
Since UDP has no built in knowledge of connections, the only way we know when we're done with a UDP flow is a timeout with no activity. To keep track of this struct udp_flow includes a timestamp to record the last time we saw traffic on the flow. For data from listening sockets and from tap, this is done implicitly via udp_flow_from_{sock,tap}() but for reply sockets it's done explicitly. However, that logic is duplicated between the vhost-user and "buf" paths. Make it common in udp_reply_sock_handler() instead. Technically this is a behavioural change: previously if we got an EPOLLIN event, but there wasn't actually any data we wouldn't update the timestamp, now we will. This should be harmless: if there's an EPOLLIN we expect there to be data, and even if there isn't the worst we can do is mildly delay the cleanup of a stale flow. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
8aa2d90c8d
commit
76e554d9ec
3 changed files with 8 additions and 19 deletions
15
udp.c
15
udp.c
|
@ -758,27 +758,21 @@ void udp_listen_sock_handler(const struct ctx *c,
|
|||
* @c: Execution context
|
||||
* @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 bool udp_buf_reply_sock_data(const struct ctx *c,
|
||||
int s, flow_sidx_t tosidx,
|
||||
const struct timespec *now)
|
||||
int s, flow_sidx_t tosidx)
|
||||
{
|
||||
const struct flowside *toside = flowside_at_sidx(tosidx);
|
||||
struct udp_flow *uflow = udp_at_sidx(tosidx);
|
||||
uint8_t topif = pif_at_sidx(tosidx);
|
||||
int n, i;
|
||||
|
||||
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;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (pif_is_socket(topif))
|
||||
udp_splice_prepare(udp_mh_recv, i);
|
||||
|
@ -825,10 +819,13 @@ void udp_reply_sock_handler(const struct ctx *c, union epoll_ref ref,
|
|||
int s = ref.fd;
|
||||
bool ret;
|
||||
|
||||
flow_trace(uflow, "Received data on reply socket");
|
||||
uflow->ts = now->tv_sec;
|
||||
|
||||
if (c->mode == MODE_VU)
|
||||
ret = udp_vu_reply_sock_data(c, s, tosidx, now);
|
||||
ret = udp_vu_reply_sock_data(c, s, tosidx);
|
||||
else
|
||||
ret = udp_buf_reply_sock_data(c, s, tosidx, now);
|
||||
ret = udp_buf_reply_sock_data(c, s, tosidx);
|
||||
|
||||
if (!ret) {
|
||||
flow_err(uflow, "Unable to forward UDP");
|
||||
|
|
9
udp_vu.c
9
udp_vu.c
|
@ -275,22 +275,17 @@ void udp_vu_listen_sock_data(const struct ctx *c, union epoll_ref ref,
|
|||
* @c: Execution context
|
||||
* @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
|
||||
*/
|
||||
bool udp_vu_reply_sock_data(const struct ctx *c, int s, flow_sidx_t tosidx,
|
||||
const struct timespec *now)
|
||||
bool udp_vu_reply_sock_data(const struct ctx *c, int s, flow_sidx_t tosidx)
|
||||
{
|
||||
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(tosidx);
|
||||
struct vu_dev *vdev = c->vdev;
|
||||
struct vu_virtq *vq = &vdev->vq[VHOST_USER_RX_QUEUE];
|
||||
int i;
|
||||
|
||||
ASSERT(uflow);
|
||||
|
||||
if (pif_at_sidx(tosidx) != PIF_TAP)
|
||||
return false;
|
||||
|
||||
|
@ -301,8 +296,6 @@ bool udp_vu_reply_sock_data(const struct ctx *c, int s, flow_sidx_t tosidx,
|
|||
iov_used = udp_vu_sock_recv(c, s, v6, &dlen);
|
||||
if (iov_used <= 0)
|
||||
break;
|
||||
flow_trace(uflow, "Received 1 datagram on reply socket");
|
||||
uflow->ts = now->tv_sec;
|
||||
|
||||
udp_vu_prepare(c, toside, dlen);
|
||||
if (*c->pcap) {
|
||||
|
|
3
udp_vu.h
3
udp_vu.h
|
@ -8,7 +8,6 @@
|
|||
|
||||
void udp_vu_listen_sock_data(const struct ctx *c, union epoll_ref ref,
|
||||
const struct timespec *now);
|
||||
bool udp_vu_reply_sock_data(const struct ctx *c, int s, flow_sidx_t tosidx,
|
||||
const struct timespec *now);
|
||||
bool udp_vu_reply_sock_data(const struct ctx *c, int s, flow_sidx_t tosidx);
|
||||
|
||||
#endif /* UDP_VU_H */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue