summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorVincent Gross <vgross@cvs.openbsd.org>2016-09-03 09:20:08 +0000
committerVincent Gross <vgross@cvs.openbsd.org>2016-09-03 09:20:08 +0000
commit831e8b66e17bcba92ec8600935c13295b89877f6 (patch)
treee9f1f58950d10aaea47ad9115875971ebe415783 /sbin
parentf6883df8590c3f9d608fd7dd2432689c14121507 (diff)
Add the missing bits to have NAT on enc(4) support in iked.
Ok mikeb@
Diffstat (limited to 'sbin')
-rw-r--r--sbin/iked/iked.h3
-rw-r--r--sbin/iked/parse.y15
-rw-r--r--sbin/iked/pfkey.c62
3 files changed, 56 insertions, 24 deletions
diff --git a/sbin/iked/iked.h b/sbin/iked/iked.h
index 1c13cb960cb..6a6a3885bf2 100644
--- a/sbin/iked/iked.h
+++ b/sbin/iked/iked.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: iked.h,v 1.96 2016/06/01 11:16:41 patrick Exp $ */
+/* $OpenBSD: iked.h,v 1.97 2016/09/03 09:20:07 vgross Exp $ */
/*
* Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
@@ -140,6 +140,7 @@ struct iked_flow {
struct iked_addr flow_src;
struct iked_addr flow_dst;
unsigned int flow_dir; /* in/out */
+ struct iked_addr flow_prenat;
unsigned int flow_loaded; /* pfkey done */
diff --git a/sbin/iked/parse.y b/sbin/iked/parse.y
index c93a97874d2..bbf63e0353d 100644
--- a/sbin/iked/parse.y
+++ b/sbin/iked/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.57 2016/08/06 07:08:59 pascal Exp $ */
+/* $OpenBSD: parse.y,v 1.58 2016/09/03 09:20:07 vgross Exp $ */
/*
* Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
@@ -2418,7 +2418,7 @@ create_ike(char *name, int af, uint8_t ipproto, struct ipsec_hosts *hosts,
{
char idstr[IKED_ID_SIZE];
unsigned int idtype = IKEV2_ID_NONE;
- struct ipsec_addr_wrap *ipa, *ipb;
+ struct ipsec_addr_wrap *ipa, *ipb, *ippn;
struct iked_policy pol;
struct iked_proposal prop[2];
unsigned int j;
@@ -2640,6 +2640,17 @@ create_ike(char *name, int af, uint8_t ipproto, struct ipsec_hosts *hosts,
flows[j].flow_dst.addr_net = ipb->netaddress;
flows[j].flow_dst.addr_port = hosts->dport;
+ ippn = ipa->srcnat;
+ if (ippn) {
+ memcpy(&flows[j].flow_prenat.addr, &ippn->address,
+ sizeof(ippn->address));
+ flows[j].flow_prenat.addr_af = ippn->af;
+ flows[j].flow_prenat.addr_mask = ippn->mask;
+ flows[j].flow_prenat.addr_net = ippn->netaddress;
+ } else {
+ flows[j].flow_prenat.addr_af = 0;
+ }
+
flows[j].flow_ipproto = ipproto;
pol.pol_nflows++;
diff --git a/sbin/iked/pfkey.c b/sbin/iked/pfkey.c
index 72c2d3193ee..d5a582f0f07 100644
--- a/sbin/iked/pfkey.c
+++ b/sbin/iked/pfkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkey.c,v 1.51 2016/03/07 19:33:26 mmcc Exp $ */
+/* $OpenBSD: pfkey.c,v 1.52 2016/09/03 09:20:07 vgross Exp $ */
/*
* Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
@@ -173,6 +173,7 @@ int
pfkey_flow(int sd, uint8_t satype, uint8_t action, struct iked_flow *flow)
{
struct sadb_msg smsg;
+ struct iked_addr *flow_src, *flow_dst;
struct sadb_address sa_src, sa_dst, sa_local, sa_peer, sa_smask,
sa_dmask;
struct sadb_protocol sa_flowtype, sa_protocol;
@@ -183,56 +184,75 @@ pfkey_flow(int sd, uint8_t satype, uint8_t action, struct iked_flow *flow)
sa_srcid = sa_dstid = NULL;
+ flow_src = &flow->flow_src;
+ flow_dst = &flow->flow_dst;
+
+ if (flow->flow_prenat.addr_af == flow_src->addr_af) {
+ switch (flow->flow_type) {
+ case SADB_X_FLOW_TYPE_USE:
+ flow_dst = &flow->flow_prenat;
+ break;
+ case SADB_X_FLOW_TYPE_REQUIRE:
+ flow_src = &flow->flow_prenat;
+ break;
+ case 0:
+ if (flow->flow_dir == IPSP_DIRECTION_IN)
+ flow_dst = &flow->flow_prenat;
+ else
+ flow_src = &flow->flow_prenat;
+ }
+ }
+
bzero(&ssrc, sizeof(ssrc));
bzero(&smask, sizeof(smask));
- memcpy(&ssrc, &flow->flow_src.addr, sizeof(ssrc));
- memcpy(&smask, &flow->flow_src.addr, sizeof(smask));
- socket_af((struct sockaddr *)&ssrc, flow->flow_src.addr_port);
- socket_af((struct sockaddr *)&smask, flow->flow_src.addr_port ?
+ memcpy(&ssrc, &flow_src->addr, sizeof(ssrc));
+ memcpy(&smask, &flow_src->addr, sizeof(smask));
+ socket_af((struct sockaddr *)&ssrc, flow_src->addr_port);
+ socket_af((struct sockaddr *)&smask, flow_src->addr_port ?
0xffff : 0);
- switch (flow->flow_src.addr_af) {
+ switch (flow_src->addr_af) {
case AF_INET:
((struct sockaddr_in *)&smask)->sin_addr.s_addr =
- prefixlen2mask(flow->flow_src.addr_net ?
- flow->flow_src.addr_mask : 32);
+ prefixlen2mask(flow_src->addr_net ?
+ flow_src->addr_mask : 32);
break;
case AF_INET6:
- prefixlen2mask6(flow->flow_src.addr_net ?
- flow->flow_src.addr_mask : 128,
+ prefixlen2mask6(flow_src->addr_net ?
+ flow_src->addr_mask : 128,
(uint32_t *)((struct sockaddr_in6 *)
&smask)->sin6_addr.s6_addr);
break;
default:
log_warnx("%s: unsupported address family %d",
- __func__, flow->flow_src.addr_af);
+ __func__, flow_src->addr_af);
return (-1);
}
smask.ss_len = ssrc.ss_len;
bzero(&sdst, sizeof(sdst));
bzero(&dmask, sizeof(dmask));
- memcpy(&sdst, &flow->flow_dst.addr, sizeof(sdst));
- memcpy(&dmask, &flow->flow_dst.addr, sizeof(dmask));
- socket_af((struct sockaddr *)&sdst, flow->flow_dst.addr_port);
- socket_af((struct sockaddr *)&dmask, flow->flow_dst.addr_port ?
+ memcpy(&sdst, &flow_dst->addr, sizeof(sdst));
+ memcpy(&dmask, &flow_dst->addr, sizeof(dmask));
+ socket_af((struct sockaddr *)&sdst, flow_dst->addr_port);
+ socket_af((struct sockaddr *)&dmask, flow_dst->addr_port ?
0xffff : 0);
- switch (flow->flow_dst.addr_af) {
+ switch (flow_dst->addr_af) {
case AF_INET:
((struct sockaddr_in *)&dmask)->sin_addr.s_addr =
- prefixlen2mask(flow->flow_dst.addr_net ?
- flow->flow_dst.addr_mask : 32);
+ prefixlen2mask(flow_dst->addr_net ?
+ flow_dst->addr_mask : 32);
break;
case AF_INET6:
- prefixlen2mask6(flow->flow_dst.addr_net ?
- flow->flow_dst.addr_mask : 128,
+ prefixlen2mask6(flow_dst->addr_net ?
+ flow_dst->addr_mask : 128,
(uint32_t *)((struct sockaddr_in6 *)
&dmask)->sin6_addr.s6_addr);
break;
default:
log_warnx("%s: unsupported address family %d",
- __func__, flow->flow_dst.addr_af);
+ __func__, flow_dst->addr_af);
return (-1);
}
dmask.ss_len = sdst.ss_len;