From owner-svn-src-head@freebsd.org Mon Sep 21 11:19:55 2015 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 58CB6A06ACC; Mon, 21 Sep 2015 11:19:55 +0000 (UTC) (envelope-from melifaro@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3CC411F5D; Mon, 21 Sep 2015 11:19:55 +0000 (UTC) (envelope-from melifaro@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id t8LBJt1X077573; Mon, 21 Sep 2015 11:19:55 GMT (envelope-from melifaro@FreeBSD.org) Received: (from melifaro@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t8LBJsLE077569; Mon, 21 Sep 2015 11:19:54 GMT (envelope-from melifaro@FreeBSD.org) Message-Id: <201509211119.t8LBJsLE077569@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: melifaro set sender to melifaro@FreeBSD.org using -f From: "Alexander V. Chernikov" Date: Mon, 21 Sep 2015 11:19:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r288062 - in head/sys: netinet netinet6 X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 21 Sep 2015 11:19:55 -0000 Author: melifaro Date: Mon Sep 21 11:19:53 2015 New Revision: 288062 URL: https://svnweb.freebsd.org/changeset/base/288062 Log: Unify nd6 state switching by using newly-created nd6_llinfo_setstate() function. The change is mostly mechanical with the following exception: Last piece of nd6_resolve_slow() was refactored: ND6_LLINFO_PERMANENT condition was removed as always-true, explicit ND6_LLINFO_NOSTATE -> ND6_LLINFO_INCOMPLETE state transition was removed as duplicate. Reviewed by: ae Sponsored by: Yandex LLC Modified: head/sys/netinet/toecore.c head/sys/netinet6/nd6.c head/sys/netinet6/nd6.h head/sys/netinet6/nd6_nbr.c Modified: head/sys/netinet/toecore.c ============================================================================== --- head/sys/netinet/toecore.c Mon Sep 21 10:27:30 2015 (r288061) +++ head/sys/netinet/toecore.c Mon Sep 21 11:19:53 2015 (r288062) @@ -468,7 +468,6 @@ restart: lle = nd6_alloc(&sin6->sin6_addr, 0, ifp); if (lle == NULL) return (ENOMEM); /* Couldn't create entry in cache. */ - lle->ln_state = ND6_LLINFO_INCOMPLETE; IF_AFDATA_WLOCK(ifp); LLE_WLOCK(lle); lle_tmp = nd6_lookup(&sin6->sin6_addr, ND6_EXCLUSIVE, ifp); @@ -478,8 +477,7 @@ restart: IF_AFDATA_WUNLOCK(ifp); if (lle_tmp == NULL) { /* Arm timer for newly-created entry and send NS */ - nd6_llinfo_settimer_locked(lle, - (long)ND_IFINFO(ifp)->retrans * hz / 1000); + nd6_llinfo_setstate(lle, ND6_LLINFO_INCOMPLETE); LLE_WUNLOCK(lle); nd6_ns_output(ifp, NULL, NULL, &sin6->sin6_addr, 0); @@ -503,8 +501,7 @@ restart: LLE_WLOCK_ASSERT(lle); lle->la_asked = 0; - lle->ln_state = ND6_LLINFO_DELAY; - nd6_llinfo_settimer_locked(lle, (long)V_nd6_delay * hz); + nd6_llinfo_setstate(lle, ND6_LLINFO_DELAY); } if (lle->la_flags & LLE_VALID) { Modified: head/sys/netinet6/nd6.c ============================================================================== --- head/sys/netinet6/nd6.c Mon Sep 21 10:27:30 2015 (r288061) +++ head/sys/netinet6/nd6.c Mon Sep 21 11:19:53 2015 (r288062) @@ -539,6 +539,44 @@ nd6_llinfo_get_holdsrc(struct llentry *l return (src); } +/* + * Switch @lle state to new state optionally arming timers. + */ +void +nd6_llinfo_setstate(struct llentry *lle, int newstate) +{ + struct ifnet *ifp; + long delay; + + delay = 0; + + switch (newstate) { + case ND6_LLINFO_INCOMPLETE: + ifp = lle->lle_tbl->llt_ifp; + delay = (long)ND_IFINFO(ifp)->retrans * hz / 1000; + break; + case ND6_LLINFO_REACHABLE: + if (!ND6_LLINFO_PERMANENT(lle)) { + ifp = lle->lle_tbl->llt_ifp; + delay = (long)ND_IFINFO(ifp)->reachable * hz; + } + break; + case ND6_LLINFO_STALE: + delay = (long)V_nd6_gctimer * hz; + break; + case ND6_LLINFO_DELAY: + lle->la_asked = 0; + delay = (long)V_nd6_delay * hz; + break; + } + + if (delay > 0) + nd6_llinfo_settimer_locked(lle, delay); + + lle->ln_state = newstate; +} + + void nd6_llinfo_settimer(struct llentry *ln, long tick) { @@ -638,10 +676,8 @@ nd6_llinfo_timer(void *arg) } break; case ND6_LLINFO_REACHABLE: - if (!ND6_LLINFO_PERMANENT(ln)) { - ln->ln_state = ND6_LLINFO_STALE; - nd6_llinfo_settimer_locked(ln, (long)V_nd6_gctimer * hz); - } + if (!ND6_LLINFO_PERMANENT(ln)) + nd6_llinfo_setstate(ln, ND6_LLINFO_STALE); break; case ND6_LLINFO_STALE: @@ -657,12 +693,10 @@ nd6_llinfo_timer(void *arg) if (ndi && (ndi->flags & ND6_IFF_PERFORMNUD) != 0) { /* We need NUD */ ln->la_asked = 1; - ln->ln_state = ND6_LLINFO_PROBE; + nd6_llinfo_setstate(ln, ND6_LLINFO_PROBE); send_ns = 1; - } else { - ln->ln_state = ND6_LLINFO_STALE; /* XXX */ - nd6_llinfo_settimer_locked(ln, (long)V_nd6_gctimer * hz); - } + } else + nd6_llinfo_setstate(ln, ND6_LLINFO_STALE); /* XXX */ break; case ND6_LLINFO_PROBE: if (ln->la_asked < V_nd6_umaxtries) { @@ -1316,11 +1350,7 @@ nd6_nud_hint(struct rtentry *rt, struct } } - ln->ln_state = ND6_LLINFO_REACHABLE; - if (!ND6_LLINFO_PERMANENT(ln)) { - nd6_llinfo_settimer_locked(ln, - (long)ND_IFINFO(rt->rt_ifp)->reachable * hz); - } + nd6_llinfo_setstate(ln, ND6_LLINFO_REACHABLE); done: LLE_WUNLOCK(ln); } @@ -1740,8 +1770,7 @@ nd6_cache_lladdr(struct ifnet *ifp, stru if (ln_tmp == NULL) { /* No existing lle, mark as new entry */ is_newentry = 1; - ln->ln_state = ND6_LLINFO_STALE; - nd6_llinfo_settimer_locked(ln, (long)V_nd6_gctimer * hz); + nd6_llinfo_setstate(ln, ND6_LLINFO_STALE); } else { lltable_free_entry(LLTABLE6(ifp), ln); ln = ln_tmp; @@ -1788,8 +1817,7 @@ nd6_cache_lladdr(struct ifnet *ifp, stru */ bcopy(lladdr, &ln->ll_addr, ifp->if_addrlen); ln->la_flags |= LLE_VALID; - ln->ln_state = ND6_LLINFO_STALE; - nd6_llinfo_settimer_locked(ln, (long)V_nd6_gctimer * hz); + nd6_llinfo_setstate(ln, ND6_LLINFO_STALE); EVENTHANDLER_INVOKE(lle_event, ln, LLENTRY_RESOLVED); @@ -1892,9 +1920,7 @@ nd6_grab_holdchain(struct llentry *ln, s * detection on expiration. * (RFC 2461 7.3.3) */ - ln->la_asked = 0; - ln->ln_state = ND6_LLINFO_DELAY; - nd6_llinfo_settimer_locked(ln, (long)V_nd6_delay * hz); + nd6_llinfo_setstate(ln, ND6_LLINFO_DELAY); } } @@ -2034,6 +2060,8 @@ nd6_resolve_slow(struct ifnet *ifp, stru const struct sockaddr_in6 *dst, u_char *desten, uint32_t *pflags) { struct llentry *lle = NULL, *lle_tmp; + struct in6_addr *psrc, src; + int send_ns; /* * Address resolution or Neighbor Unreachability Detection @@ -2061,7 +2089,6 @@ nd6_resolve_slow(struct ifnet *ifp, stru m_freem(m); return (ENOBUFS); } - lle->ln_state = ND6_LLINFO_NOSTATE; IF_AFDATA_WLOCK(ifp); LLE_WLOCK(lle); @@ -2097,11 +2124,8 @@ nd6_resolve_slow(struct ifnet *ifp, stru * neighbor unreachability detection on expiration. * (RFC 2461 7.3.3) */ - if (lle->ln_state == ND6_LLINFO_STALE) { - lle->la_asked = 0; - lle->ln_state = ND6_LLINFO_DELAY; - nd6_llinfo_settimer_locked(lle, (long)V_nd6_delay * hz); - } + if (lle->ln_state == ND6_LLINFO_STALE) + nd6_llinfo_setstate(lle, ND6_LLINFO_DELAY); /* * If the neighbor cache entry has a state other than INCOMPLETE @@ -2123,8 +2147,6 @@ nd6_resolve_slow(struct ifnet *ifp, stru * does not exceed nd6_maxqueuelen. When it exceeds nd6_maxqueuelen, * the oldest packet in the queue will be removed. */ - if (lle->ln_state == ND6_LLINFO_NOSTATE) - lle->ln_state = ND6_LLINFO_INCOMPLETE; if (lle->la_hold != NULL) { struct mbuf *m_hold; @@ -2151,20 +2173,22 @@ nd6_resolve_slow(struct ifnet *ifp, stru /* * If there has been no NS for the neighbor after entering the * INCOMPLETE state, send the first solicitation. + * Note that for newly-created lle la_asked will be 0, + * so we will transition from ND6_LLINFO_NOSTATE to + * ND6_LLINFO_INCOMPLETE state here. */ - if (!ND6_LLINFO_PERMANENT(lle) && lle->la_asked == 0) { - struct in6_addr src, *psrc; + psrc = NULL; + send_ns = 0; + if (lle->la_asked == 0) { lle->la_asked++; - - nd6_llinfo_settimer_locked(lle, - (long)ND_IFINFO(ifp)->retrans * hz / 1000); + send_ns = 1; psrc = nd6_llinfo_get_holdsrc(lle, &src); - LLE_WUNLOCK(lle); - nd6_ns_output(ifp, psrc, NULL, &dst->sin6_addr, NULL); - } else { - /* We did the lookup so we need to do the unlock here. */ - LLE_WUNLOCK(lle); + + nd6_llinfo_setstate(lle, ND6_LLINFO_INCOMPLETE); } + LLE_WUNLOCK(lle); + if (send_ns != 0) + nd6_ns_output(ifp, psrc, NULL, &dst->sin6_addr, NULL); return (EWOULDBLOCK); } Modified: head/sys/netinet6/nd6.h ============================================================================== --- head/sys/netinet6/nd6.h Mon Sep 21 10:27:30 2015 (r288061) +++ head/sys/netinet6/nd6.h Mon Sep 21 11:19:53 2015 (r288062) @@ -409,6 +409,7 @@ int nd6_options(union nd_opts *); struct llentry *nd6_lookup(const struct in6_addr *, int, struct ifnet *); struct llentry *nd6_alloc(const struct in6_addr *, int, struct ifnet *); void nd6_setmtu(struct ifnet *); +void nd6_llinfo_setstate(struct llentry *lle, int newstate); void nd6_llinfo_settimer(struct llentry *, long); void nd6_llinfo_settimer_locked(struct llentry *, long); void nd6_timer(void *); Modified: head/sys/netinet6/nd6_nbr.c ============================================================================== --- head/sys/netinet6/nd6_nbr.c Mon Sep 21 10:27:30 2015 (r288061) +++ head/sys/netinet6/nd6_nbr.c Mon Sep 21 11:19:53 2015 (r288062) @@ -769,16 +769,10 @@ nd6_na_input(struct mbuf *m, int off, in ln->la_flags |= LLE_VALID; EVENTHANDLER_INVOKE(lle_event, ln, LLENTRY_RESOLVED); if (is_solicited) { - ln->ln_state = ND6_LLINFO_REACHABLE; + nd6_llinfo_setstate(ln, ND6_LLINFO_REACHABLE); ln->ln_byhint = 0; - if (!ND6_LLINFO_PERMANENT(ln)) { - nd6_llinfo_settimer_locked(ln, - (long)ND_IFINFO(ln->lle_tbl->llt_ifp)->reachable * hz); - } - } else { - ln->ln_state = ND6_LLINFO_STALE; - nd6_llinfo_settimer_locked(ln, (long)V_nd6_gctimer * hz); - } + } else + nd6_llinfo_setstate(ln, ND6_LLINFO_STALE); if ((ln->ln_router = is_router) != 0) { /* * This means a router's state has changed from @@ -829,10 +823,8 @@ nd6_na_input(struct mbuf *m, int off, in * If state is REACHABLE, make it STALE. * no other updates should be done. */ - if (ln->ln_state == ND6_LLINFO_REACHABLE) { - ln->ln_state = ND6_LLINFO_STALE; - nd6_llinfo_settimer_locked(ln, (long)V_nd6_gctimer * hz); - } + if (ln->ln_state == ND6_LLINFO_REACHABLE) + nd6_llinfo_setstate(ln, ND6_LLINFO_STALE); goto freeit; } else if (is_override /* (2a) */ || (!is_override && (lladdr != NULL && !llchange)) /* (2b) */ @@ -853,18 +845,11 @@ nd6_na_input(struct mbuf *m, int off, in * changed, make it STALE. */ if (is_solicited) { - ln->ln_state = ND6_LLINFO_REACHABLE; ln->ln_byhint = 0; - if (!ND6_LLINFO_PERMANENT(ln)) { - nd6_llinfo_settimer_locked(ln, - (long)ND_IFINFO(ifp)->reachable * hz); - } + nd6_llinfo_setstate(ln, ND6_LLINFO_REACHABLE); } else { - if (lladdr != NULL && llchange) { - ln->ln_state = ND6_LLINFO_STALE; - nd6_llinfo_settimer_locked(ln, - (long)V_nd6_gctimer * hz); - } + if (lladdr != NULL && llchange) + nd6_llinfo_setstate(ln, ND6_LLINFO_STALE); } }