]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/netinet/ip_encap.c
xnu-2050.7.9.tar.gz
[apple/xnu.git] / bsd / netinet / ip_encap.c
index 6ce7d76117f452ee45d4879c33e5682fad658ccf..db393938ff605240536e6a357bec5dee4a2d860f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2011 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -88,6 +88,7 @@
 #include <sys/socket.h>
 #include <sys/sockio.h>
 #include <sys/mbuf.h>
+#include <sys/mcache.h>
 #include <sys/errno.h>
 #include <sys/protosw.h>
 #include <sys/queue.h>
@@ -171,6 +172,9 @@ encap4_input(m, off)
        va_end(ap);
 #endif
 
+       /* Expect 32-bit aligned data pointer on strict-align platforms */
+       MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(m);
+
        ip = mtod(m, struct ip *);
 #ifdef __APPLE__
        proto = ip->ip_p;
@@ -259,9 +263,7 @@ encap4_input(m, off)
 
 #if INET6
 int
-encap6_input(mp, offp)
-       struct mbuf **mp;
-       int *offp;
+encap6_input(struct mbuf **mp, int *offp, int proto)
 {
        struct mbuf *m = *mp;
        struct ip6_hdr *ip6;
@@ -269,11 +271,11 @@ encap6_input(mp, offp)
        const struct ip6protosw *psw;
        struct encaptab *ep, *match;
        int prio, matchprio;
-       int proto;
 
-       ip6 = mtod(m, struct ip6_hdr *);
-       proto = ip6->ip6_nxt;
+       /* Expect 32-bit aligned data pointer on strict-align platforms */
+       MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(m);
 
+       ip6 = mtod(m, struct ip6_hdr *);
        bzero(&s, sizeof(s));
        s.sin6_family = AF_INET6;
        s.sin6_len = sizeof(struct sockaddr_in6);
@@ -315,7 +317,7 @@ encap6_input(mp, offp)
                psw = (const struct ip6protosw *)match->psw;
                if (psw && psw->pr_input) {
                        encap_fillarg(m, match);
-                       return (*psw->pr_input)(mp, offp);
+                       return (*psw->pr_input)(mp, offp, proto);
                } else {
                        m_freem(m);
                        return IPPROTO_DONE;
@@ -323,7 +325,7 @@ encap6_input(mp, offp)
        }
 
        /* last resort: inject to raw socket */
-       return rip6_input(mp, offp);
+       return rip6_input(mp, offp, proto);
 }
 #endif
 
@@ -351,9 +353,7 @@ encap_attach(af, proto, sp, sm, dp, dm, psw, arg)
 {
        struct encaptab *ep;
        int error;
-       int s;
 
-       s = splnet();
        /* sanity check on args */
        if (sp->sa_len > sizeof(ep->src) || dp->sa_len > sizeof(ep->dst)) {
                error = EINVAL;
@@ -406,11 +406,9 @@ encap_attach(af, proto, sp, sm, dp, dm, psw, arg)
        encap_add(ep);
 
        error = 0;
-       splx(s);
        return ep;
 
 fail:
-       splx(s);
        return NULL;
 }
 
@@ -424,9 +422,7 @@ encap_attach_func(af, proto, func, psw, arg)
 {
        struct encaptab *ep;
        int error;
-       int s;
 
-       s = splnet();
        /* sanity check on args */
        if (!func) {
                error = EINVAL;
@@ -449,11 +445,9 @@ encap_attach_func(af, proto, func, psw, arg)
        encap_add(ep);
 
        error = 0;
-       splx(s);
        return ep;
 
 fail:
-       splx(s);
        return NULL;
 }
 
@@ -528,43 +522,42 @@ mask_match(ep, sp, dp)
                return 0;
 }
 
+struct encaptabtag {
+       void*                   *arg;
+};
+
 static void
-encap_fillarg(m, ep)
-       struct mbuf *m;
-       const struct encaptab *ep;
+encap_fillarg(
+       struct mbuf *m,
+       const struct encaptab *ep)
 {
-#if 0
-       m->m_pkthdr.aux = ep->arg;
-#else
-       struct mbuf *n;
-
-       n = m_aux_add(m, AF_INET, IPPROTO_IPV4);
-       if (n) {
-               *mtod(n, void **) = ep->arg;
-               n->m_len = sizeof(void *);
+       struct m_tag    *tag;
+       struct encaptabtag *et;
+       
+       tag = m_tag_create(KERNEL_MODULE_TAG_ID, KERNEL_TAG_TYPE_ENCAP,
+                                         sizeof(struct encaptabtag), M_WAITOK, m);
+       
+       if (tag != NULL) {
+               et = (struct encaptabtag*)(tag + 1);
+               et->arg = ep->arg;
+               m_tag_prepend(m, tag);
        }
-#endif
 }
 
 void *
 encap_getarg(m)
        struct mbuf *m;
 {
-       void *p;
-#if 0
-       p = m->m_pkthdr.aux;
-       m->m_pkthdr.aux = NULL;
-       return p;
-#else
-       struct mbuf *n;
-
-       p = NULL;
-       n = m_aux_find(m, AF_INET, IPPROTO_IPV4);
-       if (n) {
-               if (n->m_len == sizeof(void *))
-                       p = *mtod(n, void **);
-               m_aux_delete(m, n);
+       struct m_tag    *tag;
+       struct encaptabtag *et;
+       void *p = NULL;
+       
+       tag = m_tag_locate(m, KERNEL_MODULE_TAG_ID, KERNEL_TAG_TYPE_ENCAP, NULL);
+       if (tag) {
+               et = (struct encaptabtag*)(tag + 1);
+               p = et->arg;
+               m_tag_delete(m, tag);
        }
+       
        return p;
-#endif
 }