From owner-svn-src-all@FreeBSD.ORG Mon Nov 10 16:01:40 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 5C44DF7B; Mon, 10 Nov 2014 16:01:40 +0000 (UTC) Received: from svn.freebsd.org (svn.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 3D72865C; Mon, 10 Nov 2014 16:01:40 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id sAAG1enr038796; Mon, 10 Nov 2014 16:01:40 GMT (envelope-from melifaro@FreeBSD.org) Received: (from melifaro@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id sAAG1dlF038794; Mon, 10 Nov 2014 16:01:39 GMT (envelope-from melifaro@FreeBSD.org) Message-Id: <201411101601.sAAG1dlF038794@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: melifaro set sender to melifaro@FreeBSD.org using -f From: "Alexander V. Chernikov" Date: Mon, 10 Nov 2014 16:01:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r274347 - head/sys/netinet6 X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Nov 2014 16:01:40 -0000 Author: melifaro Date: Mon Nov 10 16:01:39 2014 New Revision: 274347 URL: https://svnweb.freebsd.org/changeset/base/274347 Log: * Make nd6_dad_duplicated() constant. * Simplify refcounting by using nd6_dad_add() / nd6_dad_del(). Reviewed by: ae MFC after: 2 weeks Sponsored by: Yandex LLC Modified: head/sys/netinet6/nd6.h head/sys/netinet6/nd6_nbr.c Modified: head/sys/netinet6/nd6.h ============================================================================== --- head/sys/netinet6/nd6.h Mon Nov 10 16:01:31 2014 (r274346) +++ head/sys/netinet6/nd6.h Mon Nov 10 16:01:39 2014 (r274347) @@ -430,7 +430,6 @@ void nd6_ns_output(struct ifnet *, const caddr_t nd6_ifptomac(struct ifnet *); void nd6_dad_start(struct ifaddr *, int); void nd6_dad_stop(struct ifaddr *); -void nd6_dad_duplicated(struct ifaddr *); /* nd6_rtr.c */ void nd6_rs_input(struct mbuf *, int, int); Modified: head/sys/netinet6/nd6_nbr.c ============================================================================== --- head/sys/netinet6/nd6_nbr.c Mon Nov 10 16:01:31 2014 (r274346) +++ head/sys/netinet6/nd6_nbr.c Mon Nov 10 16:01:39 2014 (r274347) @@ -79,9 +79,12 @@ __FBSDID("$FreeBSD$"); struct dadq; static struct dadq *nd6_dad_find(struct ifaddr *); +static void nd6_dad_add(struct dadq *dp); +static void nd6_dad_del(struct dadq *dp); static void nd6_dad_starttimer(struct dadq *, int); static void nd6_dad_stoptimer(struct dadq *); static void nd6_dad_timer(struct dadq *); +static void nd6_dad_duplicated(struct ifaddr *, struct dadq *); static void nd6_dad_ns_output(struct dadq *, struct ifaddr *); static void nd6_dad_ns_input(struct ifaddr *); static void nd6_dad_na_input(struct ifaddr *); @@ -1179,6 +1182,26 @@ static VNET_DEFINE(struct rwlock, dad_rw #define DADQ_WLOCK() rw_wlock(&V_dad_rwlock) #define DADQ_WUNLOCK() rw_wunlock(&V_dad_rwlock) +static void +nd6_dad_add(struct dadq *dp) +{ + + ifa_ref(dp->dad_ifa); /* just for safety */ + DADQ_WLOCK(); + TAILQ_INSERT_TAIL(&V_dadq, (struct dadq *)dp, dad_list); + DADQ_WUNLOCK(); +} + +static void +nd6_dad_del(struct dadq *dp) +{ + + ifa_free(dp->dad_ifa); + DADQ_WLOCK(); + TAILQ_REMOVE(&V_dadq, (struct dadq *)dp, dad_list); + DADQ_WUNLOCK(); +} + static struct dadq * nd6_dad_find(struct ifaddr *ifa) { @@ -1270,10 +1293,6 @@ nd6_dad_start(struct ifaddr *ifa, int de #ifdef VIMAGE dp->dad_vnet = curvnet; #endif - DADQ_WLOCK(); - TAILQ_INSERT_TAIL(&V_dadq, (struct dadq *)dp, dad_list); - DADQ_WUNLOCK(); - nd6log((LOG_DEBUG, "%s: starting DAD for %s\n", if_name(ifa->ifa_ifp), ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr))); @@ -1284,10 +1303,10 @@ nd6_dad_start(struct ifaddr *ifa, int de * (re)initialization. */ dp->dad_ifa = ifa; - ifa_ref(ifa); /* just for safety */ dp->dad_count = V_ip6_dad_count; dp->dad_ns_icount = dp->dad_na_icount = 0; dp->dad_ns_ocount = dp->dad_ns_tcount = 0; + nd6_dad_add(dp); if (delay == 0) { nd6_dad_ns_output(dp, ifa); nd6_dad_starttimer(dp, @@ -1315,12 +1334,8 @@ nd6_dad_stop(struct ifaddr *ifa) nd6_dad_stoptimer(dp); - DADQ_WLOCK(); - TAILQ_REMOVE(&V_dadq, (struct dadq *)dp, dad_list); - DADQ_WUNLOCK(); + nd6_dad_del(dp); free(dp, M_IP6NDP); - dp = NULL; - ifa_free(ifa); } static void @@ -1367,12 +1382,9 @@ nd6_dad_timer(struct dadq *dp) nd6log((LOG_INFO, "%s: could not run DAD, driver problem?\n", if_name(ifa->ifa_ifp))); - DADQ_WLOCK(); - TAILQ_REMOVE(&V_dadq, (struct dadq *)dp, dad_list); - DADQ_WUNLOCK(); + nd6_dad_del(dp); free(dp, M_IP6NDP); dp = NULL; - ifa_free(ifa); goto done; } @@ -1408,8 +1420,8 @@ nd6_dad_timer(struct dadq *dp) if (duplicate) { /* (*dp) will be freed in nd6_dad_duplicated() */ + nd6_dad_duplicated(ifa, dp); dp = NULL; - nd6_dad_duplicated(ifa); } else { /* * We are done with DAD. No NA came, no NS came. @@ -1425,12 +1437,9 @@ nd6_dad_timer(struct dadq *dp) if_name(ifa->ifa_ifp), ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr))); - DADQ_WLOCK(); - TAILQ_REMOVE(&V_dadq, (struct dadq *)dp, dad_list); - DADQ_WUNLOCK(); + nd6_dad_del(dp); free(dp, M_IP6NDP); dp = NULL; - ifa_free(ifa); } } @@ -1439,19 +1448,12 @@ done: } void -nd6_dad_duplicated(struct ifaddr *ifa) +nd6_dad_duplicated(struct ifaddr *ifa, struct dadq *dp) { struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; struct ifnet *ifp; - struct dadq *dp; char ip6buf[INET6_ADDRSTRLEN]; - dp = nd6_dad_find(ifa); - if (dp == NULL) { - log(LOG_ERR, "nd6_dad_duplicated: DAD structure not found\n"); - return; - } - log(LOG_ERR, "%s: DAD detected duplicate IPv6 address %s: " "NS in/out=%d/%d, NA in=%d\n", if_name(ifa->ifa_ifp), ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr), @@ -1504,12 +1506,8 @@ nd6_dad_duplicated(struct ifaddr *ifa) } } - DADQ_WLOCK(); - TAILQ_REMOVE(&V_dadq, (struct dadq *)dp, dad_list); - DADQ_WUNLOCK(); + nd6_dad_del(dp); free(dp, M_IP6NDP); - dp = NULL; - ifa_free(ifa); } static void @@ -1568,8 +1566,8 @@ nd6_dad_ns_input(struct ifaddr *ifa) /* XXX more checks for loopback situation - see nd6_dad_timer too */ if (duplicate) { + nd6_dad_duplicated(ifa, dp); dp = NULL; /* will be freed in nd6_dad_duplicated() */ - nd6_dad_duplicated(ifa); } else { /* * not sure if I got a duplicate. @@ -1593,5 +1591,5 @@ nd6_dad_na_input(struct ifaddr *ifa) dp->dad_na_icount++; /* remove the address. */ - nd6_dad_duplicated(ifa); + nd6_dad_duplicated(ifa, dp); }