From owner-freebsd-net@FreeBSD.ORG Thu Mar 8 02:19:08 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 3E4531065674 for ; Thu, 8 Mar 2012 02:19:08 +0000 (UTC) (envelope-from prabhakar.lakhera@gmail.com) Received: from mail-yx0-f182.google.com (mail-yx0-f182.google.com [209.85.213.182]) by mx1.freebsd.org (Postfix) with ESMTP id F2D108FC14 for ; Thu, 8 Mar 2012 02:19:07 +0000 (UTC) Received: by yenl9 with SMTP id l9so6157yen.13 for ; Wed, 07 Mar 2012 18:19:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=++mftdXNMuQaLmvlTnXE2Ki93QZwZjTk3DYzeR5F7Ec=; b=Lko1Zp+YRIPozmakX01QCH9WCpvX2rjqVudppn39+NXuGsUtxAbv31AoTdvPvMYJxK bcMeFWDtv69rVUEH+ldwk33WvFKPfD2StMwwGk/KBSZls2SXWBPbfi/4Allqf+wmRcro SuhgkbRfUSxqv/dXOk/EQVzM6eSvisPLcYKX8D56O2Y54I+Jgrru5RYdI65j35hlD43K FJysqwyU59UQEqw1d1bOyp0JXkqErLkax5mmutBZP+aGrsbWZjXlXR/zYdLDYJD5cxwh BCtmzhNdjR0qlGOyRg61MolRPDrAwurt5IRxV+O1MIMct7Jk9KYKYY+HiE77DmLtJi5P 6MOg== MIME-Version: 1.0 Received: by 10.236.192.230 with SMTP id i66mr8206139yhn.116.1331171512486; Wed, 07 Mar 2012 17:51:52 -0800 (PST) Received: by 10.101.61.11 with HTTP; Wed, 7 Mar 2012 17:51:52 -0800 (PST) Date: Wed, 7 Mar 2012 17:51:52 -0800 Message-ID: From: prabhakar lakhera To: freebsd-net@freebsd.org Content-Type: text/plain; charset=ISO-8859-1 X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Subject: Doubt regarding IPv6 DAD detection code X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 08 Mar 2012 02:19:08 -0000 Hi, I was puzzled to look at DAD detection code in FreeBSD. We check for counters for any received NA/NS for DAD in nd6_dad_timer: if (dp->dad_na_icount) { 1326 /* 1327 * the check is in nd6_dad_na_input(), 1328 * but just in case 1329 */ 1330 duplicate++; 1331 } 1332 1333 if (dp->dad_ns_icount) { 1334 /* We've seen NS, means DAD has failed. */ 1335 duplicate++; 1336 } 1337 1338 if (duplicate) { 1339 /* (*dp) will be freed in nd6_dad_duplicated() */ 1340 dp = NULL; 1341 nd6_dad_duplicated(ifa); the function later calls nd6_dad_duplicated to perform the remaining work if the address is detected duplicate. nd6_dad_duplicated also gets called from nd6_dad_na_input and nd6_dad_ns_input, both the functions are the only places which increment the input NA/NS counters respectively. 1505 static void 1506 nd6_dad_na_input(struct ifaddr *ifa) 1507 { 1508 struct dadq *dp; 1509 1510 if (ifa == NULL) 1511 panic("ifa == NULL in nd6_dad_na_input"); 1512 1513 dp = nd6_dad_find(ifa); 1514 if (dp) 1515 dp->dad_na_icount++; 1516 1517 /* remove the address. */ 1518 nd6_dad_duplicated(ifa); 1519 } nd6_dad_duplicated stops the timer among other things. Why nd6_dad_timer need check on these counters if we stop the timer on DAD failure anyways? Ok.. may be just an optimization which just "hopes" that the counters have been updated but the nd6_dad_*_input has not yet called nd6_dad_duplicated. Can the this timer and na packet processing ever run in parallel, I don;t see dp being protected by any locks, nor does it seem that it's been reference counted. Any explanation will be highly appreciated. Best, Prabhakar