summaryrefslogtreecommitdiffstats
path: root/sys/netipsec/key.c
diff options
context:
space:
mode:
authorae <ae@FreeBSD.org>2015-07-06 12:40:31 +0000
committerae <ae@FreeBSD.org>2015-07-06 12:40:31 +0000
commitf3d95907d47f500513877f43dbffeb5e34a91da7 (patch)
treeaea728070ee0221dff2813572495d8c28828ac8d /sys/netipsec/key.c
parentcb62c1ffaef8c832f82f5dd6c4788502eaff1376 (diff)
downloadFreeBSD-src-f3d95907d47f500513877f43dbffeb5e34a91da7.zip
FreeBSD-src-f3d95907d47f500513877f43dbffeb5e34a91da7.tar.gz
Fill the port and protocol information in the SADB_ACQUIRE message
in case when security policy has it as required by RFC 2367. PR: 192774 Differential Revision: https://reviews.freebsd.org/D2972 MFC after: 1 week
Diffstat (limited to 'sys/netipsec/key.c')
-rw-r--r--sys/netipsec/key.c68
1 files changed, 60 insertions, 8 deletions
diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c
index b6c6a6a..34e8c41 100644
--- a/sys/netipsec/key.c
+++ b/sys/netipsec/key.c
@@ -6088,16 +6088,21 @@ key_getprop(const struct secasindex *saidx)
static int
key_acquire(const struct secasindex *saidx, struct secpolicy *sp)
{
- struct mbuf *result = NULL, *m;
+ union sockaddr_union addr;
+ struct mbuf *result, *m;
struct secacq *newacq;
- u_int8_t satype;
- int error = -1;
u_int32_t seq;
+ int error;
+ u_int16_t ul_proto;
+ u_int8_t mask, satype;
IPSEC_ASSERT(saidx != NULL, ("null saidx"));
satype = key_proto2satype(saidx->proto);
IPSEC_ASSERT(satype != 0, ("null satype, protocol %u", saidx->proto));
+ error = -1;
+ result = NULL;
+ ul_proto = IPSEC_ULPROTO_ANY;
/*
* We never do anything about acquirng SA. There is anather
* solution that kernel blocks to send SADB_ACQUIRE message until
@@ -6134,17 +6139,64 @@ key_acquire(const struct secasindex *saidx, struct secpolicy *sp)
* anything related to NAT-T at this time.
*/
- /* set sadb_address for saidx's. */
- m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC,
- &saidx->src.sa, FULLMASK, IPSEC_ULPROTO_ANY);
+ /*
+ * set sadb_address for saidx's.
+ *
+ * Note that if sp is supplied, then we're being called from
+ * key_checkrequest and should supply port and protocol information.
+ */
+ if (sp != NULL && (sp->spidx.ul_proto == IPPROTO_TCP ||
+ sp->spidx.ul_proto == IPPROTO_UDP))
+ ul_proto = sp->spidx.ul_proto;
+
+ addr = saidx->src;
+ mask = FULLMASK;
+ if (ul_proto != IPSEC_ULPROTO_ANY) {
+ switch (sp->spidx.src.sa.sa_family) {
+ case AF_INET:
+ if (sp->spidx.src.sin.sin_port != IPSEC_PORT_ANY) {
+ addr.sin.sin_port = sp->spidx.src.sin.sin_port;
+ mask = sp->spidx.prefs;
+ }
+ break;
+ case AF_INET6:
+ if (sp->spidx.src.sin6.sin6_port != IPSEC_PORT_ANY) {
+ addr.sin6.sin6_port = sp->spidx.src.sin6.sin6_port;
+ mask = sp->spidx.prefs;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC, &addr.sa, mask, ul_proto);
if (!m) {
error = ENOBUFS;
goto fail;
}
m_cat(result, m);
- m = key_setsadbaddr(SADB_EXT_ADDRESS_DST,
- &saidx->dst.sa, FULLMASK, IPSEC_ULPROTO_ANY);
+ addr = saidx->dst;
+ mask = FULLMASK;
+ if (ul_proto != IPSEC_ULPROTO_ANY) {
+ switch (sp->spidx.dst.sa.sa_family) {
+ case AF_INET:
+ if (sp->spidx.dst.sin.sin_port != IPSEC_PORT_ANY) {
+ addr.sin.sin_port = sp->spidx.dst.sin.sin_port;
+ mask = sp->spidx.prefd;
+ }
+ break;
+ case AF_INET6:
+ if (sp->spidx.dst.sin6.sin6_port != IPSEC_PORT_ANY) {
+ addr.sin6.sin6_port = sp->spidx.dst.sin6.sin6_port;
+ mask = sp->spidx.prefd;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ m = key_setsadbaddr(SADB_EXT_ADDRESS_DST, &addr.sa, mask, ul_proto);
if (!m) {
error = ENOBUFS;
goto fail;
OpenPOWER on IntegriCloud