Source-Changes-HG archive

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

[src/trunk]: src/sys add patch from Arnaud Degroote to handle IPv6 extended o...



details:   https://anonhg.NetBSD.org/src/rev/799c34573206
branches:  trunk
changeset: 772654:799c34573206
user:      drochner <drochner%NetBSD.org@localhost>
date:      Tue Jan 10 20:01:56 2012 +0000

description:
add patch from Arnaud Degroote to handle IPv6 extended options with
(FAST_)IPSEC, tested lightly with a DSTOPTS header consisting
of PAD1

diffstat:

 sys/netinet6/ip6_input.c    |  11 +++---
 sys/netinet6/ip6_output.c   |  30 ++++-------------
 sys/netinet6/ip6_var.h      |   5 +-
 sys/netipsec/ipsec_output.c |  75 ++++++++++++++++++++++++++++++++++++++++++--
 sys/netipsec/xform_ah.c     |  70 ++++++++++++++++++++++++++++++++---------
 5 files changed, 141 insertions(+), 50 deletions(-)

diffs (truncated from 366 to 300 lines):

diff -r 12f3c3fc5158 -r 799c34573206 sys/netinet6/ip6_input.c
--- a/sys/netinet6/ip6_input.c  Tue Jan 10 18:55:37 2012 +0000
+++ b/sys/netinet6/ip6_input.c  Tue Jan 10 20:01:56 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ip6_input.c,v 1.135 2011/12/31 20:41:59 christos Exp $ */
+/*     $NetBSD: ip6_input.c,v 1.136 2012/01/10 20:01:56 drochner Exp $ */
 /*     $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $     */
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.135 2011/12/31 20:41:59 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.136 2012/01/10 20:01:56 drochner Exp $");
 
 #include "opt_gateway.h"
 #include "opt_inet.h"
@@ -161,7 +161,8 @@
 static void ip6_init2(void *);
 static struct m_tag *ip6_setdstifaddr(struct mbuf *, const struct in6_ifaddr *);
 
-static int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *);
+static int ip6_process_hopopts(struct mbuf *, u_int8_t *, int, u_int32_t *,
+       u_int32_t *);
 static struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int);
 static void sysctl_net_inet6_ip6_setup(struct sysctllog **);
 
@@ -882,7 +883,7 @@
  *
  * rtalertp - XXX: should be stored more smart way
  */
-static int
+int
 ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp, 
        struct mbuf **mp, int *offp)
 {
@@ -927,7 +928,7 @@
  * (RFC2460 p7), opthead is pointer into data content in m, and opthead to
  * opthead + hbhlen is located in continuous memory region.
  */
-int
+static int
 ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen, 
        u_int32_t *rtalertp, u_int32_t *plenp)
 {
diff -r 12f3c3fc5158 -r 799c34573206 sys/netinet6/ip6_output.c
--- a/sys/netinet6/ip6_output.c Tue Jan 10 18:55:37 2012 +0000
+++ b/sys/netinet6/ip6_output.c Tue Jan 10 20:01:56 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ip6_output.c,v 1.142 2011/12/31 20:41:59 christos Exp $        */
+/*     $NetBSD: ip6_output.c,v 1.143 2012/01/10 20:01:56 drochner Exp $        */
 /*     $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $    */
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.142 2011/12/31 20:41:59 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.143 2012/01/10 20:01:56 drochner Exp $");
 
 #include "opt_inet.h"
 #include "opt_inet6.h"
@@ -317,10 +317,6 @@
 #ifdef FAST_IPSEC
        /* Check the security policy (SP) for the packet */
     
-       /* XXX For moment, we doesn't support packet with extented action */
-       if (optlen !=0)
-               goto freehdrs;
-
        sp = ipsec6_check_policy(m,so,flags,&needipsec,&error);
        if (error != 0) {
                /*
@@ -858,28 +854,18 @@
         * it must be examined and processed even by the source node.
         * (RFC 2460, section 4.)
         */
-       if (exthdrs.ip6e_hbh) {
-               struct ip6_hbh *hbh = mtod(exthdrs.ip6e_hbh, struct ip6_hbh *);
+       if (ip6->ip6_nxt == IPV6_HOPOPTS) {
                u_int32_t dummy1; /* XXX unused */
                u_int32_t dummy2; /* XXX unused */
-
-               /*
-                *  XXX: if we have to send an ICMPv6 error to the sender,
-                *       we need the M_LOOP flag since icmp6_error() expects
-                *       the IPv6 and the hop-by-hop options header are
-                *       continuous unless the flag is set.
-                */
-               m->m_flags |= M_LOOP;
-               m->m_pkthdr.rcvif = ifp;
-               if (ip6_process_hopopts(m, (u_int8_t *)(hbh + 1),
-                   ((hbh->ip6h_len + 1) << 3) - sizeof(struct ip6_hbh),
-                   &dummy1, &dummy2) < 0) {
+               int hoff = sizeof(struct ip6_hdr);
+
+               if (ip6_hopopts_input(&dummy1, &dummy2, &m, &hoff)) {
                        /* m was already freed at this point */
                        error = EINVAL;/* better error? */
                        goto done;
                }
-               m->m_flags &= ~M_LOOP; /* XXX */
-               m->m_pkthdr.rcvif = NULL;
+
+               ip6 = mtod(m, struct ip6_hdr *);
        }
 
 #ifdef PFIL_HOOKS
diff -r 12f3c3fc5158 -r 799c34573206 sys/netinet6/ip6_var.h
--- a/sys/netinet6/ip6_var.h    Tue Jan 10 18:55:37 2012 +0000
+++ b/sys/netinet6/ip6_var.h    Tue Jan 10 20:01:56 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ip6_var.h,v 1.56 2011/11/04 00:22:33 zoltan Exp $      */
+/*     $NetBSD: ip6_var.h,v 1.57 2012/01/10 20:01:56 drochner Exp $    */
 /*     $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $        */
 
 /*
@@ -327,8 +327,7 @@
 void   ip6_delaux(struct mbuf *);
 
 int    ip6_mforward(struct ip6_hdr *, struct ifnet *, struct mbuf *);
-int    ip6_process_hopopts(struct mbuf *, u_int8_t *, int, u_int32_t *,
-                                u_int32_t *);
+int    ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *);
 void   ip6_savecontrol(struct in6pcb *, struct mbuf **, struct ip6_hdr *,
                struct mbuf *);
 void   ip6_notify_pmtu(struct in6pcb *, const struct sockaddr_in6 *,
diff -r 12f3c3fc5158 -r 799c34573206 sys/netipsec/ipsec_output.c
--- a/sys/netipsec/ipsec_output.c       Tue Jan 10 18:55:37 2012 +0000
+++ b/sys/netipsec/ipsec_output.c       Tue Jan 10 20:01:56 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ipsec_output.c,v 1.37 2011/08/31 18:31:03 plunky Exp $ */
+/*     $NetBSD: ipsec_output.c,v 1.38 2012/01/10 20:01:57 drochner Exp $       */
 
 /*-
  * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipsec_output.c,v 1.37 2011/08/31 18:31:03 plunky Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipsec_output.c,v 1.38 2012/01/10 20:01:57 drochner Exp $");
 
 /*
  * IPsec output processing.
@@ -632,6 +632,74 @@
 #endif
 
 #ifdef INET6
+static void
+compute_ipsec_pos(struct mbuf *m, int *i, int *off)
+{
+       int nxt;
+       struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr*);
+       struct ip6_ext ip6e;
+       int dstopt = 0;
+
+       *i = sizeof(struct ip6_hdr);
+       *off = offsetof(struct ip6_hdr, ip6_nxt);
+       nxt = ip6->ip6_nxt;
+
+       /*
+        * chase mbuf chain to find the appropriate place to
+        * put AH/ESP/IPcomp header.
+        *  IPv6 hbh dest1 rthdr ah* [esp* dest2 payload]
+        */
+       do {
+               switch (nxt) {
+               case IPPROTO_AH:
+               case IPPROTO_ESP:
+               case IPPROTO_IPCOMP:
+               /*
+                * we should not skip security header added
+                * beforehand.
+                */
+                       return;
+
+               case IPPROTO_HOPOPTS:
+               case IPPROTO_DSTOPTS:
+               case IPPROTO_ROUTING:
+               /*
+                * if we see 2nd destination option header,
+                * we should stop there.
+                */
+                       if (nxt == IPPROTO_DSTOPTS && dstopt)
+                               return;
+
+                       if (nxt == IPPROTO_DSTOPTS) {
+                               /*
+                                * seen 1st or 2nd destination option.
+                                * next time we see one, it must be 2nd.
+                                */
+                               dstopt = 1;
+                       } else if (nxt == IPPROTO_ROUTING) {
+                               /*
+                                * if we see destionation option next
+                                * time, it must be dest2.
+                                */
+                               dstopt = 2;
+                       }
+
+                       /* skip this header */
+                       m_copydata(m, *i, sizeof(ip6e), &ip6e);
+                       nxt = ip6e.ip6e_nxt;
+                       *off = *i + offsetof(struct ip6_ext, ip6e_nxt);
+                       /*
+                        * we will never see nxt == IPPROTO_AH
+                        * so it is safe to omit AH case.
+                        */
+                       *i += (ip6e.ip6e_len + 1) << 3;
+                       break;
+               default:
+                       return;
+               }
+       } while (*i < m->m_pkthdr.len);
+}
+
 static int
 in6_sa_equal_addrwithscope(const struct sockaddr_in6 *sa, const struct in6_addr *ia)
 {
@@ -731,8 +799,7 @@
                i = ip->ip_hl << 2;
                off = offsetof(struct ip, ip_p);
        } else {        
-               i = sizeof(struct ip6_hdr);
-               off = offsetof(struct ip6_hdr, ip6_nxt);
+               compute_ipsec_pos(m, &i, &off);
        }
        error = (*sav->tdb_xform->xf_output)(m, isr, NULL, i, off);
        splx(s);
diff -r 12f3c3fc5158 -r 799c34573206 sys/netipsec/xform_ah.c
--- a/sys/netipsec/xform_ah.c   Tue Jan 10 18:55:37 2012 +0000
+++ b/sys/netipsec/xform_ah.c   Tue Jan 10 20:01:56 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: xform_ah.c,v 1.33 2011/05/24 19:10:08 drochner Exp $   */
+/*     $NetBSD: xform_ah.c,v 1.34 2012/01/10 20:01:57 drochner Exp $   */
 /*     $FreeBSD: src/sys/netipsec/xform_ah.c,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $   */
 /*     $OpenBSD: ip_ah.c,v 1.63 2001/06/26 06:18:58 angelos Exp $ */
 /*
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.33 2011/05/24 19:10:08 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.34 2012/01/10 20:01:57 drochner Exp $");
 
 #include "opt_inet.h"
 #ifdef __FreeBSD__
@@ -72,6 +72,7 @@
 
 #ifdef INET6
 #include <netinet6/ip6_var.h>
+#include <netinet6/scope6_var.h>
 #include <netipsec/ipsec6.h>
 #  ifdef __FreeBSD__
 #  include <netinet6/ip6_ecn.h>
@@ -279,7 +280,7 @@
 #ifdef INET6
        struct ip6_ext *ip6e;
        struct ip6_hdr ip6;
-       int alloc, len, ad;
+       int alloc, ad, nxt;
 #endif /* INET6 */
 
        switch (proto) {
@@ -501,28 +502,28 @@
                } else
                        break;
 
-               off = ip6.ip6_nxt & 0xff; /* Next header type. */
+               nxt = ip6.ip6_nxt & 0xff; /* Next header type. */
 
-               for (len = 0; len < skip - sizeof(struct ip6_hdr);)
-                       switch (off) {
+               for (off = 0; off < skip - sizeof(struct ip6_hdr);)
+                       switch (nxt) {
                        case IPPROTO_HOPOPTS:
                        case IPPROTO_DSTOPTS:
-                               ip6e = (struct ip6_ext *) (ptr + len);
+                               ip6e = (struct ip6_ext *) (ptr + off);
 
                                /*
                                 * Process the mutable/immutable
                                 * options -- borrows heavily from the
                                 * KAME code.
                                 */
-                               for (count = len + sizeof(struct ip6_ext);
-                                    count < len + ((ip6e->ip6e_len + 1) << 3);) {
+                               for (count = off + sizeof(struct ip6_ext);
+                                    count < off + ((ip6e->ip6e_len + 1) << 3);) {
                                        if (ptr[count] == IP6OPT_PAD1) {
                                                count++;
                                                continue; /* Skip padding. */
                                        }
 
                                        /* Sanity check. */
-                                       if (count > len +
+                                       if (count > off +



Home | Main Index | Thread Index | Old Index