Subject: Re: destination option update

From: Erik Nordmark <[email-masked]>
Date: Fri, 15 Dec 2000 14:08:03 -0800 (PST)

> The working group has just decided the flawn is not in the specs but
> in the advanced API then either:
>  - or we found a good way to encode positions (I have no idea of how)
>  - or we arbitrary restrict the advanced API expressiveness to
>    some common cases (as it is done today but we already need to
>    add a new position for destination option headers).
> As I don't know if the first goal is possible to archieve I suggest
> to go to the second if no progress is done before a reasonnable delay.

Adding a 3rd set of options to receive a 3rd placement of destination
options in the advanced API probably isn't too hard.
However, I'm a bit concerned on how to define the semantics
when there are 1 or 2 destopt headers in the packet.

The current semantics is that IPV6_RTHDRDSTOPTS contains the destination
options before a routing header, which only make sense when there
is a routing header and a destopts header that preceeds the routing header.
When there is no routing header IPV6_DSTOPTS contains the destination options
header, and when there is a routing header IPV6_DSTOPTS contains the
destination options header after the routing header. So basically this
separates out the destination options header into those that appear before and
after a routing header. I don't think rfc2292bis says anything about the case
when there are multiple destination options headers in each of these two
logical locations.

The above is quite complex to describe to the user of the API.
Adding another IPV6_DSTOPTSAFTERIPSEC(?) concept that is conditional 
would make it even harder to describe.

So ...
perhaps it would be easier if we instead passed these routing headers
to the application in the order they where received with all of them
being tagged with the same ancillary data type (IPV6_DSTOPTS)?

This would still have some problems since certain extension headers
(fragmentation, AH, ESP) aren't passed up to the application.
Thus if the packet has
	IP header
	dstopt
	frag hdr
	dstopt
	ESP
	dstopt

or if it has
	IP header
	dstopt
	frag hdr
	dstopt
	dstopt
	ESP

the application would in both cases see 3 IPV6_DSTOPT ancillary data items 
with no intervening ancillary data items, so the application can't tell
the important difference.

The upshot of this is that either way we go the receive side interface
will be quite complex, unless we somehow can represent the location of
the extension headers (especially AH and ESP) that have been removed as
part of processing the packet.

Is that the path we should take or are there better suggestions?

   Erik

--------------------------------------------------------------------
IETF IPng Working Group Mailing List
IPng Home Page:                      http://playground.sun.com/ipng
FTP archive:                      ftp://playground.sun.com/pub/ipng
Direct all administrative requests to [email-masked]
--------------------------------------------------------------------

---

From: Francis Dupont <[email-masked]>
Date: Mon, 18 Dec 2000 19:01:05 +0100

In your previous mail you wrote:

=> I agree but I can intepret Steve's comment as this is not the good
solution. But I don't know a good way to denote the position for
individual header.
   
   I don't think rfc2292bis says anything about the case
   when there are multiple destination options headers in each of these two
   logical locations.
   
=> merge them???

=> intermediate and final should give better names...

   So ...
   
=> this is the solution I use in my current code: a big buffer with the
whole option array but:
 - this is less flexible than individual header management (for instance
   the good way to insert a header is to pickup the current array before).
 - this doesn't work well with "transparent" headers like fragmentation
   or IPsecs.

=> exactly my second concern.

=> I have followed this path then I can say we should look for a better
idea...

Thanks

[email-masked]

PS: the issue is for the API itself, in the kernel you can add zero length
place holders in the header chain (you should do it according to RFC 2401
for incomming IPsec headers). Perhaps the good solution is to manage a
stack of headers directly (pop/push/gettop) with transparent headers too
(ie. to push a fragmentation header will only indicate the relative position
of adjacent headers)?
--------------------------------------------------------------------
IETF IPng Working Group Mailing List
IPng Home Page:                      http://playground.sun.com/ipng
FTP archive:                      ftp://playground.sun.com/pub/ipng
Direct all administrative requests to [email-masked]
--------------------------------------------------------------------

---

From: Jun-ichiro itojun Hagino <[email-masked]>
Date: Tue, 19 Dec 2000 08:34:52 +0900

>=> exactly my second concern.

	one question - maybe i have lost some context.
	we are talking about socket API.  is it really necessary
	for user applications to be able to transmit arbitrary AH/ESP/fragment
	header?

	even for raw IP socket, i think it reasonable to forbid users
	from attaching arbitrary AH/ESP/fragment header (i.e. to say that
	they are "kernel" thingie).

itojun

---

From: Robert Elz <[email-masked]>
Date: Wed, 20 Dec 2000 15:42:50 +1100

Date:        Mon, 18 Dec 2000 19:01:05 +0100
    From:        Francis Dupont <[email-masked]>
    Message-ID:  <[email-masked]>

  |    when there are multiple destination options headers in each of these two
  |    logical locations.
  |    
  | => merge them???

Ugh!

  | => this is the solution I use in my current code: a big buffer with the
  | whole option array but:

Good.

  |  - this is less flexible than individual header management (for instance
  |    the good way to insert a header is to pickup the current array before).

It is more flexible, but perhaps more complex to handle.

  |  - this doesn't work well with "transparent" headers like fragmentation
  |    or IPsecs.
  | 
  |    This would still have some problems since certain extension headers
  |    (fragmentation, AH, ESP) aren't passed up to the application.
  | 
  | => exactly my second concern.

Why?   I don't mean why is it a problem, but why are those headers
not passed up to the application?   Or perhaps more directly, why
should they not be passed up to the application?   Sure, in general
they (the frag header in particular) doesn't supply much in the
way of information, and because the different frag headers on the
different frags all contain different data there's no way or reason
to send all of that - but the fact that a frag header was present, and
where it occurred in the chain of headers seems like useful information
to me (to those comparatively few processes that actually care about
any of this and aren't just doing read/write down a TCP stream anyway).

I would think that much the same would be true of AH & ESP (though those
headers are beyond where I usually venture into the dark side...) - at the
very least knowing that onet was present, and where it occurred, ought
be useful.

Similarly for sending - the kernel interface might well ignore whatever the
application stuck in one of these headers (frag, AH, ESP - perhaps others)
but it could use the presence of such a header to indicate where it should
place a header of equivalent type, constructed however it would have been
constructed without this method of determining its location.

The "I might be able to use this for DOS attacks" is nonsense - there are
plenty of easier ways to generate arbitrary packets on a wire than worrying
about how to make some arbitrary IPv6 stack do what you want via its API.

kre

---

From: Francis Dupont <[email-masked]>
Date: Wed, 20 Dec 2000 10:54:33 +0100

Why?

=> mostly because an application cannot do something useful with them...
But the positions of these "transparent" headers are important then
I believe a stack is the best data structure.

   I don't mean why is it a problem, but why are those headers
   not passed up to the application?

=> because they have a functional meaning, they doesn't carry information
by themselves.

   Or perhaps more directly, why should they not be passed up to the
   application?

=> it is more an usage than other (ie. no deep reason for a "should not")

   but the fact that a frag header was present, and where it occurred
   in the chain of headers seems like useful information to me.
   
=> we agree about what the API should provide. We have just to find
the best (ie. simplest) way to do this.

=> yes

=> we agree.

=> someone (Itojun?) mentioned BPF (:-)...

Thanks

PS: we need:
 - a way to get the header stack as it is received
 - a way to get the header stack to use for replies (ie. with only
   bidirectional items, mostly authenticated routing header).
   Should we do this in the kernel (this function exists for TCP).
 - pop/push operations
 - a set/get for the top of the stack (pop/push can do this too?)
 - the structure describing the header can be the header with
   its type, its length in the stack (zero for transparent headers).
   The effective length is a parameter of set/getsockopt() or ancillary
   data.
--------------------------------------------------------------------
IETF IPng Working Group Mailing List
IPng Home Page:                      http://playground.sun.com/ipng
FTP archive:                      ftp://playground.sun.com/pub/ipng
Direct all administrative requests to [email-masked]
--------------------------------------------------------------------

---

From: Michael Thomas <[email-masked]>
Date: Wed, 20 Dec 2000 07:31:31 -0800 (PST)

>    constructed without this method of determining its location.

  I tend to doubt that sending the AH or ESP headers up the
  stack is especially useful. What the application needs to
  know that I can think of is:
 
  1) What security policy was applied in receiving the packet
  2) What IPsec credentials were bound to #1

  The first one allows an application to know pertinent information
  like whether or not the packet was encrypted/authenticated so
  that it could perhaps reject unencrypted packets. More generally,
  the application may want to place finer grain control based on
  application layer knowledge than the SDP allows, or can express.

  The second is to stop a forgery attack; if there is no way for
  an application to query about an incoming packet/flow as to which
  credentials were used, a trivial application layer forgery attack
  could be mounted by just changing an application layer identifier
  which is not bound to a cryptographic identity (eg, the From:
  address in SMTP).

  I'm pretty much at a loss as to what seeing the actual headers
  would gain for run of the mill (read: non-packet sniffers :-)
  applications.

		Mike

---

From: Robert Elz <[email-masked]>
Date: Thu, 21 Dec 2000 20:04:42 +1100

Date:        Wed, 20 Dec 2000 07:31:31 -0800 (PST)
    From:        Michael Thomas <[email-masked]>
    Message-ID:  <[email-masked]>

  |   I tend to doubt that sending the AH or ESP headers up the
  |   stack is especially useful.

I think what you mean is that applications are unlikely to find the
contents of those options (as they would be sent on the wire) useful
- and I'm not going to argue about that, I don't know nearly enough
about them.

However, something needs to inform the application that the header
was present - for applications that actually need to know, as distinct
from a "dumb" TCP application that just wants non authenticated packets,
or packets not correctly encrypted, dropped, and after that simply assumes
that the relevant option(s) appear correctly in all packets.

On easy way to do that is to leave the header in the (ancillary) data
passed up to the application - then it is obvious to the application
that the header was there - further, it is also obvious what other
headers were encrypted in the case of ESP (the ones that follow the
ESP header, and not the ones that precede it).

What is in the data part of those headers may well be totally irrelevant
to the application (I don't know) - if that is the case, then in the
header passed back to the application could be the information that the
application does want to know (or at least, that is one possible API).
That is ...

  |   1) What security policy was applied in receiving the packet
  |   2) What IPsec credentials were bound to #1

The stack could delete the original contents of the header, and
instead place that (kind of) information there.

Similarly, when sending, the application could pass its requirements
in the data segment of those headers, which the stack would use to
know where in the header sequence the header should be inserted, and
what security policies to apply to the packet - then it would replace
the application's supplied headers with ones formatted as they're
supposed to be transmitted over the wire.

Now I'm certainly not saying that that's the only reasonable API, not
even that it would be a good choice for the API - but it is one
possibility (on the assumption that the wire format content of the
headers isn't useful to the vast majority of those applications
which would be using this API at all).

Please, don't get stuck with the assumption that the interface between
the application and the stack needs to be an almost bit for bit
analog of the wire interface - the two of them are achieving quite
different objectives.  The point of the API is to pass information to
the stack (and retrieve it from incoming packets) so that the stack can
then generate the packets that cause the protocol to effect the intent
of the application.

kre