Date: Mon, 21 Nov 2016 10:36:25 +0000 (UTC) From: "Andrey V. Elsukov" <ae@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r308917 - projects/ipsec/sys/netipsec Message-ID: <201611211036.uALAaP0T098364@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ae Date: Mon Nov 21 10:36:25 2016 New Revision: 308917 URL: https://svnweb.freebsd.org/changeset/base/308917 Log: Split key_sp2mbuf() function into key_sp2mbuf() and key_sp2msg(). Make key_sp2mbuf() static for private use only in key.c. key_sp2msg() takes buffer and its size as arguments. When given buffer is not enough to store security policy, function calculates needed size and returns it back via sadb_x_policy_len field of struct sadb_x_policy. Also reflect changing of struct ipsecrequest. Modified: projects/ipsec/sys/netipsec/key.c projects/ipsec/sys/netipsec/key.h Modified: projects/ipsec/sys/netipsec/key.c ============================================================================== --- projects/ipsec/sys/netipsec/key.c Mon Nov 21 10:23:28 2016 (r308916) +++ projects/ipsec/sys/netipsec/key.c Mon Nov 21 10:36:25 2016 (r308917) @@ -464,6 +464,7 @@ static int key_spddump(struct socket *, const struct sadb_msghdr *); static struct mbuf *key_setdumpsp(struct secpolicy *, u_int8_t, u_int32_t, u_int32_t); +static struct mbuf *key_sp2mbuf(struct secpolicy *); static size_t key_getspreqmsglen(struct secpolicy *); static int key_spdexpire(struct secpolicy *); static struct secashead *key_newsah(struct secasindex *); @@ -1724,43 +1725,66 @@ key_newreqid() /* * copy secpolicy struct to sadb_x_policy structure indicated. */ -struct mbuf * -key_sp2msg(struct secpolicy *sp) +static struct mbuf * +key_sp2mbuf(struct secpolicy *sp) { - struct sadb_x_policy *xpl; - int tlen; - caddr_t p; struct mbuf *m; - - IPSEC_ASSERT(sp != NULL, ("null policy")); + size_t tlen; tlen = key_getspreqmsglen(sp); - m = m_get2(tlen, M_NOWAIT, MT_DATA, 0); if (m == NULL) return (NULL); m_align(m, tlen); m->m_len = tlen; - xpl = mtod(m, struct sadb_x_policy *); - bzero(xpl, tlen); + if (key_sp2msg(sp, m->m_data, &tlen) != 0) { + m_freem(m); + return (NULL); + } + return (m); +} + +int +key_sp2msg(struct secpolicy *sp, void *request, size_t *len) +{ + struct sadb_x_ipsecrequest *xisr; + struct sadb_x_policy *xpl; + struct ipsecrequest *isr; + size_t xlen, ilen; + caddr_t p; + int error, i; + + IPSEC_ASSERT(sp != NULL, ("null policy")); - xpl->sadb_x_policy_len = PFKEY_UNIT64(tlen); + xlen = sizeof(*xpl); + if (*len < xlen) + return (EINVAL); + + error = 0; + bzero(request, *len); + xpl = (struct sadb_x_policy *)request; xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY; 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 ? */ if (sp->policy == IPSEC_POLICY_IPSEC) { - struct sadb_x_ipsecrequest *xisr; - struct ipsecrequest *isr; - - for (isr = sp->req; isr != NULL; isr = isr->next) { - + p = (caddr_t)xpl + sizeof(*xpl); + for (i = 0; i < sp->tcount; i++) { + isr = sp->req[i]; + ilen = PFKEY_ALIGN8(sizeof(*xisr) + + isr->saidx.src.sa.sa_len + + isr->saidx.dst.sa.sa_len); + xlen += ilen; + if (xlen > *len) { + error = ENOBUFS; + /* Calculate needed size */ + continue; + } xisr = (struct sadb_x_ipsecrequest *)p; - + xisr->sadb_x_ipsecrequest_len = ilen; xisr->sadb_x_ipsecrequest_proto = isr->saidx.proto; xisr->sadb_x_ipsecrequest_mode = isr->saidx.mode; xisr->sadb_x_ipsecrequest_level = isr->level; @@ -1770,16 +1794,15 @@ key_sp2msg(struct secpolicy *sp) bcopy(&isr->saidx.src, p, isr->saidx.src.sa.sa_len); p += isr->saidx.src.sa.sa_len; bcopy(&isr->saidx.dst, p, isr->saidx.dst.sa.sa_len); - p += isr->saidx.src.sa.sa_len; - - xisr->sadb_x_ipsecrequest_len = - PFKEY_ALIGN8(sizeof(*xisr) - + isr->saidx.src.sa.sa_len - + isr->saidx.dst.sa.sa_len); + p += isr->saidx.dst.sa.sa_len; } } - - return m; + xpl->sadb_x_policy_len = PFKEY_UNIT64(xlen); + if (error == 0) + *len = xlen; + else + *len = sizeof(*xpl); + return (error); } /* m will not be freed nor modified */ Modified: projects/ipsec/sys/netipsec/key.h ============================================================================== --- projects/ipsec/sys/netipsec/key.h Mon Nov 21 10:23:28 2016 (r308916) +++ projects/ipsec/sys/netipsec/key.h Mon Nov 21 10:36:25 2016 (r308917) @@ -99,7 +99,9 @@ extern int key_checkrequest(struct ipsec const struct secasindex *); extern struct secpolicy *key_msg2sp(struct sadb_x_policy *, size_t, int *); -extern struct mbuf *key_sp2msg(struct secpolicy *); + +int key_sp2msg(struct secpolicy *, void *request, size_t *len); + extern int key_ismyaddr(struct sockaddr *); extern int key_spdacquire(struct secpolicy *); extern u_long key_random(void);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201611211036.uALAaP0T098364>