diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet/ip_output.c | 23 | ||||
-rw-r--r-- | sys/netinet/ipsec_output.c | 24 |
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 |