Propagate an rdomain number to the nd6_lookup independently from
authormikeb <mikeb@openbsd.org>
Tue, 7 Jan 2014 17:07:45 +0000 (17:07 +0000)
committermikeb <mikeb@openbsd.org>
Tue, 7 Jan 2014 17:07:45 +0000 (17:07 +0000)
the ifp pointer which can be NULL.  This prevents a crash reported
by David Hill <dhill at mindcry ! org>.  OK bluhm

sys/netinet/tcp_input.c
sys/netinet6/icmp6.c
sys/netinet6/in6_src.c
sys/netinet6/nd6.c
sys/netinet6/nd6.h
sys/netinet6/nd6_nbr.c
sys/netinet6/nd6_rtr.c

index d9b274a..65f6804 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: tcp_input.c,v 1.269 2013/10/20 11:03:01 phessler Exp $        */
+/*     $OpenBSD: tcp_input.c,v 1.270 2014/01/07 17:07:45 mikeb Exp $   */
 /*     $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $  */
 
 /*
@@ -148,7 +148,8 @@ struct timeval tcp_ackdrop_ppslim_last;
 do { \
        if (tp && tp->t_inpcb && (tp->t_inpcb->inp_flags & INP_IPV6) && \
            tp->t_inpcb->inp_route6.ro_rt) { \
-               nd6_nud_hint(tp->t_inpcb->inp_route6.ro_rt, NULL, 0); \
+               nd6_nud_hint(tp->t_inpcb->inp_route6.ro_rt, NULL, 0, \
+                   tp->t_inpcb->inp_rtableid); \
        } \
 } while (0)
 #else
index 8173cb5..0160e2f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: icmp6.c,v 1.137 2013/12/20 02:04:08 krw Exp $ */
+/*     $OpenBSD: icmp6.c,v 1.138 2014/01/07 17:07:46 mikeb Exp $       */
 /*     $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */
 
 /*
@@ -2503,7 +2503,7 @@ icmp6_redirect_output(struct mbuf *m0, struct rtentry *rt)
                struct nd_opt_hdr *nd_opt;
                char *lladdr;
 
-               rt_nexthop = nd6_lookup(nexthop, 0, ifp);
+               rt_nexthop = nd6_lookup(nexthop, 0, ifp, ifp->if_rdomain);
                if (!rt_nexthop)
                        goto nolladdropt;
                len = sizeof(*nd_opt) + ifp->if_addrlen;
index 8569db4..7ec305a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: in6_src.c,v 1.36 2013/11/11 09:15:35 mpi Exp $        */
+/*     $OpenBSD: in6_src.c,v 1.37 2014/01/07 17:07:46 mikeb Exp $      */
 /*     $KAME: in6_src.c,v 1.36 2001/02/06 04:08:17 itojun Exp $        */
 
 /*
@@ -228,7 +228,8 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts,
 
                if (opts && opts->ip6po_nexthop) {
                        sin6_next = satosin6(opts->ip6po_nexthop);
-                       rt = nd6_lookup(&sin6_next->sin6_addr, 1, NULL);
+                       rt = nd6_lookup(&sin6_next->sin6_addr, 1, NULL,
+                           rtableid);
                        if (rt) {
                                ia6 = in6_ifawithscope(rt->rt_ifp, dst,
                                    rtableid);
index cb08b2f..92b0dbc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: nd6.c,v 1.105 2013/11/11 09:15:35 mpi Exp $   */
+/*     $OpenBSD: nd6.c,v 1.106 2014/01/07 17:07:46 mikeb Exp $ */
 /*     $KAME: nd6.c,v 1.280 2002/06/08 19:52:07 itojun Exp $   */
 
 /*
@@ -637,7 +637,8 @@ nd6_purge(struct ifnet *ifp)
 }
 
 struct rtentry *
-nd6_lookup(struct in6_addr *addr6, int create, struct ifnet *ifp)
+nd6_lookup(struct in6_addr *addr6, int create, struct ifnet *ifp,
+    u_int rtableid)
 {
        struct rtentry *rt;
        struct sockaddr_in6 sin6;
@@ -647,7 +648,7 @@ nd6_lookup(struct in6_addr *addr6, int create, struct ifnet *ifp)
        sin6.sin6_family = AF_INET6;
        sin6.sin6_addr = *addr6;
 
-       rt = rtalloc1(sin6tosa(&sin6), create, ifp->if_rdomain);
+       rt = rtalloc1(sin6tosa(&sin6), create, rtableid);
        if (rt && (rt->rt_flags & RTF_LLINFO) == 0) {
                /*
                 * This is the case for the default route.
@@ -690,7 +691,7 @@ nd6_lookup(struct in6_addr *addr6, int create, struct ifnet *ifp)
                        info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr;
                        info.rti_info[RTAX_NETMASK] = sin6tosa(&all1_sa);
                        if ((e = rtrequest1(RTM_ADD, &info, RTP_CONNECTED,
-                           &rt, ifp->if_rdomain)) != 0) {
+                           &rt, rtableid)) != 0) {
 #if 0
                                char ip[INET6_ADDRSTRLEN];
                                log(LOG_ERR,
@@ -779,7 +780,8 @@ nd6_is_addr_neighbor(struct sockaddr_in6 *addr, struct ifnet *ifp)
         * Even if the address matches none of our addresses, it might be
         * in the neighbor cache.
         */
-       if ((rt = nd6_lookup(&addr->sin6_addr, 0, ifp)) != NULL)
+       if ((rt = nd6_lookup(&addr->sin6_addr, 0, ifp,
+           ifp->if_rdomain)) != NULL)
                return (1);
 
        return (0);
@@ -902,7 +904,8 @@ nd6_free(struct rtentry *rt, int gc)
  * XXX cost-effective methods?
  */
 void
-nd6_nud_hint(struct rtentry *rt, struct in6_addr *dst6, int force)
+nd6_nud_hint(struct rtentry *rt, struct in6_addr *dst6, int force,
+    u_int rtableid)
 {
        struct llinfo_nd6 *ln;
 
@@ -913,7 +916,7 @@ nd6_nud_hint(struct rtentry *rt, struct in6_addr *dst6, int force)
        if (!rt) {
                if (!dst6)
                        return;
-               if (!(rt = nd6_lookup(dst6, 0, NULL)))
+               if (!(rt = nd6_lookup(dst6, 0, NULL, rtableid)))
                        return;
        }
 
@@ -1321,7 +1324,7 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
                }
 
                s = splsoftnet();
-               if ((rt = nd6_lookup(&nb_addr, 0, ifp)) == NULL ||
+               if ((rt = nd6_lookup(&nb_addr, 0, ifp, ifp->if_rdomain)) == NULL ||
                    (ln = (struct llinfo_nd6 *)rt->rt_llinfo) == NULL) {
                        error = EINVAL;
                        splx(s);
@@ -1378,7 +1381,7 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
         * description on it in NS section (RFC 2461 7.2.3).
         */
 
-       rt = nd6_lookup(from, 0, ifp);
+       rt = nd6_lookup(from, 0, ifp, ifp->if_rdomain);
        if (!rt) {
 #if 0
                /* nothing must be done if there's no lladdr */
@@ -1386,7 +1389,7 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
                        return NULL;
 #endif
 
-               rt = nd6_lookup(from, RT_REPORT, ifp);
+               rt = nd6_lookup(from, RT_REPORT, ifp, ifp->if_rdomain);
                is_newentry = 1;
        } else {
                /* do nothing if static ndp is set */
@@ -1698,7 +1701,8 @@ nd6_output(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m0,
                 * it is tolerable, because this should be a rare case.
                 */
                if (nd6_is_addr_neighbor(dst, ifp) &&
-                   (rt = nd6_lookup(&dst->sin6_addr, RT_REPORT, ifp)) != NULL)
+                   (rt = nd6_lookup(&dst->sin6_addr, RT_REPORT, ifp,
+                    ifp->if_rdomain)) != NULL)
                        ln = (struct llinfo_nd6 *)rt->rt_llinfo;
        }
        if (!ln || !rt) {
index c2db890..de300d9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: nd6.h,v 1.35 2013/10/25 02:54:42 deraadt Exp $        */
+/*     $OpenBSD: nd6.h,v 1.36 2014/01/07 17:07:46 mikeb Exp $  */
 /*     $KAME: nd6.h,v 1.95 2002/06/08 11:31:06 itojun Exp $    */
 
 /*
@@ -259,12 +259,12 @@ int nd6_is_addr_neighbor(struct sockaddr_in6 *, struct ifnet *);
 void nd6_option_init(void *, int, union nd_opts *);
 struct nd_opt_hdr *nd6_option(union nd_opts *);
 int nd6_options(union nd_opts *);
-struct rtentry *nd6_lookup(struct in6_addr *, int, struct ifnet *);
+struct rtentry *nd6_lookup(struct in6_addr *, int, struct ifnet *, u_int);
 void nd6_setmtu(struct ifnet *);
 void nd6_llinfo_settimer(struct llinfo_nd6 *, long);
 void nd6_timer(void *);
 void nd6_purge(struct ifnet *);
-void nd6_nud_hint(struct rtentry *, struct in6_addr *, int);
+void nd6_nud_hint(struct rtentry *, struct in6_addr *, int, u_int);
 int nd6_resolve(struct ifnet *, struct rtentry *,
        struct mbuf *, struct sockaddr *, u_char *);
 void nd6_rtrequest(int, struct rtentry *);
index f8e82ef..b45c56b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: nd6_nbr.c,v 1.72 2013/11/19 09:00:43 mpi Exp $        */
+/*     $OpenBSD: nd6_nbr.c,v 1.73 2014/01/07 17:07:46 mikeb Exp $      */
 /*     $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $        */
 
 /*
@@ -681,7 +681,7 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
         * If no neighbor cache entry is found, NA SHOULD silently be
         * discarded.
         */
-       rt = nd6_lookup(&taddr6, 0, ifp);
+       rt = nd6_lookup(&taddr6, 0, ifp, ifp->if_rdomain);
        if ((rt == NULL) ||
           ((ln = (struct llinfo_nd6 *)rt->rt_llinfo) == NULL) ||
           ((sdl = SDL(rt->rt_gateway)) == NULL))
index 80c75d7..2b0d123 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: nd6_rtr.c,v 1.74 2013/11/11 09:15:35 mpi Exp $        */
+/*     $OpenBSD: nd6_rtr.c,v 1.75 2014/01/07 17:07:46 mikeb Exp $      */
 /*     $KAME: nd6_rtr.c,v 1.97 2001/02/07 11:09:13 itojun Exp $        */
 
 /*
@@ -669,7 +669,8 @@ defrouter_select(void)
         */
        TAILQ_FOREACH(dr, &nd_defrouter, dr_entry) {
                if (!selected_dr &&
-                   (rt = nd6_lookup(&dr->rtaddr, 0, dr->ifp)) &&
+                   (rt = nd6_lookup(&dr->rtaddr, 0, dr->ifp,
+                    dr->ifp->if_rdomain)) &&
                    (ln = (struct llinfo_nd6 *)rt->rt_llinfo) &&
                    ND6_IS_LLINFO_PROBREACH(ln)) {
                        selected_dr = dr;
@@ -697,7 +698,8 @@ defrouter_select(void)
                else
                        selected_dr = TAILQ_NEXT(installed_dr, dr_entry);
        } else if (installed_dr &&
-           (rt = nd6_lookup(&installed_dr->rtaddr, 0, installed_dr->ifp)) &&
+           (rt = nd6_lookup(&installed_dr->rtaddr, 0, installed_dr->ifp,
+            installed_dr->ifp->if_rdomain)) &&
            (ln = (struct llinfo_nd6 *)rt->rt_llinfo) &&
            ND6_IS_LLINFO_PROBREACH(ln) &&
            rtpref(selected_dr) <= rtpref(installed_dr)) {
@@ -1398,7 +1400,7 @@ find_pfxlist_reachable_router(struct nd_prefix *pr)
 
        LIST_FOREACH(pfxrtr, &pr->ndpr_advrtrs, pfr_entry) {
                if ((rt = nd6_lookup(&pfxrtr->router->rtaddr, 0,
-                   pfxrtr->router->ifp)) &&
+                   pfxrtr->router->ifp, pfxrtr->router->ifp->if_rdomain)) &&
                    (ln = (struct llinfo_nd6 *)rt->rt_llinfo) &&
                    ND6_IS_LLINFO_PROBREACH(ln))
                        break;  /* found */