Subject: [Softwires] MSS and NAT64 / DS-lite parity

From: Iljitsch van Beijnum <[email-masked]>
Date: Wed, 23 Dec 2009 11:53:22 +0100

[Note that I'm not up to date with softwires work, but after Alain's comment about the MSS in the behave session in Hiroshima it seems prudent to send this to the softwires list, too.]

I was quite annoyed to hear the discussion about MSS clamping in the audio file from the behave session in Hiroshima, because I've written several messages about this in the summer, that, as far as I'm concerned, put the issue to bed but apparently nobody remembered that.

http://www.ietf.org/mail-archive/web/behave/current/msg06838.html
http://www.ietf.org/mail-archive/web/behave/current/msg07180.html
http://www.ietf.org/mail-archive/web/behave/current/msg07258.html

Specifically:

"I don't think it's worth the trouble to do this. The common situation will be for all the systems involved tohave 1500-byte MTUs. In that case, the IPv6 host will advertise a 1440- byte MSS (1500 - 40 bytes IPv6 - 20 bytes TCP) so the IPv4 host will send TCP packets of 1480 bytes (1440 + 20 bytes IPv4 + 20 bytes IPv4) which the translator then translates into 1500-byte IPv6 packets."

In short: when both ends use 1500-byte MTUs everything works without any PMTUD dependencies.

However.

In my opinion, it would be very beneficial to have a single translator implementation that can do both stateful NAT64 as well as provide termination and NAT in DS-lite deployments. In DS-lite where a CPE does the encapsulation, the hosts on either side think they can send full size packets (which I'll assume are 1500 bytes) while in fact the extra IPv6 header reduces this by 40 bytes. Even if we compress away the entire IPv4 header that only brings back 20 bytes so we're still 20 bytes short.

So either a DS-lite NAT or a DS-lite CPE would have to perform MSS clamping to avoid hitting all those PMTUD black holes that exist in the IPv4 internet. Although MSS clamping itself is not something that is stateful, in my opinion it is much uglier to do this in a stateless box than a stateful box. So I would want to do this in a DS-lite NAT, and, to maintain parity between DS-lite and stateful NAT64, perhaps in a stateful NAT64 translator, but not in a DS-lite CPE or a stateless IPv6-IPv4 translator.

Another way to go would of course be to increase the MTU on the IPv6 path to something that accommodates an encapsulated 1500-byte IPv4 path. Not sure how realistic that is, but I know I would be asking for that if I were buying a few million DS-lite capable CPEs.

About the DS-lite / NAT64 translator parity and IPv4 header compression:

The argument has been made that encapsulating IPv4 in IPv6 is cleaner than translating IPv4 to IPv6 and then back to IPv4. However, that is a very abstract argument. Something much more tangible is the ability to use the same code and boxes to handle both NAT64 and DS-lite. So let's look at the details:

IP:

Header fields can be pretty much 464 translated without loss of information. The issues with the implied DF=1 in IPv6 and minimum MTU of 1280 aren't necessary here, but as far as I can tell, there is no harm in applying the workarounds that are necesary for 64 or 46 to 464 as well.

TCP:

In principle, no issues. Only the checksum has to be recomputed. However, see maximum packet size issues, but these apply regardless of translation vs encapsulation.

UDP:

The same as TCP, except the checksum = 0 issue. A translator inserting a valid checksum where there wasn't one before poses no problems and a translator could also just forward packets with the 0 checksum when inserting one isn't possible or desirable.

ICMP:

There are many ICMP types. Some can be translated without loss of information, but not all can, especially ones that are defined after a translator is deployed. However, dropping ICMP messages, especially undefined/obscure ones, doesn't break applications.

So basically it's doable to have a CPE translate IPv4 packets to IPv6, which are then translated back into IPv4 by a "real" NAT64, without breaking perceptibly more than what would break in NAT444, too.

The only thing that needs to happen for this to work is that a DS-lite CPE maintains a separate IPv6 source address for any IPv4 client that it serves. So basically, this requires an additional /64 for this purpose. If the CPE chooses the IPv6 address for each of the IPv4 clients such that the whole thing becomes checksum neutral the CPE doesn't have to look inside TCP or UDP packets, and the only additional complexity is the translation of ICMP messages. For outgoing messages it could just send the IPv4 ICMP message, which the NAT64 can then NAT44 (which is simple), but without knowing whether it's talking to an IPv6 host or an IPv4 host behind DS-lite the NAT64 wouldn't know whether to NAT64 or NAT44 ICMP messages coming in from the IPv4 side so it would have to NAT64 them and then the CPE would have to translate them back to IPv4.