version 1.114, 2016/04/01 08:12:00 |
version 1.115, 2016/04/04 07:37:07 |
Line 543 nd6_na_input(struct mbuf *m, int off, in |
|
Line 543 nd6_na_input(struct mbuf *m, int off, in |
|
char *lladdr = NULL; |
char *lladdr = NULL; |
int lladdrlen = 0; |
int lladdrlen = 0; |
struct ifaddr *ifa; |
struct ifaddr *ifa; |
struct llentry *ln; |
struct llentry *ln = NULL; |
struct rtentry *rt = NULL; |
|
struct sockaddr_dl *sdl; |
|
union nd_opts ndopts; |
union nd_opts ndopts; |
struct sockaddr_in6 ssin6; |
struct sockaddr_in6 ssin6; |
int rt_announce; |
int rt_announce; |
Line 641 nd6_na_input(struct mbuf *m, int off, in |
|
Line 639 nd6_na_input(struct mbuf *m, int off, in |
|
* If no neighbor cache entry is found, NA SHOULD silently be |
* If no neighbor cache entry is found, NA SHOULD silently be |
* discarded. |
* discarded. |
*/ |
*/ |
rt = nd6_lookup(&taddr6, 0, ifp); |
ln = nd6_lookup(&taddr6, ifp, true); |
if ((rt == NULL) || |
if (ln == NULL) |
((ln = rt->rt_llinfo) == NULL) || |
|
((sdl = satosdl(rt->rt_gateway)) == NULL)) |
|
goto freeit; |
goto freeit; |
|
|
rt_announce = 0; |
rt_announce = 0; |
Line 659 nd6_na_input(struct mbuf *m, int off, in |
|
Line 655 nd6_na_input(struct mbuf *m, int off, in |
|
/* |
/* |
* Record link-layer address, and update the state. |
* Record link-layer address, and update the state. |
*/ |
*/ |
(void)sockaddr_dl_setaddr(sdl, sdl->sdl_len, lladdr, |
memcpy(&ln->ll_addr, lladdr, ifp->if_addrlen); |
ifp->if_addrlen); |
ln->la_flags |= LLE_VALID; |
rt_announce = 1; |
rt_announce = 1; |
if (is_solicited) { |
if (is_solicited) { |
ln->ln_state = ND6_LLINFO_REACHABLE; |
ln->ln_state = ND6_LLINFO_REACHABLE; |
Line 690 nd6_na_input(struct mbuf *m, int off, in |
|
Line 686 nd6_na_input(struct mbuf *m, int off, in |
|
if (lladdr == NULL) |
if (lladdr == NULL) |
llchange = 0; |
llchange = 0; |
else { |
else { |
if (sdl->sdl_alen) { |
if (ln->la_flags & LLE_VALID) { |
if (memcmp(lladdr, CLLADDR(sdl), ifp->if_addrlen)) |
if (memcmp(lladdr, &ln->ll_addr, ifp->if_addrlen)) |
llchange = rt_announce = 1; |
llchange = rt_announce = 1; |
else |
else |
llchange = 0; |
llchange = 0; |
Line 735 nd6_na_input(struct mbuf *m, int off, in |
|
Line 731 nd6_na_input(struct mbuf *m, int off, in |
|
* Update link-local address, if any. |
* Update link-local address, if any. |
*/ |
*/ |
if (lladdr != NULL) { |
if (lladdr != NULL) { |
(void)sockaddr_dl_setaddr(sdl, sdl->sdl_len, |
memcpy(&ln->ll_addr, lladdr, ifp->if_addrlen); |
lladdr, ifp->if_addrlen); |
ln->la_flags |= LLE_VALID; |
} |
} |
|
|
/* |
/* |
Line 770 nd6_na_input(struct mbuf *m, int off, in |
|
Line 766 nd6_na_input(struct mbuf *m, int off, in |
|
const struct in6_addr *in6; |
const struct in6_addr *in6; |
int s; |
int s; |
|
|
in6 = &satocsin6(rt_getkey(rt))->sin6_addr; |
in6 = &ln->r_l3addr.addr6; |
|
|
/* |
/* |
* Lock to protect the default router list. |
* Lock to protect the default router list. |
Line 779 nd6_na_input(struct mbuf *m, int off, in |
|
Line 775 nd6_na_input(struct mbuf *m, int off, in |
|
* context. However, we keep it just for safety. |
* context. However, we keep it just for safety. |
*/ |
*/ |
s = splsoftnet(); |
s = splsoftnet(); |
dr = defrouter_lookup(in6, rt->rt_ifp); |
dr = defrouter_lookup(in6, ln->lle_tbl->llt_ifp); |
if (dr) |
if (dr) |
defrtrlist_del(dr, NULL); |
defrtrlist_del(dr, NULL); |
else if (!ip6_forwarding) { |
else if (!ip6_forwarding) { |
Line 790 nd6_na_input(struct mbuf *m, int off, in |
|
Line 786 nd6_na_input(struct mbuf *m, int off, in |
|
* (e.g. redirect case). So we must |
* (e.g. redirect case). So we must |
* call rt6_flush explicitly. |
* call rt6_flush explicitly. |
*/ |
*/ |
rt6_flush(&ip6->ip6_src, rt->rt_ifp); |
rt6_flush(&ip6->ip6_src, ln->lle_tbl->llt_ifp); |
} |
} |
splx(s); |
splx(s); |
} |
} |
ln->ln_router = is_router; |
ln->ln_router = is_router; |
} |
} |
rt->rt_flags &= ~RTF_REJECT; |
/* |
|
* XXX: does this matter? |
|
* rt->rt_flags &= ~RTF_REJECT; |
|
*/ |
ln->ln_asked = 0; |
ln->ln_asked = 0; |
nd6_llinfo_release_pkts(ln, ifp, rt); |
nd6_llinfo_release_pkts(ln, ifp); |
|
/* FIXME */ |
|
#if 0 |
if (rt_announce) /* tell user process about any new lladdr */ |
if (rt_announce) /* tell user process about any new lladdr */ |
rt_newmsg(RTM_CHANGE, rt); |
rt_newmsg(RTM_CHANGE, rt); |
|
#endif |
|
|
freeit: |
freeit: |
|
if (ln != NULL) |
|
LLE_WUNLOCK(ln); |
|
|
m_freem(m); |
m_freem(m); |
if (rt != NULL) |
|
rtfree(rt); |
|
return; |
return; |
|
|
bad: |
bad: |
|
if (ln != NULL) |
|
LLE_WUNLOCK(ln); |
|
|
ICMP6_STATINC(ICMP6_STAT_BADNA); |
ICMP6_STATINC(ICMP6_STAT_BADNA); |
m_freem(m); |
m_freem(m); |
} |
} |