Subject: [BEHAVE] Fragmentation and NAT64 stateful translation

From: marcelo bagnulo braun <[email-masked]>
Date: Tue, 27 Oct 2009 17:26:23 +0100

Hi,

So, one thing that is still under discussion is how does the NAT64 
manages fragmentation.

the issues that i describe here are specific to the stateful translation 
and do not affect the stateless translation. (see justification in each 
case below)

I will try to present the issue concisely so we can have some discussion.

In the IPv4 to IPv6 direction:
------------------------------

The problem here is that how to handle IPv4 packets containing fragments 
that are not the first fragment i.e. that do not contain the src, dest 
port information to allow the translation of the packet.
So the question is how to handle packets containing fragments that are 
not the first.
We have essentially two options:
- We reassemble the fragments, so that we have a full packet and we 
process the full packet as any other packet. the Main problem here is 
that we need to buffer the packets.
- We process fragments independently. In order to do that we need to 
create state based on the first fragment. the state basically would 
include the set of ID fields of all the fragmented packets of a given 
session. Managing that state may require some effort, i guess. In any 
case, we will to buffer the fragments in case the arrive out of order 
until the  first fragment arrives (so we still need to buffer)

(This is specific to stateful translation cause the port information is 
only used by the stateful translator to perform the translation)

In the IPv6 to IPv4 direction:
------------------------------

The problem here is how to manage the IPv4 ID space for the IPv4 
addresses assigned to the translator.
Since the IPv4 addresses of the nat64 are shared among multiple IPv6 
hosts, we need to make sure that dfferent packets belong have different 
IDs. (this si specific to the stateful case)
(note that not all IPv6 packets carry the ID field and the IPv6 ID filed 
is 16 bits, while the IPv4 ID filed is 32 bits)

So, we have two types of incoming IPv6 packets.
- IPv6 packet withouth the fragmentation header. These packet do not 
carry a ID. these need to be translated to and IPv4 packet and needs to 
include an ID. So we need to assign them an ID. Since multiple source 
IPv6 addresses are translated as the same source IPv4 address, we need 
to make sure that they ID does not clash in the different packets. We 
could do this by simply using a counter for setting the ID of outgoing 
IPv4 packets, as any IPv4 host would do.
- IPv6 packets with the fragmentation header. these are fragments of the 
same IPv6 packet. the question is how do we handle these.
We have two options again:
-- either we translate each IPv6 fragment independently, in which case 
we need to make sure that all IPv4 packet resulting from translating 
fragments of the IPv6 packet contain the same ID and the Offset is 
copied (i think that would be enough). In order to do that, we could 
simply copy the 16 bits of the IPv6 packet ID into the IPv4 packet ID, 
as long as it does not colides with the ID s we are suing for the non 
fragmented packets. In order to do that, we could partition the ID 
number space and use one part for non fragmented IPv6 packets and 
another for fragmented IPv6 packets (this is possible since the IPv4 ID 
sapce is bigger than the one in IPv6)
-- the other option is to reassemble the IPv6 packet and process it as 
any other packet. the drawback here is that we need to buffer.

So, as you can see one option would be to simply reassemble the packets 
in both directions and process them as any other packet. This is inline 
with what the stateless document is doing. And it would not add much 
complication to the spec.

so, i am very tempted to go in that direction. does people have an 
opinion on this, why we should not do the reassemble first approach?

Thanks, marcelo

---

From: Cameron Byrne <[email-masked]>
Date: Tue, 27 Oct 2009 09:40:23 -0700

On Tue, Oct 27, 2009 at 9:26 AM, marcelo bagnulo braun
<[email-masked]> wrote:
> Hi,
>
> So, one thing that is still under discussion is how does the NAT64 manages
> fragmentation.
>
> the issues that i describe here are specific to the stateful translation and
> do not affect the stateless translation. (see justification in each case
> below)
>
> that are not the first fragment i.e. that do not contain the src, dest port
> information to allow the translation of the packet.
> So the question is how to handle packets containing fragments that are not
> the first.
> - We reassemble the fragments, so that we have a full packet and we process
> the full packet as any other packet. the Main problem here is that we need
> to buffer the packets.
> - We process fragments independently. In order to do that we need to create
> state based on the first fragment. the state basically would include the set
> of ID fields of all the fragmented packets of a given session. Managing that
> state may require some effort, i guess. In any case, we will to buffer the
> fragments in case the arrive out of order until the  first fragment arrives
> (so we still need to buffer)
>
> (This is specific to stateful translation cause the port information is only
> used by the stateful translator to perform the translation)
>
> The problem here is how to manage the IPv4 ID space for the IPv4 addresses
> assigned to the translator.
> Since the IPv4 addresses of the nat64 are shared among multiple IPv6 hosts,
> we need to make sure that dfferent packets belong have different IDs. (this
> si specific to the stateful case)
> (note that not all IPv6 packets carry the ID field and the IPv6 ID filed is
> 16 bits, while the IPv4 ID filed is 32 bits)
>
> - IPv6 packet withouth the fragmentation header. These packet do not carry a
> ID. these need to be translated to and IPv4 packet and needs to include an
> ID. So we need to assign them an ID. Since multiple source IPv6 addresses
> are translated as the same source IPv4 address, we need to make sure that
> they ID does not clash in the different packets. We could do this by simply
> using a counter for setting the ID of outgoing IPv4 packets, as any IPv4
> host would do.
> -- either we translate each IPv6 fragment independently, in which case we
> need to make sure that all IPv4 packet resulting from translating fragments
> of the IPv6 packet contain the same ID and the Offset is copied (i think
> that would be enough). In order to do that, we could simply copy the 16 bits
> of the IPv6 packet ID into the IPv4 packet ID, as long as it does not
> colides with the ID s we are suing for the non fragmented packets. In order
> to do that, we could partition the ID number space and use one part for non
> fragmented IPv6 packets and another for fragmented IPv6 packets (this is
> possible since the IPv4 ID sapce is bigger than the one in IPv6)
> -- the other option is to reassemble the IPv6 packet and process it as any
> other packet. the drawback here is that we need to buffer.
>
>
>
> So, as you can see one option would be to simply reassemble the packets in
> both directions and process them as any other packet. This is inline with
> what the stateless document is doing. And it would not add much complication
> to the spec.

Agreed.  This is also consistent with how NAT44 works in rfc4787

>
> so, i am very tempted to go in that direction. does people have an opinion
> on this, why we should not do the reassemble first approach?
>
> Thanks, marcelo
>
>
>
> _______________________________________________
> Behave mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/behave
>

---

From: Zhen Cao <[email-masked]>
Date: Wed, 28 Oct 2009 10:13:44 +0800

> In the IPv4 to IPv6 direction:

IPv6 ID is 32 bits and IPv4 is 16 bits.

> what the stateless document is doing. And it would not add much complication

Do you mean to choose option one for both 6-4 and 4-6 scenarios above?

---

From: marcelo bagnulo braun <[email-masked]>
Date: Wed, 28 Oct 2009 07:59:36 +0100

> Do you mean to choose option one for both 6-4 and 4-6 scenarios above?
yes, would that make sense to you?
Regards, marcelo

---

From: Zhen Cao <[email-masked]>
Date: Wed, 28 Oct 2009 21:46:49 +0800

I think it makes more sense if we list and analyze those options in
the document, and make some recommendation if necessary.

For the IPv4-to-IPv6 direction, the current text in the draft is good
but it implicitly suggests to keep the session state rather than wait
and reassemble.  I think in this direction, we should keep the session
state in stead of wait and assemble. If application keeps sending
fragmented packets (udp case), it is too consuming to buffer and
reassemble the ip packets.

For the IPv6-to-IPv4 directions,  i also prefer not to buffer the
packet, and tradeoff to avoid id collision should be cheaper than
buffering.

Thanks,
Zhen

On Wed, Oct 28, 2009 at 2:59 PM, marcelo bagnulo braun
<[email-masked]> wrote:
>>> in
>>> opinion

---

From: Iljitsch van Beijnum <[email-masked]>
Date: Wed, 28 Oct 2009 14:55:25 +0100

> reassemble the ip packets.

In the case where the fragments arrive out of order, there isn't much  
of a difference between the two approaches, in both cases you need to  
buffer any non-first fragments until the first fragment arrives. The  
main difference is that the reassemble-then-translate option is much  
easier to specify.

If people send fragments there isn't much you can do... Note that even  
with TCP, fragments happen in practice.

> packet, and tradeoff to avoid id collision should be cheaper than

In the IPv6-to-IPv4 direction you can always translate individual  
fragments (except non-first fragments of packets that set up a new  
session), so you don't need to buffer.

---

From: Zhen Cao <[email-masked]>
Date: Wed, 28 Oct 2009 22:13:07 +0800

On Wed, Oct 28, 2009 at 9:55 PM, Iljitsch van Beijnum
<[email-masked]> wrote:
> In the case where the fragments arrive out of order, there isn't much of a
> difference between the two approaches, in both cases you need to buffer any
> non-first fragments until the first fragment arrives. The main difference is
> that the reassemble-then-translate option is much easier to specify.
>
> If people send fragments there isn't much you can do... Note that even with
> TCP, fragments happen in practice.
>
> In the IPv6-to-IPv4 direction you can always translate individual fragments
> (except non-first fragments of packets that set up a new session), so you
> don't need to buffer.
I know, and we discussed this before. But Marcelo here does not mean
this above. I quote back his original text below.

"We have two options again:
-- either we translate each IPv6 fragment independently, in which case
we need to make sure that all IPv4 packet resulting from translating
fragments of the IPv6 packet contain the same ID and the Offset is
copied (i think that would be enough). In order to do that, we could
simply copy the 16 bits of the IPv6 packet ID into the IPv4 packet ID,
as long as it does not colides with the ID s we are suing for the non
fragmented packets. In order to do that, we could partition the ID
number space and use one part for non fragmented IPv6 packets and
another for fragmented IPv6 packets (this is possible since the IPv4
ID sapce is bigger than the one in IPv6)
-- the other option is to reassemble the IPv6 packet and process it as
any other packet. the drawback here is that we need to buffer."

---

From: marcelo bagnulo braun <[email-masked]>
Date: Wed, 28 Oct 2009 16:55:13 +0100

> main difference is that the reassemble-then-translate option is much 

Not only that, but i understand that several of the attacks that have 
been described involving fragmentation would be solved by this approach.
Of course, the vector of DoS relying on sending incomplete fragments is 
worse, but this can be dealt with by limiting the resources assigned to 
this task.

Regards, marcelo