#1088264 tayga: Tayga does not forward UDPv4 packets with zero checksums

Package:
tayga
Source:
tayga
Description:
userspace stateless NAT64
Submitter:
Mark Glines
Date:
2025-12-20 09:13:03 UTC
Severity:
normal
Tags:
#1088264#5
Date:
2024-11-26 03:23:04 UTC
From:
To:
Some DNS servers respond to requests an empty checksum field.  Tayga
does not forward these responses, thus making those DNS servers
inaccessible through Tayga.

In IPv4, UDP checksums are optional.  RFC768 says:

UDP checksums are required in IPv6.  Tayga doesn't know how to fix the
checksum field in this case, so it drops such packets on the floor:

In practice, this limits access to sites whose DNS servers only speak
IPv4 and don't include checksums.

For example, ESA (the European Space Agency) uses the domain name
"esa.int".  This domain has 4 nameservers, all of which are IPv4-only,
and all of which omit checksums.

When I make a query, by running `host -t ns esa.int ns1.esa.int` on an
ipv4-enabled host, `tshark -V` says this about the response:

Making the equivalent query from behind Tayga never got an answer,
because Tayga dropped the response packet.

A recursive resolver running behind Tayga can never resolve
"www.esa.int", because Tayga drops all the responses.

I think Tayga should populate null UDP checksum fields when forwarding
from v4 to v6.  This would greatly improve interoperability with
european space agencies, and possibly other sites and services too.

#1088264#10
Date:
2024-11-26 03:30:34 UTC
From:
To:
I've been trying to cook up a patch for this, but so far my checksum
calculations are wrong.


If I manage to get it working, I'll post a patch here.

#1088264#15
Date:
2024-11-26 03:40:18 UTC
From:
To:
I've been trying to cook up a patch for this, but so far my checksum
calculations are wrong.

If I manage to get it working, I'll post a patch here.

#1088264#20
Date:
2024-11-26 19:44:37 UTC
From:
To:
Here is an imperfect patch that calculates the UDP checksum if none was
present.

This allows the 4to6 machinery to do its thing, the aforementioned DNS
responses go through successfully, and now I can access the ESA
website.  (Hooray!)

The imperfection is that I had to add an asm("":::"memory") memory
barrier, after the newly assigned checksum gets written to the checksum
field in the UDP header.  Without this memory barrier, it wasn't working
for me (arm64, gcc 14.2.0).  When I temporarily changed -O2 to -O1, the
problem went away.  The memory barrier gets it working with -O2.  I
guess it's an aliasing problem, the compiler reordered something it
shouldn't have, but I don't fully understand it.  Here's hoping this
patch can serve as a starting point for something cleaner.

#1088264#25
Date:
2024-11-26 19:49:22 UTC
From:
To:
Hello,

Thanks, I will look into it. I can’t promise when, though, but it’s in my backlog.

#1088264#30
Date:
2025-12-19 20:53:51 UTC
From:
To:
Note, the new upstream fork (see #1107302) has a fix for this:

https://github.com/apalrd/tayga/pull/76

They make the behavior configurable, and it looks like the "calc" option
covers my use-case.

Thanks,

Mark

#1088264#35
Date:
2025-12-20 09:10:43 UTC
From:
To:
Hi Mark,

Thanks for the info!

We're already planning to switch to Andrew's fork in the next Debian
release, but working on CLAT integration is higher priorty right now.

Nice. Didn't know about the option. I'd be curious what your use-case looks
like exactly? I've been on the fence about whether having special handling
for this is actually still useful in the field (for a Linux kernel SIIT
implementation I'm working on).

Thanks,
--Daniel