Module Name: src Committed By: drochner Date: Wed Jan 25 21:58:10 UTC 2012
Modified Files: src/sys/netipsec: ipsec_input.c Log Message: After IPSEC input processing, pass a decoded/authenticated IPv4 packet to upper layers through the IP protosw, as done for IPv6. Before it was reinjected into the IP netisr queue which caused more overhead and caused artefacts like double IP option processing. Works well for me, should get more testing and review. To generate a diff of this commit: cvs rdiff -u -r1.28 -r1.29 src/sys/netipsec/ipsec_input.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/netipsec/ipsec_input.c diff -u src/sys/netipsec/ipsec_input.c:1.28 src/sys/netipsec/ipsec_input.c:1.29 --- src/sys/netipsec/ipsec_input.c:1.28 Sun Jul 17 20:54:54 2011 +++ src/sys/netipsec/ipsec_input.c Wed Jan 25 21:58:10 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ipsec_input.c,v 1.28 2011/07/17 20:54:54 joerg Exp $ */ +/* $NetBSD: ipsec_input.c,v 1.29 2012/01/25 21:58:10 drochner Exp $ */ /* $FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/netipsec/ipsec_input.c,v 1.2.4.2 2003/03/28 20:32:53 sam Exp $ */ /* $OpenBSD: ipsec_input.c,v 1.63 2003/02/20 18:35:43 deraadt Exp $ */ @@ -39,7 +39,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ipsec_input.c,v 1.28 2011/07/17 20:54:54 joerg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ipsec_input.c,v 1.29 2012/01/25 21:58:10 drochner Exp $"); /* * IPsec input processing. @@ -63,13 +63,13 @@ __KERNEL_RCSID(0, "$NetBSD: ipsec_input. #include <net/if.h> #include <net/route.h> -#include <net/netisr.h> #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> #include <netinet/ip_var.h> #include <netinet/in_var.h> +#include <netinet/in_proto.h> #include <netinet/ip6.h> #ifdef INET6 @@ -316,30 +316,20 @@ ipsec4_common_input_cb(struct mbuf *m, s return EINVAL; } - if (skip != 0) { - /* Fix IPv4 header */ - if (m->m_len < skip && (m = m_pullup(m, skip)) == NULL) { - DPRINTF(("ipsec4_common_input_cb: processing failed " - "for SA %s/%08lx\n", - ipsec_address(&sav->sah->saidx.dst), - (u_long) ntohl(sav->spi))); - IPSEC_ISTAT(sproto, ESP_STAT_HDROPS, AH_STAT_HDROPS, - IPCOMP_STAT_HDROPS); - error = ENOBUFS; - goto bad; - } - - ip = mtod(m, struct ip *); - ip->ip_len = htons(m->m_pkthdr.len); -#ifdef __FreeBSD__ - /* On FreeBSD, ip_off and ip_len assumed in host endian. */ - ip->ip_off = htons(ip->ip_off); -#endif - ip->ip_sum = 0; - ip->ip_sum = in_cksum(m, ip->ip_hl << 2); - } else { - ip = mtod(m, struct ip *); + /* Fix IPv4 header */ + if (m->m_len < skip && (m = m_pullup(m, skip)) == NULL) { + DPRINTF(("ipsec4_common_input_cb: processing failed " + "for SA %s/%08lx\n", + ipsec_address(&sav->sah->saidx.dst), + (u_long) ntohl(sav->spi))); + IPSEC_ISTAT(sproto, ESP_STAT_HDROPS, AH_STAT_HDROPS, + IPCOMP_STAT_HDROPS); + error = ENOBUFS; + goto bad; } + + ip = mtod(m, struct ip *); + ip->ip_len = htons(m->m_pkthdr.len); prot = ip->ip_p; /* IP-in-IP encapsulation */ @@ -450,18 +440,12 @@ ipsec4_common_input_cb(struct mbuf *m, s key_sa_recordxfer(sav, m); /* record data transfer */ - /* - * Re-dispatch via software interrupt. - */ - if (!IF_HANDOFF(&ipintrq, m, NULL)) { - IPSEC_ISTAT(sproto, ESP_STAT_QFULL, AH_STAT_QFULL, - IPCOMP_STAT_QFULL); - - DPRINTF(("ipsec4_common_input_cb: queue full; " - "proto %u packet dropped\n", sproto)); - return ENOBUFS; + if ((inetsw[ip_protox[prot]].pr_flags & PR_LASTHDR) != 0 && + ipsec4_in_reject(m, NULL)) { + error = EINVAL; + goto bad; } - schednetisr(NETISR_IP); + (*inetsw[ip_protox[prot]].pr_input)(m, skip, prot); return 0; bad: m_freem(m);