Diff below stops abusing nd6_rtrequest() for loopback interfaces, which means we can remove the special hack below and reduce the differences with arp_rtrequest().
This diff introduces two changes in the inet6 routing table, but they should not matter. The first one is that the gateway of the link-local entry for loopback interfaces is no longer a buggy link-layer address: -fe80::1%lo0 link#6 UHL 0 0 - 4 lo0 +fe80::1%lo0 fe80::1%lo0 UHL 0 0 - 4 lo0 The second one is that every route to network associated to the loopback interface will now have the mtu of this interface: -ff02::/16 ::1 UGRS 0 0 - 8 lo0 +ff02::/16 ::1 UGRS 0 0 33192 8 lo0 Both changes are consistent with the IPv4 behavior, ok? Index: netinet6/in6.c =================================================================== RCS file: /home/ncvs/src/sys/netinet6/in6.c,v retrieving revision 1.136 diff -u -p -r1.136 in6.c --- netinet6/in6.c 5 May 2014 11:44:33 -0000 1.136 +++ netinet6/in6.c 7 May 2014 10:29:24 -0000 @@ -1399,7 +1399,7 @@ in6_ifinit(struct ifnet *ifp, struct in6 /* Add ownaddr as loopback rtentry, if necessary (ex. on p2p link). */ if (newhost) { /* set the rtrequest function to create llinfo */ - if ((ifp->if_flags & IFF_POINTOPOINT) == 0) + if ((ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) == 0) ia6->ia_ifa.ifa_rtrequest = nd6_rtrequest; rt_ifa_addloop(&(ia6->ia_ifa)); Index: netinet6/nd6.c =================================================================== RCS file: /home/ncvs/src/sys/netinet6/nd6.c,v retrieving revision 1.116 diff -u -p -r1.116 nd6.c --- netinet6/nd6.c 7 May 2014 08:14:59 -0000 1.116 +++ netinet6/nd6.c 7 May 2014 10:29:24 -0000 @@ -1059,20 +1059,14 @@ nd6_rtrequest(int req, struct rtentry *r #endif /* FALLTHROUGH */ case RTM_RESOLVE: - if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) == 0) { - /* - * Address resolution isn't necessary for a point to - * point link, so we can skip this test for a p2p link. - */ - if (gate->sa_family != AF_LINK || - gate->sa_len < sizeof(null_sdl)) { - log(LOG_DEBUG, "%s: bad gateway value: %s\n", - __func__, ifp->if_xname); - break; - } - SDL(gate)->sdl_type = ifp->if_type; - SDL(gate)->sdl_index = ifp->if_index; + if (gate->sa_family != AF_LINK || + gate->sa_len < sizeof(null_sdl)) { + log(LOG_DEBUG, "%s: bad gateway value: %s\n", + __func__, ifp->if_xname); + break; } + SDL(gate)->sdl_type = ifp->if_type; + SDL(gate)->sdl_index = ifp->if_index; if (ln != NULL) break; /* This happens on a route change */ /*