Index: sys/net/if_llatbl.h =================================================================== --- sys/net/if_llatbl.h +++ sys/net/if_llatbl.h @@ -263,6 +263,9 @@ lle->lle_tbl->llt_mark_used(lle); } +void llentry_request_feedback(struct llentry *lle); +time_t llentry_get_hittime(struct llentry *lle); + int lla_rt_output(struct rt_msghdr *, struct rt_addrinfo *); enum { Index: sys/net/if_llatbl.c =================================================================== --- sys/net/if_llatbl.c +++ sys/net/if_llatbl.c @@ -386,6 +386,26 @@ return (error); } +void +llentry_request_feedback(struct llentry *lle) +{ + LLE_REQ_LOCK(lle); + lle->r_skip_req = 1; + LLE_REQ_UNLOCK(lle); +} + +time_t +llentry_get_hittime(struct llentry *lle) +{ + time_t lle_hittime = 0; + + LLE_REQ_LOCK(lle); + if ((lle->r_skip_req == 0) && (lle_hittime < lle->lle_hittime)) + lle_hittime = lle->lle_hittime; + LLE_REQ_UNLOCK(lle); + + return (lle_hittime); +} /* * Update link-layer header for given @lle after * interface lladdr was changed. Index: sys/netinet/if_ether.c =================================================================== --- sys/netinet/if_ether.c +++ sys/netinet/if_ether.c @@ -207,7 +207,6 @@ { struct llentry *lle = (struct llentry *)arg; struct ifnet *ifp; - int r_skip_req; if (lle->la_flags & LLE_STATIC) { return; @@ -247,20 +246,14 @@ * fast path. Change state and re-schedule * ourselves. */ - LLE_REQ_LOCK(lle); - lle->r_skip_req = 1; - LLE_REQ_UNLOCK(lle); + llentry_request_feedback(lle); lle->ln_state = ARP_LLINFO_VERIFY; callout_schedule(&lle->lle_timer, hz * V_arpt_rexmit); LLE_WUNLOCK(lle); CURVNET_RESTORE(); return; case ARP_LLINFO_VERIFY: - LLE_REQ_LOCK(lle); - r_skip_req = lle->r_skip_req; - LLE_REQ_UNLOCK(lle); - - if (r_skip_req == 0 && lle->la_preempt > 0) { + if (llentry_get_hittime(lle) > 0 && lle->la_preempt > 0) { /* Entry was used, issue refresh request */ struct epoch_tracker et; struct in_addr dst; Index: sys/netinet6/nd6.c =================================================================== --- sys/netinet6/nd6.c +++ sys/netinet6/nd6.c @@ -617,7 +617,7 @@ static int 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; long delay; @@ -625,12 +625,9 @@ nd_gctimer = V_nd6_gctimer; nd_delay = V_nd6_delay; - LLE_REQ_LOCK(lle); - r_skip_req = lle->r_skip_req; - lle_hittime = lle->lle_hittime; - LLE_REQ_UNLOCK(lle); + lle_hittime = llentry_get_hittime(lle); - if (r_skip_req > 0) { + if (lle_hittime > 0) { /* * Nonzero r_skip_req value was set upon entering * STALE state. Since value was not changed, no @@ -709,9 +706,7 @@ * 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); + llentry_request_feedback(lle); nd_delay = V_nd6_delay; nd_gctimer = V_nd6_gctimer;