Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 17 Nov 2015 14:39:33 +0000 (UTC)
From:      Fabien Thomas <fabient@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r290982 - in head/sys: net netipsec
Message-ID:  <201511171439.tAHEdXl1041097@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: fabient
Date: Tue Nov 17 14:39:33 2015
New Revision: 290982
URL: https://svnweb.freebsd.org/changeset/base/290982

Log:
  Implement the sadb_x_policy_priority field as it is done in Linux:
  lower priority policies are inserted first.
  
  Submitted by:	Emeric Poupon <emeric.poupon@stormshield.eu>
  Reviewed by:	ae
  Sponsored by:	Stormshield

Modified:
  head/sys/net/pfkeyv2.h
  head/sys/netipsec/ipsec.h
  head/sys/netipsec/key.c

Modified: head/sys/net/pfkeyv2.h
==============================================================================
--- head/sys/net/pfkeyv2.h	Tue Nov 17 14:22:56 2015	(r290981)
+++ head/sys/net/pfkeyv2.h	Tue Nov 17 14:39:33 2015	(r290982)
@@ -225,7 +225,7 @@ struct sadb_x_policy {
   u_int8_t sadb_x_policy_dir;		/* direction, see ipsec.h */
   u_int8_t sadb_x_policy_reserved;
   u_int32_t sadb_x_policy_id;
-  u_int32_t sadb_x_policy_reserved2;
+  u_int32_t sadb_x_policy_priority;
 };
 _Static_assert(sizeof(struct sadb_x_policy) == 16, "struct size mismatch");
 

Modified: head/sys/netipsec/ipsec.h
==============================================================================
--- head/sys/netipsec/ipsec.h	Tue Nov 17 14:22:56 2015	(r290981)
+++ head/sys/netipsec/ipsec.h	Tue Nov 17 14:39:33 2015	(r290982)
@@ -92,6 +92,7 @@ struct secpolicy {
 	u_int state;
 #define	IPSEC_SPSTATE_DEAD	0
 #define	IPSEC_SPSTATE_ALIVE	1
+	u_int32_t priority;		/* priority of this policy */
 	u_int32_t id;			/* It's unique number on the system. */
 	/*
 	 * lifetime handler.

Modified: head/sys/netipsec/key.c
==============================================================================
--- head/sys/netipsec/key.c	Tue Nov 17 14:22:56 2015	(r290981)
+++ head/sys/netipsec/key.c	Tue Nov 17 14:39:33 2015	(r290982)
@@ -473,7 +473,7 @@ static void key_porttosaddr(struct socka
 	key_porttosaddr((struct sockaddr *)(saddr), (port))
 static struct mbuf *key_setsadbxsa2(u_int8_t, u_int32_t, u_int32_t);
 static struct mbuf *key_setsadbxpolicy(u_int16_t, u_int8_t,
-	u_int32_t);
+	u_int32_t, u_int32_t);
 static struct seckey *key_dup_keymsg(const struct sadb_key *, u_int, 
 				     struct malloc_type *);
 static struct seclifetime *key_dup_lifemsg(const struct sadb_lifetime *src,
@@ -1209,6 +1209,29 @@ key_unlink(struct secpolicy *sp)
 }
 
 /*
+ * insert a secpolicy into the SP database. Lower priorities first
+ */
+static void
+key_insertsp(struct secpolicy *newsp)
+{
+	struct secpolicy *sp;
+
+	SPTREE_WLOCK();
+	TAILQ_FOREACH(sp, &V_sptree[newsp->spidx.dir], chain) {
+		if (newsp->priority < sp->priority) {
+			TAILQ_INSERT_BEFORE(sp, newsp, chain);
+			goto done;
+		}
+	}
+
+	TAILQ_INSERT_TAIL(&V_sptree[newsp->spidx.dir], newsp, chain);
+
+done:
+	newsp->state = IPSEC_SPSTATE_ALIVE;
+	SPTREE_WUNLOCK();
+}
+
+/*
  * Must be called after calling key_allocsp().
  * For the packet with socket.
  */
@@ -1391,6 +1414,7 @@ key_msg2sp(struct sadb_x_policy *xpl0, s
 
 	newsp->spidx.dir = xpl0->sadb_x_policy_dir;
 	newsp->policy = xpl0->sadb_x_policy_type;
+	newsp->priority = xpl0->sadb_x_policy_priority;
 
 	/* check policy */
 	switch (xpl0->sadb_x_policy_type) {
@@ -1627,6 +1651,7 @@ key_sp2msg(struct secpolicy *sp)
 	xpl->sadb_x_policy_type = sp->policy;
 	xpl->sadb_x_policy_dir = sp->spidx.dir;
 	xpl->sadb_x_policy_id = sp->id;
+	xpl->sadb_x_policy_priority = sp->priority;
 	p = (caddr_t)xpl + sizeof(*xpl);
 
 	/* if is the policy for ipsec ? */
@@ -1904,10 +1929,7 @@ key_spdadd(struct socket *so, struct mbu
 	newsp->lifetime = lft ? lft->sadb_lifetime_addtime : 0;
 	newsp->validtime = lft ? lft->sadb_lifetime_usetime : 0;
 
-	SPTREE_WLOCK();
-	TAILQ_INSERT_TAIL(&V_sptree[newsp->spidx.dir], newsp, chain);
-	newsp->state = IPSEC_SPSTATE_ALIVE;
-	SPTREE_WUNLOCK();
+	key_insertsp(newsp);
 
 	/* delete the entry in spacqtree */
 	if (mhp->msg->sadb_msg_type == SADB_X_SPDUPDATE) {
@@ -3744,7 +3766,7 @@ key_porttosaddr(struct sockaddr *sa, u_i
  * set data into sadb_x_policy
  */
 static struct mbuf *
-key_setsadbxpolicy(u_int16_t type, u_int8_t dir, u_int32_t id)
+key_setsadbxpolicy(u_int16_t type, u_int8_t dir, u_int32_t id, u_int32_t priority)
 {
 	struct mbuf *m;
 	struct sadb_x_policy *p;
@@ -3764,6 +3786,7 @@ key_setsadbxpolicy(u_int16_t type, u_int
 	p->sadb_x_policy_type = type;
 	p->sadb_x_policy_dir = dir;
 	p->sadb_x_policy_id = id;
+	p->sadb_x_policy_priority = priority;
 
 	return m;
 }
@@ -6205,7 +6228,7 @@ key_acquire(const struct secasindex *sai
 
 	/* set sadb_x_policy */
 	if (sp) {
-		m = key_setsadbxpolicy(sp->policy, sp->spidx.dir, sp->id);
+		m = key_setsadbxpolicy(sp->policy, sp->spidx.dir, sp->id, sp->priority);
 		if (!m) {
 			error = ENOBUFS;
 			goto fail;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201511171439.tAHEdXl1041097>