Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/netipsec After IPSEC input processing, pass a decoded/au...



details:   https://anonhg.NetBSD.org/src/rev/35c4e3e38323
branches:  trunk
changeset: 773056:35c4e3e38323
user:      drochner <drochner%NetBSD.org@localhost>
date:      Wed Jan 25 21:58:10 2012 +0000

description:
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.

diffstat:

 sys/netipsec/ipsec_input.c |  58 ++++++++++++++++-----------------------------
 1 files changed, 21 insertions(+), 37 deletions(-)

diffs (101 lines):

diff -r 9985a91065f6 -r 35c4e3e38323 sys/netipsec/ipsec_input.c
--- a/sys/netipsec/ipsec_input.c        Wed Jan 25 21:11:45 2012 +0000
+++ b/sys/netipsec/ipsec_input.c        Wed Jan 25 21:58:10 2012 +0000
@@ -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 @@
 
 #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 @@
                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;
-               }
+       /* 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 *);
-       }
+       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 @@
 
        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);



Home | Main Index | Thread Index | Old Index