gluon
gluon copied to clipboard
introduce XLAT, native IPv4 for clients
This introduces native ipv4 support for clients in a babel-based, ipv6-only network. There is a jool instance expected somewhere on the network for the plat part. This setup is used in Magdeburg and working well.
I do not think the ipv4 connections survive roaming with the current implementation but at least android-clients do not disconnect from the network any more due to missing ipv4 connectivity.
@Codefetch I do hope you do not disapprove raising a PR partly containing your work. Let me know if you do and we can work something out.
- [x] provide usage documentation including the backend
- [x] In our tests we are still seeing performance issues that are not fully understood. Those have to be resolved.
- [x] ensure nextnode.ipv4 address is defined
@christf Thank you for raising this PR. I think PLAT support should be removed, because it is not usable without N2N/S2N support. Rotanid's remarks regarding indentation and double newlines are correct. I didn't bother at the time of writing it.
yeah, I will rework it to make it mergable. For now I just wanted to share that there is such a set of packages while still commencing the tests. I am still experiencing performance issues in my test network related to MTU problems. This PR will remain WIP until those are resolved.
@christf Indeed the MTU issue is not handled correctly. From the comments the NAT46 device is intended to be used with a big MTU (as much as the WLAN interface plus IPv6 overhead in our case). But that contradicts the RFC which says for the IPv4 network a very small MTU should be set (IPv6-MTU minus IP-header-size-difference - e.g. 1280 - 60 = 1220). Because the problem is that the resulting IPv6 packets won't get fragmented as the default for IPv6 is "don't fragment". So it needs to happen on the IPv4-side with MSS clamping enabled. The NAT46 modules does not check whether packets are too big at the moment https://github.com/ayourtch/nat46/blob/master/nat46/modules/nat46-core.c#L1843.
Performance-wise the NAT46 module might be heavy as it processes each skb directly instead of using a separate worker which is correct in general, but it can take up much memory on high traffic flows, because it reallocates a bigger skb as far as I remember and it takes time until the old one gets freed. This could be optimized. I think the newer kernels have a function to put in a page at the beginning for the IPv6 header and leave the rest of the data untouched and for unlinking references to the resulting skb. So we could possibly save most of the copying process.
@CodeFetch:
Performance-wise the NAT46 module might be heavy as it processes each skb directly instead of using a separate worker which is correct in general
Is there an accidental mixup in this sentence? It's the other way round, queuing something onto a kworker with queue_work() is a performance killer. You don't want to use that on the fast-path for your payload packet flow. The only reason you might want to queue something on a kworker is if you have some packet that needs a longer time to be processed and therefore should be processed in a sleepable/interruptable handler.
But lifting onto such a handler is heavy.
@T-X Yes, sorry I changed the sentence and didn't read it again. Performance-wise it's ordinarily better, but not memory-performance wise. The module uses skb_copy/reallocates the skbs instead of skb_cloning them and adding/removing the headers with push-pull and removing the references, but this would require a worker which checks on the references on the original one and only starts changing the headers when the old skb has been released by everything else. Do you know what I mean?
Edit: Maybe one just needs to check on the reference count... I don't know what could still hold a reference when the skb is handed over to the netdev... Thus a worker might not be needed at all. At least for IPv6 to IPv4 translation copying the whole skb seems to be overkill. I ran OOM with this module when using iperf on a 64 MB device.
Edit2: @T-X I assume pskb_expand_head won't give us a real improvement for linear skb's translation from IPv4 to IPv6 as the 60 additional bytes won't be within the margin of the IPv4 max headroom (do you remember where this value is being defined?).
Another option could be to set dev->needed_headroom = 60;
, but this will likely also result in a call to pskb_expand_head, but I'm not sure...
actually outgoing traffic is ok but inbound is problematic. This is not menat to be a high-performance solution. It just has to work barely enough to allow the few remaining clients that refuse to work without ipv4 use the network. When larger scale applications are required, the best performance optimization is to stop the dns server to hand out A records...
@christf I agree. I'd still be happy to hear T-X's point, because I don't want to have the same problems with NAT426, but it's OT. In the worst case (if rebooting nodes happen often) we can have a second look (maybe there is just a bug we haven't found, yet) or do throttling to keep the nodes stable.
I have this integrated now into our gluon builds. PMTU discovery works with the additional clat rule. My TL-WR740 with all of its 400Mhz was able to process 17Mbit through wireguard and the clat module. Hence upgrading this PR.
The following changes were performed:
- rename of the package, update title
- fixing indentation, using tabs now as mentined in the developers guide
- added docs
- removal of plat references that are not actually used anywhere
- instead of removing ddhcp init script, ddhcpd is disabled
I am using the Magdeburg firmware and therefore this PR since a couple of weeks and did not see any issues in that while.
shellcheck:
+ make lint-sh
Checking contrib/depdot.sh
Checking contrib/lsupgrade.sh
Checking contrib/sign.sh
Checking contrib/sigtest.sh
Checking contrib/actions/install-dependencies.sh
Checking contrib/actions/run-build.sh
Checking package/gluon-464xlat-clat/files/lib/netifd/proto/xlat464clat.sh
package/gluon-464xlat-clat/files/lib/netifd/proto/xlat464clat.sh:82:5: warning: debug is referenced but not assigned. [SC2154]
package/gluon-464xlat-clat/files/lib/netifd/proto/xlat464clat.sh:157:36: warning: local_ip is referenced but not assigned (did you mean 'local_v4'?). [SC2154]
make: *** [Makefile:136: lint-sh] Error 1
script returned exit code 2
Hey @christf , your PR got a review 4 weeks ago and is waiting to be updated :-)
The Linux kernel and Babel got support for routing IPv4 packets via IPv6 routes:
- https://alioth-lists.debian.net/pipermail/babel-users/2022-March/003895.html
- https://www.rfc-editor.org/rfc/rfc9229.html
Which sounds like a neat idea and overall a lot simpler than XLAT?
@T-X Yes, indeed it looks promising. As a sidenote: I've kind of lost interest in Babel, because there is more future potential in Batman as it is much easier to implement technologies like multipath bonding. Maybe we can have a discussion about it at the end of the year. Btw rhashtables was something to keep in mind for improving Batman performance and possibly fixing the scaling issues.
Closed because of #3105