svn commit: r283101 - head/sys/netipsec

Andrey V. Elsukov ae at FreeBSD.org
Tue May 19 08:30:05 UTC 2015


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 <tobias at strongswan dot org>
  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 */


More information about the svn-src-all mailing list