From owner-svn-src-all@FreeBSD.ORG Tue May 19 08:30:05 2015 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 161C5ABE; Tue, 19 May 2015 08:30:05 +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 EBA4010AF; Tue, 19 May 2015 08:30:04 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t4J8U45j099901; Tue, 19 May 2015 08:30:04 GMT (envelope-from ae@FreeBSD.org) Received: (from ae@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t4J8U4k8099900; Tue, 19 May 2015 08:30:04 GMT (envelope-from ae@FreeBSD.org) Message-Id: <201505190830.t4J8U4k8099900@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: ae set sender to ae@FreeBSD.org using -f From: "Andrey V. Elsukov" Date: Tue, 19 May 2015 08:30:04 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r283101 - head/sys/netipsec 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.20 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: Tue, 19 May 2015 08:30:05 -0000 Author: ae Date: Tue May 19 08:30:04 2015 New Revision: 283101 URL: https://svnweb.freebsd.org/changeset/base/283101 Log: Teach key_expire() send SADB_EXPIRE message with the SADB_EXT_LIFETIME_HARD extension header type. The key_flush_sad() now will send SADB_EXPIRE message when HARD lifetime expires. This is required by RFC 2367 and some keying daemons rely on these messages. HARD lifetime messages have precedence over SOFT lifetime messages, so now they will be checked first. Also now SADB_EXPIRE messages will be send even the SA has not been used, because keying daemons might want to rekey such SA. PR: 200282, 200283 Submitted by: Tobias Brunner MFC after: 2 weeks Modified: head/sys/netipsec/key.c Modified: head/sys/netipsec/key.c ============================================================================== --- head/sys/netipsec/key.c Tue May 19 08:00:39 2015 (r283100) +++ head/sys/netipsec/key.c Tue May 19 08:30:04 2015 (r283101) @@ -537,7 +537,7 @@ static int key_acquire2(struct socket *, const struct sadb_msghdr *); static int key_register(struct socket *, struct mbuf *, const struct sadb_msghdr *); -static int key_expire(struct secasvar *); +static int key_expire(struct secasvar *, int); static int key_flush(struct socket *, struct mbuf *, const struct sadb_msghdr *); static int key_dump(struct socket *, struct mbuf *, @@ -4242,41 +4242,29 @@ key_flush_sad(time_t now) "time, why?\n", __func__)); continue; } - - /* check SOFT lifetime */ - if (sav->lft_s->addtime != 0 && - now - sav->created > sav->lft_s->addtime) { - key_sa_chgstate(sav, SADB_SASTATE_DYING); - /* - * Actually, only send expire message if - * SA has been used, as it was done before, - * but should we always send such message, - * and let IKE daemon decide if it should be - * renegotiated or not ? - * XXX expire message will actually NOT be - * sent if SA is only used after soft - * lifetime has been reached, see below - * (DYING state) - */ - if (sav->lft_c->usetime != 0) - key_expire(sav); - } - /* check SOFT lifetime by bytes */ /* - * XXX I don't know the way to delete this SA - * when new SA is installed. Caution when it's - * installed too big lifetime by time. + * RFC 2367: + * HARD lifetimes MUST take precedence over SOFT + * lifetimes, meaning if the HARD and SOFT lifetimes + * are the same, the HARD lifetime will appear on the + * EXPIRE message. */ - else if (sav->lft_s->bytes != 0 && - sav->lft_s->bytes < sav->lft_c->bytes) { - + /* check HARD lifetime */ + if ((sav->lft_h->addtime != 0 && + now - sav->created > sav->lft_h->addtime) || + (sav->lft_h->bytes != 0 && + sav->lft_h->bytes < sav->lft_c->bytes)) { + key_sa_chgstate(sav, SADB_SASTATE_DEAD); + key_expire(sav, 1); + KEY_FREESAV(&sav); + } + /* check SOFT lifetime */ + else if ((sav->lft_s->addtime != 0 && + now - sav->created > sav->lft_s->addtime) || + (sav->lft_s->bytes != 0 && + sav->lft_s->bytes < sav->lft_c->bytes)) { key_sa_chgstate(sav, SADB_SASTATE_DYING); - /* - * XXX If we keep to send expire - * message in the status of - * DYING. Do remove below code. - */ - key_expire(sav); + key_expire(sav, 0); } } @@ -4295,6 +4283,7 @@ key_flush_sad(time_t now) if (sav->lft_h->addtime != 0 && now - sav->created > sav->lft_h->addtime) { + key_expire(sav, 1); key_sa_chgstate(sav, SADB_SASTATE_DEAD); KEY_FREESAV(&sav); } @@ -4311,12 +4300,13 @@ key_flush_sad(time_t now) * If there is no SA then sending * expire message. */ - key_expire(sav); + key_expire(sav, 0); } #endif /* check HARD lifetime by bytes */ else if (sav->lft_h->bytes != 0 && sav->lft_h->bytes < sav->lft_c->bytes) { + key_expire(sav, 1); key_sa_chgstate(sav, SADB_SASTATE_DEAD); KEY_FREESAV(&sav); } @@ -6721,7 +6711,7 @@ key_freereg(struct socket *so) * others : error number */ static int -key_expire(struct secasvar *sav) +key_expire(struct secasvar *sav, int hard) { int satype; struct mbuf *result = NULL, *m; @@ -6779,11 +6769,19 @@ key_expire(struct secasvar *sav) lt->sadb_lifetime_usetime = sav->lft_c->usetime; lt = (struct sadb_lifetime *)(mtod(m, caddr_t) + len / 2); lt->sadb_lifetime_len = PFKEY_UNIT64(sizeof(struct sadb_lifetime)); - lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; - lt->sadb_lifetime_allocations = sav->lft_s->allocations; - lt->sadb_lifetime_bytes = sav->lft_s->bytes; - lt->sadb_lifetime_addtime = sav->lft_s->addtime; - lt->sadb_lifetime_usetime = sav->lft_s->usetime; + if (hard) { + lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; + lt->sadb_lifetime_allocations = sav->lft_h->allocations; + lt->sadb_lifetime_bytes = sav->lft_h->bytes; + lt->sadb_lifetime_addtime = sav->lft_h->addtime; + lt->sadb_lifetime_usetime = sav->lft_h->usetime; + } else { + lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; + lt->sadb_lifetime_allocations = sav->lft_s->allocations; + lt->sadb_lifetime_bytes = sav->lft_s->bytes; + lt->sadb_lifetime_addtime = sav->lft_s->addtime; + lt->sadb_lifetime_usetime = sav->lft_s->usetime; + } m_cat(result, m); /* set sadb_address for source */