summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/ip_output.c23
-rw-r--r--sys/netinet/ipsec_output.c24
2 files changed, 41 insertions, 6 deletions
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 48d96b5452b..926071c5dad 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_output.c,v 1.90 2001/05/16 12:53:36 ho Exp $ */
+/* $OpenBSD: ip_output.c,v 1.91 2001/05/20 08:34:29 angelos Exp $ */
/* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */
/*
@@ -126,6 +126,8 @@ ip_output(m0, va_alist)
#ifdef IPSEC
union sockaddr_union sdst;
u_int32_t sspi;
+ struct m_tag *mtag;
+ struct tdb_ident *tdbi;
struct inpcb *inp;
struct tdb *tdb;
@@ -280,11 +282,11 @@ ip_output(m0, va_alist)
if (inp && inp->inp_tdb_out &&
inp->inp_tdb_out->tdb_dst.sa.sa_family == AF_INET &&
!bcmp(&inp->inp_tdb_out->tdb_dst.sin.sin_addr,
- &ip->ip_dst, sizeof(ip->ip_dst)))
+ &ip->ip_dst, sizeof(ip->ip_dst)))
tdb = inp->inp_tdb_out;
else
tdb = ipsp_spd_lookup(m, AF_INET, hlen, &error,
- IPSP_DIRECTION_OUT, NULL, inp);
+ IPSP_DIRECTION_OUT, NULL, inp);
if (tdb == NULL) {
splx(s);
@@ -327,6 +329,21 @@ ip_output(m0, va_alist)
goto done_spd;
}
+ /* Loop detection */
+ for (mtag = m_tag_find(m, PACKET_TAG_IPSEC_DONE, NULL); mtag;
+ mtag = m_tag_find(m, PACKET_TAG_IPSEC_DONE, mtag)) {
+ tdbi = (struct tdb_ident *)(mtag + 1);
+ if (tdbi->spi == tdb->tdb_spi &&
+ tdbi->proto == tdb->tdb_sproto &&
+ !bcmp(&tdbi->dst, &tdb->tdb_dst,
+ sizeof(union sockaddr_union))) {
+ splx(s);
+ sproto = 0; /* mark as no-IPsec-needed */
+ DPRINTF(("ip_output: IPsec loop detected, skipping further IPsec processing.\n"));
+ goto done_spd;
+ }
+ }
+
/* We need to do IPsec */
bcopy(&tdb->tdb_dst, &sdst, sizeof(sdst));
sspi = tdb->tdb_spi;
diff --git a/sys/netinet/ipsec_output.c b/sys/netinet/ipsec_output.c
index 486a85c1535..05a0a479f4e 100644
--- a/sys/netinet/ipsec_output.c
+++ b/sys/netinet/ipsec_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipsec_output.c,v 1.7 2001/05/11 17:20:11 aaron Exp $ */
+/* $OpenBSD: ipsec_output.c,v 1.8 2001/05/20 08:34:27 angelos Exp $ */
/*
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
@@ -291,6 +291,9 @@ ipsp_process_done(struct mbuf *m, struct tdb *tdb, struct tdb *tdb2)
struct ip6_hdr *ip6;
#endif /* INET6 */
+ struct tdb_ident *tdbi;
+ struct m_tag *mtag;
+
switch (tdb->tdb_dst.sa.sa_family)
{
#ifdef INET
@@ -332,6 +335,22 @@ ipsp_process_done(struct mbuf *m, struct tdb *tdb, struct tdb *tdb2)
return ENXIO;
}
+ /* Add a record of what we've done to the packet */
+ mtag = m_tag_get(PACKET_TAG_IPSEC_DONE, sizeof(struct tdb_ident),
+ M_NOWAIT);
+ if (mtag == NULL)
+ {
+ m_freem(m);
+ DPRINTF(("ipsp_process_done(): could not allocate packet tag\n"));
+ return ENOMEM;
+ }
+ tdbi = (struct tdb_ident *)(mtag + 1);
+ bcopy(&tdb->tdb_dst, &tdbi->dst, sizeof(union sockaddr_union));
+ tdbi->proto = tdb->tdb_sproto;
+ tdbi->spi = tdb->tdb_spi;
+
+ m_tag_prepend(m, mtag);
+
/* If there's another (bundled) TDB to apply, do so */
if (tdb->tdb_onext)
return ipsp_process_packet(m, tdb->tdb_onext, tdb->tdb_dst.sa.sa_family,
@@ -353,8 +372,7 @@ ipsp_process_done(struct mbuf *m, struct tdb *tdb, struct tdb *tdb2)
NTOHS(ip->ip_len);
NTOHS(ip->ip_off);
- return ip_output(m, NULL, NULL, IP_ENCAPSULATED | IP_RAWOUTPUT,
- NULL, NULL);
+ return ip_output(m, NULL, NULL, IP_RAWOUTPUT, NULL, NULL);
#endif /* INET */
#ifdef INET6