in6_selectsrc() uses two different rtalloc calls depending on whether or
not the destination address is multicast or not, but there is nothing to
explain why. I dug a bit and found this commit from itojun@ :

diff -u -r1.6 -r1.7
--- src/sys/netinet6/in6_src.c  2000/06/18 04:49:32     1.6
+++ src/sys/netinet6/in6_src.c  2000/06/18 17:02:59     1.7
@@ -244,7 +244,11 @@
                        ro->ro_dst.sin6_family = AF_INET6;
                        ro->ro_dst.sin6_len = sizeof(struct sockaddr_in6);
                        ro->ro_dst.sin6_addr = *dst;
-                       if (!IN6_IS_ADDR_MULTICAST(dst)) {
+                       ro->ro_dst.sin6_scope_id = dstsock->sin6_scope_id;
+                       if (IN6_IS_ADDR_MULTICAST(dst)) {
+                               ro->ro_rt = rtalloc1(&((struct route *)ro)
+                                                    ->ro_dst, 0);
+                       } else {
                                rtalloc((struct route *)ro);
                        }
                }

Below are rtalloc() and rtalloc1() from sys/net/route.c r1.19 commited
on 05/21/2000 :

> void
> rtalloc(ro)
>       register struct route *ro;
> {
>       if (ro->ro_rt && ro->ro_rt->rt_ifp && (ro->ro_rt->rt_flags & RTF_UP))
>               return;                          /* XXX */
>       ro->ro_rt = rtalloc1(&ro->ro_dst, 1);
> }
> 
> struct rtentry *
> rtalloc1(dst, report)
>       register struct sockaddr *dst;
>       int report;
> {
[...]
>       /*
>        * IP encapsulation does lots of lookups where we don't need nor want
>        * the RTM_MISSes that would be generated.  It causes RTM_MISS storms
>        * sent upward breaking user-level routing queries.
>        */
>       miss:   if (report && dst->sa_family != PF_KEY) {
>                       bzero((caddr_t)&info, sizeof(info));
>                       info.rti_info[RTAX_DST] = dst;
>                       rt_missmsg(msgtype, &info, 0, err);
>               }
>       }
>       splx(s);
>       return (newrt);
> }


So this if(MULTICAST) has been introduced to prevent RTM_MISS storms when
looking up routes to multicast addresses ; multicast and unicast route lookups
are the same.

Also, rtalloc(foo, RT_RESOLVE, bar) and rtalloc_mpath(foo, NULL, bar) are both
equivalent to _rtalloc(foo, NULL, RT_RESOLVE, bar).

Let's remove this if(MULTICAST), it's just confusing.

ok ?

Index: sys/netinet6/in6_src.c
===================================================================
RCS file: /cvs/src/sys/netinet6/in6_src.c,v
retrieving revision 1.71
diff -u -p -r1.71 in6_src.c
--- sys/netinet6/in6_src.c      2 Dec 2015 13:29:26 -0000       1.71
+++ sys/netinet6/in6_src.c      5 Dec 2015 12:03:48 -0000
@@ -240,13 +240,8 @@ in6_selectsrc(struct in6_addr **in6src, 
                        sa6->sin6_len = sizeof(struct sockaddr_in6);
                        sa6->sin6_addr = *dst;
                        sa6->sin6_scope_id = dstsock->sin6_scope_id;
-                       if (IN6_IS_ADDR_MULTICAST(dst)) {
-                               ro->ro_rt = rtalloc(sin6tosa(&ro->ro_dst),
-                                   RT_RESOLVE, ro->ro_tableid);
-                       } else {
-                               ro->ro_rt = rtalloc_mpath(sin6tosa(&ro->ro_dst),
-                                   NULL, ro->ro_tableid);
-                       }
+                       ro->ro_rt = rtalloc(sin6tosa(&ro->ro_dst),
+                           RT_RESOLVE, ro->ro_tableid);
                }
 
                /*

Reply via email to