Subject: [BEHAVE] Non reversibility of address mappings in the "NAT66" draft

From: Rémi Després <[email-masked]>
Date: Tue, 25 Nov 2008 19:15:52 +0100

Margaret, Fred,

In section 5.1 of your draft,
you propose a technique for Checksum-Neutral Mapping.

Due to the two ways to represent 0 in one's complement, it doesn't work
in all cases:

In 16 bits, +0 is 0x0000 and -0 is 0xFFFF.

If the field which is modified contains -0 or +0,  adding to it, or
subtracting from it, any non zero value wipes out the difference
between the two zeros.

For example, in one's complement:

.  0x0000 - 0x0001 = 0xFFFE

.  0xFFFF - 0x0001 = 0xFFFE

I therefore believe that it is unavoidable to modify the UDP or TCP
checksum if we want a reversible mapping between a local and a global
address (which I believe is a good approach to avoid classical NATs in
IPv6). This modification can be done incrementally.  Finding the
UDP/TCP header  may require in IPv6 to parse a few headers, but this
seems quite acceptable.

Regards,

RD

_______________________________________________
Behave mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/behave

---

From: Fred Baker <[email-masked]>
Date: Mon, 24 Nov 2008 13:23:57 -0800

Not sure I buy that. In UDP and TCP, the value stored in the header is  
set of 0xFFFF if the sum adds to 0x0000, but I don't see any reason  
that has to be the case in the modification of the IP address.

I'll let you look at the code I put up to test this if you like. You  
can tell me what I missed.
     ftp://ftpeng.cisco.com/fred/gse/checksum.c

On Nov 25, 2008, at 10:15 AM, Rémi Després wrote:

> Margaret, Fred,
>
> In section 5.1 of your draft, you propose a technique for Checksum- 
> Neutral Mapping.
>
> Due to the two ways to represent 0 in one's complement, it doesn't  
> work in all cases:
>
> checksum if we want a reversible mapping between a local and a  
> global address (which I believe is a good approach to avoid  
> classical NATs in IPv6). This modification can be done  
> incrementally.  Finding the UDP/TCP header  may require in IPv6 to  
> parse a few headers, but this seems quite acceptable.
>
> Regards,
>
> RD

---

From: Rémi Després <[email-masked]>
Date: Wed, 26 Nov 2008 10:39:03 +0100

Fred Baker   (1-12/1-31/200x) 11/24/08 10:23 PM:

No reason, you are right, but the point I was making is different.

It concerns the 16 bits in which the prefix
checksum difference is
subtracted, in outgoing packets, when these 16 bits happen to be 0000
(i.e. +0 in one's
complement).  After the
subtraction, which in general gives a non-zero result, it will no
longer be possible to determine whether the original value was -0 or
+0.

If the checksum difference to be subtracted from 0000 is for example
0001, the result is FFFE (i.e. - 1).

When trying to reverse the mapping, adding 0001
to FFFE gives FFFF (i.e. -0), while the original value in the outbound
packet was 0000 (i.e. +0) :-(.

I'll let you look at the code I put up to test this if you like.
You can tell me what I missed.

What had been missed is not in the code, which seems perfectly fine,
but in the specification.

Regards,

RD

Margaret, Fred,

Regards,

RD

Behave mailing list

[email-masked]

---

From: Michael Procter <[email-masked]>
Date: Tue, 25 Nov 2008 12:01:22 +0000

Rémi Després wrote:
>> Not sure I buy that. In UDP and TCP, the value stored in the header
>> is set of 0xFFFF if the sum adds to 0x0000, but I don't see any
>> reason that has to be the case in the modification of the IP address.
> It concerns the 16 bits in which the prefix checksum difference is
> (i.e. +0 in one's complement).  After the subtraction, which in
> general gives a non-zero result, it will no longer be possible to
> determine whether the original value was -0 or +0. 
>
> When trying to reverse the mapping, adding 0001 to FFFE gives FFFF
> (i.e. -0), while the original value in the outbound packet was 0000
> (i.e. +0) :-(.

Are you saying that an internal subnet of zero does not survive the
mapping?  It is transformed to subnet 0xFFFF upon return?  If so, then I
agree with you, and a minor change to Fred's code shows this.  Changing
the 'test' address to {0xFD01, 0x0203, 0x0405, 0x0000, 0, 0, 0, 0x1234}
means that the program generates the following output:

=================
inverted one's complement sum of  FD01+0203+0405 is fcf5
inverted one's complement sum of  2001+0DB8+0001 is d245
d245 - fcf5 = d54f
        fd01:0203:0405:0000:0000:0000:0000:1234
        2001:0db8:0001:0000:0000:0000:0000:0000
offset is d54f
        2001:0db8:0001:d54f:0000:0000:0000:1234
        fd01:0203:0405:ffff:0000:0000:0000:1234
checksum of outside is eac1
checksum of inside is eac1
checked all checksum values from 0:0::/32 to 8:0::/32 and found no errors
=================

Note that the first and last indented address lines are supposed to be
the same, but the subnet field has changed from 0x0000 to 0xFFFF.  This,
as you say, is because the information about whether the subnet was +0
or -0 is lost.

Best regards,

Michael Procter

---

From: Margaret Wasserman <[email-masked]>
Date: Tue, 25 Nov 2008 10:52:55 -0500

Hi Remi,

I ran some numbers this morning, and you are right.

If the _original_ value of the 16-bit checksum correction field is  
0x0000, it will be restored to 0xFFFF, which is wrong.  The checksum  
correction works fine (as Fred's tests have proven), but the  
restoration of the value doesn't work properly.  It can be made to  
work properly for either 0x0000 or 0xFFFF, but I haven' t figured out  
a way to make it work right for both values as the information to  
distinguish between them is lost.

There are three approaches we can take to fix this

1) As you have proposed, we could changing NAT66 so that it modifies  
the transport header checksum.  This would involve every NAT66 box  
knowing how to traverse the IPv6 extension header chain, and might  
effectively limit IPv6 NAT to transporting ICMPv6, TCP and UDP-based  
protocols, because we wouldn't know how to correct the checksum in  
other protocols.

2) The NAT66 device can store one-bit-per-host of state for any host  
that has 0xFFFF or 0x0000 in the field that is used for the checksum  
correction.  Although we would be required to implement this, we could  
explain to network administrators how to avoid it, at least in the  
case where the bits used for checksum correction are the subnet bits.   
I'm not sure if this would be better or worse than updating the  
transport layer checksum, though, as it would result in inferior  
service for a small set of hosts, but would provide better service to  
most hosts.

2) We can do the checksum correction in a 16-bit field that we _know_  
will never contain one of the two one's complement 0 values (0x0000 or  
0xFFFF).  There are two different cases here, but I think there are  
choices for both that would work:

2a) For the case of /48 or shorter prefixes, we could still do the  
checksum correction in the lowest order 16 subnet bits  and document  
that subnet values containing 0xFFFF in their lowest order 16 bits  
should not be used with NAT66.  This has the advantage of retaining  
the IID value unchanged, but might result in some misconfigurations  
and support calls.

2b) For longer prefixes, we could perform the checksum correction in  
the highest order 16 bits of the IID.  I've looked into this in the  
IEEE specs, and we should never have an IID with both the "g" bit and  
the "u" bit set.  The "g" (individual/group) bit should always be '0'  
in EUI 64s that are assigned to specific interfaces (a "1" indicates  
that this is a "group" address, similar to an Ethernet multicast  
address), and if a host uses an IID that was generated some other way,  
it is expected to clear the "u" bit to indicate that the value isn't a  
universally scoped EUI-64.  So, we should be able to safely assume  
that the first 2 bits of an IID will never be "11".  Therefore, the  
first 16 bits can never contain 0xFFFF.  The issues here is that we  
would end-up generating IIDs that have the "universal" bit set that  
are not universally scoped.  I am not sure how big of an issue that  
is, as we don't have any documents that use the fact that a  
universally scoped IID contains an EUI-64, at least not to my knowledge.

Thoughts?

Margaret

On Nov 26, 2008, at 4:39 AM, Rémi Després wrote:

> subtracted, in outgoing packets, when these 16 bits happen to be  
> 0000 (i.e. +0 in one's complement).  After the subtraction, which in  
>>> If the field which is modified contains -0 or +0,  adding to it,  
>>> or subtracting from it, any non zero value wipes out the  
>>> difference between the two zeros.
>>>
>>> I therefore believe that it is unavoidable to modify the UDP or  
>>> TCP checksum if we want a reversible mapping between a local and a

---

From: Rémi Després <[email-masked]>
Date: Wed, 26 Nov 2008 17:56:43 +0100

Margaret,

Thanks for the quick study of the problem.

Personally,  I still believe that solution 1 is the most
straightforward and the cleanest solution. Unless I am mistaken,
traversing the IPv6 extension header chain is not complex and will in
most cases be on a chain of length 1 or two.

Solution 2 is somewhat stateful. Also, it interferes with the total
freedom of having any value in  the chosen 16 bits, all of them being
equal.  This kind of interaction between layers is in general not
recommended, right?

Drawbacks of solution 2a (rather 3a, I suppose, but no ambiguity) are
such that no one should like it.

I also thought about solution 2b, but to also reject it. The fact that
u and g bits are never 11 is the only door we have to define new IPv6
address formats in the  future. We should not lose it. (As a matter of
fact my SAM proposal uses it and... proposes to have FF in the 9th
octet of the address!)

Next there is the question of accepting or not, in a convergence
approach, what I proposed in subaddress
& port scrambling, i.e. to ensure  host privacy and topology
hiding by acting also, statelessly, on port numbers. (BTW in slide 5,
an important comma is missing after "bit(s)").

Best regards,

RD

Margaret Wasserman   (1-12/1-31/200x) 11/25/08 4:52 PM:

Hi Remi,

If the _original_ value of the 16-bit checksum correction field is
0x0000, it will be restored to 0xFFFF, which is wrong.  The checksum
correction works fine (as Fred's tests have proven), but the
restoration of the value doesn't work properly.  It can be made to work
properly for either 0x0000 or 0xFFFF, but I haven' t figured out a way
to make it work right for both values as the information to distinguish
between them is lost.

2) The NAT66 device can store one-bit-per-host of state for any host
that has 0xFFFF or 0x0000 in the field that is used for the checksum
correction.  Although we would be required to implement this, we could
explain to network administrators how to avoid it, at least in the case
where the bits used for checksum correction are the subnet bits.  I'm
not sure if this would be better or worse than updating the transport
layer checksum, though, as it would result in inferior service for a
small set of hosts, but would provide better service to most hosts.

2a) For the case of /48 or shorter prefixes, we could still do the
checksum correction in the lowest order 16 subnet bits  and document
that subnet values containing 0xFFFF in their lowest order 16 bits
should not be used with NAT66.  This has the advantage of retaining the
IID value unchanged, but might result in some misconfigurations and
support calls.

2b) For longer prefixes, we could perform the checksum correction in
the highest order 16 bits of the IID.  I've looked into this in the
IEEE specs, and we should never have an IID with both the "g" bit and
the "u" bit set.  The "g" (individual/group) bit should always be '0'
in EUI 64s that are assigned to specific interfaces (a "1" indicates
that this is a "group" address, similar to an Ethernet multicast
address), and if a host uses an IID that was generated some other way,
it is expected to clear the "u" bit to indicate that the value isn't a
universally scoped EUI-64.  So, we should be able to safely assume that
the first 2 bits of an IID will never be "11".  Therefore, the first 16
bits can never contain 0xFFFF.  The issues here is that we would end-up
generating IIDs that have the "universal" bit set that are not
universally scoped.  I am not sure how big of an issue that is, as we
don't have any documents that use the fact that a universally scoped
IID contains an EUI-64, at least not to my knowledge.

Thoughts?

Margaret

Fred Baker   (1-12/1-31/200x) 11/24/08 10:23
PM:

It concerns the 16 bits in which the prefix checksum difference is
subtracted, in outgoing packets, when these 16 bits happen to be 0000
(i.e. +0 in one's complement).  After the subtraction, which in general
gives a non-zero result, it will no longer be possible to determine
whether the original value was -0 or +0.

Regards,

RD

On Nov 25, 2008, at 10:15 AM, Rémi Després
wrote:

Margaret, Fred,

In section 5.1 of your draft, you propose a technique for
Checksum-Neutral Mapping.

Regards,

RD

Behave mailing list

[email-masked]

---

From: Margaret Wasserman <[email-masked]>
Date: Tue, 25 Nov 2008 12:43:16 -0500

On Nov 26, 2008, at 11:56 AM, Rémi Després wrote:
> I also thought about solution 2b, but to also reject it. The fact  
> that u and g bits are never 11 is the only door we have to define  
> new IPv6 address formats in the  future. We should not lose it. (As  
> a matter of fact my SAM proposal uses it and... proposes to have FF  
> in the 9th  octet of the address!)

Actually, it isn't correct that this is our only door for a new IPv6  
address format.  So far, we have only defined the structure for one  
eighth of the IPv6 address space (addresses starting with three zero  
bits).  So, we have 7/8th of the IPv6 address space in reserve for  
different formats.  Also, I forgot to mention in my earlier message, f  
we do overwrite it, we can map any 0xFFFF result to 0x0000, so that  
the property that the first 16 bits is never 0xFFFF will be  
maintained.  I can understand if we don't want to do this, though.

Why do you think no one should like restricting the use of subnet  
0xFFFF behind NAT66 devices?

> approach, what I proposed in subaddress & port scrambling, i.e. to  
> ensure  host privacy and topology hiding by acting also,  
> statelessly, on port numbers. (BTW in slide 5, an important comma is  
> missing after "bit(s)").

I think that we (the IETF) have a bunch of work to do to determine  
what the requirements are for topology hiding before we know what a  
topology hiding solution needs to hide.  We're getting conflicting  
information at the moment.  Is it enough to hide the subnet  
information?    Do we need to hide the _number_ of hosts on the  
network?  Do we need to prevent correlation of multiple connections  
with the same host?  Do we need to hide port number information?   
There even seem to be some people who want to hide TTL information,  
but I don't know why.

I think my preferred approach at this point, in the NAT66 document,  
would be to offer a NAT transform that encrypts the subnet information  
and indicates that it may be used as part of a larger topology hiding  
solution and leave it at that.  I hope that someone else will write a  
document for how to do topology hiding in IPv6, and if they end-up  
using the NAT66 encrypted address mapping, that would be great.

Margaret

---

From: Magnus Westerlund <[email-masked]>
Date: Wed, 26 Nov 2008 10:48:24 +0100

Rémi Després skrev:
> Personally,  I still believe that solution 1 is the most straightforward
> and the cleanest solution. Unless I am mistaken, traversing the IPv6
> extension header chain is not complex and will in most cases be on a
> chain of length 1 or two.
> 

That is bad because you make NAT66 once more transport protocol aware
and that hinders evolution in the transport protocol space.

Cheers

Magnus Westerlund

IETF Transport Area Director & TSVWG Chair
----------------------------------------------------------------------
Multimedia Technologies, Ericsson Research EAB/TVM
----------------------------------------------------------------------
Ericsson AB                | Phone  +46 10 7148287
Färögatan 6                | Mobile +46 73 0949079
SE-164 80 Stockholm, Sweden| mailto: [email-masked]
----------------------------------------------------------------------
_______________________________________________
Behave mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/behave

---

From: Rémi Després <[email-masked]>
Date: Wed, 26 Nov 2008 10:51:21 +0100

Margaret Wasserman   (1-12/1-31/200x) 11/25/08 6:43 PM:

I also thought about solution 2b, but to also
reject it. The fact that u and g bits are never 11 is the only door we
have to define new IPv6 address formats in the  future. We should not
lose it. (As a matter of fact my SAM proposal uses it and... proposes
to have FF in the 9th  octet of the address!)

different formats.

Formally right.

However, any use of high order bits has an impact on routing tables,
which IMHO should be avoided.

Using  u and g bits to express something that concerns interior of
customer sites, not having such an impact, is preferable.

The particular use of these bits in SAM, is to extend subnet IDs beyond
64
bits in customer sites.

Also, I forgot to mention in my earlier message, f we do
overwrite it, we can map any 0xFFFF result to 0x0000, so that the
property that the first 16 bits is never 0xFFFF will be maintained.  I
can understand if we don't want to do this, though.

Next there is the question of accepting or
not, in a convergence approach, what I proposed in subaddress &
port scrambling, i.e. to ensure  host privacy and topology hiding by
acting also, statelessly, on port numbers. (BTW in slide 5, an
important comma is missing after "bit(s)").

I think that we (the IETF) have a bunch of work to do to determine what
the requirements are for topology hiding before we know what a topology
hiding solution needs to hide.  We're getting conflicting information
at the moment.  Is it enough to hide the subnet information?    Do we
need to hide the _number_ of hosts on the network?  Do we need to
prevent correlation of multiple connections with the same host?  Do we
need to hide port number information?  There even seem to be some
people who want to hide TTL information, but I don't know why.

I understand that you find it too early to attempt
convergence of our two proposals, which is of course perfectly
acceptable.

I should then work more on Subaddress
and Port Scrambling, when having time
to do it, and we can se later if convergence makes sense.

Regards

RD

---

From: Iljitsch van Beijnum <[email-masked]>
Date: Wed, 26 Nov 2008 16:19:54 +0100

On 25 nov 2008, at 16:52, Margaret Wasserman wrote:

> It can be made to work properly for either 0x0000 or 0xFFFF, but I  
> haven' t figured out a way to make it work right for both values as  
> the information to distinguish between them is lost.

Right, effectively we're throwing away a tiny part of our 16 bits by  
having both +0 and -0 so some information is lost.

> the transport header checksum.

Bad idea.

> correction.

Don't like this either.

> 2) We can do the checksum correction in a 16-bit field that we  
> _know_ will never contain one of the two one's complement 0 values  
> (0x0000 or 0xFFFF).  There are two different cases here, but I think  
> there are choices for both that would work:

May want to do this on bits 96 - 111 and forbit 0xffff, as 96 - 103  
contain 0xfe to pad the 48-bit MAC address to 64 bits, or catch the  
top bits because u/l = u and g=1 should be uncommon, although I don't  
think we want to forbid their use, we should keep those for special  
use at some point in the future.

But if clashing is uncommon, then a NAT device could proxy DAD for all  
the addresses that clash, although I'm afraid there is no way to avoid  
having such a device do multicast filtering in software because it  
would have to listen to too many multicast addresses.

In the case of a /48 it is of course simplest to forbid the use of  
either subnet 0x0000 or 0xffff. With something between /48 and /64, a  
bit from the checksum compensation bits in the IID can be copied into  
one of the subnet bits to detect the 0x0000 vs 0xffff occurrences.
_______________________________________________
Behave mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/behave

---

From: Rémi Després <[email-masked]>
Date: Wed, 26 Nov 2008 16:51:41 +0100

Magnus Westerlund  -  le (m/j/a) 11/26/08 10:48 AM:

Rémi Després skrev:

Margaret,

Margaret's proposal assumes that transport checksums are based on
16-bit One's complement, which essentially limits it to UDP and TCP. My
proposal doesn't change this.

Cheers,

RD

---

From: Margaret Wasserman <[email-masked]>
Date: Wed, 26 Nov 2008 10:54:57 -0500

On Nov 26, 2008, at 10:19 AM, Iljitsch van Beijnum wrote:
> contain 0xfe to pad the 48-bit MAC address to 64 bits,

I thought of this... In an actual EUI-64, the 10th nibble (second half  
of byte 5) is specifically prohibited from being either 0xE or 0xF.   
So, that would perfectly for EUI-64-based identifiers.  Unfortunately,  
when we wrote the Privacy Addresses spec, we remembered to have  
privacy addresses clear the "u" bit, but we didn't require that they  
do anything to make sure that the 10th nibble didn't take on an  
invalid value for an EUI-64.  Nor, did we indicate that these values  
were restricted for manual address configuration.  So, sadly, I don't  
think that this option is available to us in IIDs.

> or catch the top bits because u/l = u and g=1 should be uncommon,  
> although I don't think we want to forbid their use, we should keep  
> those for special use at some point in the future.

Yes, this is what I proposed, although it will result in destroying  
the value of the "u" bit for determining whether an IID is a  
universally scoped EUI-64.

> But if clashing is uncommon, then a NAT device could proxy DAD for  
> all the addresses that clash, although I'm afraid there is no way to  
> avoid having such a device do multicast filtering in software  
> because it would have to listen to too many multicast addresses.

It would also have to maintain state for this purpose, which has worse  
implications, IMO, than having the NAT66 box modify the transport  
layer header.

> either subnet 0x0000 or 0xffff. With something between /48 and /64,  
> a bit from the checksum compensation bits in the IID can be copied  
> into one of the subnet bits to detect the 0x0000 vs 0xffff  
> occurrences.

Yes, we could use subnet bits in this way if we have them, but that  
means that the NAT66 mechanism wouldn't work or would need to fall  
back to modifying transport layer checksums if the prefixes were /64.

I'm loathe to give up on the automatic checksum correction, because I  
think it is very slick, but I wonder if it will end-up being more  
complicated than its benefits are actually worth...

Margaret

---

From: Margaret Wasserman <[email-masked]>
Date: Wed, 26 Nov 2008 11:00:42 -0500

On Nov 26, 2008, at 10:51 AM, Rémi Després wrote:
> Margaret's proposal assumes that transport checksums are based on 16- 
> bit One's complement, which essentially limits it to UDP and TCP. My  

Not quite.  It assumes that the IPv6 pseudo-header checksum value in  
upper layer protocols will be calculated using 16-bit one's  
complement.  They could actually use any checksum mechanism they like  
for checking their own header and/or payload.  You are correct,  
though, that this is only a 16-bit one's complement correction.

The real problem here is that we are missing one bit...  We can move  
that problem around, but it doesn't go away...

Margaret

---

From: Iljitsch van Beijnum <[email-masked]>
Date: Wed, 26 Nov 2008 17:06:56 +0100

On 26 nov 2008, at 16:54, Margaret Wasserman wrote:

>> But if clashing is uncommon,

(because of the previous suggestions, with privacy addresses you would  
only hit the forbidden 0xffff one time out of 65536)

>> then a NAT device could proxy DAD for all the addresses that clash,  
>> although I'm afraid there is no way to avoid having such a device  
>> do multicast filtering in software because it would have to listen  
>> to too many multicast addresses.

> It would also have to maintain state for this purpose

I don't think so. It just has to listen for neigbor solicitations that  
match the addresses we want to disallow and then reply with a neighbor  
advertisement to make the remote system think the address is already  
taken.

> I'm loathe to give up on the automatic checksum correction, because  
> I think it is very slick, but I wonder if it will end-up being more  

I think the benefits are compelling. In the /48 case we don't have a  
problem if we sacrifice one subnet. Seems like a no brainer.

In the /48 - /64 case we have to sacrifice a subnet bit, which would  
hurt a bit more, and modify IIDs, which some people don't like. Here,  
there could be a tradeoff between keeping state or not. (The state  
only needs to be per address, not per session.) A good reason to avoid  
it would be that you can then have failover between NATs or asymmetric  
routing with different outgoing/incoming NATs.

In the /64 case it's probably not too problematic to keep the per host  
state although with selecting the bits carefully and the DAD trick  
it's still possible to get around that if desired.
_______________________________________________
Behave mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/behave

---

From: Margaret Wasserman <[email-masked]>
Date: Wed, 26 Nov 2008 11:50:55 -0500

Hi Iljitsch,

I think you've summed this up pretty well...  Sorry for not  
understanding your DAD trick the first time, but I understand now...

On Nov 26, 2008, at 11:06 AM, Iljitsch van Beijnum wrote:
> hurt a bit more, and modify IIDs, which some people don't like.  
> Here, there could be a tradeoff between keeping state or not. (The  
> state only needs to be per address, not per session.) A good reason  
> to avoid it would be that you can then have failover between NATs or  
> asymmetric routing with different outgoing/incoming NATs.
>
> In the /64 case it's probably not too problematic to keep the per  
> host state although with selecting the bits carefully and the DAD  
> trick it's still possible to get around that if desired.

However, I've actually been thinking about a different trick to make  
this work...

What if we add the correction value to the lowest order set of 16 IID  
bits that isn't 0xFFFF, starting with bytes 7&8 of the IID (address  
bits 113-128) and moving backwards from there?  If the result of that  
addition is to set the 16-bits to 0xFFFF, we set them to 0x0000  
instead (which we know won't change the checksum or the results of the  
reversal algorithm, this being the source of our issue in the first  
place).  [This is necessary to allow reversal, and so that the right  
thing will happen if we have more than one NAT66 in an outbound path].

In most cases, the correction would be written in bytes 7 & 8.  In one  
time out of 65535, it would be written in bytes 5 & 6 (which won't  
contain 0xFFFF in a valid univeral IID),  in an astronomically small  
number of cases, the correction would be written in bits 3 & 4.  If  
someone played strange games with manual configuration, it might be  
written in bits 1 & 2, which can't legally be 0xFFFF if bytes 5 & 6  
were 0xFFFF, because this can't be an actual EUI-64, so the "u" bit  
should be 0.  In this _extremely_ unlikely cases, we might end-up  
creating an IID that isn't universal but has the universal bit set,  
but the chance of this happening is microscopically small, and we know  
that we'll already see this situation when administrators choose to  
use prefixes that are longer than /64, or when someone makes a mistake  
with manual configuration. so we better not build a world that will  
melt down if this happens very rarely.  If the whole IID is ones, log  
an error somewhere if we can, and just throw the packet away because  
it has an illegal IID.

To restore the value, we'd look at bytes 7 & 8, if they are 0xFFFF  
then they can't be the checksum correction value, so we move to bytes  
5&6, etc.  When we find the correction value (the first 16-bit field  
we check that isn't 0xFFFF) we perform the reverse algorithm as  
specified in the current spec.  If we ever see an IID of  
0xFFFFFFFFFFFFFFFF in this direction, we also throw the packet away.

This gains us back a bit, because an IID is prohibited from being  
0xFFFFFFFFFFFFFFFF according to the IPv6 specifications.

We could either use this mechanism all of the time, or we could use  
the subnet bits (with the 0xFFFF restriction) when the prefix is /48  
or shorter.

What do you think?

Margaret