From patchwork Thu Jun 21 06:26:01 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fan Du X-Patchwork-Id: 166231 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id B2359B72DF for ; Thu, 21 Jun 2012 16:26:16 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754759Ab2FUG0P (ORCPT ); Thu, 21 Jun 2012 02:26:15 -0400 Received: from mail1.windriver.com ([147.11.146.13]:44447 "EHLO mail1.windriver.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754557Ab2FUG0N (ORCPT ); Thu, 21 Jun 2012 02:26:13 -0400 Received: from ALA-HCA.corp.ad.wrs.com (ala-hca [147.11.189.40]) by mail1.windriver.com (8.14.3/8.14.3) with ESMTP id q5L6Q8pT005512 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=FAIL); Wed, 20 Jun 2012 23:26:08 -0700 (PDT) Received: from pek-lpgbuild5.wrs.com (128.224.162.11) by ALA-HCA.corp.ad.wrs.com (147.11.189.50) with Microsoft SMTP Server id 14.1.255.0; Wed, 20 Jun 2012 23:26:07 -0700 From: Fan Du To: , CC: Subject: [PATCH] [XFRM] Fix unexpected SA hard expiration after changing date Date: Thu, 21 Jun 2012 14:26:01 +0800 Message-ID: <1340259961-30354-2-git-send-email-fdu@windriver.com> X-Mailer: git-send-email 1.7.11 In-Reply-To: <1340259961-30354-1-git-send-email-fdu@windriver.com> References: <1340259961-30354-1-git-send-email-fdu@windriver.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org After SA is setup, one timer is armed to detect soft/hard expiration, however the timer handler uses xtime to do the math. This makes hard expiration occurs first before soft expiration after setting new date with big interval. As a result new child SA is deleted before rekeying the new one. Signed-off-by: Fan Du --- include/net/xfrm.h | 3 +++ net/xfrm/xfrm_state.c | 21 +++++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 2933d74..8d16777 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -197,6 +197,8 @@ struct xfrm_state struct xfrm_lifetime_cur curlft; struct timer_list timer; + /* used to fix curlft->add_time when changing date */ + long saved_tmo; /* Last used time */ unsigned long lastused; @@ -218,6 +220,7 @@ struct xfrm_state /* xflags - make enum if more show up */ #define XFRM_TIME_DEFER 1 +#define XFRM_SOFT_EXPIRE 2 enum { XFRM_STATE_VOID, diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index fd77cf0..2b55244 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -442,8 +442,17 @@ static void xfrm_timer_handler(unsigned long data) if (x->lft.hard_add_expires_seconds) { long tmo = x->lft.hard_add_expires_seconds + x->curlft.add_time - now; - if (tmo <= 0) - goto expired; + if (tmo <= 0) { + if (x->xflags & XFRM_SOFT_EXPIRE) { + /* enter hard expire without soft expire first?! + * setting a new date could trigger this. + * workarbound: fix x->curflt.add_time by below: + */ + x->curlft.add_time = now - x->saved_tmo - 1; + tmo = x->lft.hard_add_expires_seconds - x->saved_tmo; + } else + goto expired; + } if (tmo < next) next = tmo; } @@ -460,10 +469,14 @@ static void xfrm_timer_handler(unsigned long data) if (x->lft.soft_add_expires_seconds) { long tmo = x->lft.soft_add_expires_seconds + x->curlft.add_time - now; - if (tmo <= 0) + if (tmo <= 0) { warn = 1; - else if (tmo < next) + x->xflags &= ~XFRM_SOFT_EXPIRE; + } else if (tmo < next) { next = tmo; + x->xflags |= XFRM_SOFT_EXPIRE; + x->saved_tmo = tmo; + } } if (x->lft.soft_use_expires_seconds) { long tmo = x->lft.soft_use_expires_seconds +