diff options
author | Renato Botelho <renato@netgate.com> | 2015-08-17 13:53:27 -0300 |
---|---|---|
committer | Renato Botelho <renato@netgate.com> | 2015-08-17 13:53:27 -0300 |
commit | d3b775b3db2819bebcac765dca33db7f8f5143c7 (patch) | |
tree | 016f0040db13d31ac4b832e67a967c9b7119c8c3 /sys/netipsec | |
parent | fce52da9925f213a049387e0accff1daa3ed0b20 (diff) | |
download | FreeBSD-src-d3b775b3db2819bebcac765dca33db7f8f5143c7.zip FreeBSD-src-d3b775b3db2819bebcac765dca33db7f8f5143c7.tar.gz |
Importing pfSense patch ipsec-oneshot-dump.diff
Diffstat (limited to 'sys/netipsec')
-rw-r--r-- | sys/netipsec/key.c | 42 | ||||
-rw-r--r-- | sys/netipsec/keysock.c | 17 | ||||
-rw-r--r-- | sys/netipsec/keysock.h | 1 |
3 files changed, 39 insertions, 21 deletions
diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c index 17bbab6..3d709ed 100644 --- a/sys/netipsec/key.c +++ b/sys/netipsec/key.c @@ -2434,7 +2434,7 @@ key_spddump(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) struct secpolicy *sp; int cnt; u_int dir; - struct mbuf *n; + struct mbuf *n, *rh, *rt; IPSEC_ASSERT(so != NULL, ("null socket")); IPSEC_ASSERT(m != NULL, ("null mbuf")); @@ -2455,20 +2455,30 @@ key_spddump(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) return key_senderror(so, m, ENOENT); } + rh = rt = NULL; for (dir = 0; dir < IPSEC_DIR_MAX; dir++) { LIST_FOREACH(sp, &V_sptree[dir], chain) { --cnt; n = key_setdumpsp(sp, SADB_X_SPDDUMP, cnt, mhp->msg->sadb_msg_pid); + if (!n) { + SPTREE_UNLOCK(); + m_freem(rh); + return key_senderror(so, m, ENOBUFS); + } + + if (rt) + rt->m_nextpkt = n; + else + rh = n; + rt = n; - if (n) - key_sendup_mbuf(so, n, KEY_SENDUP_ONE); } } SPTREE_UNLOCK(); m_freem(m); - return 0; + return key_sendup_mbuf(so, rh, KEY_SENDUP_ONESHOT); } static struct mbuf * @@ -3333,7 +3343,7 @@ static struct mbuf * key_setdumpsa(struct secasvar *sav, u_int8_t type, u_int8_t satype, u_int32_t seq, u_int32_t pid) { - struct mbuf *result = NULL, *tres = NULL, *m; + struct mbuf *result = NULL, *m; int i; int dumporder[] = { SADB_EXT_SA, SADB_X_EXT_SA2, @@ -3355,7 +3365,7 @@ key_setdumpsa(struct secasvar *sav, u_int8_t type, u_int8_t satype, goto fail; result = m; - for (i = sizeof(dumporder)/sizeof(dumporder[0]) - 1; i >= 0; i--) { + for (i = 0; i < sizeof(dumporder)/sizeof(dumporder[0]); i++) { m = NULL; switch (dumporder[i]) { case SADB_EXT_SA: @@ -3473,13 +3483,9 @@ key_setdumpsa(struct secasvar *sav, u_int8_t type, u_int8_t satype, if (!m) goto fail; - if (tres) - m_cat(m, tres); - tres = m; - + m_cat(result, m); } - m_cat(result, tres); if (result->m_len < sizeof(struct sadb_msg)) { result = m_pullup(result, sizeof(struct sadb_msg)); if (result == NULL) @@ -3497,7 +3503,6 @@ key_setdumpsa(struct secasvar *sav, u_int8_t type, u_int8_t satype, fail: m_freem(result); - m_freem(tres); return NULL; } @@ -7058,7 +7063,7 @@ key_dump(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) u_int8_t state; int cnt; struct sadb_msg *newmsg; - struct mbuf *n; + struct mbuf *rh, *rt, *n; IPSEC_ASSERT(so != NULL, ("null socket")); IPSEC_ASSERT(m != NULL, ("null mbuf")); @@ -7097,6 +7102,7 @@ key_dump(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) /* send this to the userland, one at a time. */ newmsg = NULL; + rh = rt = NULL; LIST_FOREACH(sah, &V_sahtree, chain) { if (mhp->msg->sadb_msg_satype != SADB_SATYPE_UNSPEC && proto != sah->saidx.proto) @@ -7105,6 +7111,7 @@ key_dump(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) /* map proto to satype */ if ((satype = key_proto2satype(sah->saidx.proto)) == 0) { SAHTREE_UNLOCK(); + m_freem(rh); ipseclog((LOG_DEBUG, "%s: there was invalid proto in " "SAD.\n", __func__)); return key_senderror(so, m, EINVAL); @@ -7119,16 +7126,21 @@ key_dump(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) --cnt, mhp->msg->sadb_msg_pid); if (!n) { SAHTREE_UNLOCK(); + m_freem(rh); return key_senderror(so, m, ENOBUFS); } - key_sendup_mbuf(so, n, KEY_SENDUP_ONE); + if (rt) + rt->m_nextpkt = n; + else + rh = n; + rt = n; } } } SAHTREE_UNLOCK(); m_freem(m); - return 0; + return key_sendup_mbuf(so, rh, KEY_SENDUP_ONESHOT); } /* diff --git a/sys/netipsec/keysock.c b/sys/netipsec/keysock.c index 4b55e05..fa9f839 100644 --- a/sys/netipsec/keysock.c +++ b/sys/netipsec/keysock.c @@ -284,6 +284,16 @@ key_sendup_mbuf(struct socket *so, struct mbuf *m, int target) msg = mtod(m, struct sadb_msg *); PFKEYSTAT_INC(in_msgtype[msg->sadb_msg_type]); } + if (target == KEY_SENDUP_ONESHOT) { + rp = sotorawcb(so); + if (!sbappendaddrchain(&rp->rcb_socket->so_rcv, + (struct sockaddr *) &key_src, m)) { + m_freem(m); + error = ENOBUFS; + } + sorwakeup(rp->rcb_socket); + return error; + } mtx_lock(&rawcb_mtx); LIST_FOREACH(rp, &V_rawcb_list, list) { @@ -339,12 +349,7 @@ key_sendup_mbuf(struct socket *so, struct mbuf *m, int target) return ENOBUFS; } - if ((error = key_sendup0(rp, n, 0)) != 0) { - m_freem(m); - mtx_unlock(&rawcb_mtx); - return error; - } - + key_sendup0(rp, n, 0); n = NULL; } diff --git a/sys/netipsec/keysock.h b/sys/netipsec/keysock.h index 86de261..944c94b 100644 --- a/sys/netipsec/keysock.h +++ b/sys/netipsec/keysock.h @@ -61,6 +61,7 @@ struct pfkeystat { #define KEY_SENDUP_ONE 0 #define KEY_SENDUP_ALL 1 #define KEY_SENDUP_REGISTERED 2 +#define KEY_SENDUP_ONESHOT 3 #ifdef _KERNEL #include <sys/counter.h> |