Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet6/nd6.c
Show First 20 Lines • Show All 611 Lines • ▼ Show 20 Lines | |||||
* the next timer interval in @pdelay). | * the next timer interval in @pdelay). | ||||
* | * | ||||
* Returns zero value if original timer expired or we need to switch to | * Returns zero value if original timer expired or we need to switch to | ||||
* PROBE (store that in @do_switch variable). | * PROBE (store that in @do_switch variable). | ||||
*/ | */ | ||||
static int | static int | ||||
nd6_is_stale(struct llentry *lle, long *pdelay, int *do_switch) | nd6_is_stale(struct llentry *lle, long *pdelay, int *do_switch) | ||||
{ | { | ||||
int nd_delay, nd_gctimer, r_skip_req; | int nd_delay, nd_gctimer; | ||||
time_t lle_hittime; | time_t lle_hittime; | ||||
long delay; | long delay; | ||||
*do_switch = 0; | *do_switch = 0; | ||||
nd_gctimer = V_nd6_gctimer; | nd_gctimer = V_nd6_gctimer; | ||||
nd_delay = V_nd6_delay; | nd_delay = V_nd6_delay; | ||||
LLE_REQ_LOCK(lle); | lle_hittime = llentry_get_hittime(lle); | ||||
r_skip_req = lle->r_skip_req; | |||||
lle_hittime = lle->lle_hittime; | |||||
LLE_REQ_UNLOCK(lle); | |||||
if (r_skip_req > 0) { | if (lle_hittime == 0) { | ||||
/* | /* | ||||
* Nonzero r_skip_req value was set upon entering | * Datapath feedback has been requested upon entering | ||||
* STALE state. Since value was not changed, no | * STALE state. No packets has been passed using this lle. | ||||
* packets were passed using this lle. Ask for | * Ask for the timer reschedule and keep STALE state. | ||||
* timer reschedule and keep STALE state. | |||||
*/ | */ | ||||
delay = (long)(MIN(nd_gctimer, nd_delay)); | delay = (long)(MIN(nd_gctimer, nd_delay)); | ||||
delay *= hz; | delay *= hz; | ||||
if (lle->lle_remtime > delay) | if (lle->lle_remtime > delay) | ||||
lle->lle_remtime -= delay; | lle->lle_remtime -= delay; | ||||
else { | else { | ||||
delay = lle->lle_remtime; | delay = lle->lle_remtime; | ||||
lle->lle_remtime = 0; | lle->lle_remtime = 0; | ||||
▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | nd6_llinfo_setstate(struct llentry *lle, int newstate) | ||||
case ND6_LLINFO_REACHABLE: | case ND6_LLINFO_REACHABLE: | ||||
if (!ND6_LLINFO_PERMANENT(lle)) { | if (!ND6_LLINFO_PERMANENT(lle)) { | ||||
ifp = lle->lle_tbl->llt_ifp; | ifp = lle->lle_tbl->llt_ifp; | ||||
delay = (long)ND_IFINFO(ifp)->reachable * hz; | delay = (long)ND_IFINFO(ifp)->reachable * hz; | ||||
} | } | ||||
break; | break; | ||||
case ND6_LLINFO_STALE: | case ND6_LLINFO_STALE: | ||||
/* | llentry_request_feedback(lle); | ||||
* Notify fast path that we want to know if any packet | |||||
* is transmitted by setting r_skip_req. | |||||
*/ | |||||
LLE_REQ_LOCK(lle); | |||||
lle->r_skip_req = 1; | |||||
LLE_REQ_UNLOCK(lle); | |||||
nd_delay = V_nd6_delay; | nd_delay = V_nd6_delay; | ||||
nd_gctimer = V_nd6_gctimer; | nd_gctimer = V_nd6_gctimer; | ||||
delay = (long)(MIN(nd_gctimer, nd_delay)) * hz; | delay = (long)(MIN(nd_gctimer, nd_delay)) * hz; | ||||
remtime = (long)nd_gctimer * hz - delay; | remtime = (long)nd_gctimer * hz - delay; | ||||
break; | break; | ||||
case ND6_LLINFO_DELAY: | case ND6_LLINFO_DELAY: | ||||
lle->la_asked = 0; | lle->la_asked = 0; | ||||
▲ Show 20 Lines • Show All 1,526 Lines • ▼ Show 20 Lines | nd6_resolve(struct ifnet *ifp, int is_gw, struct mbuf *m, | ||||
ln = nd6_lookup(&dst6->sin6_addr, plle ? LLE_EXCLUSIVE : LLE_UNLOCKED, | ln = nd6_lookup(&dst6->sin6_addr, plle ? LLE_EXCLUSIVE : LLE_UNLOCKED, | ||||
ifp); | ifp); | ||||
if (ln != NULL && (ln->r_flags & RLLE_VALID) != 0) { | if (ln != NULL && (ln->r_flags & RLLE_VALID) != 0) { | ||||
/* Entry found, let's copy lle info */ | /* Entry found, let's copy lle info */ | ||||
bcopy(ln->r_linkdata, desten, ln->r_hdrlen); | bcopy(ln->r_linkdata, desten, ln->r_hdrlen); | ||||
if (pflags != NULL) | if (pflags != NULL) | ||||
*pflags = LLE_VALID | (ln->r_flags & RLLE_IFADDR); | *pflags = LLE_VALID | (ln->r_flags & RLLE_IFADDR); | ||||
/* Check if we have feedback request from nd6 timer */ | llentry_provide_feedback(ln); | ||||
if (ln->r_skip_req != 0) { | |||||
LLE_REQ_LOCK(ln); | |||||
ln->r_skip_req = 0; /* Notify that entry was used */ | |||||
ln->lle_hittime = time_uptime; | |||||
LLE_REQ_UNLOCK(ln); | |||||
} | |||||
if (plle) { | if (plle) { | ||||
LLE_ADDREF(ln); | LLE_ADDREF(ln); | ||||
*plle = ln; | *plle = ln; | ||||
LLE_WUNLOCK(ln); | LLE_WUNLOCK(ln); | ||||
} | } | ||||
return (0); | return (0); | ||||
} else if (plle && ln) | } else if (plle && ln) | ||||
LLE_WUNLOCK(ln); | LLE_WUNLOCK(ln); | ||||
▲ Show 20 Lines • Show All 391 Lines • Show Last 20 Lines |