-
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
Setting the interface MTU with "ip link" isn't a full replacement for a correct implementation of --minMTU6 #136
Comments
FWIW, IPv6 packets that have nothing to do with Jool (forwarded or locally originated) will also be impacted. From a practical standpoint, this issue means that an operator cannot co-locate a Jool instance on a host that also serves as a traditional router/firewall, unless the IPv6 network Jool will translate to/from is 100% under the operator's control (so he can ascertain that there are no IPv6 MTUs lower than 1500). |
I am trying to deploy Jool to an Ubuntu 16.04.2 VM on Google Compute Engine (GCE). GCE's MTU is 1460 and I am having performance problems related to fragmentation. I am trying to When I use the IPv4 version of the curl command, performance is 1000x faster. This is what I see on the VM when I tcpdump the IPv6 version of the curl command:
I have tried adding a mtu size: I have changed the mtu size of the Docker bridge, veth's and the container's eth0 interface but nothing is helping. |
I don't think that IP fragmentation should induce this level of catastrophe. Can it? Quick check: Are you positive that there is no offloading going on? Because, at least on a quick look, this does seem like a typical case of GRO/LRO-induced black-holing.
This might be relevant since you're running Jool in a contained environment. |
@ydahhrk thank you for your response. I disabled offloads on the Ubuntu VM and in the container according to this doc but still no luck. As you mentioned, offloads should be disabled on the host's uplink ports, but my Ubuntu VM is running on a GCE host so that is not possible. I have tested hosting the same tarball on a nginx container and
|
It appears that this fragmentation/performance issue only comes into play when you’re using Jool with only 1 interface for both (translated) IPv4 and (synthesized-IP) IPv6 traffic. When I use Jool with 1 interface, docker pulls are slow due to fragmentation, but when I use Jool with separate interfaces for IPv4 vs. IPv6, docker pulls go at normal speed. I believe that the issue is that when Jool is being used with a single interface, it may be applying the wrong “effective” MTU size for path MTU discovery. For example, if the interface MTU size is 1500, it represents that as its MTU for path MTU discovery… so a sender might send IPv4 packets up to 1480 in payload size (accounting for a 20-octet IPv4 header). However, when a 1480-octet packet gets translated by NAT64 to IPv6, the resulting packet size would be 1520 (1480 payload + 40 octet header), and this would violate the interface MTU, so NAT64 must respond back with a “needs fragmentation”, since it can’t fragment IPv6 packets. |
We are using two interfaces in the lab and see the issue, but are wondering if it is what @leblancd is saying where the MTU calc is not accounting for the differences in header sizes. If I set the MTU of the host interface and docker to 9000, where no fragmenting occurs, it works. Granted, if packets exceed 8920, I suspect it will fail. |
Jool continues to send ICMP unreachables even when the interface MTU's are configured properly. The
However, Jool continues to send icmp unreachables to the
I see the same icmp errors with or without receive offloads:
I can not disable offloads on the host since this is GCE. |
No. Indeed, I think there's something fishy going on here.
Ok, I'm looking into this. By the way: If anyone else wants to experiment, if one compiles Jool with debugging messages enabled, it will print some numbers that can help us figure out what it's trying to do. For example, if Jool's attached interface is too small, it prints me this:
While, on the other hand, it's translating an ICMP fragmentation needed error, it will print something like this:
("Packet MTU" is the MTU contained in the incoming ICMP error, "Resulting MTU" should be the number it prints in the resulting ICMP error.) @danehans: Can you give me these numbers? They should reveal where Jool is messing up.
It should be accounting for these sizes. If I recall correctly, we have unit tests specifically intended to enforce this. |
@danehans You should try to figure out what size the packet that is causing Jool to emit the ICMPv4 need to frag message is. If it's >1500 it is in all likelihood offloading that is causing your problem.
That, I suspect, might be the root cause. If your VM gets oversized packets from the GCE host, I don't really see how to make it work. |
Yep. The first number in the following output will give you a rough estimate of the size of the packet Jool received:
(It's the size of the outgoing packet, not the incoming one. That's why I say "rough estimate".)
+1. You know what? I think I see how to make it work. Currently, the following happens in order:
The reason why Jool cannot handle offloads is because they require special treatment, but on some configurations offloaded packets look no different than IP-reassembled fragments. So Jool cannot handle them differently. So how about creating a module that undoes offloading before the IP reassembly comes into play? This way, Jool will never have to fear mistaking an offload for a fragment.
Granted, it's a vile hack. It's not perfect because it requires an additional (Also, I need to check whether it's actually viable from code. I'm thinking of a particular Netfilter quirk that could get in the way.) |
In my host based config, I disabled GRO (LRO already disabled), and it appears to be working! I’ll try the suggestions you have regarding Jool in container, and if that works, we can disable GRO on the VM for GRE and maybe things will work for that case. Fingers crossed… |
I am unable to compile the jool kernel module according to the provided document. Here are the details. |
Wait. How so? I don't see any errors in the output. |
Wait. Actually, I don't see the |
@ydahhrk I am getting module not founf when I try the modprobe step:
|
|
@ydahhrk |
2018-11-25 Update
Hello. If you came here from the survey, you'll notice that this thread comes from rather nowhere. Please read this to get some context.
Progress: There has been no progress on this feature. I'm not even sure if it's possible to fix given the packet API that the kernel exports to us.
Original post
Our solution to #121 sucks.
Plagiarized from one of Tore Anderson's e-mails:
For this issue to be closed, Jool needs to behave as follows:
Because 3.3 doesn't have
--minimum-ipv6-mtu
, what Jool 3.3 currently does is this:(Jool 3.2 used to do something different, which was also wrong.)
The reasoning is, we're asking the user to set
nexthop MTU = --minimum-ipv6-mtu
. While this doesn't actually break anything, it introduces needless fragmentation and artificially small MTUs.nexthop MTU
and--minimum-ipv6-mtu
need to be separate variables because some packets should be affected by the former but not the latter:--minimum-ipv6-mtu
but don't cross any--minimum-ipv6-mtu
-MTU'd links along their way.Thanks to Tore Anderson for reporting this.
The text was updated successfully, but these errors were encountered: