Bug 87 - udp_sock_init() does not fill correctly udp_tap_map since commit bb9bf0bb8f57
Summary: udp_sock_init() does not fill correctly udp_tap_map since commit bb9bf0bb8f57
Status: RESOLVED FIXED
Alias: None
Product: passt
Classification: Unclassified
Component: UDP (show other bugs)
Version: unspecified
Hardware: All Linux
: Normal quite bad
Assignee: David Gibson
URL:
Depends on:
Blocks:
 
Reported: 2024-04-22 20:34 UTC by Laurent Jacquot
Modified: 2024-04-25 00:16 UTC (History)
2 users (show)

See Also:


Attachments

Description Laurent Jacquot 2024-04-22 20:34:38 UTC
Hello,
my dns container does not work anymore since the latest fedora update and a quick git bisect shows commit bb9bf0bb8f576186b62af5c8506741a7bc545f3e : tcp, udp: Don't precompute port remappings in epoll references

everything is OK for tcp flows, but I believe this udp change is not correct:

@ -999,16 +1004,13 @@ int udp_sock_init(const struct ctx *c, int ns, sa_family_t af,
                  const void *addr, const char *ifname, in_port_t port)
 {
        union udp_epoll_ref uref = { .splice = (c->mode == MODE_PASTA),
-                                    .orig = true };
+                                    .orig = true, .port = port };
        int s, r4 = FD_REF_MAX + 1, r6 = FD_REF_MAX + 1;

-       if (ns) {
+       if (ns)
                uref.pif = PIF_SPLICE;
-               uref.port = (in_port_t)(port + c->udp.fwd_out.f.delta[port]);
-       } else {
+       else
                uref.pif = PIF_HOST;
-               uref.port = (in_port_t)(port + c->udp.fwd_in.f.delta[port]);
-       }

In the (ns) case, the computation is done later on in udp_sock_handler and it works
but in the (!ns) case, uref is no more updated and the socket number is stored in the wrong udp_tap_map reference

To reproduce, setup a pasta namespace:
./pasta --config-net  --debug  -a 192.168.22.12 -o 192.168.22.12 -u 192.168.22.12/5333:53 -t192.168.22.12/5333:53 -T none -U none

and launch a dns 
dnsmasq -C /dev/null -h -k -d -q -R --server=2a01:e0c:1:1599::22

in another terminal, dig an ip in udp
dig -p 5333 A free.fr @192.168.22.12 +short

or dig in tcp
dig -p 5333 A free.fr @192.168.22.12 +short +vc

tcp is working everytime, udp timeout since commit bb9bf0bb8f57

if I change the patch to re-add the last "else" statement, it works

feel free to ask me for some more information and/or to test patches
regards
Laurent Jacquot
Comment 1 David Gibson 2024-04-23 06:47:38 UTC
Laurent,

Thanks for the report.  I've reproduced the problem and tracked it down.  It's not actually that we don't do the port translation when we get the UDP packets - those were getting through.  It's that we don't correctly apply the reverse translation to the source port of reply packets.

I have a draft fix here:
    https://gitlab.com/dgibson/passt/-/tree/bug87?ref_type=heads

Assuming it works for you, I'll submit it for merge.
Comment 2 Laurent Jacquot 2024-04-23 11:31:15 UTC
Hello
I confirm it works for me
Comment 3 David Gibson 2024-04-24 01:06:01 UTC
Thanks, I've posted the patch for inclusion.
Comment 4 David Gibson 2024-04-25 00:16:49 UTC
Fix is now applied to main branch.

Note You need to log in before you can comment on or make changes to this bug.