summaryrefslogtreecommitdiff
path: root/sys/netinet6
diff options
context:
space:
mode:
authorMike Belopuhov <mikeb@cvs.openbsd.org>2014-01-07 17:07:47 +0000
committerMike Belopuhov <mikeb@cvs.openbsd.org>2014-01-07 17:07:47 +0000
commite51e51a57642cbf68309e265e3a2ec33dba590d3 (patch)
treed0390e394678a6cd71700a20de688e00be713aee /sys/netinet6
parent889f42b40ec8aa7c9c40d60e3ca54caea303302e (diff)
Propagate an rdomain number to the nd6_lookup independently from
the ifp pointer which can be NULL. This prevents a crash reported by David Hill <dhill at mindcry ! org>. OK bluhm
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/icmp6.c4
-rw-r--r--sys/netinet6/in6_src.c5
-rw-r--r--sys/netinet6/nd6.c26
-rw-r--r--sys/netinet6/nd6.h6
-rw-r--r--sys/netinet6/nd6_nbr.c4
-rw-r--r--sys/netinet6/nd6_rtr.c10
6 files changed, 31 insertions, 24 deletions
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index 8173cb55b6b..0160e2ff484 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -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;
diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c
index 8569db45f08..7ec305abbc7 100644
--- a/sys/netinet6/in6_src.c
+++ b/sys/netinet6/in6_src.c
@@ -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);
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index cb08b2fce5a..92b0dbcbfeb 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -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) {
diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h
index c2db89055f7..de300d99d96 100644
--- a/sys/netinet6/nd6.h
+++ b/sys/netinet6/nd6.h
@@ -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 *);
diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c
index f8e82ef910a..b45c56b49d0 100644
--- a/sys/netinet6/nd6_nbr.c
+++ b/sys/netinet6/nd6_nbr.c
@@ -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))
diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c
index 80c75d7a6bc..2b0d123f792 100644
--- a/sys/netinet6/nd6_rtr.c
+++ b/sys/netinet6/nd6_rtr.c
@@ -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 */