diff options
author | sam <sam@FreeBSD.org> | 2002-10-16 02:25:05 +0000 |
---|---|---|
committer | sam <sam@FreeBSD.org> | 2002-10-16 02:25:05 +0000 |
commit | 0ef6c52bbcc67b0dce67c7ad7a6fc685828a6400 (patch) | |
tree | ae7276b550c8f6a3436b1985ff4cb31e8a826d66 /sys/netinet | |
parent | b12d57e66aba52a8bea632c34b458fa9d734aef7 (diff) | |
download | FreeBSD-src-0ef6c52bbcc67b0dce67c7ad7a6fc685828a6400.zip FreeBSD-src-0ef6c52bbcc67b0dce67c7ad7a6fc685828a6400.tar.gz |
Tie new "Fast IPsec" code into the build. This involves the usual
configuration stuff as well as conditional code in the IPv4 and IPv6
areas. Everything is conditional on FAST_IPSEC which is mutually
exclusive with IPSEC (KAME IPsec implmentation).
As noted previously, don't use FAST_IPSEC with INET6 at the moment.
Reviewed by: KAME, rwatson
Approved by: silence
Supported by: Vernier Networks
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/in_pcb.c | 10 | ||||
-rw-r--r-- | sys/netinet/in_pcb.h | 2 | ||||
-rw-r--r-- | sys/netinet/in_proto.c | 17 | ||||
-rw-r--r-- | sys/netinet/ip_icmp.c | 6 | ||||
-rw-r--r-- | sys/netinet/ip_input.c | 133 | ||||
-rw-r--r-- | sys/netinet/ip_output.c | 148 | ||||
-rw-r--r-- | sys/netinet/raw_ip.c | 20 | ||||
-rw-r--r-- | sys/netinet/tcp_input.c | 19 | ||||
-rw-r--r-- | sys/netinet/tcp_output.c | 5 | ||||
-rw-r--r-- | sys/netinet/tcp_reass.c | 19 | ||||
-rw-r--r-- | sys/netinet/tcp_subr.c | 8 | ||||
-rw-r--r-- | sys/netinet/tcp_syncache.c | 10 | ||||
-rw-r--r-- | sys/netinet/tcp_timewait.c | 8 | ||||
-rw-r--r-- | sys/netinet/udp_usrreq.c | 125 |
14 files changed, 438 insertions, 92 deletions
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 9ad3607..8411fe8 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -72,6 +72,16 @@ #include <netkey/key.h> #endif /* IPSEC */ +#ifdef FAST_IPSEC +#if defined(IPSEC) || defined(IPSEC_ESP) +#error "Bad idea: don't compile with both IPSEC and FAST_IPSEC!" +#endif + +#include <netipsec/ipsec.h> +#include <netipsec/key.h> +#define IPSEC +#endif /* FAST_IPSEC */ + struct in_addr zeroin_addr; /* diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h index 4fe626b..f08151b 100644 --- a/sys/netinet/in_pcb.h +++ b/sys/netinet/in_pcb.h @@ -42,10 +42,10 @@ #include <sys/_mutex.h> #include <net/route.h> -#include <netinet6/ipsec.h> /* for IPSEC */ #define in6pcb inpcb /* for KAME src sync over BSD*'s */ #define in6p_sp inp_sp /* for KAME src sync over BSD*'s */ +struct inpcbpolicy; /* * Common structure pcb for internet protocol implementation. diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c index 876d8b6..5ecbe65 100644 --- a/sys/netinet/in_proto.c +++ b/sys/netinet/in_proto.c @@ -76,6 +76,14 @@ #include <netinet6/ipcomp.h> #endif /* IPSEC */ +#ifdef FAST_IPESC +#include <netipsec/ipsec.h> +#define ah4_input ipsec4_common_input +#define esp4_input ipsec4_common_input +#define ipcomp4_input ipsec4_common_input +#define IPSEC +#endif /* FAST_IPSEC */ + #ifdef IPXIP #include <netipx/ipx_ip.h> #endif @@ -232,9 +240,18 @@ SYSCTL_NODE(_net_inet, IPPROTO_ICMP, icmp, CTLFLAG_RW, 0, "ICMP"); SYSCTL_NODE(_net_inet, IPPROTO_UDP, udp, CTLFLAG_RW, 0, "UDP"); SYSCTL_NODE(_net_inet, IPPROTO_TCP, tcp, CTLFLAG_RW, 0, "TCP"); SYSCTL_NODE(_net_inet, IPPROTO_IGMP, igmp, CTLFLAG_RW, 0, "IGMP"); +#ifdef FAST_IPSEC +/* XXX no protocol # to use, pick something "reserved" */ +SYSCTL_NODE(_net_inet, 253, ipsec, CTLFLAG_RW, 0, "IPSEC"); +SYSCTL_NODE(_net_inet, IPPROTO_AH, ah, CTLFLAG_RW, 0, "AH"); +SYSCTL_NODE(_net_inet, IPPROTO_ESP, esp, CTLFLAG_RW, 0, "ESP"); +SYSCTL_NODE(_net_inet, IPPROTO_IPCOMP, ipcomp, CTLFLAG_RW, 0, "IPCOMP"); +SYSCTL_NODE(_net_inet, IPPROTO_IPIP, ipip, CTLFLAG_RW, 0, "IPIP"); +#else #ifdef IPSEC SYSCTL_NODE(_net_inet, IPPROTO_AH, ipsec, CTLFLAG_RW, 0, "IPSEC"); #endif /* IPSEC */ +#endif /* !FAST_IPSEC */ SYSCTL_NODE(_net_inet, IPPROTO_RAW, raw, CTLFLAG_RW, 0, "RAW"); #ifdef IPDIVERT SYSCTL_NODE(_net_inet, IPPROTO_DIVERT, divert, CTLFLAG_RW, 0, "DIVERT"); diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c index 5dd82ef..c893340 100644 --- a/sys/netinet/ip_icmp.c +++ b/sys/netinet/ip_icmp.c @@ -65,6 +65,12 @@ #include <netkey/key.h> #endif +#ifdef FAST_IPSEC +#include <netipsec/ipsec.h> +#include <netipsec/key.h> +#define IPSEC +#endif + #include <machine/in_cksum.h> /* diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 1feee4a..f22d550 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -88,6 +88,11 @@ #include <netkey/key.h> #endif +#ifdef FAST_IPSEC +#include <netipsec/ipsec.h> +#include <netipsec/key.h> +#endif + int rsvp_on = 0; int ipforwarding = 0; @@ -290,6 +295,12 @@ ip_input(struct mbuf *m) struct mbuf *m0; int rv; #endif /* PFIL_HOOKS */ +#ifdef FAST_IPSEC + struct m_tag *mtag; + struct tdb_ident *tdbi; + struct secpolicy *sp; + int s, error; +#endif /* FAST_IPSEC */ args.eh = NULL; args.oif = NULL; @@ -656,6 +667,34 @@ pass: goto bad; } #endif /* IPSEC */ +#ifdef FAST_IPSEC + mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL); + s = splnet(); + if (mtag != NULL) { + tdbi = (struct tdb_ident *)(mtag + 1); + sp = ipsec_getpolicy(tdbi, IPSEC_DIR_INBOUND); + } else { + sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, + IP_FORWARDING, &error); + } + if (sp == NULL) { /* NB: can happen if error */ + splx(s); + /*XXX error stat???*/ + DPRINTF(("ip_input: no SP for forwarding\n")); /*XXX*/ + goto bad; + } + + /* + * Check security policy against packet attributes. + */ + error = ipsec_in_reject(sp, m); + KEY_FREESP(&sp); + splx(s); + if (error) { + ipstat.ips_cantforward++; + goto bad; + } +#endif /* FAST_IPSEC */ ip_forward(m, 0, args.next_hop); } return; @@ -825,6 +864,45 @@ found: goto bad; } #endif +#if FAST_IPSEC + /* + * enforce IPsec policy checking if we are seeing last header. + * note that we do not visit this with protocols with pcb layer + * code - like udp/tcp/raw ip. + */ + if ((inetsw[ip_protox[ip->ip_p]].pr_flags & PR_LASTHDR) != 0) { + /* + * Check if the packet has already had IPsec processing + * done. If so, then just pass it along. This tag gets + * set during AH, ESP, etc. input handling, before the + * packet is returned to the ip input queue for delivery. + */ + mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL); + s = splnet(); + if (mtag != NULL) { + tdbi = (struct tdb_ident *)(mtag + 1); + sp = ipsec_getpolicy(tdbi, IPSEC_DIR_INBOUND); + } else { + sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, + IP_FORWARDING, &error); + } + if (sp != NULL) { + /* + * Check security policy against packet attributes. + */ + error = ipsec_in_reject(sp, m); + KEY_FREESP(&sp); + } else { + /* XXX error stat??? */ + error = EINVAL; +DPRINTF(("ip_input: no SP, packet discarded\n"));/*XXX*/ + goto bad; + } + splx(s); + if (error) + goto bad; + } +#endif /* FAST_IPSEC */ /* * Switch out to protocol's input routine. @@ -1625,7 +1703,7 @@ ip_forward(struct mbuf *m, int srcrt, struct sockaddr_in *next_hop) n_long dest; struct in_addr pkt_dst; struct ifnet *destifp; -#ifdef IPSEC +#if defined(IPSEC) || defined(FAST_IPSEC) struct ifnet dummyifp; #endif @@ -1839,7 +1917,58 @@ ip_forward(struct mbuf *m, int srcrt, struct sockaddr_in *next_hop) key_freesp(sp); } } -#else +#elif FAST_IPSEC + /* + * If the packet is routed over IPsec tunnel, tell the + * originator the tunnel MTU. + * tunnel MTU = if MTU - sizeof(IP) - ESP/AH hdrsiz + * XXX quickhack!!! + */ + if (ipforward_rt.ro_rt) { + struct secpolicy *sp = NULL; + int ipsecerror; + int ipsechdr; + struct route *ro; + + sp = ipsec_getpolicybyaddr(mcopy, + IPSEC_DIR_OUTBOUND, + IP_FORWARDING, + &ipsecerror); + + if (sp == NULL) + destifp = ipforward_rt.ro_rt->rt_ifp; + else { + /* count IPsec header size */ + ipsechdr = ipsec4_hdrsiz(mcopy, + IPSEC_DIR_OUTBOUND, + NULL); + + /* + * find the correct route for outer IPv4 + * header, compute tunnel MTU. + * + * XXX BUG ALERT + * The "dummyifp" code relies upon the fact + * that icmp_error() touches only ifp->if_mtu. + */ + /*XXX*/ + destifp = NULL; + if (sp->req != NULL + && sp->req->sav != NULL + && sp->req->sav->sah != NULL) { + ro = &sp->req->sav->sah->sa_route; + if (ro->ro_rt && ro->ro_rt->rt_ifp) { + dummyifp.if_mtu = + ro->ro_rt->rt_ifp->if_mtu; + dummyifp.if_mtu -= ipsechdr; + destifp = &dummyifp; + } + } + + KEY_FREESP(&sp); + } + } +#else /* !IPSEC && !FAST_IPSEC */ if (ipforward_rt.ro_rt) destifp = ipforward_rt.ro_rt->rt_ifp; #endif /*IPSEC*/ diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index e78ef26..0a9d66a 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -79,6 +79,12 @@ static MALLOC_DEFINE(M_IPMOPTS, "ip_moptions", "internet multicast options"); #endif #endif /*IPSEC*/ +#ifdef FAST_IPSEC +#include <netipsec/ipsec.h> +#include <netipsec/xform.h> +#include <netipsec/key.h> +#endif /*FAST_IPSEC*/ + #include <netinet/ip_fw.h> #include <netinet/ip_dummynet.h> @@ -134,6 +140,13 @@ ip_output(m0, opt, ro, flags, imo, inp) struct secpolicy *sp = NULL; struct socket *so = inp ? inp->inp_socket : NULL; #endif +#ifdef FAST_IPSEC + struct route iproute; + struct m_tag *mtag; + struct secpolicy *sp = NULL; + struct tdb_ident *tdbi; + int s; +#endif /* FAST_IPSEC */ struct ip_fw_args args; int src_was_INADDR_ANY = 0; /* as the name says... */ #ifdef PFIL_HOOKS @@ -182,6 +195,10 @@ ip_output(m0, opt, ro, flags, imo, inp) m = m0; KASSERT(!m || (m->m_flags & M_PKTHDR) != 0, ("ip_output: no HDR")); +#ifndef FAST_IPSEC + KASSERT(ro != NULL, ("ip_output: no route, proto %d", + mtod(m, struct ip *)->ip_p)); +#endif if (args.rule != NULL) { /* dummynet already saw us */ ip = mtod(m, struct ip *); @@ -216,6 +233,12 @@ ip_output(m0, opt, ro, flags, imo, inp) hlen = IP_VHL_HL(ip->ip_vhl) << 2; } +#ifdef FAST_IPSEC + if (ro == NULL) { + ro = &iproute; + bzero(ro, sizeof (*ro)); + } +#endif /* FAST_IPSEC */ dst = (struct sockaddr_in *)&ro->ro_dst; /* * If there is a cached route, @@ -569,6 +592,119 @@ sendit: ip->ip_off = ntohs(ip->ip_off); skip_ipsec: #endif /*IPSEC*/ +#ifdef FAST_IPSEC + /* + * Check the security policy (SP) for the packet and, if + * required, do IPsec-related processing. There are two + * cases here; the first time a packet is sent through + * it will be untagged and handled by ipsec4_checkpolicy. + * If the packet is resubmitted to ip_output (e.g. after + * AH, ESP, etc. processing), there will be a tag to bypass + * the lookup and related policy checking. + */ + mtag = m_tag_find(m, PACKET_TAG_IPSEC_PENDING_TDB, NULL); + s = splnet(); + if (mtag != NULL) { + tdbi = (struct tdb_ident *)(mtag + 1); + sp = ipsec_getpolicy(tdbi, IPSEC_DIR_OUTBOUND); + if (sp == NULL) + error = -EINVAL; /* force silent drop */ + m_tag_delete(m, mtag); + } else { + sp = ipsec4_checkpolicy(m, IPSEC_DIR_OUTBOUND, flags, + &error, inp); + } + /* + * There are four return cases: + * sp != NULL apply IPsec policy + * sp == NULL, error == 0 no IPsec handling needed + * sp == NULL, error == -EINVAL discard packet w/o error + * sp == NULL, error != 0 discard packet, report error + */ + if (sp != NULL) { + /* Loop detection, check if ipsec processing already done */ + KASSERT(sp->req != NULL, ("ip_output: no ipsec request")); + for (mtag = m_tag_first(m); mtag != NULL; + mtag = m_tag_next(m, mtag)) { + if (mtag->m_tag_cookie != MTAG_ABI_COMPAT) + continue; + if (mtag->m_tag_id != PACKET_TAG_IPSEC_OUT_DONE && + mtag->m_tag_id != PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED) + continue; + /* + * Check if policy has an SA associated with it. + * This can happen when an SP has yet to acquire + * an SA; e.g. on first reference. If it occurs, + * then we let ipsec4_process_packet do its thing. + */ + if (sp->req->sav == NULL) + break; + tdbi = (struct tdb_ident *)(mtag + 1); + if (tdbi->spi == sp->req->sav->spi && + tdbi->proto == sp->req->sav->sah->saidx.proto && + bcmp(&tdbi->dst, &sp->spidx.dst, + sizeof (union sockaddr_union)) == 0) { + /* + * No IPsec processing is needed, free + * reference to SP. + * + * NB: null pointer to avoid free at + * done: below. + */ + KEY_FREESP(&sp), sp = NULL; + splx(s); + goto spd_done; + } + } + + /* + * Do delayed checksums now because we send before + * this is done in the normal processing path. + */ + if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { + in_delayed_cksum(m); + m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; + } + + ip->ip_len = htons(ip->ip_len); + ip->ip_off = htons(ip->ip_off); + + /* NB: callee frees mbuf */ + error = ipsec4_process_packet(m, sp->req, flags, 0); + splx(s); + goto done; + } else { + splx(s); + + if (error != 0) { + /* + * Hack: -EINVAL is used to signal that a packet + * should be silently discarded. This is typically + * because we asked key management for an SA and + * it was delayed (e.g. kicked up to IKE). + */ + if (error == -EINVAL) + error = 0; + goto bad; + } else { + /* No IPsec processing for this packet. */ + } +#ifdef notyet + /* + * If deferred crypto processing is needed, check that + * the interface supports it. + */ + mtag = m_tag_find(m, PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED, NULL); + if (mtag != NULL && (ifp->if_capenable & IFCAP_IPSEC) == 0) { + /* notify IPsec to do its own crypto */ + ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1)); + error = EHOSTUNREACH; + goto bad; + } +#endif + } +spd_done: +#endif /* FAST_IPSEC */ /* * IpHack's section. @@ -1078,6 +1214,14 @@ done: key_freesp(sp); } #endif /* IPSEC */ +#ifdef FAST_IPSEC + if (ro == &iproute && ro->ro_rt) { + RTFREE(ro->ro_rt); + ro->ro_rt = NULL; + } + if (sp != NULL) + KEY_FREESP(&sp); +#endif /* FAST_IPSEC */ return (error); bad: m_freem(m); @@ -1340,7 +1484,7 @@ ip_ctloutput(so, sopt) } break; -#ifdef IPSEC +#if defined(IPSEC) || defined(FAST_IPSEC) case IP_IPSEC_POLICY: { caddr_t req; @@ -1444,7 +1588,7 @@ ip_ctloutput(so, sopt) error = ip_getmoptions(sopt, inp->inp_moptions); break; -#ifdef IPSEC +#if defined(IPSEC) || defined(FAST_IPSEC) case IP_IPSEC_POLICY: { struct mbuf *m = NULL; diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c index 144554a..de539fa 100644 --- a/sys/netinet/raw_ip.c +++ b/sys/netinet/raw_ip.c @@ -71,6 +71,10 @@ #include <netinet/ip_fw.h> #include <netinet/ip_dummynet.h> +#ifdef FAST_IPSEC +#include <netipsec/ipsec.h> +#endif /*FAST_IPSEC*/ + #ifdef IPSEC #include <netinet6/ipsec.h> #endif /*IPSEC*/ @@ -157,6 +161,13 @@ rip_input(m, off) /* do not inject data to pcb */ } #endif /*IPSEC*/ +#ifdef FAST_IPSEC + /* check AH/ESP integrity. */ + if (ipsec4_in_reject(n, last)) { + policyfail = 1; + /* do not inject data to pcb */ + } +#endif /*FAST_IPSEC*/ #ifdef MAC if (policyfail == 0 && mac_check_socket_deliver(last->inp_socket, @@ -195,6 +206,15 @@ rip_input(m, off) return; } #endif /*IPSEC*/ +#ifdef FAST_IPSEC + /* check AH/ESP integrity. */ + if (ipsec4_in_reject(m, last)) { + m_freem(m); + ipstat.ips_delivered--; + /* do not inject data to pcb */ + return; + } +#endif /*FAST_IPSEC*/ #ifdef MAC if (mac_check_socket_deliver(last->inp_socket, m) != 0) { m_freem(m); diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 59cf6ae..7849ea0 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -84,6 +84,13 @@ #include <netinet/tcp_debug.h> #endif /* TCPDEBUG */ +#ifdef FAST_IPSEC +#include <netipsec/ipsec.h> +#ifdef INET6 +#include <netipsec/ipsec6.h> +#endif +#endif /*FAST_IPSEC*/ + #ifdef IPSEC #include <netinet6/ipsec.h> #include <netinet6/ipsec6.h> @@ -566,6 +573,18 @@ findpcb: } } #endif +#ifdef FAST_IPSEC +#ifdef INET6 + if (isipv6) { + if (inp != NULL && ipsec6_in_reject(m, inp)) { + goto drop; + } + } else +#endif /* INET6 */ + if (inp != NULL && ipsec4_in_reject(m, inp)) { + goto drop; + } +#endif /*FAST_IPSEC*/ /* * If the state is CLOSED (i.e., TCB does not exist) then diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c index 4128be5..1200282 100644 --- a/sys/netinet/tcp_output.c +++ b/sys/netinet/tcp_output.c @@ -79,6 +79,11 @@ #include <netinet6/ipsec.h> #endif /*IPSEC*/ +#ifdef FAST_IPSEC +#include <netipsec/ipsec.h> +#define IPSEC +#endif /*FAST_IPSEC*/ + #include <machine/in_cksum.h> #ifdef notyet diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c index 59cf6ae..7849ea0 100644 --- a/sys/netinet/tcp_reass.c +++ b/sys/netinet/tcp_reass.c @@ -84,6 +84,13 @@ #include <netinet/tcp_debug.h> #endif /* TCPDEBUG */ +#ifdef FAST_IPSEC +#include <netipsec/ipsec.h> +#ifdef INET6 +#include <netipsec/ipsec6.h> +#endif +#endif /*FAST_IPSEC*/ + #ifdef IPSEC #include <netinet6/ipsec.h> #include <netinet6/ipsec6.h> @@ -566,6 +573,18 @@ findpcb: } } #endif +#ifdef FAST_IPSEC +#ifdef INET6 + if (isipv6) { + if (inp != NULL && ipsec6_in_reject(m, inp)) { + goto drop; + } + } else +#endif /* INET6 */ + if (inp != NULL && ipsec4_in_reject(m, inp)) { + goto drop; + } +#endif /*FAST_IPSEC*/ /* * If the state is CLOSED (i.e., TCB does not exist) then diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index d9b3ecf..02da281 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -99,6 +99,14 @@ #endif #endif /*IPSEC*/ +#ifdef FAST_IPSEC +#include <netipsec/ipsec.h> +#ifdef INET6 +#include <netipsec/ipsec6.h> +#endif +#define IPSEC +#endif /*FAST_IPSEC*/ + #include <machine/in_cksum.h> #include <sys/md5.h> diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c index 49197bf..8426a63 100644 --- a/sys/netinet/tcp_syncache.c +++ b/sys/netinet/tcp_syncache.c @@ -81,9 +81,17 @@ #ifdef INET6 #include <netinet6/ipsec6.h> #endif -#include <netkey/key.h> #endif /*IPSEC*/ +#ifdef FAST_IPSEC +#include <netipsec/ipsec.h> +#ifdef INET6 +#include <netipsec/ipsec6.h> +#endif +#include <netipsec/key.h> +#define IPSEC +#endif /*FAST_IPSEC*/ + #include <machine/in_cksum.h> #include <vm/uma.h> diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c index d9b3ecf..02da281 100644 --- a/sys/netinet/tcp_timewait.c +++ b/sys/netinet/tcp_timewait.c @@ -99,6 +99,14 @@ #endif #endif /*IPSEC*/ +#ifdef FAST_IPSEC +#include <netipsec/ipsec.h> +#ifdef INET6 +#include <netipsec/ipsec6.h> +#endif +#define IPSEC +#endif /*FAST_IPSEC*/ + #include <machine/in_cksum.h> #include <sys/md5.h> diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 1a07cea..cc816d8 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -78,6 +78,10 @@ #include <netinet/udp.h> #include <netinet/udp_var.h> +#ifdef FAST_IPSEC +#include <netipsec/ipsec.h> +#endif /*FAST_IPSEC*/ + #ifdef IPSEC #include <netinet6/ipsec.h> #endif /*IPSEC*/ @@ -167,10 +171,6 @@ udp_input(m, off) struct mbuf *opts = 0; int len; struct ip save_ip; - struct sockaddr *append_sa; -#ifdef MAC - int error; -#endif udpstat.udps_ipackets++; @@ -203,6 +203,16 @@ udp_input(m, off) goto badunlocked; /* + * Construct sockaddr format source address. + * Stuff source address and datagram in user buffer. + */ + udp_in.sin_port = uh->uh_sport; + udp_in.sin_addr = ip->ip_src; +#ifdef INET6 + udp_in6.uin6_init_done = udp_ip6.uip6_init_done = 0; +#endif + + /* * Make mbuf data length reflect UDP length. * If not enough data to reflect UDP length, drop. */ @@ -272,18 +282,10 @@ udp_input(m, off) */ /* - * Construct sockaddr format source address. - */ - udp_in.sin_port = uh->uh_sport; - udp_in.sin_addr = ip->ip_src; - /* * Locate pcb(s) for datagram. * (Algorithm copied from raw_intr().) */ last = NULL; -#ifdef INET6 - udp_in6.uin6_init_done = udp_ip6.uip6_init_done = 0; -#endif LIST_FOREACH(inp, &udb, inp_list) { INP_LOCK(inp); if (inp->inp_lport != uh->uh_dport) { @@ -308,29 +310,12 @@ udp_input(m, off) if (last != NULL) { struct mbuf *n; - int policyfail; - policyfail = 0; -#ifdef IPSEC - /* check AH/ESP integrity. */ - if (ipsec4_in_reject_so(m, last->inp_socket)) { - ipsecstat.in_polvio++; - policyfail = 1; - /* do not inject data to pcb */ - } -#endif /*IPSEC*/ -#ifdef MAC - if (mac_check_socket_deliver(last->inp_socket, - m) != 0) - policyfail = 1; -#endif - if (!policyfail) { - n = m_copy(m, 0, M_COPYALL); - if (n != NULL) - udp_append(last, ip, n, + n = m_copy(m, 0, M_COPYALL); + if (n != NULL) + udp_append(last, ip, n, iphlen + sizeof(struct udphdr)); - } INP_UNLOCK(last); } last = inp; @@ -355,13 +340,6 @@ udp_input(m, off) udpstat.udps_noportbcast++; goto badheadlocked; } -#ifdef IPSEC - /* check AH/ESP integrity. */ - if (ipsec4_in_reject_so(m, last->inp_socket)) { - ipsecstat.in_polvio++; - goto badheadlocked; - } -#endif /*IPSEC*/ INP_UNLOCK(last); INP_INFO_RUNLOCK(&udbinfo); udp_append(last, ip, m, iphlen + sizeof(struct udphdr)); @@ -399,58 +377,12 @@ udp_input(m, off) } INP_LOCK(inp); INP_INFO_RUNLOCK(&udbinfo); -#ifdef IPSEC - if (ipsec4_in_reject_so(m, inp->inp_socket)) { - ipsecstat.in_polvio++; - goto bad; - } -#endif /*IPSEC*/ -#ifdef MAC - error = mac_check_socket_deliver(inp->inp_socket, m); - if (error) - goto bad; -#endif - - /* - * Construct sockaddr format source address. - * Stuff source address and datagram in user buffer. - */ - udp_in.sin_port = uh->uh_sport; - udp_in.sin_addr = ip->ip_src; - if (inp->inp_flags & INP_CONTROLOPTS - || inp->inp_socket->so_options & SO_TIMESTAMP) { -#ifdef INET6 - if (inp->inp_vflag & INP_IPV6) { - int savedflags; - - ip_2_ip6_hdr(&udp_ip6.uip6_ip6, ip); - savedflags = inp->inp_flags; - inp->inp_flags &= ~INP_UNMAPPABLEOPTS; - ip6_savecontrol(inp, &opts, &udp_ip6.uip6_ip6, m); - inp->inp_flags = savedflags; - } else -#endif - ip_savecontrol(inp, &opts, ip, m); - } - m_adj(m, iphlen + sizeof(struct udphdr)); -#ifdef INET6 - if (inp->inp_vflag & INP_IPV6) { - in6_sin_2_v4mapsin6(&udp_in, &udp_in6.uin6_sin); - append_sa = (struct sockaddr *)&udp_in6; - } else -#endif - append_sa = (struct sockaddr *)&udp_in; - if (sbappendaddr(&inp->inp_socket->so_rcv, append_sa, m, opts) == 0) { - udpstat.udps_fullsock++; - goto bad; - } - sorwakeup(inp->inp_socket); + udp_append(inp, ip, m, iphlen + sizeof(struct udphdr)); INP_UNLOCK(inp); return; badheadlocked: INP_INFO_RUNLOCK(&udbinfo); -bad: if (inp) INP_UNLOCK(inp); badunlocked: @@ -493,6 +425,27 @@ udp_append(last, ip, n, off) struct sockaddr *append_sa; struct mbuf *opts = 0; +#ifdef IPSEC + /* check AH/ESP integrity. */ + if (ipsec4_in_reject_so(n, last->inp_socket)) { + ipsecstat.in_polvio++; + m_freem(n); + return; + } +#endif /*IPSEC*/ +#ifdef FAST_IPSEC + /* check AH/ESP integrity. */ + if (ipsec4_in_reject(n, last)) { + m_freem(n); + return; + } +#endif /*FAST_IPSEC*/ +#ifdef MAC + if (mac_check_socket_deliver(last->inp_socket, n) != 0) { + m_freem(n); + return; + } +#endif if (last->inp_flags & INP_CONTROLOPTS || last->inp_socket->so_options & SO_TIMESTAMP) { #ifdef INET6 |