-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Device Driver mode #140
Comments
Fifth option:
Most work, more complicated for the user to install, maximum versatility. |
Performance is an important concern. Make sure to go for a approach that lets you make use all the CPU cores in the machine. I'm wondering if today's framework might be the best performing since a packet only have to make one pass through the routing system. Going in and out of a virtual interface (either a device driver or connected to a user-space process) would probably mean the packet would be routed twice. On the other hand, using DPDK in user-space is supposedly how you really push the envelope of how fast you can make a machine push packets. Maybe that would be something worth looking into, too. When it comes to operational convenience (installation, setup, etc): Having it in the upstream kernel (i.e., the distro packages) is preferable to having it in user-space, which in turn is preferable to having it a stand-alone kernel module. Finally I'd like to point out that if you solve the Host-Based Edge Translation use case, you've certainly solved the 464XLAT CLAT use case, too. |
My concern is that it go upstream, that it be integrated with ip/nffilter, While someone might want to put this into DPDK, the more interesting |
Having a virtual interface as the way that to route traffic into jool I think that having an iptables module which is attached (-i jool0) to |
Correct.
Thank you :)
AFAIK there is very little difference between being a Netfilter/iptables module (ie. Jool now) than being integrated to Netfilter/iptables. It seems like the second address is a result of us doing something wrong, but I can't put my finger on what it is ATM. It's something I've wanted to truly sit down and think about since a long time ago, but I've always had more pressing matters to attend.
Thank you :)
Thank you :). I guess it'd be better to explain to operators if it feels more natural.
It's an SIIT within an end node, and it's similar to 464XLAT's "Wireless 3GPP" Network setup. Jool's 464XLAT tutorial complains about Jool not supporting it:
The point, I gather, is to not depend on an SIIT service elsewhere when you need translation.
I think it's mostly a problem with stability. If an userspace service crashes, it dies alone. If a kernel module crashes, it compromises the entire system. Of course, we aim to never crash, but we're humans. |
…born in a separate network namespace, Jool would spit an incorrect layer-4 checksum. (Actually, the incoming packet already had an incorrect checksum.) There were two problems: 1. The checksum was incorrect because it was unset. Jool wasn't handling CHECKSUM_PARTIAL differently; it started with an unset incorrect checksum, and ended with a set incorrect checksum. 2. Jool was intercepting packets in all namespaces. This triggered fake hairpinning symptoms, which in turn yielded misled packet drops. I fixed this poorly by making Jool only global-namespace sensitive. This solution is a very dirty patch, but I can't solve this better until #140 is fixed.
I'm toying with the idea of integrating SIIT-DC into OpenStack. In case you're familiar with OpenStack, what I'm thinking of doing is to integrate stateless translator support (SIIT/SIIT-EAM) in the virtual routers created by the Neutron L3 Agent. However, since these virtual routers live inside their own dedicated Linux network namespace, I can't do it with Jool as far as I can tell. I can with TAYGA, but Jool would of course be preferred... :-) I don't know if you've decided yet on how the new framework will work, but I'm hoping you'll take this use case into consideration. The requirement would simply be to be able to start a distinct instance of Jool inside each network namespace (i.e., one per virtual router). It would also be useful to be able to run a Jool instance in Stateful NAT64 mode and another Jool instance in stateless mode inside a single network namespace at the same time. |
Hmmm, no. I'm not familiar with OpenStack. Need me to read on the subject?
I'm waiting for the 3.4 code to be ready to start making decisions on this. That said, as far as SIIT goes, my current thinking is that options 1 and 2 (network (pseudo-)device driver and userspace) are dominant strategies hands down, performance notwithstanding. These solutions would also solve your first requirement (what with being able to have any number of Jools per namespace). NAT64 is more fuzzy. There's actually a sixth option:
This is probably best in the long run, and I'm thinking it would also address your problem. RFC6146 compliance would have to be tested all over again, though.
Yes, this might prove important whether Jool switches frameworks or not. Recognizing a packet's namespace shouldn't be too hard, so if you're in a hurry, I could assign this to my new coworker as his first assignment, and release this in Jool 3.4. It would most likely work completely different as it will in Jool 4.0, though.
Hmmm. The inability to have a SIIT and a NAT64 simultaneously is the Netlink socket's fault. This should probably be considered a bug. |
Which instance should intercept packets earlier? |
I don't think you need to read up on OpenStack unless you feel like it. As long as it can work with network namespaces it should work with OpenStack. If I can spin up multiple instances that are connected to its own virtual network device (much like a TAYGA process is connected to its own TUN interface), that ought to do the trick. Then I could do something like this:
Or by creating the instance directly in the namespace:
With regards to dropping NAT64, don't do that - you can't simply mix SIIT + iptables NAPT44 to create a fully featured NAT64. For starters, you have 2^128 potential IPv6 clients accessing the NAT64, so you simply cannot map them into an IPv4 source address in a stateless manner. If you're going down the virtual network device path the answer to your question on which instance should go first is easy - the routing table will decide what goes where. For example:
I'm not in a hurry. :-) BTW: I'm at the IETF93 meeting at the moment and I saw that there are two people from NIC Mexico attending too: Julio Cossio and Jorge Cano. Are they involved in Jool development? If so I'd like to locate them and say hi... |
The reason this was initially implemented as a kernel-space tool was mostly because of performance. We knew there existed a userland tool but at the time it didn't meet the performance requirements Dr. Nolazco might recall something of that. Anyway, seems to me like those performance issues would now be solved using DPDK, though, that would tie the project to x86. Your call though. |
Oh yeah, I had a NAT66 in mind without realizing it. How silly. Scratch that, then :)
Wanna jabber this?
Thank you. Standards compliance takes precedence, though. Not that I'd get angry if a way to fix the issues without having to switch frameworks appeared.
Well, they seem to be wanting to increase their supported architectures, so this annoyance might hopefully be temporary. (On the other hand, DPDK's installation procedure looks bananas. Sounds like efforts towards #163 will be in vain.) Hmmm. |
I just wanted to add here a discussion I recently had with @fingon and @sbyx from the OpenWrt project about the possibility about adding support for Stateful NAT64. It would appear that they have some problems with the current framework that prevents them from implementing that using Jool in a sensible manner. I was thinking that when deciding on an approach for the new framework, you might want to reach out to them to ensure the chosen new approach resolves their issues. At least I think it would have been really nice to have Jool in OpenWrt, which could then be used for 464XLAT (both PLAT/NAT64 and CLAT functions) as well as for MAP-T (probably).
|
Question I can easily see SIIT moving over to the interface model, but NAT64 is weird (from IPv4 it looks more like NAT than SIIT). Since each interface is normally connected to different networks, won't it mean the user will have to define a separate address block for pool4? |
Well my point is ideally I would be able to have one NAT64 instance per outgoing (IPv4) interface that i want to NAT too and I am by some means able to decide which incoming interfaces are NAT64'ed and to which outgoing interface. |
As discussed on IRC, ideally NAT64 = NAT66 + SIIT + NAT44. BTW: 'move to userspace' option noted in original post kills performance, so I do not consider it an option. |
Can you explain each step? I don't see what the NAT66 step does. ] Never tell me the odds! | ipv6 mesh networks [ |
Especially step 3 is important since it lets you use a shared NAT-state / port-space for the IPv4 NAT, you don't have to worry about distinct port-spaces for regular NAT44 and NAT64 and you don't have to worry about what happens if you don't have a "full" IPv4-address (i.e. MAP-E / MAP-T / LW4over6) or if the ISP does the NAT for you (DS-Lite). |
So I guess it's not strange. Good, I guess. :-) This is the current direction of this development, then. Doesn't all that routing also hamper performance, though?
|
'route' is not probably the correct word here. Or well, it could be, but I would not design it that way. You could even chain these 3 steps as single netfilter chain ('NAT64' = NAT66 + SIIT + MASQUERADE(ish) steps; in the other direction, there would be probably de-NAT, and then the SIIT+NAT66 steps), so there would be just one netfilter match (dst=/96 given to NAT64 for IPv4 mapped to IPv6) and then just bunch of matching rules without their own matching. Correct design would be probably something slightly less efficient and more generic; I haven't really thought it through, but in general, even if you do lookup or two more in kernel, it is much cheaper than going to userland and back. Separating the steps would probably result in better modularity/configurability.. |
I think you'll end up with kind of mongrel NAT64 this way. RFC6146 compliance will most likely go out the window. One obvious example: A NAT64 is supposed to have a Binding Information Base for each protocol it supports. Each entry contains the address (X') and source port (x) of the IPv6 client , and the IPv4 transport address (T; «SNAT address») and transport port (t) it is mapped to. Thus: tore@nat64gw1-osl2:~$ jool --bib -n | head -5
TCP:
[Dynamic] 192.0.2.240#1024 - 2001:db8:402:2:216:3eff:feba:3cd#48832
[Dynamic] 192.0.2.240#1029 - 2001:db8:202:2:216:3eff:febb:bd63#37221
[Dynamic] 192.0.2.240#1032 - 2001:db8:402:2:216:3eff:fe36:c893#50971
[Dynamic] 192.0.2.240#1034 - 2001:db8:202:a:18:59ff:fe3a:3953#52116 |
I do not like RFC6146 anyway - e.g. SIIT defines better fragment handling semantics. You could synthesize BIB-like information out of NAT66 + SIIT + NAT44 state if it was helpful (for user experience), but obviously implementation would not follow RFC6146 processing rules etc as they are defined in terms of BIB and not in terms of what actually needs to be done. For the end user though, the result would not be different though; packets would come in via IPv6 and wind up IPv4 :-) (And fragmentation would actually work better, or at least, in case of NAT64, it is underspecified but SIIT defines relatively sane handling for it, including ICMP blackhole logic.) |
I believe the problem is that I'm missing some instructions to configure Jool in LEDE (by the way is the same as OpenWRT). My script in Ubuntu, just works. I don't need to tell Ubuntu to forward 64:ff9b::/96 to Jool ... In LEDE, using the LEDE CPE itself as the "client" of Jool (also tried from outside), it has a default router to the IPv6 gateway (the ISP link), and I don't see "how to" tell LEDE that anything for the Jool pool (64:ff9b::/96 in my case), needs to go to "Jool" instead of sent directly to the default GW ... Other protocols in LEDE, you need to configure an Interface for them. For example tried with Tayga some time ago, and it was working fine. |
But other users have confirmed that Jool is working fine in OpenWRT, without special configuration.
I think this is what's strange, not the LEDE stuff. Jool is a Netfilter module that only hooks itself to the prerouting chain. By definition, it never translates traffic generated by its own node. You can emulate the interface thing by enclosing Jool in a namespace, and sending packets to that namespace by means of a virtual interface.
Is this working or not? If it worked, it is normal. If it didn't, I think there is something preventing the packets from reaching Jool.
Yeah, that's what I want to improve by turning Jool into a device driver. Jool 4.0.0 will function exactly like this, but for now we have to work around Netfilter's limitations. |
@jordipalet @ydahhrk I faced the same problem and I think what's happening is that OpenWrt's modprobe is ignoring the module arguments passed in the command line. I changed to insmod like so |
@petrosagg You're right, thank you. It hadn't dawned upon me that OpenWRT is such a different world. And, as a stumbling newcomer myself, I can see that Jool's documentation wouldn't be very useful to get it running there. I think it's worth some notes. BRB. |
I'm a newcomer to OpenWrt too, it took me a lot of frustration to figure it out... |
Sorry for the troubles. I just added this to the documentation. I also added OpenWRT code tabs to the tutorials. (All of this might need a browser F5 refresh.) Hopefully, this won't happen again. |
That's awesome! Thanks a lot for making this quality module :) |
Thanks for the patience :) |
Fantastic Alberto, thanks a lot!
Saludos,
Jordi
De: Alberto Leiva Popper <[email protected]>
Responder a: NICMx/Jool <[email protected]>
Fecha: martes, 6 de marzo de 2018, 20:32
Para: NICMx/Jool <[email protected]>
CC: jordipalet <[email protected]>, Mention <[email protected]>
Asunto: Re: [NICMx/Jool] Switching frameworks might immediately solve several other issues (#140)
Sorry for the troubles.
I just added this to the documentation. I also added OpenWRT code tabs to the tutorials. (All of this might need a browser F5 refresh.) Hopefully, this won't happen again.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
**********************************************
IPv4 is over
Are you ready for the new Internet ?
http://www.consulintel.es
The IPv6 Company
This electronic message contains information which may be privileged or confidential. The information is intended to be for the exclusive use of the individual(s) named above and further non-explicilty authorized disclosure, copying, distribution or use of the contents of this information, even if partially, including attached files, is strictly prohibited and will be considered a criminal offense. If you are not the intended recipient be aware that any disclosure, copying, distribution or use of the contents of this information, even if partially, including attached files, is strictly prohibited, will be considered a criminal offense, so you must reply to the original sender to inform about this communication and delete it.
|
What you are currently doing is to reinvent the network stack (connection tracking for FTP etc.). @ydahhrk is right. Jool should aim to become a mainstream kernel module and that is only possible if it either gets tightly integrated into netfilter, which will likely not be possible easily, because it would need at least another two tables one before NAT and one after NAT if I'm not mistaken, it will be ugly and needs heavy modification of several userspace tools and APIs. |
Hmm. The idea of "becoming a mainstream kernel module" has popped up often and isn't really the same as the device driver support feature. Maybe it's time to open a new bug.
Just to clarify: Do you mean this as a bad thing or as a neutral thing? You seem to be voting for both device driver and mainstream module, but none of these will prevent Jool from having to do FTP connection tracking once #114 is implemented. (Unless I'm missing something.) |
|
Would this work for MAP-E or DS-lite transition mechanism? |
@Omardyab No idea. |
@Omardyab |
2018-11-25 Update
Hello. If you came here from the survey, you'll notice that this thread is rather large, has evolved and often wildly branches off-topic. So here's a quick summary for what Device Driver mode is:
Basically, Device Driver Jool will be an alternative to Netfilter Jool and iptables Jool. Your translator will look like a network interface (
jool0
in the snippet below):It will behave similarly to loopback; it will look like an interface, but will in fact be a virtual one. An IPv6 packet routed towards it will be bounced back as an IPv4 packet, and vice-versa. You will send traffic to it by means of Linux's routing table rather than iptables rules.
The setup will probably very most intuitive for some people. The only drawback that I can think of is that, if you set it up on a translator meant to forward traffic, the machine will end up subtracting 3 (instead of 1) from the packet's
TTL
/Hop Limit
field: One by Linux (when the packet is forwarded frometh0
tojool0
), another one by Jool itself, and a last one by Linux again (when the packet is forwarded fromjool0
toeth1
).And that's all, really. If that didn't already trigger chemistry in your brain, you probably don't need it.
Progress: Though I've tried to start this feature twice already, this work has been quickly obsoleted by a quickly evolving main branch. It's not practical to merge. I would have to start over from the beginning.
Original post
(As you will see, I still haven't finished writing this. I would, however, like this in the public domain in case someone has something interesting to say. I will come back and analyse this further once I've finished a lot of post-release and planning paperwork I need to flush from my desk.)
Being in the middle of Netfilter, we break Netfilter's assumptions.
As far as I can tell, the people who preceded me decided it would make sense for Jool to be a Netfilter/iptables module, because it's similar to NAT, and NAT is an iptables module.
Personally, I feel like we've hit a wall when it comes to pushing Netfilter's versatility, and we should find a way to more elegantly merge Jool with the kernel.
We seem to have the following options:
Both 1) and 2) appear to solve all of the following current annoyances:
Filtering. Because doc from iptables discourages filtering on mangle, I'm renuent to ask users to do so (Even though I don't know what's the problem with mangle filtering, other than it looking somewhat counter-intuitive).Because Jool would look like an interface (1) or some userspace daemon (2), packets would not skip either the INPUT or the FORWARD chain, and therefore they would be filtered normally.This was already fixed using namespaces.
Host-Based Edge Translation. 1) and 2) will naturally let the kernel know a route towards the RFC6052 prefix/EAM records/etc, so packets will survive ingress filtering.Currently, Jool cannot post a packet for local reception because it switches the layer-3 protocol of the packet. Linux goes "This is an IPv6 packet, but it came from an IPv4-only interface. Dropping."This can maybe currently be forced to work, but I don't think it's going to be pretty.This was already implemented using namespaces.
--minMTU6
. We can't ask the kernel to fragment to a particular size; ip_fragment() infers the MTU from the cached route, which is not--minMTU6
-sensitive (though whether that's not better than--minMTU6
is still to be looked upon - another TODO).I decided to start deferring fragmentation to the kernel because the code is tricky to get right by ourselves and atrocious to learn and maintain.
If we left Netfilter we would be free from the kernel's fragment representation and would be able to do it a lot easier.
(though it would be best if the kernel exported a fragmentation function which received MTU as an argument, but that's not going to happen, particularly for old kernels.)
Perhaps we would get rid of the need for two separate IPv4 addresses in stateful NAT64 mode. Not sure on this one; I need to think this more thoroughly - TODOpool4 port ranges fix this.Less important but still worth mentioning:
blacklist
would be able to stop returning loopback and other evil addresses since, being far from pre-routing, Jool would naturally stop seeing these packets.In my opinion, 1) is the most elegant option. This is because Host-Based Edge Translation forces the other options to include a dummy interface (so processes have an IPv4 address to snap themselves to). If an interface is necessary no matter the configuration, it would be cleanest if Jool itself "were" the interface.
Perhaps by adopting 2) we would attract new users who would not trust their kernels to us. On the other hand, it looks like a lot more work (I do not know to what extent is Jool married to kernel-only routines). It's also bound to make Jool somewhat slower, since packets need to be copied whenever they get in or out of kernelspace.
Other than perhaps get rid of the pools, I think there's not much to be earned from 3). Though we will look more like NAT, we will probably face roughly the same limitations as a Netfilter module (or perhaps more, since I'm not sure how
NF_HOOK_THRESH()
would behave when called from an iptables module).3 and 4 sound like the most performance-friendly options (since there's less routing and no copying), and I feel like their symmetry with the kernel's NATting would make it the most elegant solution from the eyes of the kernel devs (which is important if we ever want to push Jool into Linux). I'm just wild guessing, though. Perhaps they want to keep Netfilter free of any more hacks and they'd prefer some of the other options better - TODO ask them.
Due to lack of experience, we're currently not aware of any roadblocks we might run into. More planning is necessary - TODO.
Criticism (on this post) and more ideas welcomed.
The text was updated successfully, but these errors were encountered: