remove a limitation that inner and outer IP version must be equal

for an ESP tunnel, and add some fixes which make v4-in-v6 work
(v6 as inner protocol isn't ready, even v6-in-v6 can never have worked)

being here, fix a statistics counter and kill an unused variable
This commit is contained in:
drochner 2011-06-06 16:48:35 +00:00
parent ec1797c173
commit a46f4db6fd
3 changed files with 28 additions and 37 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ipsec_output.c,v 1.32 2011/02/18 16:12:26 drochner Exp $ */
/* $NetBSD: ipsec_output.c,v 1.33 2011/06/06 16:48:35 drochner 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.32 2011/02/18 16:12:26 drochner Exp $");
__KERNEL_RCSID(0, "$NetBSD: ipsec_output.c,v 1.33 2011/06/06 16:48:35 drochner Exp $");
/*
* IPsec output processing.
@ -608,9 +608,15 @@ ipsec4_process_packet(
* for reclaiming their resources.
*/
if (sav->tdb_xform->xf_type != XF_IP4) {
ip = mtod(m, struct ip *);
i = ip->ip_hl << 2;
off = offsetof(struct ip, ip_p);
union sockaddr_union *dst = &sav->sah->saidx.dst;
if (dst->sa.sa_family == AF_INET) {
ip = mtod(m, struct ip *);
i = ip->ip_hl << 2;
off = offsetof(struct ip, ip_p);
} else {
i = sizeof(struct ip6_hdr);
off = offsetof(struct ip6_hdr, ip6_nxt);
}
error = (*sav->tdb_xform->xf_output)(m, isr, NULL, i, off);
} else {
error = ipsec_process_done(m, isr);

View File

@ -1,4 +1,4 @@
/* $NetBSD: key.c,v 1.71 2011/05/23 15:17:25 drochner Exp $ */
/* $NetBSD: key.c,v 1.72 2011/06/06 16:48:35 drochner Exp $ */
/* $FreeBSD: src/sys/netipsec/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.71 2011/05/23 15:17:25 drochner Exp $");
__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.72 2011/06/06 16:48:35 drochner Exp $");
/*
* This code is referd to RFC 2367
@ -1942,24 +1942,6 @@ key_spdadd(struct socket *so, struct mbuf *m,
KFREE(newsp);
return key_senderror(so, m, EINVAL);
}
#if 1
if (newsp->req && newsp->req->saidx.src.sa.sa_family) {
struct sockaddr *sa;
sa = (struct sockaddr *)(src0 + 1);
if (sa->sa_family != newsp->req->saidx.src.sa.sa_family) {
KFREE(newsp);
return key_senderror(so, m, EINVAL);
}
}
if (newsp->req && newsp->req->saidx.dst.sa.sa_family) {
struct sockaddr *sa;
sa = (struct sockaddr *)(dst0 + 1);
if (sa->sa_family != newsp->req->saidx.dst.sa.sa_family) {
KFREE(newsp);
return key_senderror(so, m, EINVAL);
}
}
#endif
newsp->created = time_uptime;
newsp->lastused = newsp->created;

View File

@ -1,4 +1,4 @@
/* $NetBSD: xform_ipip.c,v 1.26 2011/02/18 20:40:58 drochner Exp $ */
/* $NetBSD: xform_ipip.c,v 1.27 2011/06/06 16:48:35 drochner Exp $ */
/* $FreeBSD: src/sys/netipsec/xform_ipip.c,v 1.3.2.1 2003/01/24 05:11:36 sam Exp $ */
/* $OpenBSD: ip_ipip.c,v 1.25 2002/06/10 18:04:55 itojun Exp $ */
@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: xform_ipip.c,v 1.26 2011/02/18 20:40:58 drochner Exp $");
__KERNEL_RCSID(0, "$NetBSD: xform_ipip.c,v 1.27 2011/06/06 16:48:35 drochner Exp $");
/*
* IP-inside-IP processing
@ -203,7 +203,6 @@ _ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp)
struct ip6_hdr *ip6 = NULL;
u_int8_t itos;
#endif
u_int8_t nxt;
int isr;
u_int8_t otos;
u_int8_t v;
@ -322,14 +321,12 @@ _ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp)
#ifdef INET
case 4:
ipo = mtod(m, struct ip *);
nxt = ipo->ip_p;
ip_ecn_egress(ip4_ipsec_ecn, &otos, &ipo->ip_tos);
break;
#endif /* INET */
#ifdef INET6
case 6:
ip6 = (struct ip6_hdr *) ipo;
nxt = ip6->ip6_nxt;
itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
ip_ecn_egress(ip6_ipsec_ecn, &otos, &itos);
ip6->ip6_flow &= ~htonl(0xff << 20);
@ -549,12 +546,14 @@ ipip_output(
goto bad;
}
/* scoped address handling */
ip6 = mtod(m, struct ip6_hdr *);
if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src))
ip6->ip6_src.s6_addr16[1] = 0;
if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
ip6->ip6_dst.s6_addr16[1] = 0;
if (tp == (IPV6_VERSION >> 4)) {
/* scoped address handling */
ip6 = mtod(m, struct ip6_hdr *);
if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src))
ip6->ip6_src.s6_addr16[1] = 0;
if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
ip6->ip6_dst.s6_addr16[1] = 0;
}
M_PREPEND(m, sizeof(struct ip6_hdr), M_DONTWAIT);
if (m == 0) {
@ -573,6 +572,10 @@ ipip_output(
ip6o->ip6_hlim = ip_defttl;
ip6o->ip6_dst = saidx->dst.sin6.sin6_addr;
ip6o->ip6_src = saidx->src.sin6.sin6_addr;
if (IN6_IS_SCOPE_LINKLOCAL(&ip6o->ip6_dst))
ip6o->ip6_dst.s6_addr16[1] = htons(saidx->dst.sin6.sin6_scope_id);
if (IN6_IS_SCOPE_LINKLOCAL(&ip6o->ip6_src))
ip6o->ip6_src.s6_addr16[1] = htons(saidx->src.sin6.sin6_scope_id);
#ifdef INET
if (tp == IPVERSION) {
@ -636,7 +639,7 @@ nofamily:
tdb->tdb_cur_bytes +=
m->m_pkthdr.len - sizeof(struct ip6_hdr);
#endif
IPIP_STATADD(IPIP_STAT_IBYTES,
IPIP_STATADD(IPIP_STAT_OBYTES,
m->m_pkthdr.len - sizeof(struct ip6_hdr));
}
#endif /* INET6 */