From owner-svn-src-projects@freebsd.org Fri Dec 23 14:22:33 2016 Return-Path: Delivered-To: svn-src-projects@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E921BC8EB58 for ; Fri, 23 Dec 2016 14:22:33 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::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 A9C308D1; Fri, 23 Dec 2016 14:22:33 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id uBNEMWex073419; Fri, 23 Dec 2016 14:22:32 GMT (envelope-from ae@FreeBSD.org) Received: (from ae@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id uBNEMW2h073413; Fri, 23 Dec 2016 14:22:32 GMT (envelope-from ae@FreeBSD.org) Message-Id: <201612231422.uBNEMW2h073413@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ae set sender to ae@FreeBSD.org using -f From: "Andrey V. Elsukov" Date: Fri, 23 Dec 2016 14:22:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r310476 - projects/ipsec/sys/netipsec X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 23 Dec 2016 14:22:34 -0000 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 +#include #include #include @@ -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);