ipsecif(4) supports multiple peers in the same NAPT.
E.g. ipsec0 connects between NetBSD_A and NetBSD_B, ipsec1 connects NetBSD_A and NetBSD_C at the following figure. +----------+ +----| NetBSD_B | +----------+ +------+ | +----------+ | NetBSD_A |--- ... ---| NAPT |---+ +----------+ +------+ | +----------+ +----| NetBSD_C | +----------+ Add ATF later.
This commit is contained in:
parent
64706e18ff
commit
58c5602068
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ipsec_output.c,v 1.81 2018/11/22 04:48:34 knakahara Exp $ */
|
||||
/* $NetBSD: ipsec_output.c,v 1.82 2018/12/26 08:58:51 knakahara Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
|
||||
|
@ -29,7 +29,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ipsec_output.c,v 1.81 2018/11/22 04:48:34 knakahara Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ipsec_output.c,v 1.82 2018/12/26 08:58:51 knakahara Exp $");
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_inet.h"
|
||||
|
@ -289,6 +289,24 @@ static void
|
|||
ipsec_fill_saidx_bymbuf(struct secasindex *saidx, const struct mbuf *m,
|
||||
const int af)
|
||||
{
|
||||
struct m_tag *mtag;
|
||||
u_int16_t natt_src = IPSEC_PORT_ANY;
|
||||
u_int16_t natt_dst = IPSEC_PORT_ANY;
|
||||
|
||||
/*
|
||||
* For NAT-T enabled ipsecif(4), set NAT-T port numbers
|
||||
* even if the saidx uses transport mode.
|
||||
*
|
||||
* See also ipsecif[46]_output().
|
||||
*/
|
||||
mtag = m_tag_find(m, PACKET_TAG_IPSEC_NAT_T_PORTS);
|
||||
if (mtag) {
|
||||
u_int16_t *natt_ports;
|
||||
|
||||
natt_ports = (u_int16_t *)(mtag + 1);
|
||||
natt_src = natt_ports[1];
|
||||
natt_dst = natt_ports[0];
|
||||
}
|
||||
|
||||
if (af == AF_INET) {
|
||||
struct sockaddr_in *sin;
|
||||
|
@ -298,14 +316,14 @@ ipsec_fill_saidx_bymbuf(struct secasindex *saidx, const struct mbuf *m,
|
|||
sin = &saidx->src.sin;
|
||||
sin->sin_len = sizeof(*sin);
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_port = IPSEC_PORT_ANY;
|
||||
sin->sin_port = natt_src;
|
||||
sin->sin_addr = ip->ip_src;
|
||||
}
|
||||
if (saidx->dst.sa.sa_len == 0) {
|
||||
sin = &saidx->dst.sin;
|
||||
sin->sin_len = sizeof(*sin);
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_port = IPSEC_PORT_ANY;
|
||||
sin->sin_port = natt_dst;
|
||||
sin->sin_addr = ip->ip_dst;
|
||||
}
|
||||
} else {
|
||||
|
@ -316,7 +334,7 @@ ipsec_fill_saidx_bymbuf(struct secasindex *saidx, const struct mbuf *m,
|
|||
sin6 = (struct sockaddr_in6 *)&saidx->src;
|
||||
sin6->sin6_len = sizeof(*sin6);
|
||||
sin6->sin6_family = AF_INET6;
|
||||
sin6->sin6_port = IPSEC_PORT_ANY;
|
||||
sin6->sin6_port = natt_src;
|
||||
sin6->sin6_addr = ip6->ip6_src;
|
||||
if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
|
||||
/* fix scope id for comparing SPD */
|
||||
|
@ -329,7 +347,7 @@ ipsec_fill_saidx_bymbuf(struct secasindex *saidx, const struct mbuf *m,
|
|||
sin6 = (struct sockaddr_in6 *)&saidx->dst;
|
||||
sin6->sin6_len = sizeof(*sin6);
|
||||
sin6->sin6_family = AF_INET6;
|
||||
sin6->sin6_port = IPSEC_PORT_ANY;
|
||||
sin6->sin6_port = natt_dst;
|
||||
sin6->sin6_addr = ip6->ip6_dst;
|
||||
if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
|
||||
/* fix scope id for comparing SPD */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ipsecif.c,v 1.12 2018/12/07 09:11:04 knakahara Exp $ */
|
||||
/* $NetBSD: ipsecif.c,v 1.13 2018/12/26 08:58:51 knakahara Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2017 Internet Initiative Japan Inc.
|
||||
|
@ -27,7 +27,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ipsecif.c,v 1.12 2018/12/07 09:11:04 knakahara Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ipsecif.c,v 1.13 2018/12/26 08:58:51 knakahara Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_inet.h"
|
||||
|
@ -71,6 +71,7 @@ __KERNEL_RCSID(0, "$NetBSD: ipsecif.c,v 1.12 2018/12/07 09:11:04 knakahara Exp $
|
|||
|
||||
#include <net/if_ipsec.h>
|
||||
|
||||
static int ipsecif_set_natt_ports(struct ipsec_variant *, struct mbuf *);
|
||||
static void ipsecif4_input(struct mbuf *, int, int, void *);
|
||||
static int ipsecif4_output(struct ipsec_variant *, int, struct mbuf *);
|
||||
static int ipsecif4_filter4(const struct ip *, struct ipsec_variant *,
|
||||
|
@ -102,6 +103,32 @@ static const struct encapsw ipsecif4_encapsw = {
|
|||
static const struct encapsw ipsecif6_encapsw;
|
||||
#endif
|
||||
|
||||
static int
|
||||
ipsecif_set_natt_ports(struct ipsec_variant *var, struct mbuf *m)
|
||||
{
|
||||
|
||||
KASSERT(if_ipsec_heldref_variant(var));
|
||||
|
||||
if (var->iv_sport || var->iv_dport) {
|
||||
struct m_tag *mtag;
|
||||
|
||||
mtag = m_tag_get(PACKET_TAG_IPSEC_NAT_T_PORTS,
|
||||
sizeof(uint16_t) + sizeof(uint16_t), M_DONTWAIT);
|
||||
if (mtag) {
|
||||
uint16_t *natt_port;
|
||||
|
||||
natt_port = (uint16_t *)(mtag + 1);
|
||||
natt_port[0] = var->iv_dport;
|
||||
natt_port[1] = var->iv_sport;
|
||||
m_tag_prepend(m, mtag);
|
||||
} else {
|
||||
return ENOBUFS;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
ipsecif4_prepend_hdr(struct ipsec_variant *var, struct mbuf *m,
|
||||
uint8_t proto, uint8_t tos)
|
||||
|
@ -394,6 +421,13 @@ ipsecif4_output(struct ipsec_variant *var, int family, struct mbuf *m)
|
|||
if (mtu > 0)
|
||||
return ipsecif4_fragout(var, family, m, mtu);
|
||||
|
||||
/* set NAT-T ports */
|
||||
error = ipsecif_set_natt_ports(var, m);
|
||||
if (error) {
|
||||
m_freem(m);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* IPsec output */
|
||||
IP_STATINC(IP_STAT_LOCALOUT);
|
||||
error = ipsec4_process_packet(m, sp->req, &sa_mtu);
|
||||
|
@ -586,6 +620,13 @@ ipsecif6_output(struct ipsec_variant *var, int family, struct mbuf *m)
|
|||
}
|
||||
rtcache_unref(rt, &iro->ir_ro);
|
||||
|
||||
/* set NAT-T ports */
|
||||
error = ipsecif_set_natt_ports(var, m);
|
||||
if (error) {
|
||||
m_freem(m);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* force fragmentation to minimum MTU, to avoid path MTU discovery.
|
||||
* it is too painful to ask for resend of inner packet, to achieve
|
||||
|
@ -593,9 +634,10 @@ ipsecif6_output(struct ipsec_variant *var, int family, struct mbuf *m)
|
|||
*/
|
||||
error = ip6_output(m, 0, &iro->ir_ro,
|
||||
ip6_ipsec_pmtu ? 0 : IPV6_MINMTU, 0, NULL, NULL);
|
||||
|
||||
out:
|
||||
if (error)
|
||||
rtcache_free(&iro->ir_ro);
|
||||
|
||||
mutex_exit(iro->ir_lock);
|
||||
percpu_putref(sc->ipsec_ro_percpu);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: key.c,v 1.259 2018/12/26 08:55:14 knakahara Exp $ */
|
||||
/* $NetBSD: key.c,v 1.260 2018/12/26 08:58:51 knakahara Exp $ */
|
||||
/* $FreeBSD: key.c,v 1.3.2.3 2004/02/14 22:23:23 bms Exp $ */
|
||||
/* $KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $ */
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.259 2018/12/26 08:55:14 knakahara Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.260 2018/12/26 08:58:51 knakahara Exp $");
|
||||
|
||||
/*
|
||||
* This code is referred to RFC 2367
|
||||
|
@ -4567,13 +4567,13 @@ key_saidx_match(
|
|||
sa1dst = &saidx1->dst.sa;
|
||||
/*
|
||||
* If NAT-T is enabled, check ports for tunnel mode.
|
||||
* Don't do it for transport mode, as there is no
|
||||
* port information available in the SP.
|
||||
* Also don't check ports if they are set to zero
|
||||
* For ipsecif(4), check ports for transport mode, too.
|
||||
* Don't check ports if they are set to zero
|
||||
* in the SPD: This means we have a non-generated
|
||||
* SPD which can't know UDP ports.
|
||||
*/
|
||||
if (saidx1->mode == IPSEC_MODE_TUNNEL)
|
||||
if (saidx1->mode == IPSEC_MODE_TUNNEL ||
|
||||
saidx1->mode == IPSEC_MODE_TRANSPORT)
|
||||
chkport = PORT_LOOSE;
|
||||
else
|
||||
chkport = PORT_NONE;
|
||||
|
|
Loading…
Reference in New Issue