Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 23 Dec 2016 14:22:32 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r310476 - projects/ipsec/sys/netipsec
Message-ID:  <201612231422.uBNEMW2h073413@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Fri Dec 23 14:22:32 2016
New Revision: 310476
URL: https://svnweb.freebsd.org/changeset/base/310476

Log:
  Add an ability to unregister IPsec transforms.
  
  Remove unused xf_flags field from xformsw structure. Add xform_attach()
  and xform_detach() functions. Use them in each xform_* file to register
  and unregister xform using SYSINIT interface.
  In key.c add xforms_lock to protect access to xforms list.

Modified:
  projects/ipsec/sys/netipsec/key.c
  projects/ipsec/sys/netipsec/xform.h
  projects/ipsec/sys/netipsec/xform_ah.c
  projects/ipsec/sys/netipsec/xform_esp.c
  projects/ipsec/sys/netipsec/xform_ipcomp.c
  projects/ipsec/sys/netipsec/xform_tcp.c

Modified: projects/ipsec/sys/netipsec/key.c
==============================================================================
--- projects/ipsec/sys/netipsec/key.c	Fri Dec 23 12:11:56 2016	(r310475)
+++ projects/ipsec/sys/netipsec/key.c	Fri Dec 23 14:22:32 2016	(r310476)
@@ -464,7 +464,13 @@ MALLOC_DEFINE(M_IPSEC_SAR, "ipsec-reg", 
 static VNET_DEFINE(uma_zone_t, key_lft_zone);
 #define	V_key_lft_zone		VNET(key_lft_zone)
 
-static struct xformsw* xforms = NULL;
+static LIST_HEAD(xforms_list, xformsw) xforms = LIST_HEAD_INITIALIZER();
+static struct mtx xforms_lock;
+#define	XFORMS_LOCK_INIT()	\
+    mtx_init(&xforms_lock, "xforms_list", "IPsec transforms list", MTX_DEF)
+#define	XFORMS_LOCK_DESTROY()	mtx_destroy(&xforms_lock)
+#define	XFORMS_LOCK()		mtx_lock(&xforms_lock)
+#define	XFORMS_UNLOCK()		mtx_unlock(&xforms_lock)
 
 /*
  * set parameters into secpolicyindex buffer.
@@ -669,7 +675,7 @@ static int key_validate_ext(const struct
 static int key_align(struct mbuf *, struct sadb_msghdr *);
 static struct mbuf *key_setlifetime(struct seclifetime *, uint16_t);
 static struct mbuf *key_setkey(struct seckey *, uint16_t);
-static int xform_init(struct secasvar *, int);
+static int xform_init(struct secasvar *, u_short);
 
 #define	DBG_IPSEC_INITREF(t, p)	do {				\
 	refcount_init(&(p)->refcnt, 1);				\
@@ -7714,6 +7720,7 @@ key_init(void)
 	if (!IS_DEFAULT_VNET(curvnet))
 		return;
 
+	XFORMS_LOCK_INIT();
 	SPTREE_LOCK_INIT();
 	REGTREE_LOCK_INIT();
 	SAHTREE_LOCK_INIT();
@@ -7975,28 +7982,66 @@ comp_algorithm_lookup(int alg)
 }
 
 /*
- * Register a transform; typically at system startup.
+ * Register a transform.
  */
-void
+static int
 xform_register(struct xformsw* xsp)
 {
+	struct xformsw *entry;
 
-	xsp->xf_next = xforms;
-	xforms = xsp;
+	XFORMS_LOCK();
+	LIST_FOREACH(entry, &xforms, chain) {
+		if (entry->xf_type == xsp->xf_type) {
+			XFORMS_UNLOCK();
+			return (EEXIST);
+		}
+	}
+	LIST_INSERT_HEAD(&xforms, xsp, chain);
+	XFORMS_UNLOCK();
+	return (0);
+}
+
+void
+xform_attach(void *data)
+{
+	struct xformsw *xsp = (struct xformsw *)data;
+
+	if (xform_register(xsp) != 0)
+		printf("%s: failed to register %s xform\n", __func__,
+		    xsp->xf_name);
+}
+
+void
+xform_detach(void *data)
+{
+	struct xformsw *xsp = (struct xformsw *)data;
+
+	XFORMS_LOCK();
+	LIST_REMOVE(xsp, chain);
+	XFORMS_UNLOCK();
 }
 
 /*
  * Initialize transform support in an sav.
  */
 static int
-xform_init(struct secasvar *sav, int xftype)
+xform_init(struct secasvar *sav, u_short xftype)
 {
-	struct xformsw *xsp;
+	struct xformsw *entry;
+	int ret;
 
-	if (sav->tdb_xform != NULL)	/* Previously initialized. */
-		return (0);
-	for (xsp = xforms; xsp; xsp = xsp->xf_next)
-		if (xsp->xf_type == xftype)
-			return ((*xsp->xf_init)(sav, xsp));
+	IPSEC_ASSERT(sav->tdb_xform == NULL,
+	    ("tdb_xform is already initialized"));
+
+	ret = EINVAL;
+	XFORMS_LOCK();
+	LIST_FOREACH(entry, &xforms, chain) {
+	    if (entry->xf_type == xftype) {
+		    ret = (*entry->xf_init)(sav, entry);
+		    break;
+	    }
+	}
+	XFORMS_UNLOCK();
 	return (EINVAL);
 }
+

Modified: projects/ipsec/sys/netipsec/xform.h
==============================================================================
--- projects/ipsec/sys/netipsec/xform.h	Fri Dec 23 12:11:56 2016	(r310475)
+++ projects/ipsec/sys/netipsec/xform.h	Fri Dec 23 14:22:32 2016	(r310476)
@@ -42,6 +42,7 @@
 #define _NETIPSEC_XFORM_H_
 
 #include <sys/types.h>
+#include <sys/queue.h>
 #include <netinet/in.h>
 #include <opencrypto/xform.h>
 
@@ -49,6 +50,7 @@
 #define	AH_HMAC_MAXHASHLEN	(SHA2_512_HASH_LEN/2)	/* Keep this updated */
 #define	AH_HMAC_INITIAL_RPL	1	/* replay counter initial value */
 
+#ifdef _KERNEL
 struct secpolicy;
 struct secasvar;
 
@@ -76,38 +78,34 @@ struct xform_data {
 	uint8_t			nxt;		/* next protocol, e.g. IPV4 */
 };
 
-struct xformsw {
-	u_short	xf_type;		/* xform ID */
 #define	XF_IP4		1	/* unused */
 #define	XF_AH		2	/* AH */
 #define	XF_ESP		3	/* ESP */
 #define	XF_TCPSIGNATURE	5	/* TCP MD5 Signature option, RFC 2358 */
 #define	XF_IPCOMP	6	/* IPCOMP */
-	u_short	xf_flags;
-#define	XFT_AUTH	0x0001
-#define	XFT_CONF	0x0100
-#define	XFT_COMP	0x1000
-	char	*xf_name;			/* human-readable name */
+
+struct xformsw {
+	u_short	xf_type;		/* xform ID */
+	char	*xf_name;		/* human-readable name */
 	int	(*xf_init)(struct secasvar*, struct xformsw*);	/* setup */
 	int	(*xf_zeroize)(struct secasvar*);		/* cleanup */
 	int	(*xf_input)(struct mbuf*, struct secasvar*,	/* input */
 			int, int);
 	int	(*xf_output)(struct mbuf*,			/* output */
 	    struct secpolicy *, struct secasvar *, u_int, int, int);
-	struct xformsw *xf_next;		/* list of registered xforms */
+	LIST_ENTRY(xformsw)	chain;
 };
 
-#ifdef _KERNEL
 const struct enc_xform * enc_algorithm_lookup(int);
 const struct auth_hash * auth_algorithm_lookup(int);
 const struct comp_algo * comp_algorithm_lookup(int);
 
-extern void xform_register(struct xformsw*);
-extern int xform_ah_authsize(struct auth_hash *esph);
+void xform_attach(void *);
+void xform_detach(void *);
 
 struct cryptoini;
-
 /* XF_AH */
+extern int xform_ah_authsize(struct auth_hash *esph);
 extern int ah_init0(struct secasvar *, struct xformsw *, struct cryptoini *);
 extern int ah_zeroize(struct secasvar *sav);
 extern size_t ah_hdrsiz(struct secasvar *);

Modified: projects/ipsec/sys/netipsec/xform_ah.c
==============================================================================
--- projects/ipsec/sys/netipsec/xform_ah.c	Fri Dec 23 12:11:56 2016	(r310475)
+++ projects/ipsec/sys/netipsec/xform_ah.c	Fri Dec 23 14:22:32 2016	(r310476)
@@ -1129,15 +1129,15 @@ bad:
 }
 
 static struct xformsw ah_xformsw = {
-	XF_AH,		XFT_AUTH,	"IPsec AH",
-	ah_init,	ah_zeroize,	ah_input,	ah_output,
+	.xf_type =	XF_AH,
+	.xf_name =	"IPsec AH",
+	.xf_init =	ah_init,
+	.xf_zeroize =	ah_zeroize,
+	.xf_input =	ah_input,
+	.xf_output =	ah_output,
 };
 
-static void
-ah_attach(void)
-{
-
-	xform_register(&ah_xformsw);
-}
-
-SYSINIT(ah_xform_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE, ah_attach, NULL);
+SYSINIT(ah_xform_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE,
+    xform_attach, &ah_xformsw);
+SYSUNINIT(ah_xform_uninit, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE,
+    xform_detach, &ah_xformsw);

Modified: projects/ipsec/sys/netipsec/xform_esp.c
==============================================================================
--- projects/ipsec/sys/netipsec/xform_esp.c	Fri Dec 23 12:11:56 2016	(r310475)
+++ projects/ipsec/sys/netipsec/xform_esp.c	Fri Dec 23 14:22:32 2016	(r310476)
@@ -941,16 +941,17 @@ bad:
 	key_freesp(&sp);
 	return (error);
 }
+
 static struct xformsw esp_xformsw = {
-	XF_ESP,		XFT_CONF|XFT_AUTH,	"IPsec ESP",
-	esp_init,	esp_zeroize,		esp_input,
-	esp_output
+	.xf_type =	XF_ESP,
+	.xf_name =	"IPsec ESP",
+	.xf_init =	esp_init,
+	.xf_zeroize =	esp_zeroize,
+	.xf_input =	esp_input,
+	.xf_output =	esp_output,
 };
 
-static void
-esp_attach(void)
-{
-
-	xform_register(&esp_xformsw);
-}
-SYSINIT(esp_xform_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE, esp_attach, NULL);
+SYSINIT(esp_xform_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE,
+    xform_attach, &esp_xformsw);
+SYSUNINIT(esp_xform_uninit, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE,
+    xform_detach, &esp_xformsw);

Modified: projects/ipsec/sys/netipsec/xform_ipcomp.c
==============================================================================
--- projects/ipsec/sys/netipsec/xform_ipcomp.c	Fri Dec 23 12:11:56 2016	(r310475)
+++ projects/ipsec/sys/netipsec/xform_ipcomp.c	Fri Dec 23 14:22:32 2016	(r310476)
@@ -645,12 +645,6 @@ bad:
 	return (error);
 }
 
-static struct xformsw ipcomp_xformsw = {
-	XF_IPCOMP,		XFT_COMP,		"IPcomp",
-	ipcomp_init,		ipcomp_zeroize,		ipcomp_input,
-	ipcomp_output
-};
-
 #ifdef INET
 static const struct encaptab *ipe4_cookie = NULL;
 extern struct domain inetdomain;
@@ -734,6 +728,15 @@ ipcomp6_nonexp_encapcheck(const struct m
 }
 #endif
 
+static struct xformsw ipcomp_xformsw = {
+	.xf_type =	XF_IPCOMP,
+	.xf_name =	"IPcomp",
+	.xf_init =	ipcomp_init,
+	.xf_zeroize =	ipcomp_zeroize,
+	.xf_input =	ipcomp_input,
+	.xf_output =	ipcomp_output,
+};
+
 static void
 ipcomp_attach(void)
 {
@@ -746,8 +749,23 @@ ipcomp_attach(void)
 	ipe6_cookie = encap_attach_func(AF_INET6, -1,
 	    ipcomp6_nonexp_encapcheck, &ipcomp6_protosw, NULL);
 #endif
-	xform_register(&ipcomp_xformsw);
+	xform_attach(&ipcomp_xformsw);
+}
+
+static void
+ipcomp_detach(void)
+{
+
+#ifdef INET
+	encap_detach(ipe4_cookie);
+#endif
+#ifdef INET6
+	encap_detach(ipe6_cookie);
+#endif
+	xform_attach(&ipcomp_xformsw);
 }
 
 SYSINIT(ipcomp_xform_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE,
     ipcomp_attach, NULL);
+SYSUNINIT(ipcomp_xform_uninit, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE,
+    ipcomp_detach, NULL);

Modified: projects/ipsec/sys/netipsec/xform_tcp.c
==============================================================================
--- projects/ipsec/sys/netipsec/xform_tcp.c	Fri Dec 23 12:11:56 2016	(r310475)
+++ projects/ipsec/sys/netipsec/xform_tcp.c	Fri Dec 23 14:22:32 2016	(r310476)
@@ -393,17 +393,15 @@ tcpsignature_output(struct mbuf *m, stru
 }
 
 static struct xformsw tcpsignature_xformsw = {
-	XF_TCPSIGNATURE,	XFT_AUTH,		"TCPMD5",
-	tcpsignature_init,	tcpsignature_zeroize,
-	tcpsignature_input,	tcpsignature_output
+	.xf_type =	XF_TCPSIGNATURE,
+	.xf_name =	"TCPMD5",
+	.xf_init =	tcpsignature_init,
+	.xf_zeroize =	tcpsignature_zeroize,
+	.xf_input =	tcpsignature_input,
+	.xf_output =	tcpsignature_output,
 };
 
-static void
-tcpsignature_attach(void)
-{
-
-	xform_register(&tcpsignature_xformsw);
-}
-
 SYSINIT(tcpsignature_xform_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE,
-    tcpsignature_attach, NULL);
+    xform_attach, &tcpsignature_xformsw);
+SYSUNINIT(tcpsignature_xform_uninit, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE,
+    xform_detach, &tcpsignature_xformsw);



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