Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys Fix unexpected failure when ipsecif(4) over IPv6 is chan...
details: https://anonhg.NetBSD.org/src/rev/ad5153eb2213
branches: trunk
changeset: 360908:ad5153eb2213
user: knakahara <knakahara%NetBSD.org@localhost>
date: Fri Apr 06 10:38:53 2018 +0000
description:
Fix unexpected failure when ipsecif(4) over IPv6 is changed port number only.
Here is an example of the operation which causes this problem.
# ifconfig ipsec0 create link0
# ifconfig ipsec0 tunnel fc00:1001::2,4500 fc00:1001::1,4501
# ifconfig ipsec0 tunnel fc00:1001::2,4500 fc00:1001::1,4502
diffstat:
sys/net/if_ipsec.c | 37 ++++++++++++++++++++++++------
sys/netipsec/ipsecif.c | 59 +++++++++++++++++++++++++++++++++++++++++++++----
sys/netipsec/ipsecif.h | 3 +-
3 files changed, 85 insertions(+), 14 deletions(-)
diffs (176 lines):
diff -r 2799a643441d -r ad5153eb2213 sys/net/if_ipsec.c
--- a/sys/net/if_ipsec.c Fri Apr 06 10:31:35 2018 +0000
+++ b/sys/net/if_ipsec.c Fri Apr 06 10:38:53 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ipsec.c,v 1.10 2018/04/06 09:30:09 knakahara Exp $ */
+/* $NetBSD: if_ipsec.c,v 1.11 2018/04/06 10:38:53 knakahara Exp $ */
/*
* Copyright (c) 2017 Internet Initiative Japan Inc.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ipsec.c,v 1.10 2018/04/06 09:30:09 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ipsec.c,v 1.11 2018/04/06 10:38:53 knakahara Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -280,7 +280,7 @@
int
if_ipsec_encap_func(struct mbuf *m, int off, int proto, void *arg)
{
- struct ip ip;
+ uint8_t v;
struct ipsec_softc *sc;
struct ipsec_variant *var = NULL;
struct psref psref;
@@ -304,18 +304,39 @@
goto out;
}
- if (m->m_pkthdr.len < sizeof(ip))
- goto out;
+ m_copydata(m, 0, sizeof(v), &v);
+ v = (v >> 4) & 0xff; /* Get the IP version number. */
- m_copydata(m, 0, sizeof(ip), &ip);
- switch (ip.ip_v) {
+ switch (v) {
#ifdef INET
- case IPVERSION:
+ case IPVERSION: {
+ struct ip ip;
+
+ if (m->m_pkthdr.len < sizeof(ip))
+ goto out;
+
+ m_copydata(m, 0, sizeof(ip), &ip);
if (var->iv_psrc->sa_family != AF_INET ||
var->iv_pdst->sa_family != AF_INET)
goto out;
ret = ipsecif4_encap_func(m, &ip, var);
break;
+ }
+#endif
+#ifdef INET6
+ case (IPV6_VERSION >> 4): {
+ struct ip6_hdr ip6;
+
+ if (m->m_pkthdr.len < sizeof(ip6))
+ goto out;
+
+ m_copydata(m, 0, sizeof(ip6), &ip6);
+ if (var->iv_psrc->sa_family != AF_INET6 ||
+ var->iv_pdst->sa_family != AF_INET6)
+ goto out;
+ ret = ipsecif6_encap_func(m, &ip6, var);
+ break;
+ }
#endif
default:
goto out;
diff -r 2799a643441d -r ad5153eb2213 sys/netipsec/ipsecif.c
--- a/sys/netipsec/ipsecif.c Fri Apr 06 10:31:35 2018 +0000
+++ b/sys/netipsec/ipsecif.c Fri Apr 06 10:38:53 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ipsecif.c,v 1.6 2018/04/06 10:31:35 knakahara Exp $ */
+/* $NetBSD: ipsecif.c,v 1.7 2018/04/06 10:38:53 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.6 2018/04/06 10:31:35 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipsecif.c,v 1.7 2018/04/06 10:38:53 knakahara Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -412,6 +412,57 @@
}
#ifdef INET6
+int
+ipsecif6_encap_func(struct mbuf *m, struct ip6_hdr *ip6, struct ipsec_variant *var)
+{
+ struct m_tag *mtag;
+ struct sockaddr_in6 *src, *dst;
+ u_int16_t src_port = 0;
+ u_int16_t dst_port = 0;
+
+ KASSERT(var != NULL);
+
+ src = satosin6(var->iv_psrc);
+ dst = satosin6(var->iv_pdst);
+ mtag = m_tag_find(m, PACKET_TAG_IPSEC_NAT_T_PORTS, NULL);
+ if (mtag) {
+ u_int16_t *ports;
+
+ ports = (u_int16_t *)(mtag + 1);
+ src_port = ports[0];
+ dst_port = ports[1];
+ }
+
+ /* address match */
+ if (!IN6_ARE_ADDR_EQUAL(&src->sin6_addr, &ip6->ip6_dst) ||
+ !IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &ip6->ip6_src))
+ return 0;
+
+ /* UDP encap? */
+ if (mtag == NULL && var->iv_sport == 0 && var->iv_dport == 0)
+ goto match;
+
+ /* port match */
+ if (src_port != var->iv_dport ||
+ dst_port != var->iv_sport) {
+#ifdef DEBUG
+ printf("%s: port mismatch: pkt(%u, %u), if(%u, %u)\n",
+ __func__, ntohs(src_port), ntohs(dst_port),
+ ntohs(var->iv_sport), ntohs(var->iv_dport));
+#endif
+ return 0;
+ }
+
+match:
+ /*
+ * hide NAT-T information from encapsulated traffics.
+ * they don't know about IPsec.
+ */
+ if (mtag)
+ m_tag_delete(m, mtag);
+ return sizeof(src->sin6_addr) + sizeof(dst->sin6_addr);
+}
+
static int
ipsecif6_output(struct ipsec_variant *var, int family, struct mbuf *m)
{
@@ -841,9 +892,7 @@
mask6.sin6_addr.s6_addr32[0] = mask6.sin6_addr.s6_addr32[1] =
mask6.sin6_addr.s6_addr32[2] = mask6.sin6_addr.s6_addr32[3] = ~0;
- var->iv_encap_cookie6 = encap_attach(AF_INET6, -1,
- var->iv_psrc, (struct sockaddr *)&mask6,
- var->iv_pdst, (struct sockaddr *)&mask6,
+ var->iv_encap_cookie6 = encap_attach_func(AF_INET6, -1, if_ipsec_encap_func,
&ipsecif6_encapsw, sc);
if (var->iv_encap_cookie6 == NULL)
return EEXIST;
diff -r 2799a643441d -r ad5153eb2213 sys/netipsec/ipsecif.h
--- a/sys/netipsec/ipsecif.h Fri Apr 06 10:31:35 2018 +0000
+++ b/sys/netipsec/ipsecif.h Fri Apr 06 10:38:53 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ipsecif.h,v 1.1 2018/01/10 10:56:30 knakahara Exp $ */
+/* $NetBSD: ipsecif.h,v 1.2 2018/04/06 10:38:53 knakahara Exp $ */
/*
* Copyright (c) 2017 Internet Initiative Japan Inc.
@@ -39,6 +39,7 @@
int ipsecif4_attach(struct ipsec_variant *);
int ipsecif4_detach(struct ipsec_variant *);
+int ipsecif6_encap_func(struct mbuf *, struct ip6_hdr *, struct ipsec_variant *);
int ipsecif6_attach(struct ipsec_variant *);
int ipsecif6_detach(struct ipsec_variant *);
void *ipsecif6_ctlinput(int, const struct sockaddr *, void *, void *);
Home |
Main Index |
Thread Index |
Old Index