version 1.30, 2000/05/19 01:40:19 |
version 1.30.4.1, 2000/07/20 00:07:05 |
|
|
/* $NetBSD$ */ |
/* $NetBSD$ */ |
/* $KAME: nd6.c,v 1.63 2000/05/17 12:35:59 jinmei Exp $ */ |
/* $KAME: nd6.c,v 1.68 2000/07/02 14:48:02 itojun Exp $ */ |
|
|
/* |
/* |
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. |
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. |
Line 91 int nd6_useloopback = 1; /* use loopback |
|
Line 91 int nd6_useloopback = 1; /* use loopback |
|
/* preventing too many loops in ND option parsing */ |
/* preventing too many loops in ND option parsing */ |
int nd6_maxndopt = 10; /* max # of ND options allowed */ |
int nd6_maxndopt = 10; /* max # of ND options allowed */ |
|
|
|
int nd6_maxnudhint = 0; /* max # of subsequent upper layer hints */ |
|
|
/* for debugging? */ |
/* for debugging? */ |
static int nd6_inuse, nd6_allocated; |
static int nd6_inuse, nd6_allocated; |
|
|
|
|
*/ |
*/ |
if (in6_maxmtu < ndi->linkmtu) |
if (in6_maxmtu < ndi->linkmtu) |
in6_maxmtu = ndi->linkmtu; |
in6_maxmtu = ndi->linkmtu; |
} |
} else |
else |
|
in6_setmaxmtu(); |
in6_setmaxmtu(); |
} |
} |
} |
} |
Line 467 nd6_timer(ignored_arg) |
|
Line 468 nd6_timer(ignored_arg) |
|
nd6_ns_output(ifp, &dst->sin6_addr, |
nd6_ns_output(ifp, &dst->sin6_addr, |
&dst->sin6_addr, |
&dst->sin6_addr, |
ln, 0); |
ln, 0); |
} |
} else |
else |
|
ln->ln_state = ND6_LLINFO_STALE; /* XXX */ |
ln->ln_state = ND6_LLINFO_STALE; /* XXX */ |
break; |
break; |
case ND6_LLINFO_PROBE: |
case ND6_LLINFO_PROBE: |
Line 497 nd6_timer(ignored_arg) |
|
Line 497 nd6_timer(ignored_arg) |
|
t = TAILQ_NEXT(dr, dr_entry); |
t = TAILQ_NEXT(dr, dr_entry); |
defrtrlist_del(dr); |
defrtrlist_del(dr); |
dr = t; |
dr = t; |
} else |
} else { |
dr = TAILQ_NEXT(dr, dr_entry); |
dr = TAILQ_NEXT(dr, dr_entry); |
|
} |
} |
} |
pr = nd_prefix.lh_first; |
pr = nd_prefix.lh_first; |
while (pr) { |
while (pr) { |
Line 709 nd6_lookup(addr6, create, ifp) |
|
Line 710 nd6_lookup(addr6, create, ifp) |
|
(struct llinfo_nd6 *)rt->rt_llinfo; |
(struct llinfo_nd6 *)rt->rt_llinfo; |
ln->ln_state = ND6_LLINFO_NOSTATE; |
ln->ln_state = ND6_LLINFO_NOSTATE; |
} |
} |
} |
} else |
else |
|
return(NULL); |
return(NULL); |
} |
} |
rt->rt_refcnt--; |
rt->rt_refcnt--; |
|
|
* XXX cost-effective metods? |
* XXX cost-effective metods? |
*/ |
*/ |
void |
void |
nd6_nud_hint(rt, dst6) |
nd6_nud_hint(rt, dst6, force) |
struct rtentry *rt; |
struct rtentry *rt; |
struct in6_addr *dst6; |
struct in6_addr *dst6; |
|
int force; |
{ |
{ |
struct llinfo_nd6 *ln; |
struct llinfo_nd6 *ln; |
long time_second = time.tv_sec; |
long time_second = time.tv_sec; |
Line 893 nd6_nud_hint(rt, dst6) |
|
Line 894 nd6_nud_hint(rt, dst6) |
|
return; |
return; |
} |
} |
|
|
if ((rt->rt_flags & RTF_GATEWAY) |
if ((rt->rt_flags & RTF_GATEWAY) != 0 || |
|| (rt->rt_flags & RTF_LLINFO) == 0 |
(rt->rt_flags & RTF_LLINFO) == 0 || |
|| !rt->rt_llinfo |
!rt->rt_llinfo || !rt->rt_gateway || |
|| !rt->rt_gateway |
rt->rt_gateway->sa_family != AF_LINK) { |
|| rt->rt_gateway->sa_family != AF_LINK) { |
|
/* This is not a host route. */ |
/* This is not a host route. */ |
return; |
return; |
} |
} |
Line 906 nd6_nud_hint(rt, dst6) |
|
Line 906 nd6_nud_hint(rt, dst6) |
|
if (ln->ln_state < ND6_LLINFO_REACHABLE) |
if (ln->ln_state < ND6_LLINFO_REACHABLE) |
return; |
return; |
|
|
|
/* |
|
* if we get upper-layer reachability confirmation many times, |
|
* it is possible we have false information. |
|
*/ |
|
if (!force) { |
|
ln->ln_byhint++; |
|
if (ln->ln_byhint > nd6_maxnudhint) |
|
return; |
|
} |
|
|
ln->ln_state = ND6_LLINFO_REACHABLE; |
ln->ln_state = ND6_LLINFO_REACHABLE; |
if (ln->ln_expire) |
if (ln->ln_expire) |
ln->ln_expire = time_second + |
ln->ln_expire = time_second + |
Line 1127 nd6_rtrequest(req, rt, sa) |
|
Line 1137 nd6_rtrequest(req, rt, sa) |
|
* which is specified by ndp command. |
* which is specified by ndp command. |
*/ |
*/ |
ln->ln_state = ND6_LLINFO_REACHABLE; |
ln->ln_state = ND6_LLINFO_REACHABLE; |
|
ln->ln_byhint = 0; |
} else { |
} else { |
/* |
/* |
* When req == RTM_RESOLVE, rt is created and |
* When req == RTM_RESOLVE, rt is created and |
Line 1151 nd6_rtrequest(req, rt, sa) |
|
Line 1162 nd6_rtrequest(req, rt, sa) |
|
caddr_t macp = nd6_ifptomac(ifp); |
caddr_t macp = nd6_ifptomac(ifp); |
ln->ln_expire = 0; |
ln->ln_expire = 0; |
ln->ln_state = ND6_LLINFO_REACHABLE; |
ln->ln_state = ND6_LLINFO_REACHABLE; |
|
ln->ln_byhint = 0; |
if (macp) { |
if (macp) { |
Bcopy(macp, LLADDR(SDL(gate)), ifp->if_addrlen); |
Bcopy(macp, LLADDR(SDL(gate)), ifp->if_addrlen); |
SDL(gate)->sdl_alen = ifp->if_addrlen; |
SDL(gate)->sdl_alen = ifp->if_addrlen; |
Line 1174 nd6_rtrequest(req, rt, sa) |
|
Line 1186 nd6_rtrequest(req, rt, sa) |
|
} else if (rt->rt_flags & RTF_ANNOUNCE) { |
} else if (rt->rt_flags & RTF_ANNOUNCE) { |
ln->ln_expire = 0; |
ln->ln_expire = 0; |
ln->ln_state = ND6_LLINFO_REACHABLE; |
ln->ln_state = ND6_LLINFO_REACHABLE; |
|
ln->ln_byhint = 0; |
|
|
/* join solicited node multicast for proxy ND */ |
/* join solicited node multicast for proxy ND */ |
if (ifp->if_flags & IFF_MULTICAST) { |
if (ifp->if_flags & IFF_MULTICAST) { |
Line 1313 nd6_ioctl(cmd, data, ifp) |
|
Line 1326 nd6_ioctl(cmd, data, ifp) |
|
if (IN6_IS_ADDR_LINKLOCAL(&drl->defrouter[i].rtaddr)) { |
if (IN6_IS_ADDR_LINKLOCAL(&drl->defrouter[i].rtaddr)) { |
/* XXX: need to this hack for KAME stack */ |
/* XXX: need to this hack for KAME stack */ |
drl->defrouter[i].rtaddr.s6_addr16[1] = 0; |
drl->defrouter[i].rtaddr.s6_addr16[1] = 0; |
} |
} else |
else |
|
log(LOG_ERR, |
log(LOG_ERR, |
"default router list contains a " |
"default router list contains a " |
"non-linklocal address(%s)\n", |
"non-linklocal address(%s)\n", |
Line 1359 nd6_ioctl(cmd, data, ifp) |
|
Line 1371 nd6_ioctl(cmd, data, ifp) |
|
if (IN6_IS_ADDR_LINKLOCAL(&RTRADDR)) { |
if (IN6_IS_ADDR_LINKLOCAL(&RTRADDR)) { |
/* XXX: hack for KAME */ |
/* XXX: hack for KAME */ |
RTRADDR.s6_addr16[1] = 0; |
RTRADDR.s6_addr16[1] = 0; |
} |
} else |
else |
|
log(LOG_ERR, |
log(LOG_ERR, |
"a router(%s) advertises " |
"a router(%s) advertises " |
"a prefix with " |
"a prefix with " |