Subject: Remaining MUSTs in default-addr-select-02

From: "M. T. Hollinger" <[email-masked]>
Date: Thu, 14 Dec 2000 17:53:31 -0500

Rich, thanks for putting so much work into this draft.  I generally like it,
and think this is an important area to work on.

I have some concerns about the details, primarily because my years of
working on a "strong host model" network layer have led me to really
question that model.  It's probably too late, for the protocol stack I work
on, but I'd like to make sure it's easy for other implementers to use a weak
host model.  Also, I want to make sure applications are empowered to select
their own addresses with minimal second-guessing at the network layer.

>  All IPv6 nodes, including both hosts and routers, must implement
>  default address selection as defined in this specification.

It seems funny to have a "must" (different from a "MUST"?)  in the abstract,
and since half the draft talks about destination address selection
(typically not an issue for routers, which may not even include a BIND
resolver or host table), I don't see why routers are required to implement
it.

> The IPv6
> addressing architecture defines scope field values for node-local
> (0x1), link-local (0x2), site-local (0x5), ...
> ...
> IPv4 loopback addresses [11, section 4.2.2.11], which
> have the prefix 127/8, are assigned link-local scope.

Why not node-local, since you went to the trouble of mentioning it earlier?
I see from the revision history that you changed this to link-local in an
earlier version of the draft, but I wasn't following the discussion at that
time.  Maybe a parenthetical expression like "node-local (0x1, not used in
this draft)" would be appropriate, if you're really sure you don't want to
use that scope here.

Still, it might be handy.  If we're sending to a link-local destination
address, and we're trying to select a source address, then I would think a
link-local source address would be more appropriate than a loopback address.
Rule 2 (Prefer appropriate scope) would ensure selection of a link-local
address, except that you've defined loopback as also being link-local.  Rule
3 (Avoid deprecated addresses) won't avoid the loopback, because you've
defined loopback addresses as preferred (sec 2.4).  Rule 5 (prefer outgoing
interface) may save us here, but some implementations may just add the
loopback address to another interface, rather than having a separate
loopback interface.  Rule 6 (prefer matching label) or Rule 8 (longest
match) will save us, at least for the IPv6 case (and IPv4 source address
selection is out-of-scope anyway), if we get that far.

Consider this source address selection problem:

   Destination: fe80::2
   Sources: fe80::1 (deprecated) vs ::1
   Result: ::1 (avoid deprecated address)

Is it legal to have a deprecated link-local address?  If so, this
configuration is valid, and the result is non-intuitive.  Rule 2 could have
saved us, but again, sec 2.4 says:

>  The loopback address should be treated as having link-local scope
>  and "preferred" configuration status.

As an aside, if loopback addresses were defined as having node-local scope,
then perhaps the first (::1/128) rule of your default policy table would
become redundant.  Alternatively, perhaps the cleanest solution would be to
add something like this to sec 3:

   For non-loopback destination addresses, the set of
   candidate source addresses MUST NOT include any
   loopback addresses.

>  It is RECOMMENDED that the candidate source addresses be the set of
>  unicast addresses assigned to the interface that will be used to
>  send to the destination. (The "outgoing" interface.)

Whoa!  That's pretty restrictive.  Keep this in mind, as many of my other
concerns stem from the possibility that some implementors may follow this
RECOMMENDATION.

>  On routers, the
>  candidate set MAY include unicast addresses assigned to any
>  interface that could forward the destination address to the outgoing
>  interface.

This wording presumes a lot about the implementation, and seems to imply
that only routers MAY deviate from your RECOMMENDATION.  As you know, "weak
host model" protocol stacks don't consider it "forwarding" to send a
locally-originating packet out an interface other than the one its source
address is associated with.  (Some stacks even let you have a local address
not associated with any interface.)

>  For multicast ... destination addresses, the set of
>  candidate source addresses MUST only include addresses assigned to
>  interfaces belonging to the same link as the outgoing interface.

Hmm.  What if I'm a multicast router?  I'm specifically concerned about the
case of a node which is sending a multicast stream, where the node's owners
have gone to great lengths to achieve reliability.  They may have some
application-specific reason why all the packets in this multicast stream
need to have the same source address (to be granted preferred routing
treatment, perhaps, or to traverse firewalls).  That means the application
will bind to a particular global address -- say, one associated with
interface A.  If the ISP for interface A fails, we now need to send
multicast packets with A's source address out interface B, switching  to our
backup ISP, with whom we have presumably made advance arrangements to carry
the traffic.

For that matter, if the first ISP happens to be down at the moment our
application comes up, binds to A's global address (in anticipation of that
ISP coming back soon), and sends its very first packet, it should in my
opinion still be allowed.  On UDP traffic flows, I'm not sure whether the
complete source address selection algorithm should be repeated each time a
packet is transmitted, or whether the previously-used address should be
cached.  If the application has explicitly bound to a source address and
successfully sent some traffic in the past, how frequently should the
network layer re-validate that specified address?  Every time routing
information changes, perhaps?  If we check it on every packet, that's a big
performance hit, but if we don't, we can't fully enforce all these
"candidate set" rules -- which I mostly don't think should be enforced
anyway, if the application has explicitly chosen an address.

To keep hammering on the multicast cases, what if I find myself sending to a
global multicast destination address via an interface with only a link-local
address?  Assuming the application hasn't bound to a particular address, is
it better to use the global address from some other interface as the source,
or to go ahead and send the packet with the link-local source address?  If I
use an address from another interface, my local routers may drop it rather
than forwarding it off the link.  Of course, they'll do that anyway if I
select the link-local source address.

Now, what if the application has explicitly bound to a certain global
address and now sends multicast traffic that will be routed via some other
interface?  This is an unusual thing to do (since the router will probably
not forward such multicast traffic), but maybe the folks running my
application configured it that way because they had made special
arrangements with the router operator to act as a backup in case of another
router's failure.  This is similar to my previous example, except that in
this case, I'm just a multi-homed host, not actually a router.  Here again,
we need the packets to go out with a consistent global source address,
regardless of the routing decisions.

>  If an application or upper-layer specifies a source address that is
>  not in the candidate set for the destination, then the network layer
>  MUST treat this is an error.

Again, this is what gives me heartburn, particularly in light of that
earlier RECOMMENDATION that the candidate set include only those source
addresses associated with the outgoing interface.  If the application has
gone to the trouble of binding to a particular local address, then I think
the network layer should go ahead and use that source address, even if the
routing table happens to dictate that the packet gets transmitted out a
different interface.  This is particularly true if the routing table changes
during a particular information flow (UDP application dialog or TCP
connection).  At that point, we can't change the source address, even though
we are suddenly sending the packets out a different interface which may well
have available addresses of its own.

In general, perhaps the set of source addresses which can be specified
explicitly by an application should be larger than the set of addresses
which might be automatically selected by the network layer.  Don't try so
hard to protect the network from misbehaving applications.

In the summary the changes for the -02 draft, it says:

>  Clarified that an implementation should prevent an application or
>  upper-layer from choosing a source address that is not in the
>  candidate set and not prevent an application or upper-layer from
>  choosing a source address that is in the candidate set.

I like the summary ("should") more than what the draft actually says ("the
network layer MUST treat this as an error"), particularly given the narrow
way the candidate set has been defined.  Reflecting upon the title of this
draft, I can't see how a statement that the network layer MUST prevent
applications from choosing particular addresses fits the topic of DEFAULT
address selection.  Even SHOULD is a stretch; my preference would be
somewhere between MAY and SHOULD NOT.

>  Rule 2: Prefer appropriate scope.
>  If Scope(SA) < Scope(SB). If Scope(SA) < Scope(D), then choose SB
>  and otherwise choose SA.

I found this rule quite hard to understand.  I had to keep going through and
plugging in specific examples.  To paraphrase: if the scope of SA is
narrower than the scope of SB, and also too narrow for the given
destination, then choose SB.  Now that I understand the phrasing, I agree.

>  Rule 5: Prefer outgoing interface.
>  If SA is assigned to the interface that will be used to send to D
>  and SB is assigned to a different interface, then prefer SA.

Yes!  I agree with this rule.  This is a good way to prefer addresses
associated with the outgoing interface.  Of course, it only comes into play
when an implementation deviates from your RECOMMENDATION that only addresses
assigned to the outgoing interface be considered.  It's rather telling that
when you had to rank this rule, you put it down at number 5, while the
RECOMMENDATION would effectively make it number 0.

>  In this approach, the implementation may not have
>  knowledge of the outgoing interface for each destination, so it MAY
>  use a looser definition of the candidate set during destination
>  address ordering.

OK, but let's make sure the network layer doesn't enforce its own definition
of the candidate set at transmit time.  If getaddrinfo() comes up with a
destination address that the network layer can't actually reach (because the
selected outgoing interface doesn't have a global address, for example),
then this inconsistency might prevent communication -- yet another reason
why the network layer should not, in my opinion, be enforcing the
interface-matching rule on outgoing source addresses.

>  ...no more than one second out
>  of date. For example, an implementation might make a system call to
>  check if any routing table entries or source address assignments
>  that might affect these algorithms have changed.

Well, that would probably take several system calls, so doing it every 1
second sounds too frequent, to me.  I'd think 5 or 10 seconds would be
appropriate.

Bearing in mind that the output from this selection process should be a list
of address pairs to try, I can't help observing that the results are
sometimes suboptimal.  As written, this design will lead well-behaved
applications to try a list of *destination* addresses, in some reasonable
order.  However, for each destination address, we'll try only a single
source address.  Suppose we want to reach a distant host with 7 different
global IPv6 addresses and 1 IPv4 address.  Suppose further that we ourselves
have 2 global IPv6 addresses and an IPv4 address.  This algorithm will lead
our application to try all 7 of the remote IPv6 addresses before ever trying
the IPv4 address.  The network layer may well use the same IPv6 source
address in all 7 attempts, if the bits happen to fall in such a way that it
represents the longest match.  If there is some routing problem with that
address, then we won't get through until the 8th try, at which point we'll
finally fall back to IPv4, never having tried our other IPv6 global source
address at all.

It would seem to me like a better bet to cycle through the local addresses,
and perhaps incorporate other feedback between routing, destination address
selection, and source address selection.  When we talked about this in
Pittsburgh, I heard substantial support for the notion of changing the API
so that a typical application would no longer have to handle IP addresses at
all.  Instead of calling getaddrinfo() and then connect(), a client of the
future might call connectbyname() and let the protocol stack take care of
all the details.  Such a routine could sequence the retries intelligently,
and of course it could also handle all parsing of the specified string which
might be a hostname, an IPv4 address, or an IPv6 address (with optional
scope identifier).

Is anyone actually working on such an approach?  This draft is limited by
its assumption of an unchanged sockets API -- which is great for near-term
deployment, but I'd also like to see a longer-term effort to improve the
API.  Anyone for connectbyname() ?

           - Mark

--------------------------------------------------------------------
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: Richard Draves <[email-masked]>
Date: Wed, 20 Dec 2000 10:12:23 -0800

> I believe this is why "node" is defined the way it is in RFC 
> 2460. It's an
> inclusive term and all you need to say is that the address selection
> mechanisms apply to all nodes.

The current text in the draft is:

Rich