Subject: [advanced API] how to get the destination address for IPV6_RECVPATHMTU

From: JINMEI Tatuya / 神明達哉<[email-masked]>
Date: Mon, 06 Nov 2000 00:39:39 +0900

I need a clarification about the IPV6_PATHMTU ancillary data item
defined in draft-ietf-ipngwg-rfc2292bis-01.txt. The draft does not
(explicitly) mention how the application knows the corresponding
destination address for the returned MTU value. Which is correct?

1. this option has its meaning for a connected socket only. The
   destination is the foreign address of the socket.
2. the destination address should be specified in the msg_name member
   returned by the corresponding recvmsg() call.
3. the current spec is buggy. The ancillary data should contain the
   socket address structure for the destination.
4. others

In any case, I think some text about this point should be added in the
next revision of the spec. Thanks,

					JINMEI, Tatuya
					Communication Platform Lab.
					Corporate R&D Center, Toshiba Corp.
					[email-masked]
--------------------------------------------------------------------
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: Erik Nordmark <[email-masked]>
Date: Mon, 6 Nov 2000 13:11:07 -0800 (PST)

>    socket address structure for the destination.

The spec is clearly incomplete in this area.
I do think we want this to work for unconnected datagram sockets i.e. 1 is
not an option.

Does the implementors have any preferences between #2 and #3?
Doing #3 would require defining a data structure containing an MTU field
plus a socketaddr_in6.

  Erik

---

From: Francis Dupont <[email-masked]>
Date: Tue, 07 Nov 2000 12:00:33 +0100

In your previous mail you wrote:

=> but 1 (connected sockets) should work of course.

=> by problem with #3 is the path MTU is a property of the path, not
of an address, ie. with a routing header the path MTU can be different.
I know this is not implemented like that (ie. pMTU are cached by destination
address and if someone plays with a routing header one can spuriously
change the pMTU :-) but it should then we have to keep the distinction...

Thanks

[email-masked]

PS: rfc2292bis is more than expired today...

---

From: JINMEI Tatuya / 神明達哉<[email-masked]>
Date: Thu, 09 Nov 2000 01:32:54 +0900

>>>>> On Tue, 07 Nov 2000 12:00:33 +0100, 
>>>>> Francis Dupont <[email-masked]> said:

> change the pMTU :-) but it should then we have to keep the distinction...

I personally like #3, because it seems the most flexible one (e.g. to
contain the real "path" including all intermediate nodes - although
I'm not sure if this kind of stuff is worth implementing despite of
its complexity). But this will affect existing implementations, so I
won't insist on this idea. I vote for #3 if pre-implementors of this
option do not object. (We've not implemented this option yet.)

> PS: rfc2292bis is more than expired today...

Yes, but we've finally seen the latest one.

					JINMEI, Tatuya

---

From: JINMEI Tatuya / 神明達哉<[email-masked]>
Date: Tue, 14 Nov 2000 10:18:30 +0900

Hello,

I'm now considering UDP applications that are sensitive to path MTU
(toward the destinations). I recalled a discussion about a new socket
option "IPV6_USEMTU", which allowed an application to specify an
appropriate path MTU for packets sent from the application. I checked
the archive of this list in April 2000, and, to my suprise, the
discussion suddenly disappeared without any consensus.

I think it is a good idea, and even essential for such UDP
applications. What was wrong with the option? Or can we raise the
option again as a clarification for rfc2292bis?

Thanks,

					JINMEI, Tatuya

---

From: Francis Dupont <[email-masked]>
Date: Tue, 14 Nov 2000 09:42:19 +0100

=> today only IPV6_USE_MIN_MTU seems to be defined, implemented and
used (for instance by BIND and racoon, the KAME IKE daemon).
I don't know if IPV6_USEMTU as you define is very useful but the
getsockopt() counterpart (which gives the actual path MTU) *is* useful.
Perhaps the getsockopt() with a standard way to disable fragmentation
is enough (it should be enough for a traceroute_pmtu6)?

Regards

---

From: Yves Legrandgerard <[email-masked]>
Date: Tue, 14 Nov 2000 10:43:32 +0100 (CET)

> is enough (it should be enough for a traceroute_pmtu6)?

I agree, we need two things:
1) a new option for getsockopt() to get the actual path MTU (there is no
standard way to do that).
2) a new option for setsockopt() to disable fragmentation (until now, to do
that, we have to use non standard option like: IP_HDRINCL).
These two new options would be sufficient to code "traceroute_pmtu6" (in fact,
only one of them is necessary: 1) or 2))
Best regards,

----------------------------------
Yves Legrandgérard
E-Mail: [email-masked]
Date: 14-Nov-00
Time: 10:18:20
----------------------------------
--------------------------------------------------------------------
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: JINMEI Tatuya / 神明達哉<[email-masked]>
Date: Thu, 16 Nov 2000 22:37:46 +0900

>>>>> On Tue, 14 Nov 2000 09:42:19 +0100, 

> is enough (it should be enough for a traceroute_pmtu6)?

My main concern is about UDP applications that can't divide outgoing
data into multiple packets but do not want to fragment the packet in a
(much) smaller size than the path MTU. Possible examples would be NFS
and DHCP. I admit that NFS may not be a good example, because in UNIX
systems, NFS is typically implemented in the kernel.

					JINMEI, Tatuya

---

From: JINMEI Tatuya / 神明達哉<[email-masked]>
Date: Thu, 16 Nov 2000 22:40:19 +0900

>>>>> On Tue, 14 Nov 2000 10:43:32 +0100 (CET), 
>>>>> Yves Legrandgerard <[email-masked]> said:

> standard way to do that).

Applications can dynamically grab the path MTU by the IPV6_RECVPATHMTU
socket option (upon receiving an ICMPv6 packet toobig error).

					JINMEI, Tatuya

---

From: JINMEI Tatuya / 神明達哉<[email-masked]>
Date: Thu, 16 Nov 2000 22:52:31 +0900

>>>>> On Thu, 09 Nov 2000 01:32:54 +0900, 
>>>>> JINMEI Tatuya <[email-masked]> said:

> option do not object. (We've not implemented this option yet.)

I've implemented the IPV6_RECVPATHMTU option adopting #3 approach. I
defined a new structure "ip6_mtuinfo" as ancillary data item for
IPV6_PATHMTU as follows:

struct ip6_mtuinfo {
	u_int32_t ip6mtu_mtu;
	struct sockaddr_in6 ip6mtu_dst;
};

I used the sockaddr_in6 structure for the ip6mtu_dst (not just
in6_addr) in order to support scoped addresses. As Francis pointed
out, the finally destination does not necessarily give complete
information of a "path", but I think it is usually enough in a
practical point of view. We could also add some additional data after
the ip6mtu_dst if we wanted.

By the way, the rfc2292bis draft seems a bit ambiguous on the byte
order of the 32-bit MTU value. Like other fields used in the spec, I
treated the value in the network byte order, but the spec should
clearly specify the byte order.

					JINMEI, Tatuya

---

From: Hideaki YOSHIFUJI (吉藤英明) <[email-masked]>
Date: Thu, 16 Nov 2000 23:04:01 +0900

> 	struct sockaddr_in6 ip6mtu_dst;

How do you think about alignment?

-- 
Hideaki YOSHIFUJI @ USAGI Project  <[email-masked]>
PGP5i FP: F731 6599 5EB2 BBA7 1515  1323 1806 A96F 5700 6B25 
--------------------------------------------------------------------
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: JINMEI Tatuya / 神明達哉<[email-masked]>
Date: Thu, 16 Nov 2000 23:39:42 +0900

>>>>> On Thu, 16 Nov 2000 23:04:01 +0900, 
>>>>> Hideaki YOSHIFUJI <[email-masked]> said:

> How do you think about alignment?

Currently, I only consider 32-bit alignment, but I'm open to hear
others' opinions.

					JINMEI, Tatuya

---

From: [email-masked] (Niels M�ller)
Date: 16 Nov 2000 17:23:14 +0100

> 	struct sockaddr_in6 ip6mtu_dst;

...

> clearly specify the byte order.

Is this value ever transmitted on the wire? If not, it should probably
use host byte order.

/Niels

---

From: Jun-ichiro itojun Hagino <[email-masked]>
Date: Fri, 17 Nov 2000 00:09:34 +0900

>Currently, I only consider 32-bit alignment, but I'm open to hear

	as this structure is host-local (will not appear on wire) there's no
	serious issue with alignment, I believe.
	ip6mtu_dst will be aligned to whatever look natural to the machine
	based on sockaddr_in6 declaration.

itojun

---

From: Francis Dupont <[email-masked]>
Date: Thu, 16 Nov 2000 17:58:40 +0100

=> I disagree, I'd like to be able to defined struct in6_addr as a pair
of 64 bit integers one day (:-)!

=> please do something similar to in6_pktinfo...

---

From: JINMEI Tatuya / 神明達哉<[email-masked]>
Date: Fri, 17 Nov 2000 02:12:18 +0900

>>>>> On Mon, 6 Nov 2000 13:11:07 -0800 (PST), 
>>>>> Erik Nordmark <[email-masked]> said:

> I do think we want this to work for unconnected datagram sockets i.e. 1 is

Then, I believe the spec should clearly state the point, because (for
example) BSD derived kernels do not notify unconnected sockets of
errors.

					JINMEI, Tatuya

---

From: JINMEI Tatuya / 神明達哉<[email-masked]>
Date: Fri, 17 Nov 2000 01:34:37 +0900

>>>>> On 16 Nov 2000 17:23:14 +0100, 
>>>>> [email-masked] (Niels Möller) said:

> Is this value ever transmitted on the wire?

No, but the MTU value would be copied from the corresponding ICMPv6
error message, so I don't surprise if an implementation keeps the
field in the network byte order.

However, I don't stick to using the network byte order. The point is
that we should clearly state the byte order in the spec.

					JINMEI, Tatuya

---

From: Yves Legrandgerard <[email-masked]>
Date: Thu, 16 Nov 2000 18:55:04 +0100 (CET)

> socket option (upon receiving an ICMPv6 packet toobig error).

Is that mean, when IPV6_RECVPATHMTU option is setted (UDP/raw socket), that
fragmentation is disabled ? 

Date: 16-Nov-00
Time: 18:46:04

---

From: Matti Aarnio <[email-masked]>
Date: Thu, 16 Nov 2000 16:52:09 +0200

> Currently, I only consider 32-bit alignment, but I'm open to hear

	My main tool for IPv6 related development is 64-bit
	Alpha, and I do presume that within a year or two we
	will have ia64 systems to consider as well.

> 					[email-masked]

/Matti Aarnio  <[email-masked]> <[email-masked]>

---

From: Francis Dupont <[email-masked]>
Date: Thu, 16 Nov 2000 18:23:14 +0100

=> or if there is no ICMPv6 error the MTU value would be copied from
the outgoing interface MTU parameter which has no reason to be
in the network byte order (this will only make comparaison harder).

=> I agree and I vote for the host byte order.

Thanks

---

From: Erik Nordmark <[email-masked]>
Date: Thu, 16 Nov 2000 11:42:34 -0800 (PST)

> example) BSD derived kernels do not notify unconnected sockets of

I agree completely that, once we know what we want the API to look like,
we need to make this very clear in the spec.

  Erik

---

From: Erik Nordmark <[email-masked]>
Date: Thu, 16 Nov 2000 14:46:36 -0800 (PST)

> fragmentation is disabled ? 

No, I don't think so.
IPV6_RECVPATHMTU is so that e.g. UDP applications that do packetization
can determine when the path MTU changes and adjust the size of the
packets they are sending.

Should we just define the semantic equivalent of setting IP_DF on
a raw socket with IP_HDRINCL set for IPv6? (IPV6_DONTFRAG?)

This would allow a traceroute to detect the MTU, and it would allow
the above UDP example application to avoid "accidental" fragmentation
by a too helpful IP/UDP layer. (The IP/UDP layer needs to be helpful for
UDP applications which are not involved in PMTU discovery.)

  Erik

---

From: Jun-ichiro itojun Hagino <[email-masked]>
Date: Fri, 17 Nov 2000 06:22:13 +0900

>of 64 bit integers one day (:-)!

	I don't understand what you are saying, at all.
	ip6mtu_dst will be aligned to the alignment whatever necessary for us,
	depending on how your compiler aligns it.  sockaddr_in6 includes
	struct in6_addr (sin6_addr), and if you declare in6_addr like:
		struct in6_addr {
			union {
				uint8_t foo8[16];
				uint16_t foo16[8];
				uint32_t foo32[4];
				uint64_t foo32[2];
			} foo;
		};
	ip6mtu_dst.sin6_addr should be aligned to 64bit boundary.

itojun

---

From: Erik Nordmark <[email-masked]>
Date: Thu, 16 Nov 2000 13:45:38 -0800 (PST)

> >   	based on sockaddr_in6 declaration.

You are correct that the compiler will take care of this by inserting
any necessary padding in the data structure.
I think there were some concerns about data structure size when sockaddr_in6
was defined which is why the flowid was placed before the address. This
ensured that even if in6_addr is 64 bit aligned the compiler wouldn't
need to insert a pad of 32 bits.

I don't know if there is a concern of wasting space in the ip6_mtuinfo
structure by having compiler inserted padding. This can be avoided 
by placing the mtu after the sockaddr_in6.

  Erik

---

From: Yves Legrandgerard <[email-masked]>
Date: Fri, 17 Nov 2000 14:50:38 +0100 (CET)

> a raw socket with IP_HDRINCL set for IPv6? (IPV6_DONTFRAG?)

[ylg]=> Yes, that's exactly wee need, a socket option like :
        int on = 1;

        setsockopt(fd, IPPROTO_IPV6, IPV6_DONTFRAG, &on, sizeof(&on));
to disable fragmentation for UDP/Raw sockets (and of course on = 0 to
(re)enable fragmentation which would be the default).

> UDP applications which are not involved in PMTU discovery.)

As we said in a previous message, F. Dupont and me, a useful option would be a
new option to getsockopt() to get the outgoing MTU. For example, it helps
tracemtu to discover the right mtu to start (otherwise, we have to set
IPV6_DONTFRAG option, and try successive MTU (choosen in a list of possible
MTU, ordered decreasingly) until we don't get EMSGSIZE error (an other pb :
does exist such a list, i.e. the (right) list of all possible MTUs?).

Regards,

Date: 17-Nov-00
Time: 14:24:22

---

From: Erik Nordmark <[email-masked]>
Date: Fri, 17 Nov 2000 07:18:14 -0800 (PST)

> (re)enable fragmentation which would be the default).

I'll add it to 2292bis.

> As we said in a previous message, F. Dupont and me, a useful option would be
> a new option to getsockopt() to get the outgoing MTU. For example, it helps

Presumably such an option needs to take a sockaddr_in6 as an argument
to specify the destination. We can reuse the proposed ip6_mtuinfo structure
for this.

Do you care to know whether the kernel has path mtu information or
is just returning the mtu of the outgoing interface?

  Erik

---

From: Yves Legrandgerard <[email-masked]>
Date: Fri, 17 Nov 2000 17:59:33 +0100 (CET)

>> (re)enable fragmentation which would be the default).

[ylg]=> Nice, thanks.

> is just returning the mtu of the outgoing interface?

[ylg]=> No, I don't care. I'm only interessed in outgoing interface mtu. I
think that your proposal to reuse the proposed ip6_mtuinfo structure is a good
idea.

Regards,

Time: 17:49:40

---

From: JINMEI Tatuya / 神明達哉<[email-masked]>
Date: Sat, 18 Nov 2000 02:02:19 +0900

>>>>> On Thu, 16 Nov 2000 14:46:36 -0800 (PST), 
>>>>> Erik Nordmark <[email-masked]> said:

> packets they are sending.

My understanding is the same as yours.

> a raw socket with IP_HDRINCL set for IPv6? (IPV6_DONTFRAG?)

I think this type of option can be useful, but I still think the
IPV6_USEMTU option (which allows an application to specify the path
MTU for an outgoing packet) is useful as well. And, if we take this
approach, prohibiting fragment can be implemented as a special case of
the option (i.e, setting a very large value as the MTU). What do you
think of this?

					JINMEI, Tatuya

---

From: Yves Legrandgerard <[email-masked]>
Date: Fri, 17 Nov 2000 19:06:56 +0100 (CET)

On 17-Nov-00 JINMEI Tatuya / $B?@L@C#:H(B wrote:
> Then why not just look up the routing table and get the MTU of the
> outgoing interface? I admit that a single operation to do that would
> be convenient, but I personally don't think we have to add a separate
> socket option for this particular purpose.
> 

You're right but, as you mentionned, it's not a single operation. I still think
that it would be useful to get the outgoing interface MTU with a single
operation not only for the particular case of tracemtu (I admit that create a
new option just for a particular case is a bad idea) because UDP/Raw
applications eventually need to know outgoing interface MTU when they have
disabled fragmentation.

Regards,

Time: 18:50:12

---

From: [email-masked]
Date: Sat, 18 Nov 2000 03:27:02 +0900

>=> if in6_addr is defined as four 32 bit integers then the compiler
>won't add padding. If it is defined as a pair of 64 bit integers the
>compiler may add 32 bits for padding if the MTU field is before and
>the architecture needs 64 bit alignment for 64 bit quantities.

	well, i'd like to know how far do we need to go.  think of binary
	compatibility with 32/64/128/256bit CPUs, i believe we cannot do
	much here anyways.

itojun

---

From: [email-masked]
Date: Sat, 18 Nov 2000 03:33:39 +0900

>=> no, my concern is binary compatibility for the same 32 bit CPU with
>two different definitions of struct in6_addr.

	maybe i wrongly assumed that you are talking about sparc64.  i still
	don't understand how generic your problem is...

itojun

---

From: Francis Dupont <[email-masked]>
Date: Fri, 17 Nov 2000 17:23:23 +0100

=> but we (you and me) have not the last definition, I don't know your
reasons but I tried and got too many problems.

   			} foo;
   		};
   
Regards

---

From: JINMEI Tatuya / 神明達哉<[email-masked]>
Date: Sat, 18 Nov 2000 02:07:27 +0900

>>>>> On Fri, 17 Nov 2000 17:59:33 +0100 (CET), 

					JINMEI, Tatuya

---

From: Francis Dupont <[email-masked]>
Date: Fri, 17 Nov 2000 19:33:15 +0100

---

From: Francis Dupont <[email-masked]>
Date: Fri, 17 Nov 2000 19:25:51 +0100

> socket option for this particular purpose.

=> I agree, it should be a library function (still in advanced API
but not as a getsockopt()).

PS: on some systems getsockopt() is not supposed to have an argument
(ie. optval points only to a buffer for the result) then be careful.
--------------------------------------------------------------------
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: Erik Nordmark <[email-masked]>
Date: Fri, 17 Nov 2000 16:21:19 -0800 (PST)

> the option (i.e, setting a very large value as the MTU). What do you

If we want an IPV6_USEMTU option I think that needs to be separate from
prohibiting fragmentation, since I think the overloading you propose would
be confusing.

If the path MTU is 2000 bytes and the interface MTU is 8000 bytes
I would expect that an IPV6_USEMTU value between 2000 and 8000 would 
transmit an unfragmented packet. I assume your proposal is that when the
IPv6_USEMTU value is set to a number larger than 8000 this would cause
the packet to be dropped (and an IPV6_PATHMTU sent up as ancillary data
if the socket had IPV6_RECVPATHMTU enabled). Thus setting IPV6_USEMTU
to 2^^32-1 would be the same as disabling fragmentation.

But when using IPV6_USEMTU as you propose would the MTU be for all
destination addresses on the socket? Or would IPV6_USEMTU carry
an address in addition to an mtu?

Do you have an example of an application which might need such a feature?

  Erik

---

From: Erik Nordmark <[email-masked]>
Date: Fri, 17 Nov 2000 16:28:00 -0800 (PST)

This is what I've edited together so far.
Note that the IPV6_PATHMTU option is used both as ancillary data (when
IPV6_RECVPATHMTU is enabled) and with getsockopt to retrieve the 
current path MTU value for a destination.

Comments?
   Erik

11.1.  Sending with the Minimum MTU

   Some applications might not want to incur the overhead of path MTU
   discovery, especially if the applications only send a single datagram
   to a destination.  A potential example is a DNS server.

   This specification defines a mechanism to avoid path MTU discovery by
   sending at the minimum IPv6 MTU [RFC-2460].  If the packet is larger
   than the minimum MTU and this feature has been enabled the IP layer
   will fragment to the minimum MTU.  This can be enabled using the
   IPV6_USE_MIN_MTU socket option.

       int  on = 1;
       setsockopt(fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU, &on, sizeof(on));

   By default, this socket option is disabled.  Setting the value to 0
   also disables the option.  This option can also be sent as ancillary
   data.

11.2.  Sending without fragmentation

   In order to provide for easy porting of existing UDP and raw socket
   applications IPv6 implementations will, when originating packets,
   automatically insert a fragment header in the packet if the packet is
   too big for the path MTU.

   Some applications might not want this behavior.  An example is
   traceroute which might want to discover the actual path MTU.

   This specification defines a mechanism to turn off the automatic
   inserting of a fragment header for UDP and raw sockets.  This can be
   enabled using the IPV6_DONTFRAG socket option.

       int on = 1;

   By default, this socket option is disabled.  Setting the value to 0
   also disables the option i.e. reverts to the default behavior of
   automatic inserting.  This option can also be sent as ancillary data.

11.3.  Path MTU Discovery and UDP

   UDP and raw socket applications need to be able to  determine the
   "maximum send transport-message size" (Section 5.1 of [RFC-1981]) to
   a given destination so that those applications can participate in
   path MTU discovery.  This lets those applications send smaller
   datagrams to the destination, avoiding fragmentation.

   This is accomplished using a new ancillary data item (IPV6_PATHMTU)
   which is delivered to recvmsg() without any actual data.  The
   application enable the receipt of IPV6_PATHMTU ancillary data items
   by enabing IPV6_RECVPATHMTU.

       int  on = 1;
       setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPATHMTU, &on, sizeof(on));

   By default, this socket option is disabled.  Setting the value to 0
   also disables the option.

   When the application is sending packets too big for the path MTU
   recvmsg will return zero (indicating no data) but there will be a
   cmsghdr with cmsg_type set to IPV6_PATHMTU, and cmsg_len will
   indicate that cmsg_data is 4 bytes long.  CMSG_DATA will point to a
   struct ip6_ carrying the path MTU to use together with the IPv6
   destination address.

       struct ip6_mtuinfo {
         struct sockaddr_in6 ip6m_addr;    /* dst IPv6 address including scope
*/
         unsigned int        ip6m_mtu;     /* path MTU in host byte order */
       };

   XXX What about more complex paths e.g. when using a routing header?

11.4.  Determining the current path MTU

   Some applications might need to determine the current path MTU e.g.
   applications using IPV6_RECVPATHMTU might want to pick a good
   starting value.

   This specification defines a socket option to retrieve the current
   path MTU value for a given destination address.  If the IP layer does
   not have a cached path MTU value it will return the interface MTU for
   the interface that will be used when sending to the specified IPv6
   address.

   This information is retrived using IPV6_PATHMTU.

       struct ip6_mtuinfo mtuinfo;
       mtuinfo.ip6m_addr = addr;    /* address */
       getsockopt(fd, IPPROTO_IPV6, IPV6_PATHMTU, &mtuinfo, sizeof(&mtuinfo));

---

From: Erik Nordmark <[email-masked]>
Date: Fri, 17 Nov 2000 16:29:30 -0800 (PST)

> (ie. optval points only to a buffer for the result) then be careful.

Good point. getsockopt only does a copyout from the kernel.

Do you have a proposal for a name of a function which retrieves the
path MTU for a destination/path?

   Erik

---

From: JINMEI Tatuya / 神明達哉<[email-masked]>
Date: Sat, 18 Nov 2000 16:15:34 +0900

>>>>> On Fri, 17 Nov 2000 16:28:00 -0800 (PST), 

> 11.2.  Sending without fragmentation

We might have to clarify what happens if the application disables
fragmentation, but sends a larger packet than the MTU of the outgoing
interface. For example, just return an EMSGSIZE error, return an
IPV6_PATHMTU ancillary data item (if the application sets
IPV6_RECVPATHMTU beforehand), or both...

>    indicate that cmsg_data is 4 bytes long.  CMSG_DATA will point to a

Now we define and use struct ip6_mtuinfo, thus the size of cmsg_data
is not 4 bytes, but (at least) sizeof(struct ip6_mtuinfo).

>    struct ip6_ carrying the path MTU to use together with the IPv6

"mtuinfo" is missed after "ip6_".

>          unsigned int        ip6m_mtu;     /* path MTU in host byte order */

Is "unsigned int" appropriate here (I'm just wondering, not sure on
this)?

And, as I said in a pervious message, the draft should clearly state
that this ancillary data should be passed to every socket that wants,
even if the socket is non-connected. I'd propsose the following
paragraph to be added.

   This cmsghdr will be passed to every socket that sets the
   IPV6_RECVPATHMTU socket option, even if the socket is
   non-connected. Note that this also means an application that sets
   the option may get the ancillary data upon a too big message sent
   from other applications to the same destination. An implementation
   may skip to deliver the data to sockets that connect a different
   foreign address from the destination address of the corresponding
   ip6_mtuinfo strucutre.

This is based on the behavior of our implementation, but I don't stick
to minor details (e.g. the last sentence).

>    XXX What about more complex paths e.g. when using a routing header?

How about the following text?

  When an application sends packet with a routing header, the final
  destination stored in the ip6m_addr member does not necessarily
  contain complete information of the entire path. Thus, an
  implementation may append an additional data structure after
  ip6_mtuinfo to tell the application precise information of the
  entire path. This definition of the additinaol structure is beyond
  the scope of this document.

					JINMEI, Tatuya

---

From: JINMEI Tatuya / 神明達哉<[email-masked]>
Date: Sat, 18 Nov 2000 15:33:18 +0900

>>>>> On Fri, 17 Nov 2000 16:21:19 -0800 (PST), 

> prohibiting fragmentation, since I think the overloading you propose would

Hmm, okay, I agree.

> to 2^^32-1 would be the same as disabling fragmentation.

Yes, that was my intention, but I now agree with a separate socket
option to disable fragmentation.

> an address in addition to an mtu?

Well, sorry, the wording was incorrect in the original message. I
intended a new ancillary data item "IPV6_USEMTU" (not a socket option)
for outgoing UDP or raw IPv6 packets, because I imagined an
application which opens a singe, non-connected socket for multiple
destinations. The IPV6_USEMTU item, of course, would affect the
corresponding outgoing packet only. This also means that the actual
data for IPV6_USEMTU contains the path MTU only (which may be a 32bit
integer).

> Do you have an example of an application which might need such a feature?

Yes, please see the attached e-mail. As described in the message, NFS
might not be a good example (due to the actual implementation issue).
However, NetBSD's IPv6 NFS implementation has this kind of problem,
and currently does not work if the path MTU is smaller than the MTU of
the outgoing interface. I can easily imagine a same kind of prroblem
can arise for "pure" user space applications, and, in fact, DHCPv6
server could be a practical example (as I said in the attached
e-mail).

					JINMEI, Tatuya

Subject: Re: IPV6_USEMTU socket option
From: JINMEI Tatuya / 神明達哉<[email-masked]>
To: [email-masked]
Date: Thu, 16 Nov 2000 22:37:46 +0900

   

					JINMEI, Tatuya

---

From: JINMEI Tatuya / 神明達哉<[email-masked]>
Date: Sat, 18 Nov 2000 18:37:46 +0900

>    by enabing IPV6_RECVPATHMTU.

I have one more question about the option. What if the size of an
outgoing packet is larger than the MTU of the outgoing interface on
the sending node, when the application set the IPV6_RECVPATHMTU
option? Should the kerenl pass the IPV6_PATHMTU ancillary data with
the MTU of the outgoing interface? 

(BTW, our current implementation does not pass the ancillary data on
the sending node. In such a case, it just fragment the packet using
the MTU of the outgoing interface.)

					JINMEI, Tatuya

---

From: Francis Dupont <[email-masked]>
Date: Sat, 18 Nov 2000 16:16:03 +0100

=> I am sorry but this tries to give some data (here the address) to the kernel
via a getsockopt(). This is both not implementable on many kernels and
not compliant with standard getsockopt() definition.
For instance on my FreeBSD 3.x I have:

GETSOCKOPT(2)             FreeBSD System Calls Manual            GETSOCKOPT(2)

NAME
     getsockopt, setsockopt - get and set options on sockets

SYNOPSIS
     #include <sys/types.h>
     #include <sys/socket.h>

     int
     getsockopt(int s, int level, int optname, void *optval, int *optlen)

     int
     setsockopt(int s, int level, int optname, const void *optval, int optlen)

DESCRIPTION
     ...

     The parameters optval and optlen are used to access option values for
     setsockopt().  For getsockopt() they identify a buffer in which the value
     for the requested option(s) are to be returned.  For getsockopt(), optlen
     is a value-result parameter, initially containing the size of the buffer
     pointed to by optval, and modified on return to indicate the actual size
     of the value returned.  If no option value is to be supplied or returned,
     optval may be NULL.

I've looked at getsockopt() definition on some other OSs, the only difference
is some say NULL, some say 0...

Regards

PS: of course the connected option (not the #3) has not this problem.
I believe the path MTU is a PCB property then for an unconnected PCB
the path MTU should be the largest compatible interface MTU (or the
specified MTU if IPV6_USE*MTU is set).
--------------------------------------------------------------------
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: Sat, 18 Nov 2000 16:34:18 +0100

=> and your precedent mail proposed something which doesn't work...

=> getpathmtu() ? But see the postscriptum.

Thanks

PS: I have changed my mind: Yves Legrandgerard convinced me that the whole
stuff should have similar interfaces then a getsockopt() is better but
should return only the MTU (32 bit unsigned integer) for connected sockets
(or largest compatible interface MTU for unconnected sockets). Same
for the ancillary data version (where the address is redundant).
PPS: NetBSD has something similar named IP_ERRORMTU which gets (by
a getsockopt()) the MTU to use at the last EMSGSIZE error.
--------------------------------------------------------------------
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: Sat, 18 Nov 2000 17:58:05 +0100

=> I don't understand: you can't get ancillary data from a sending
system call then the only possibility is to return an EMSGSIZE error.
Of course the kernel can/should keep the value of the MTU to use...

   And, as I said in a pervious message, the draft should clearly state
   that this ancillary data should be passed to every socket that wants,
   even if the socket is non-connected.

=> I don't understand what is non-connected with ancillary data.
If you have ancillary data then addresses are available, non-connected
is for get/setsockopt()...

   
   
=> finally I believe the option #3 is too complex for its little utility...

Regards

---

From: Francis Dupont <[email-masked]>
Date: Sat, 18 Nov 2000 18:13:40 +0100

=> I am in the principle strongly against something which is available
only as an ancillary data and not a socket option.

=> with IPV6_USEMTU IPV6_USE_MIN_MTU is no more useful (it is IPV6_USEMTU
with 1280).

=> I still can't see if IPV6_USEMTU is very useful. Why don't rely
on the standard fragmentation when paths are stable and on IPV6_USE_MIN_MTU
when they are unstable and this is very important to avoid the lost
of first packets (the price of path MTU discovery). NFS is in the first
category, the DNS and IKE in the second with perhaps off-link DHCP.

Thanks

---

From: Francis Dupont <[email-masked]>
Date: Sat, 18 Nov 2000 18:21:15 +0100

=> I can't see the issue. The kernel doesn't return ancillary data
on sending system calls. It will fragment the packet or return an
EMSGSIZE if fragmentation is disable, and will return the path MTU
(less or equal to the MTU of the outgoing interface) in an ancillary
data on a receiving system call or a getsockopt().

=> IPV6_RECVPATHMTU is not supposed to do something on the sending side,
is it?

---

From: JINMEI Tatuya / 神明達哉<[email-masked]>
Date: Mon, 20 Nov 2000 02:32:30 +0900

>>>>> On Sat, 18 Nov 2000 18:21:15 +0100, 

   
> => IPV6_RECVPATHMTU is not supposed to do something on the sending side,

I think you and I said the same thing, but there may be some
misunderstanding due to my poor explanation (sorry). My intention was,

    What if the size of an outgoing packet is larger than the MTU of
    the outgoing interface on the sending node, when the application
    set the IPV6_RECVPATHMTU option? Should the application receive an
    IPV6_PATHMTU ancillary data item in a succeeding recvmsg call?

and your answer is "yes". Am I clear enough now?

					JINMEI, Tatuya

---

From: JINMEI Tatuya / 神明達哉<[email-masked]>
Date: Mon, 20 Nov 2000 02:25:30 +0900

>>>>> On Sat, 18 Nov 2000 17:58:05 +0100, 

   
> Of course the kernel can/should keep the value of the MTU to use...

I meant that the output routine put the ancillary data into the
receive queue of the sending packet.

> is for get/setsockopt()...

Sorry, I don't understand what you meant here. BTW: my proposal is

>> destination is the foreign address of the socket.
(snip)

   
   
> => finally I believe the option #3 is too complex for its little utility...

Okay, then how do we pass the destination address to non-noconnected socket?

					JINMEI, Tatuya

---

From: JINMEI Tatuya / 神明達哉<[email-masked]>
Date: Mon, 20 Nov 2000 03:04:04 +0900

>>>>> On Sat, 18 Nov 2000 18:13:40 +0100, 

> only as an ancillary data and not a socket option.

A setsockopt equivalent of this ancillary data item is also available
(especially for connected sockets). However, my main concern here is
about non-connected UDP server applications, where ancillary data
would be more suitable than a sticky socket option.

> => with IPV6_USEMTU IPV6_USE_MIN_MTU is no more useful (it is IPV6_USEMTU

Correct. So, IPV6_USEMTU would obsolete IPV6_USE_MIN_MTU.

> category, the DNS and IKE in the second with perhaps off-link DHCP.

Because we can't always rely on the kernel performing path MTU
discovery when there's no connected PCB. The latest version of NetBSD
is an example of not performing path MTU discovery without a
corresponding connected PCB (for a security reason)[*]. I agree that
we don't need the IPV6_USEMTU ancillary data (and socket option) if
all kernel implementations surely perform path MTU discovery
regardless of existence of a connected PCB.

([*]there are some other conditions, but they are not really related
to this discussion, so I just omitted them.)

					JINMEI, Tatuya

---

From: Yves Legrandgerard <[email-masked]>
Date: Mon, 20 Nov 2000 10:59:24 +0100 (CET)

> => with IPV6_USEMTU IPV6_USE_MIN_MTU is no more useful (it is IPV6_USEMTU

We could also add an another special case in the more general option
IPV6_USEMTU: IPV6_USEMTU with null MTU which would mean we want to use outgoing
MTU.

Date: 20-Nov-00
Time: 10:52:04

---

From: Yves Legrandgerard <[email-masked]>
Date: Mon, 20 Nov 2000 11:42:51 +0100 (CET)

> 11.1.  Sending with the Minimum MTU
[ylg]=> I would prefer to replace this option by the more general one 
IPV6_USEMTU (IPV6_USE_MIN_MTU <=> (IPV6_USEMTU, 1280)) and add the particular
case (IPV6_USEMTU, 0) to say to the application to use the outgoing MTU (case
which is not covered in your proposal, see below 11.4)

> 11.2.  Sending without fragmentation
[ylg]=> That's OK. And, as you wrote in a previous message, I think this stuff
must be keeped separate from preceding paragraph 11.1.

>    the interface that will be used when sending to the specified IPv6

[ylg]=> It does not solve the problem to get/use the MTU of outgoing
interface because you need the path MTU for the destination to be uncached
(unless, of course, the route is deleted before).

Time: 11:18:14

---

From: Erik Nordmark <[email-masked]>
Date: Mon, 20 Nov 2000 11:48:58 -0800 (PST)

> IPV6_RECVPATHMTU beforehand), or both...

I'll add this.

> Is "unsigned int" appropriate here (I'm just wondering, not sure on

What would you like to see instead?
uint32_t? uint16_t?

>    foreign address from the destination address of the corresponding

I'll add the above. THanks for the text.

>   the scope of this document.

I can add this unless somebody has any concerns about essentially making
this implementation specific.

  Erik

---

From: Erik Nordmark <[email-masked]>
Date: Mon, 20 Nov 2000 11:53:48 -0800 (PST)

> the MTU of the outgoing interface? 

My assumption was that it would send up an IPV6_PATHMTU and
also fragment and send the packet.

  Erik

---

From: JINMEI Tatuya / 神明達哉<[email-masked]>
Date: Tue, 21 Nov 2000 14:18:03 +0900

>>>>> On Mon, 20 Nov 2000 11:48:58 -0800 (PST), 

> What would you like to see instead?

I  would (personally) like uint32_t, because icmp6_hdr.icmp6_mtu has
the same type.

					JINMEI, Tatuya