From: Stefano Brivio <sbrivio@redhat.com>
To: Yumei Huang <yuhuang@redhat.com>
Cc: passt-dev@passt.top, david@gibson.dropbear.id.au
Subject: Re: [PATCH] udp: Split activity timeouts for UDP flows
Date: Fri, 13 Feb 2026 10:12:58 +0100 (CET) [thread overview]
Message-ID: <20260213101255.1600250b@elisabeth> (raw)
In-Reply-To: <CANsz47m8BPdUK2N-_Ka5GUHP_USnyHgO01Accktf-wxuX5rxDw@mail.gmail.com>
[Side note: can you disable sending HTML emails, otherwise they won't
be archived for the passt-dev list for simplicity / security? Thanks]
On Fri, 13 Feb 2026 15:49:41 +0800
Yumei Huang <yuhuang@redhat.com> wrote:
> On Fri, Feb 13, 2026 at 3:08 PM Stefano Brivio <sbrivio@redhat.com> wrote:
>
> > On Fri, 13 Feb 2026 14:45:24 +0800
> > Yumei Huang <yuhuang@redhat.com> wrote:
> >
> > > On Fri, Feb 13, 2026 at 5:51 AM Stefano Brivio <sbrivio@redhat.com>
> > wrote:
> > >
> > > > Oops, I missed one point at a first review, and also during a quick
> > > > test.
> > > >
> > > > I just tried outbound DNS queries in pasta with single responses, not
> > > > inbound traffic or passt in vhost-user mode. Then I realised
> > > > that:
> > > >
> > > > On Thu, 12 Feb 2026 16:04:14 +0800
> > > > Yumei Huang <yuhuang@redhat.com> wrote:
> > > >
> > > > > [...]
> > > > > @@ -954,6 +964,7 @@ void udp_sock_handler(const struct ctx *c,
> > union
> > > > epoll_ref ref,
> > > > >
> > > > > flow_trace(uflow, "Received data on reply socket");
> > > > > uflow->ts = now->tv_sec;
> > > > > + udp_flow_activity(uflow, !tosidx.sidei);
> > > >
> > > > ...this only covers three of the four paths we need to act upon:
> > > >
> > > > 1. inbound datagrams received on the reply socket via
> > > > udp_buf_sock_to_tap(), called from here
> > > >
> > > > 2. inbound datagrams received on the reply socket in passt's vhost-user
> > > > mode, that's udp_vu_sock_recv(), also called from here
> > > >
> > > > 3. "spliced" sockets (that's not really the case for UDP, we can't call
> > > > splice(), but a pair of recvmmsg() / sendmmsg()), that is, loopback
> > > > UDP traffic, handled by udp_sock_to_sock(), called from here as well
> > > >
> > > > but not:
> > > >
> > > > 4. outbound, non-spliced datagrams from container/guest: that's
> > > > udp_tap_handler(), in both vhost-user and non-vhost-user cases, or
> > > > udp_flow_from_tap() in udp_flow.c.
> > > >
> > > > I guess we want to take care of this directly from
> > udp_flow_from_tap(),
> > > > for consistency, because that's also where we update the timestamp
> > > > value:
> > > >
> > > > sidx = flow_lookup_sa(c, IPPROTO_UDP, pif, s_in, dst, port);
> > > > if ((uflow = udp_at_sidx(sidx))) {
> > > > uflow->ts = now->tv_sec;
> > > >
> > > > ^^^ here
> > > >
> > > > return flow_sidx_opposite(sidx);
> > > > }
> > > >
> > > > I haven't really tested this side of it but it should be fairly easy
> > > > with socat and a UDP "server" inside pasta or a guest.
> > >
> > > Somehow, it worked well in my tests with pasta, it looks like the if
> > > condition always returns false.
> >
> > Hmm, weird, it should return false only for the first *inbound* datagram
> > of a UDP flow.
> >
> > > But now when I test with passt, it becomes
> > > an issue and we need to track the activity here as you mentioned.
> > >
> > > Besides, I also noticed we update the timestamp value in
> > > udp_flow_from_sock() as well. I feel we should call udp_flow_activity()
> > > there too, but couldn't come up with a test to prove it.
> >
> > I haven't really checked, but udp_sock_handler() should anyway be
> > called for the datagram triggering udp_flow_from_sock(), so I don't
> > think you need an extra call to udp_flow_activity() there.
> >
> > But you should check that with a pair of debugging prints, I guess.
>
> Actually I did. udp_sock_handler() is called everytime there is new data
> from the socket.
Okay, so the udp_flow_activity() you already added (at least for the
socket -> tap path) is enough, right...?
> But in my test, udp_flow_from_sock() is only called for
> the first datagram, so the if condition after flow_lookup_sa() always
> returns false, and a new UDP flow is created.
Ah, right! See below.
> Tried either spliced /
> non-spliced, pasta / passt case, no exceptions observed. I was wondering
> if there is a scenario I'm not aware of.
Yes, I think it's just for one corner case David described in the "Flow
sockets" section of the "Theory of Operation" documentation in udp.c:
* NOTE: A flow socket can have a bound address overlapping with a listening
* socket. That will happen naturally for flows initiated from a socket, but is
* also possible (though unlikely) for tap initiated flows, depending on the
* source port. We assume datagrams for the flow will come to a connect()ed
* socket in preference to a listening socket. The sample program
* doc/platform-requirements/reuseaddr-priority.c documents and tests that
* assumption.
...if they don't come through the connect()ed socket, we would end up
in that case.
Long story short, we need to update the activity array there as well,
because it could happen. I'm not sure if reuseaddr-priority.c can be
used to test this case together with pasta, I don't think it's really
needed though.
> > > On top of it, I just found two other issues.
> > > 1. in udp_flow_new(), we should initialize uflow->activity[INISIDE] to 1
> > > instead of 0. Otherwise, we fail to track the first datagram.
> >
> > Same here, I *thought* that calling udp_flow_activity() from
> > udp_sock_handler() *and* udp_tap_handler() would anyway account for the
> > first datagram, but I didn't check.
>
> udp_sock_handler() is only called *after* the flow is created. But only
> when the first datagram comes, we create the flow. Similarly,
> udp_flow_from_tap() (called by udp_tap_handler()) calls udp_flow_new() to
> create a new flow for the first datagram too. That's why we missed the
> first one.
Oh, I see, thanks for the explanation.
--
Stefano
next prev parent reply other threads:[~2026-02-13 9:13 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-12 8:04 Yumei Huang
2026-02-12 8:59 ` Stefano Brivio
2026-02-12 21:51 ` Stefano Brivio
[not found] ` <CANsz47mGXDgJSKpLqFiW_n5bXW13ZiayC_xhBEEGeBJTZwN5Xw@mail.gmail.com>
2026-02-13 7:08 ` Stefano Brivio
[not found] ` <CANsz47m8BPdUK2N-_Ka5GUHP_USnyHgO01Accktf-wxuX5rxDw@mail.gmail.com>
2026-02-13 9:12 ` Stefano Brivio [this message]
2026-02-13 9:54 ` Yumei Huang
2026-02-13 10:00 ` Stefano Brivio
2026-02-13 10:04 ` Yumei Huang
2026-02-13 10:17 ` Stefano Brivio
2026-02-14 7:20 ` Yumei Huang
2026-02-14 9:15 ` 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=20260213101255.1600250b@elisabeth \
--to=sbrivio@redhat.com \
--cc=david@gibson.dropbear.id.au \
--cc=passt-dev@passt.top \
--cc=yuhuang@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).