Use rtalloc(9) directly instead of in6_selectsr() in NS/NA output
authormpi <mpi@openbsd.org>
Tue, 23 Aug 2016 11:03:10 +0000 (11:03 +0000)
committermpi <mpi@openbsd.org>
Tue, 23 Aug 2016 11:03:10 +0000 (11:03 +0000)
routines.

This is another little step towards deprecating 'struct route{,_in6}'.

ok bluhm@

sys/netinet6/nd6_nbr.c

index f845628..ac0398f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: nd6_nbr.c,v 1.109 2016/08/22 10:33:22 mpi Exp $       */
+/*     $OpenBSD: nd6_nbr.c,v 1.110 2016/08/23 11:03:10 mpi Exp $       */
 /*     $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $        */
 
 /*
@@ -368,10 +368,6 @@ nd6_ns_output(struct ifnet *ifp, struct in6_addr *daddr6,
        int icmp6len;
        int maxlen;
        caddr_t mac;
-       struct route_in6 ro;
-
-       bzero(&ro, sizeof(ro));
-       ro.ro_tableid = ifp->if_rdomain;
 
        if (IN6_IS_ADDR_MULTICAST(taddr6))
                return;
@@ -467,24 +463,23 @@ nd6_ns_output(struct ifnet *ifp, struct in6_addr *daddr6,
                if (saddr6 && in6ifa_ifpwithaddr(ifp, saddr6))
                        src_sa.sin6_addr = *saddr6;
                else {
-                       struct in6_addr *src0;
-                       int error;
+                       struct rtentry *rt;
 
-                       bcopy(&dst_sa, &ro.ro_dst, sizeof(dst_sa));
-                       error = in6_selectsrc(&src0, &dst_sa, NULL, &ro,
+                       rt = rtalloc(sin6tosa(&dst_sa), RT_RESOLVE,
                            m->m_pkthdr.ph_rtableid);
-                       if (error) {
+                       if (!rtisvalid(rt)) {
                                char addr[INET6_ADDRSTRLEN];
 
                                nd6log((LOG_DEBUG,
-                                   "nd6_ns_output: source can't be "
-                                   "determined: dst=%s, error=%d\n",
-                                   inet_ntop(AF_INET6, &dst_sa.sin6_addr,
-                                       addr, sizeof(addr)),
-                                   error));
+                                   "%s: source can't be determined: dst=%s\n",
+                                   __func__, inet_ntop(AF_INET6,
+                                   &dst_sa.sin6_addr, addr, sizeof(addr))));
+                               rtfree(rt);
                                goto bad;
                        }
-                       src_sa.sin6_addr = *src0;
+                       src_sa.sin6_addr =
+                           ifatoia6(rt->rt_ifa)->ia_addr.sin6_addr;
+                       rtfree(rt);
                }
        } else {
                /*
@@ -537,20 +532,12 @@ nd6_ns_output(struct ifnet *ifp, struct in6_addr *daddr6,
        nd_ns->nd_ns_cksum = 0;
        m->m_pkthdr.csum_flags |= M_ICMP_CSUM_OUT;
 
-       ip6_output(m, NULL, &ro, dad ? IPV6_UNSPECSRC : 0, &im6o, NULL);
+       ip6_output(m, NULL, NULL, dad ? IPV6_UNSPECSRC : 0, &im6o, NULL);
        icmp6stat.icp6s_outhist[ND_NEIGHBOR_SOLICIT]++;
-
-       if (ro.ro_rt) {         /* we don't cache this route. */
-               rtfree(ro.ro_rt);
-       }
        return;
 
   bad:
-       if (ro.ro_rt) {
-               rtfree(ro.ro_rt);
-       }
        m_freem(m);
-       return;
 }
 
 /*
@@ -913,18 +900,13 @@ nd6_na_output(struct ifnet *ifp, struct in6_addr *daddr6,
     struct sockaddr *sdl0)
 {
        struct mbuf *m;
+       struct rtentry *rt = NULL;
        struct ip6_hdr *ip6;
        struct nd_neighbor_advert *nd_na;
        struct ip6_moptions im6o;
-       struct sockaddr_in6 src_sa, dst_sa;
-       struct in6_addr *src0;
-       int icmp6len, maxlen, error;
-       caddr_t mac;
-       struct route_in6 ro;
-
-       mac = NULL;
-       bzero(&ro, sizeof(ro));
-       ro.ro_tableid = ifp->if_rdomain;
+       struct sockaddr_in6 dst_sa;
+       int icmp6len, maxlen;
+       caddr_t mac = NULL;
 
        /* estimate the size of message */
        maxlen = sizeof(*ip6) + sizeof(*nd_na);
@@ -969,10 +951,9 @@ nd6_na_output(struct ifnet *ifp, struct in6_addr *daddr6,
        ip6->ip6_vfc |= IPV6_VERSION;
        ip6->ip6_nxt = IPPROTO_ICMPV6;
        ip6->ip6_hlim = 255;
-       bzero(&src_sa, sizeof(src_sa));
        bzero(&dst_sa, sizeof(dst_sa));
-       src_sa.sin6_len = dst_sa.sin6_len = sizeof(struct sockaddr_in6);
-       src_sa.sin6_family = dst_sa.sin6_family = AF_INET6;
+       dst_sa.sin6_len = sizeof(struct sockaddr_in6);
+       dst_sa.sin6_family = AF_INET6;
        dst_sa.sin6_addr = *daddr6;
        if (IN6_IS_ADDR_UNSPECIFIED(daddr6)) {
                /* reply to DAD */
@@ -989,20 +970,18 @@ nd6_na_output(struct ifnet *ifp, struct in6_addr *daddr6,
        /*
         * Select a source whose scope is the same as that of the dest.
         */
-       bcopy(&dst_sa, &ro.ro_dst, sizeof(dst_sa));
-       error = in6_selectsrc(&src0, &dst_sa, NULL, &ro,
-           m->m_pkthdr.ph_rtableid);
-       if (error) {
+       rt = rtalloc(sin6tosa(&dst_sa), RT_RESOLVE, ifp->if_rdomain);
+       if (!rtisvalid(rt)) {
                char addr[INET6_ADDRSTRLEN];
 
-               nd6log((LOG_DEBUG, "nd6_na_output: source can't be "
-                   "determined: dst=%s, error=%d\n",
-                   inet_ntop(AF_INET6, &dst_sa.sin6_addr, addr, sizeof(addr)),
-                   error));
+               nd6log((LOG_DEBUG, "%s: source can't be determined: dst=%s\n",
+                   __func__, inet_ntop(AF_INET6, &dst_sa.sin6_addr, addr,
+                   sizeof(addr))));
+               rtfree(rt);
                goto bad;
        }
-       src_sa.sin6_addr = *src0;
-       ip6->ip6_src = src_sa.sin6_addr;
+       ip6->ip6_src = ifatoia6(rt->rt_ifa)->ia_addr.sin6_addr;
+       rtfree(rt);
        nd_na = (struct nd_neighbor_advert *)(ip6 + 1);
        nd_na->nd_na_type = ND_NEIGHBOR_ADVERT;
        nd_na->nd_na_code = 0;
@@ -1059,20 +1038,12 @@ nd6_na_output(struct ifnet *ifp, struct in6_addr *daddr6,
        nd_na->nd_na_cksum = 0;
        m->m_pkthdr.csum_flags |= M_ICMP_CSUM_OUT;
 
-       ip6_output(m, NULL, &ro, 0, &im6o, NULL);
+       ip6_output(m, NULL, NULL, 0, &im6o, NULL);
        icmp6stat.icp6s_outhist[ND_NEIGHBOR_ADVERT]++;
-
-       if (ro.ro_rt) {         /* we don't cache this route. */
-               rtfree(ro.ro_rt);
-       }
        return;
 
   bad:
-       if (ro.ro_rt) {
-               rtfree(ro.ro_rt);
-       }
        m_freem(m);
-       return;
 }
 
 caddr_t