From owner-freebsd-net@FreeBSD.ORG Fri Jul 27 09:39:25 2007 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CE9CA16A41A for ; Fri, 27 Jul 2007 09:39:25 +0000 (UTC) (envelope-from vanhu@zeninc.net) Received: from smtp.zeninc.net (reverse-25.fdn.fr [80.67.176.25]) by mx1.freebsd.org (Postfix) with ESMTP id 8FB3813C46E for ; Fri, 27 Jul 2007 09:39:25 +0000 (UTC) (envelope-from vanhu@zeninc.net) Received: from jayce.zen.inc (jayce.zen.inc [192.168.1.7]) by smtp.zeninc.net (smtpd) with ESMTP id EAD583F73 for ; Fri, 27 Jul 2007 11:39:22 +0200 (CEST) Received: by jayce.zen.inc (Postfix, from userid 1000) id 245582E464; Fri, 27 Jul 2007 11:39:23 +0200 (CEST) Date: Fri, 27 Jul 2007 11:39:22 +0200 From: VANHULLEBUS Yvan To: freebsd-net@freebsd.org Message-ID: <20070727093922.GA981@jayce.zen.inc> References: <46A81171.1040107@zyxel.com.tw> <46A9BAB4.9030309@zyxel.com.tw> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <46A9BAB4.9030309@zyxel.com.tw> User-Agent: All mail clients suck. This one just sucks less. Subject: Re: SADB_X_SPDFLUSH message handling for latest version of IPsec 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: Fri, 27 Jul 2007 09:39:25 -0000 On Fri, Jul 27, 2007 at 05:28:20PM +0800, blue wrote: [....] > I was tracing the codes so had the conclusion. in key_spdflush() in key.c, > the loop > > for (dir = 0; dir < IPSEC_DIR_MAX; dir++) { > SPTREE_LOCK(); > LIST_FOREACH(sp, &sptree[dir], chain) > sp->state = IPSEC_SPSTATE_DEAD; > SPTREE_UNLOCK(); > } > > only sets policy entry's status as DEAD, but not remove it from the SPD. On > the other hand, in KAME implementation (known as IPSEC in previous FreeBSD > version), the SP entry will be removed. > > for (sp = TAILQ_FIRST(&sptailq); sp; sp = nextsp) { > nextsp = TAILQ_NEXT(sp, tailq); > if (sp->persist) > continue; > if (sp->state == IPSEC_SPSTATE_DEAD) > continue; > key_sp_dead(sp); > key_sp_unlink(sp); > sp = NULL; > } Have a look at key_sp_unlink: static void key_sp_unlink(sp) struct secpolicy *sp; { /* remove from SP index */ if (__LIST_CHAINED(sp)) { LIST_REMOVE(sp, chain); key_freesp(sp); } } For now, it has just been removed from the list. And then have a look at key_freesp: void key_freesp(sp) struct secpolicy *sp; { /* sanity check */ if (sp == NULL) panic("key_freesp: NULL pointer is passed."); sp->refcnt--; KEYDEBUG(KEYDEBUG_IPSEC_STAMP, printf("DP freesp cause refcnt--:%d SP:%p\n", sp->refcnt, sp)); if (sp->refcnt == 0) key_delsp(sp); return; } The SPD entry will only be "really" removed if it's reference count is 0. In both IPSec stacks, the memory structure can't just be removed because some other parts of the kernel may still be using it (that's why there is a reference count). They just use different ways to mark the SP entry as "obsolete", and to clean the structure when it won't be used anymore... Yvan. -- NETASQ http://www.netasq.com