Subject: [BEHAVE] Summary of the issues related to fragmentation and v4/v6 translation

From: marcelo bagnulo braun <[email-masked]>
Date: Fri, 30 Oct 2009 11:10:58 +0100

Hi,

I attach next a summary of the issues related to fragmentation some of
which are common to the stateless and stateful cases and some of which
are specific to the stateful case.
I think we should decide what to do with these in the next meeting.
Comments are welcome?

Summary of the issues related to fragmentation
-----------------------------------------------

Incoming IPv4 packet

- Full packet, DF=1: Resulting IPv6 packet does NOT include the fragment
  header (PMUTD should work e2e)
  Issue: If the packet is too big for the outgoing MTU in IPv6, should the
  translator generate and ICMP error Packet too big? This is not 
specified in
  the stateless document AFAICT.
  This affects both stateless and stateful,
  should we use the same approach to both?

- Full packet, DF=0: Resulting IPv6 packets MUST fit in 1280 bytes, so 
add the
  fragment header if needed. The fields of the fragment header are 
copied from
  the IPv4 fields.
  Issue: Would this result in significant amount of fragmentation?
  Should the translator perform PMUTD for IPv6 destinations?
  This affects both stateless and stateful,
  should we use the same approach to both?
  see thread in behave ml - My reading so far is that we should
  send 1280 byte long packets (As currently defined)

- Fragment: Add fragment header, copy fields from IPv4 header, also make 
sure
  that the packet does not exceeds 1280 bytes.
  Issue: how to determine the session for fragments, reassembly or keep 
state.
  This issue is described in detail in (*) below and it is specific to the
  stateful case

Incoming IPv6 packet

- Without Fragment header: Id set to all zeros and DF set to 1.
  Issue: Black hole in cases the IPv6 side filters ICMP packet too big and
  simply sends packets of 1280 bytes. This may be not negligible 
according to
  the analysis from Ben.
  This affects both stateless and stateful,
  should we use the same approach to both? The issue is detailed in (**)
  Issue: If the outgoing IPv4 MTU is smaller than the packet, should the
  translator send an ICMP packet too big back?
  This affects both stateless and stateful,
  should we use the same approach to both?

- With Fragment header: copy fields from the fragment header to the
  IPv4 header fragmentation fields
  Issue: higher probability of clashes on the ID fields for the stateful 
case
  This is somehow specific to the stateful case, see the issue detailed 
in (***)

Detailed description of issues (mostly) specific to the stateful translation
----------------------------------------------------------------------------

(*) - Issue#1: Processing of incoming IPv4 packets containing a fragment
other than the first one.

In order to translate an IPv4 packet, we need to know the 5-tuple.
When an IPv4 packet contains a fragment other than the first one,
the port information is not available, so the port information must
be retrieved from somewhere else.
The possibilities are:
a)- Reassemble the IPv4 packet, and translate it.
b)- Store state that allows to translate packets containing fragments
other than the first one. The state needed is the ID value. The state
is learned from the packet containing the first segment. So the procedure
would be:
If packets that contain fragments that are not the first arrive and the
ID does not match to any of the stored ID values for the src and dst 
addreses,
then store the packets.
If packets that contain fragments that are not the first arrive and the
ID does match to any of the stored ID values for the src and dst addresses,
then use the corresponding session to translate the packet.
If packet that contain the first fragment arrive, then store the ID value
in the session state and forward the packet.

The differences between the two approaches are:
- The approach a) will require more memory for storing fragments.
- The approach b) will require additional complexity and state. In 
particular,
it is important to deal with the attacks defined in RFC3128 and RFC1858 
(that
i understand that do not apply if we use approach a)

(***) Issue#2: Setting the ID value for outgoing IPv4 packets.

The ID field of outgoing IPv4 packets must be different for different 
packets.
Since multiple IPv6 addresses potentially communicating with the same 
destination
may share the same IPv4 address, we need to avoid clashes in the ID field.

We have two types of incoming IPv6 packets: those with the fragment 
header and those
without the fragment header.

(**)----- this is common for the stateful and the stateless----------

Those without the fragment header do not contain any ID value. The 
stateless document
defines that the ID value is set to 0 and the DF set to 1. That works 
modulo the
following black hole situation:
Suppose that an IPv6 site is configured to drop ICMP packet too big msgs 
and configure
its hosts to only send packet of 1280 bytes. That would work for any 
communication
with other IPv6 hosts, but it would break for a communication with an 
IPv4 host
behind a translator and sitting on a link with MTU smaller than 1280.
In order to solve this problem, we should set the ID value different for 
different
packets and set DF to zero. In order to do that, we should generate 
values for the ID
field so that they do not clash

----- end of common part-----------

Those IPv6 packets coming with the fragment header, the stateless 
document recommends
to set the DF to 0 and copy the lower 16 bits of the ID field of the 
IPv6 fragment
header into the ID value of the IPv4 header.
This may result in clashes in the stateless case, but the problem in the 
stateful
case is that there may be several IPv6 source using the same ID value 
would result in
a higher probability of clashes. The probability increases even more if 
we decide to
use a non zero value for the IPv4 packets resulting from IPv6 packet 
without the
fragment header.

There are three possible approaches to approach this issue:
a) We decide that the clash probability is still negligible and we keep 
it as it is.
b) Reassemble all the IPv6 fragments, translate as a normal packet (with 
DF set to 0
and setting a valid value of ID)
c) Split the IPv4 ID value space into two. Use the ID witht he MSB set 
to 0 for
IPv6 packets with the fragment header (And copy the lower 15 bits) and 
use the ID
with the MSB set to 1 for the IPv6 packets without the fragment header 
(and generate
ID values and set DF to 0)

---

From: Simon Perreault <[email-masked]>
Date: Fri, 30 Oct 2009 11:49:46 -0400

Adding to your question list...

>  that the packet does not exceeds 1280 bytes.

If the fragment exceeds 1280 bytes, do you just fragment the fragment by itself,
or wait for the other fragments to arrive then fragment the reassembled packet
as a whole?

If you're going to do reassembly anyway you might as well fragment the packet as
a whole. However that would need changing text in the stateless draft (section
2.1, first paragraph).

Simon
-- 
DNS64 open-source   --> http://ecdysis.viagenie.ca
STUN/TURN server    --> http://numb.viagenie.ca
vCard 4.0           --> http://www.vcarddav.org

---

From: marcelo bagnulo braun <[email-masked]>
Date: Fri, 30 Oct 2009 19:25:20 +0100

right
thanks, marcelo