IPv6 Source selection is a mess!

> ICMP6 messages
> are generated with a source of, I think, the local address associated with
> the route to the recipient,

It is not that simple.  Look at in6_ifawithscope() in sys/netinet6/in6.c.

                        /*
                         * At this point, we have two cases:
                         * 1. we are looking at a non-deprecated address,
                         *    and ia6_best is also non-deprecated.
                         * 2. we are looking at a deprecated address,
                         *    and ia6_best is also deprecated.
                         * Also, we do not have to consider a case where
                         * the scope of if_best is larger(smaller) than dst and
                         * the scope of the current address is smaller(larger)
                         * than dst. Such a case has already been covered.
                         * Tiebreaking is done according to the following
                         * items:
                         * - the scope comparison between the address and
                         *   dst (dscopecmp)
                         * - the scope comparison between the address and
                         *   ia6_best (bscopecmp)
                         * - if the address match dst longer than ia6_best
                         *   (matchcmp)
                         * - if the address is on the outgoing I/F (outI/F)
                         *
                         * Roughly speaking, the selection policy is
                         * - the most important item is scope. The same scope
                         *   is best. Then search for a larger scope.
                         *   Smaller scopes are the last resort.
                         * - A deprecated address is chosen only when we have
                         *   no address that has an enough scope, but is
                         *   prefered to any addresses of smaller scopes.
                         * - Longest address match against dst is considered
                         *   only for addresses that has the same scope of dst.
                         * - If there is no other reasons to choose one,
                         *   addresses on the outgoing I/F are preferred.
                         *
                         * The precise decision table is as follows:
                         * dscopecmp bscopecmp matchcmp outI/F | replace?
                         *    !equal     equal      N/A    Yes |      Yes (1)
                         *    !equal     equal      N/A     No |       No (2)
                         *    larger    larger      N/A    N/A |       No (3)
                         *    larger   smaller      N/A    N/A |      Yes (4)
                         *   smaller    larger      N/A    N/A |      Yes (5)
                         *   smaller   smaller      N/A    N/A |       No (6)
                         *     equal   smaller      N/A    N/A |      Yes (7)
                         *     equal    larger       (already done)
                         *     equal     equal   larger    N/A |      Yes (8)
                         *     equal     equal  smaller    N/A |       No (9)
                         *     equal     equal    equal    Yes |      Yes (a)
                         *     equal     equal    equal     No |       No (b)
                         */

Could you provide your ifconfig and route output?  So we could
figure out into which path of this algorith you are running.

Once I have have added the following rule from a newer RFC.  It
makes things better for many caes, but not with OSPF6.  There you
may have an interface with only link-local addresses.  Then this
link-local is used instead of another better scoped one.

                        /* RFC 3484 5. Rule 5: Prefer outgoing interface */

>  4  2001:728:0:5000::55  7.843 ms  8.236 ms  7.391 ms

How can this work?  Does your AS-Boundary Router do NAT?

> What's anyone else doing? Just living with it or has anyone figured a way
> to make it nicer? I'd like to reply with either a global scope address for
> the interface, or a loopback address,

We have implemented more or less a very old RFC.  There are two
newer RFCs with different algorithms.  There is recommendation to
store policies from user-land into the kernel for address selection.

I have just looked at FreeBSD in6_ifawithifp(), it is quite simple.
Perhaps this is a way to go.

> I didn't get anywhere with PF
> translation though.

pf with IPv6 link-local addresses does not work properly.  I think
it cannot parse the %if suffixes.  The KAME hack scope id is not
handled.

bluhm

Reply via email to