summaryrefslogtreecommitdiffstats
path: root/lib/libipsec
diff options
context:
space:
mode:
authorae <ae@FreeBSD.org>2017-04-27 12:16:58 +0000
committerae <ae@FreeBSD.org>2017-04-27 12:16:58 +0000
commit50ac70e9ae73d6c1dc2690d5c4e5266ab1a59601 (patch)
tree79cab23ec9de3cbda06793ced7044ad940801d19 /lib/libipsec
parent6286e9852a12088fe739142a3ff25c51f33d539a (diff)
downloadFreeBSD-src-50ac70e9ae73d6c1dc2690d5c4e5266ab1a59601.zip
FreeBSD-src-50ac70e9ae73d6c1dc2690d5c4e5266ab1a59601.tar.gz
MFC r316759:
Add large replay widow support to setkey(8) and libipsec. When the replay window size is large than UINT8_MAX, add to the request the SADB_X_EXT_SA_REPLAY extension header that was added in r309144. Also add support of SADB_X_EXT_NAT_T_TYPE, SADB_X_EXT_NAT_T_SPORT, SADB_X_EXT_NAT_T_DPORT, SADB_X_EXT_NAT_T_OAI, SADB_X_EXT_NAT_T_OAR, SADB_X_EXT_SA_REPLAY, SADB_X_EXT_NEW_ADDRESS_SRC, SADB_X_EXT_NEW_ADDRESS_DST extension headers to the key_debug that is used by `setkey -x`. Modify kdebug_sockaddr() to use inet_ntop() for IP addresses formatting. And modify kdebug_sadb_x_policy() to show policy scope and priority. Reviewed by: gnn, Emeric Poupon Differential Revision: https://reviews.freebsd.org/D10375
Diffstat (limited to 'lib/libipsec')
-rw-r--r--lib/libipsec/pfkey.c43
1 files changed, 42 insertions, 1 deletions
diff --git a/lib/libipsec/pfkey.c b/lib/libipsec/pfkey.c
index 34a3ac3..4791ddc 100644
--- a/lib/libipsec/pfkey.c
+++ b/lib/libipsec/pfkey.c
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <netipsec/ipsec.h>
#include <stdlib.h>
+#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
@@ -69,6 +70,7 @@ static caddr_t pfkey_setsadbmsg(caddr_t, caddr_t, u_int, u_int,
u_int, u_int32_t, pid_t);
static caddr_t pfkey_setsadbsa(caddr_t, caddr_t, u_int32_t, u_int,
u_int, u_int, u_int32_t);
+static caddr_t pfkey_setsadbxreplay(caddr_t, caddr_t, uint32_t);
static caddr_t pfkey_setsadbaddr(caddr_t, caddr_t, u_int,
struct sockaddr *, u_int, u_int);
static caddr_t pfkey_setsadbkey(caddr_t, caddr_t, u_int, caddr_t, u_int);
@@ -1196,6 +1198,13 @@ pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize,
+ sizeof(struct sadb_lifetime)
+ sizeof(struct sadb_lifetime);
+ if (wsize > UINT8_MAX) {
+ if (wsize > (UINT32_MAX - 32) >> 3) {
+ __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
+ return (-1);
+ }
+ len += sizeof(struct sadb_x_sa_replay);
+ }
if (e_type != SADB_EALG_NONE)
len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(e_keylen));
if (a_type != SADB_AALG_NONE)
@@ -1223,6 +1232,13 @@ pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize,
free(newmsg);
return -1;
}
+ if (wsize > UINT8_MAX) {
+ p = pfkey_setsadbxreplay(p, ep, wsize);
+ if (!p) {
+ free(newmsg);
+ return (-1);
+ }
+ }
p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen,
IPSEC_ULPROTO_ANY);
if (!p) {
@@ -1982,7 +1998,7 @@ pfkey_setsadbsa(buf, lim, spi, wsize, auth, enc, flags)
p->sadb_sa_len = PFKEY_UNIT64(len);
p->sadb_sa_exttype = SADB_EXT_SA;
p->sadb_sa_spi = spi;
- p->sadb_sa_replay = wsize;
+ p->sadb_sa_replay = wsize > UINT8_MAX ? UINT8_MAX: wsize;
p->sadb_sa_state = SADB_SASTATE_LARVAL;
p->sadb_sa_auth = auth;
p->sadb_sa_encrypt = enc;
@@ -1992,6 +2008,31 @@ pfkey_setsadbsa(buf, lim, spi, wsize, auth, enc, flags)
}
/*
+ * Set data into sadb_x_sa_replay.
+ * `buf' must has been allocated sufficiently.
+ */
+static caddr_t
+pfkey_setsadbxreplay(caddr_t buf, caddr_t lim, uint32_t wsize)
+{
+ struct sadb_x_sa_replay *p;
+ u_int len;
+
+ p = (struct sadb_x_sa_replay *)buf;
+ len = sizeof(struct sadb_x_sa_replay);
+
+ if (buf + len > lim)
+ return (NULL);
+
+ memset(p, 0, len);
+ p->sadb_x_sa_replay_len = PFKEY_UNIT64(len);
+ p->sadb_x_sa_replay_exttype = SADB_X_EXT_SA_REPLAY;
+ /* Convert wsize from bytes to number of packets. */
+ p->sadb_x_sa_replay_replay = wsize << 3;
+
+ return (buf + len);
+}
+
+/*
* set data into sadb_address.
* `buf' must has been allocated sufficiently.
* prefixlen is in bits.
OpenPOWER on IntegriCloud