summaryrefslogtreecommitdiffstats
path: root/sys/netinet/ipsec_input.c
diff options
context:
space:
mode:
authormpf <mpf@openbsd.org>2006-01-13 10:11:23 +0000
committermpf <mpf@openbsd.org>2006-01-13 10:11:23 +0000
commitf421c88b261c44f11c1002a19ad7af228c1a6115 (patch)
tree4f015096b5bd68482cd26b0a6d03a11b094fc9d7 /sys/netinet/ipsec_input.c
parent+asms (diff)
downloadwireguard-openbsd-f421c88b261c44f11c1002a19ad7af228c1a6115.tar.xz
wireguard-openbsd-f421c88b261c44f11c1002a19ad7af228c1a6115.zip
Path MTU discovery for NAT-T.
OK markus@, "looks good" hshoexer@
Diffstat (limited to 'sys/netinet/ipsec_input.c')
-rw-r--r--sys/netinet/ipsec_input.c56
1 files changed, 55 insertions, 1 deletions
diff --git a/sys/netinet/ipsec_input.c b/sys/netinet/ipsec_input.c
index 17e23e856e0..aaddbf4a778 100644
--- a/sys/netinet/ipsec_input.c
+++ b/sys/netinet/ipsec_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipsec_input.c,v 1.76 2005/07/31 03:52:19 pascoe Exp $ */
+/* $OpenBSD: ipsec_input.c,v 1.77 2006/01/13 10:11:23 mpf Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr) and
@@ -859,6 +859,60 @@ ipsec_common_ctlinput(int cmd, struct sockaddr *sa, void *v, int proto)
}
void *
+udpencap_ctlinput(int cmd, struct sockaddr *sa, void *v)
+{
+ struct ip *ip = v;
+ struct tdb *tdbp;
+ struct icmp *icp;
+ u_int32_t mtu;
+ ssize_t adjust;
+ struct sockaddr_in dst, src;
+ union sockaddr_union *su_dst, *su_src;
+ int s;
+
+ icp = (struct icmp *)((caddr_t) ip - offsetof(struct icmp, icmp_ip));
+ mtu = ntohs(icp->icmp_nextmtu);
+
+ /*
+ * Ignore the packet, if we do not receive a MTU
+ * or the MTU is too small to be acceptable.
+ */
+ if (mtu < 296)
+ return (NULL);
+
+ bzero(&dst, sizeof(dst));
+ dst.sin_family = AF_INET;
+ dst.sin_len = sizeof(struct sockaddr_in);
+ dst.sin_addr.s_addr = ip->ip_dst.s_addr;
+ su_dst = (union sockaddr_union *)&dst;
+ bzero(&src, sizeof(src));
+ src.sin_family = AF_INET;
+ src.sin_len = sizeof(struct sockaddr_in);
+ src.sin_addr.s_addr = ip->ip_src.s_addr;
+ su_src = (union sockaddr_union *)&src;
+
+ s = spltdb();
+ tdbp = gettdbbysrcdst(0, su_src, su_dst, IPPROTO_ESP);
+
+ for (; tdbp != NULL; tdbp = tdbp->tdb_snext) {
+ if (tdbp->tdb_sproto == IPPROTO_ESP &&
+ ((tdbp->tdb_flags & (TDBF_INVALID|TDBF_UDPENCAP))
+ == TDBF_UDPENCAP) &&
+ !bcmp(&tdbp->tdb_dst, &dst, SA_LEN(&su_dst->sa)) &&
+ !bcmp(&tdbp->tdb_src, &src, SA_LEN(&su_src->sa))) {
+ if ((adjust = ipsec_hdrsz(tdbp)) != -1) {
+ /* Store adjusted MTU in tdb */
+ tdbp->tdb_mtu = mtu - adjust;
+ tdbp->tdb_mtutimeout = time_second +
+ ip_mtudisc_timeout;
+ }
+ }
+ }
+ splx(s);
+ return (NULL);
+}
+
+void *
esp4_ctlinput(int cmd, struct sockaddr *sa, void *v)
{
if (sa->sa_family != AF_INET ||