Subject: Re: Heads-up, status update on FAST_IPSEC
To: None <tech-kern@netbsd.org>
From: Jun-ichiro itojun Hagino <itojun@iijlab.net>
List: tech-kern
Date: 08/05/2003 09:46:07
>I have a NetBSD port of Sam Leffler's FAST_IPSEC which works well
>enough to start some work on integration -- enough that other
>developers/users can start testing, if they wish. The current version
>is IPv4-only. The source code can co-exist with KAME IPsec, but only
>one or the other can be configured into a kernel at one time.
before committing FAST_IPSEC code, please make sure transport-mode
packet does not get injected into ip_input() again. it has bad
sideeffects such as:
- stat counters being not accurate
- ip options evaluated twice
- ip header processed twice
the attached diff should solve that for openbsd-current.
itojun
Index: ip_ipsp.h
===================================================================
RCS file: /cvs/src/sys/netinet/ip_ipsp.h,v
retrieving revision 1.123
diff -u -r1.123 ip_ipsp.h
--- ip_ipsp.h 24 Jul 2003 08:03:20 -0000 1.123
+++ ip_ipsp.h 5 Aug 2003 00:45:15 -0000
@@ -570,7 +570,7 @@
#ifdef INET
extern void ah4_input(struct mbuf *, ...);
-extern int ah4_input_cb(struct mbuf *, ...);
+extern int ah4_input_cb(struct mbuf *, int, int);
extern void *ah4_ctlinput(int, struct sockaddr *, void *);
#endif /* INET */
@@ -591,7 +591,7 @@
#ifdef INET
extern void esp4_input(struct mbuf *, ...);
-extern int esp4_input_cb(struct mbuf *, ...);
+extern int esp4_input_cb(struct mbuf *, int, int);
extern void *esp4_ctlinput(int, struct sockaddr *, void *);
#endif /* INET */
@@ -612,7 +612,7 @@
#ifdef INET
extern void ipcomp4_input(struct mbuf *, ...);
-extern int ipcomp4_input_cb(struct mbuf *, ...);
+extern int ipcomp4_input_cb(struct mbuf *, int, int);
#endif /* INET */
#ifdef INET6
Index: ipsec_input.c
===================================================================
RCS file: /cvs/src/sys/netinet/ipsec_input.c,v
retrieving revision 1.69
diff -u -r1.69 ipsec_input.c
--- ipsec_input.c 28 Jul 2003 10:10:16 -0000 1.69
+++ ipsec_input.c 5 Aug 2003 00:45:16 -0000
@@ -88,6 +88,8 @@
int ah_enable = 1;
int ipcomp_enable = 0;
+extern struct protosw inetsw[];
+extern u_char ip_protox[];
#ifdef INET6
extern struct ip6protosw inet6sw[];
extern u_char ip6_protox[];
@@ -584,13 +586,13 @@
switch (sproto)
{
case IPPROTO_ESP:
- return esp4_input_cb(m);
+ return esp4_input_cb(m, skip, protoff);
case IPPROTO_AH:
- return ah4_input_cb(m);
+ return ah4_input_cb(m, skip, protoff);
case IPPROTO_IPCOMP:
- return ipcomp4_input_cb(m);
+ return ipcomp4_input_cb(m, skip, protoff);
default:
DPRINTF(("ipsec_common_input_cb(): unknown/unsupported"
@@ -701,31 +703,29 @@
/* IPv4 AH callback. */
int
-ah4_input_cb(struct mbuf *m, ...)
+ah4_input_cb(struct mbuf *m, int off, int protoff)
{
- struct ifqueue *ifq = &ipintrq;
- int s = splimp();
+ int nxt;
+ u_int8_t nxt8;
+
+ /* Retrieve new protocol */
+ m_copydata(m, protoff, sizeof(u_int8_t), (caddr_t) &nxt8);
+ nxt = nxt8;
/*
- * Interface pointer is already in first mbuf; chop off the
- * `outer' header and reschedule.
+ * Protection against faulty packet - there should be
+ * more sanity checks in header chain processing.
*/
-
- if (IF_QFULL(ifq)) {
- IF_DROP(ifq);
- ahstat.ahs_qfull++;
- splx(s);
-
- m_freem(m);
- DPRINTF(("ah4_input_cb(): dropped packet because of full "
- "IP queue\n"));
- return ENOBUFS;
+ if (m->m_pkthdr.len < off) {
+ ipstat.ips_tooshort++;
+ goto bad;
}
-
- IF_ENQUEUE(ifq, m);
- schednetisr(NETISR_IP);
- splx(s);
+ (*inetsw[ip_protox[nxt]].pr_input)(m, off, NULL, 0);
return 0;
+
+ bad:
+ m_freem(m);
+ return EINVAL;
}
@@ -756,30 +756,9 @@
/* IPv4 ESP callback. */
int
-esp4_input_cb(struct mbuf *m, ...)
+esp4_input_cb(struct mbuf *m, int off, int protoff)
{
- struct ifqueue *ifq = &ipintrq;
- int s = splimp();
-
- /*
- * Interface pointer is already in first mbuf; chop off the
- * `outer' header and reschedule.
- */
- if (IF_QFULL(ifq)) {
- IF_DROP(ifq);
- espstat.esps_qfull++;
- splx(s);
-
- m_freem(m);
- DPRINTF(("esp4_input_cb(): dropped packet because of full "
- "IP queue\n"));
- return ENOBUFS;
- }
-
- IF_ENQUEUE(ifq, m);
- schednetisr(NETISR_IP);
- splx(s);
- return 0;
+ return ah4_input_cb(m, off, protoff);
}
/* IPv4 IPCOMP wrapper */
@@ -798,30 +777,9 @@
/* IPv4 IPCOMP callback */
int
-ipcomp4_input_cb(struct mbuf *m, ...)
+ipcomp4_input_cb(struct mbuf *m, int off, int protoff)
{
- struct ifqueue *ifq = &ipintrq;
- int s = splimp();
-
- /*
- * Interface pointer is already in first mbuf; chop off the
- * `outer' header and reschedule.
- */
- if (IF_QFULL(ifq)) {
- IF_DROP(ifq);
- ipcompstat.ipcomps_qfull++;
- splx(s);
-
- m_freem(m);
- DPRINTF(("ipcomp4_input_cb(): dropped packet because of full IP queue\n"));
- return ENOBUFS;
- }
-
- IF_ENQUEUE(ifq, m);
- schednetisr(NETISR_IP);
- splx(s);
-
- return 0;
+ return ah4_input_cb(m, off, protoff);
}
void *