summaryrefslogtreecommitdiffstats
path: root/sys/netipsec
diff options
context:
space:
mode:
authorRenato Botelho <renato@netgate.com>2015-08-17 13:53:27 -0300
committerRenato Botelho <renato@netgate.com>2015-08-17 13:53:27 -0300
commitd3b775b3db2819bebcac765dca33db7f8f5143c7 (patch)
tree016f0040db13d31ac4b832e67a967c9b7119c8c3 /sys/netipsec
parentfce52da9925f213a049387e0accff1daa3ed0b20 (diff)
downloadFreeBSD-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.c42
-rw-r--r--sys/netipsec/keysock.c17
-rw-r--r--sys/netipsec/keysock.h1
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>
OpenPOWER on IntegriCloud