summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2002-10-16 01:54:46 +0000
committersam <sam@FreeBSD.org>2002-10-16 01:54:46 +0000
commit2a86be217a6aed33eda6628df2b175e49172cd9f (patch)
treeb26e1e9f49b40642051748bcd3961cc2a2b5ff1d
parent733bfbdd78ddb9efc129532b2c2239d0bacfaf1a (diff)
downloadFreeBSD-src-2a86be217a6aed33eda6628df2b175e49172cd9f.zip
FreeBSD-src-2a86be217a6aed33eda6628df2b175e49172cd9f.tar.gz
Replace aux mbufs with packet tags:
o instead of a list of mbufs use a list of m_tag structures a la openbsd o for netgraph et. al. extend the stock openbsd m_tag to include a 32-bit ABI/module number cookie o for openbsd compatibility define a well-known cookie MTAG_ABI_COMPAT and use this in defining openbsd-compatible m_tag_find and m_tag_get routines o rewrite KAME use of aux mbufs in terms of packet tags o eliminate the most heavily used aux mbufs by adding an additional struct inpcb parameter to ip_output and ip6_output to allow the IPsec code to locate the security policy to apply to outbound packets o bump __FreeBSD_version so code can be conditionalized o fixup ipfilter's call to ip_output based on __FreeBSD_version Reviewed by: julian, luigi (silent), -arch, -net, darren Approved by: julian, silence from everyone else Obtained from: openbsd (mostly) MFC after: 1 month
-rw-r--r--sys/contrib/ipfilter/netinet/ip_auth.c3
-rw-r--r--sys/dev/hfa/fore_receive.c2
-rw-r--r--sys/kern/subr_mbuf.c21
-rw-r--r--sys/kern/uipc_mbuf.c2
-rw-r--r--sys/kern/uipc_mbuf2.c202
-rw-r--r--sys/net/bridge.c2
-rw-r--r--sys/net/if_gre.c2
-rw-r--r--sys/net/if_loop.c3
-rw-r--r--sys/net/if_stf.c2
-rw-r--r--sys/netinet/igmp.c2
-rw-r--r--sys/netinet/in_gif.c2
-rw-r--r--sys/netinet/ip_divert.c2
-rw-r--r--sys/netinet/ip_dummynet.c2
-rw-r--r--sys/netinet/ip_encap.c36
-rw-r--r--sys/netinet/ip_fw2.c2
-rw-r--r--sys/netinet/ip_icmp.c2
-rw-r--r--sys/netinet/ip_input.c14
-rw-r--r--sys/netinet/ip_mroute.c4
-rw-r--r--sys/netinet/ip_output.c16
-rw-r--r--sys/netinet/ip_var.h3
-rw-r--r--sys/netinet/raw_ip.c9
-rw-r--r--sys/netinet/tcp_input.c2
-rw-r--r--sys/netinet/tcp_output.c15
-rw-r--r--sys/netinet/tcp_reass.c2
-rw-r--r--sys/netinet/tcp_subr.c11
-rw-r--r--sys/netinet/tcp_syncache.c14
-rw-r--r--sys/netinet/tcp_timewait.c11
-rw-r--r--sys/netinet/udp_usrreq.c8
-rw-r--r--sys/netinet6/icmp6.c14
-rw-r--r--sys/netinet6/in6_gif.c4
-rw-r--r--sys/netinet6/ip6_input.c61
-rw-r--r--sys/netinet6/ip6_mroute.c2
-rw-r--r--sys/netinet6/ip6_output.c8
-rw-r--r--sys/netinet6/ip6_var.h7
-rw-r--r--sys/netinet6/ipsec.c130
-rw-r--r--sys/netinet6/ipsec.h3
-rw-r--r--sys/netinet6/mld6.c2
-rw-r--r--sys/netinet6/nd6_nbr.c12
-rw-r--r--sys/netinet6/raw_ip6.c9
-rw-r--r--sys/netinet6/route6.c7
-rw-r--r--sys/netinet6/udp6_output.c8
-rw-r--r--sys/netipx/ipx_ip.c2
-rw-r--r--sys/sys/mbuf.h179
43 files changed, 370 insertions, 474 deletions
diff --git a/sys/contrib/ipfilter/netinet/ip_auth.c b/sys/contrib/ipfilter/netinet/ip_auth.c
index b395b53..fb9910d 100644
--- a/sys/contrib/ipfilter/netinet/ip_auth.c
+++ b/sys/contrib/ipfilter/netinet/ip_auth.c
@@ -458,7 +458,8 @@ fr_authioctlloop:
bzero((char *)&ro, sizeof(ro));
# if ((_BSDI_VERSION >= 199802) && (_BSDI_VERSION < 200005)) || \
- defined(__OpenBSD__) || (defined(IRIX) && (IRIX >= 605))
+ defined(__OpenBSD__) || (defined(IRIX) && (IRIX >= 605)) || \
+ (__FreeBSD_version >= 500042)
error = ip_output(m, NULL, &ro, IP_FORWARDING, NULL,
NULL);
# else
diff --git a/sys/dev/hfa/fore_receive.c b/sys/dev/hfa/fore_receive.c
index 4f14edd..3bcae97 100644
--- a/sys/dev/hfa/fore_receive.c
+++ b/sys/dev/hfa/fore_receive.c
@@ -443,7 +443,7 @@ retry:
*/
mhead->m_pkthdr.rcvif = NULL;
mhead->m_pkthdr.csum_flags = 0;
- mhead->m_pkthdr.aux = NULL;
+ SLIST_INIT(&mhead->m_pkthdr.tags);
KB_PLENSET(mhead, pdulen);
fup->fu_pif.pif_ipdus++;
fup->fu_pif.pif_ibytes += pdulen;
diff --git a/sys/kern/subr_mbuf.c b/sys/kern/subr_mbuf.c
index b8dc867..87b9da6 100644
--- a/sys/kern/subr_mbuf.c
+++ b/sys/kern/subr_mbuf.c
@@ -1037,7 +1037,7 @@ mb_reclaim(void)
(m)->m_flags = M_PKTHDR; \
(m)->m_pkthdr.rcvif = NULL; \
(m)->m_pkthdr.csum_flags = 0; \
- (m)->m_pkthdr.aux = NULL; \
+ SLIST_INIT(&(m)->m_pkthdr.tags); \
} while (0)
#define _mcl_setup(m) do { \
@@ -1333,11 +1333,8 @@ m_free(struct mbuf *mb)
int cchnum;
short persist = 0;
- /* XXX: This check is bogus... please fix (see KAME). */
- if ((mb->m_flags & M_PKTHDR) != 0 && mb->m_pkthdr.aux) {
- m_freem(mb->m_pkthdr.aux);
- mb->m_pkthdr.aux = NULL;
- }
+ if ((mb->m_flags & M_PKTHDR) != 0)
+ m_tag_delete_chain(mb, NULL);
#ifdef MAC
if ((mb->m_flags & M_PKTHDR) &&
(mb->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED))
@@ -1371,8 +1368,7 @@ m_free(struct mbuf *mb)
* we'll eventually be holding the lock across more than merely two
* consecutive frees but right now this is hard to implement because of
* things like _mext_dealloc_ref (may do a free()) and atomic ops in the
- * loop, as well as the fact that we may recurse on m_freem() in
- * m_pkthdr.aux != NULL cases.
+ * loop.
*
* - mb: the mbuf chain to free.
*/
@@ -1384,11 +1380,8 @@ m_freem(struct mbuf *mb)
short persist;
while (mb != NULL) {
- /* XXX: This check is bogus... please fix (see KAME). */
- if ((mb->m_flags & M_PKTHDR) != 0 && mb->m_pkthdr.aux) {
- m_freem(mb->m_pkthdr.aux);
- mb->m_pkthdr.aux = NULL;
- }
+ if ((mb->m_flags & M_PKTHDR) != 0)
+ m_tag_delete_chain(mb, NULL);
#ifdef MAC
if ((mb->m_flags & M_PKTHDR) &&
(mb->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED))
@@ -1448,7 +1441,7 @@ m_getcl(int how, short type, int flags)
mb->m_nextpkt = NULL;
mb->m_pkthdr.rcvif = NULL;
mb->m_pkthdr.csum_flags = 0;
- mb->m_pkthdr.aux = NULL;
+ SLIST_INIT(&mb->m_pkthdr.tags);
}
mb->m_ext.ext_buf = (caddr_t)mb_alloc(&mb_list_clust, how,
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index cad6d3e..6aedd11 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -89,7 +89,7 @@ m_copy_pkthdr(struct mbuf *to, struct mbuf *from)
mac_init_mbuf(to, 1); /* XXXMAC no way to fail */
mac_create_mbuf_from_mbuf(from, to);
#endif
- from->m_pkthdr.aux = NULL;
+ SLIST_INIT(&from->m_pkthdr.tags);
}
/*
diff --git a/sys/kern/uipc_mbuf2.c b/sys/kern/uipc_mbuf2.c
index 37ee53e..b3f053d 100644
--- a/sys/kern/uipc_mbuf2.c
+++ b/sys/kern/uipc_mbuf2.c
@@ -70,11 +70,14 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/mutex.h>
+MALLOC_DEFINE(M_PACKET_TAGS, "tag", "packet-attached information");
+
/* can't call it m_dup(), as freebsd[34] uses m_dup() with different arg */
static struct mbuf *m_dup1(struct mbuf *, int, int, int);
@@ -301,104 +304,153 @@ m_dup1(struct mbuf *m, int off, int len, int wait)
return n;
}
-/*
- * pkthdr.aux chain manipulation.
- * we don't allow clusters at this moment.
- */
-struct mbuf *
-m_aux_add2(struct mbuf *m, int af, int type, void *p)
+/* Get a packet tag structure along with specified data following. */
+struct m_tag *
+m_tag_alloc(u_int32_t cookie, int type, int len, int wait)
{
- struct mbuf *n;
- struct mauxtag *t;
+ struct m_tag *t;
- if ((m->m_flags & M_PKTHDR) == 0)
+ if (len < 0)
+ return NULL;
+ t = malloc(len + sizeof(struct m_tag), M_PACKET_TAGS, wait);
+ if (t == NULL)
return NULL;
+ t->m_tag_id = type;
+ t->m_tag_len = len;
+ t->m_tag_cookie = cookie;
+ return t;
+}
- n = m_aux_find(m, af, type);
- if (n)
- return n;
+/* Free a packet tag. */
+void
+m_tag_free(struct m_tag *t)
+{
+ free(t, M_PACKET_TAGS);
+}
- MGET(n, M_DONTWAIT, m->m_type);
- if (n == NULL)
- return NULL;
+/* Prepend a packet tag. */
+void
+m_tag_prepend(struct mbuf *m, struct m_tag *t)
+{
+ KASSERT(m && t, ("m_tag_prepend: null argument, m %p t %p", m, t));
+ SLIST_INSERT_HEAD(&m->m_pkthdr.tags, t, m_tag_link);
+}
- t = mtod(n, struct mauxtag *);
- bzero(t, sizeof(*t));
- t->af = af;
- t->type = type;
- t->p = p;
- n->m_data += sizeof(struct mauxtag);
- n->m_len = 0;
- n->m_next = m->m_pkthdr.aux;
- m->m_pkthdr.aux = n;
- return n;
+/* Unlink a packet tag. */
+void
+m_tag_unlink(struct mbuf *m, struct m_tag *t)
+{
+ KASSERT(m && t, ("m_tag_unlink: null argument, m %p t %p", m, t));
+ SLIST_REMOVE(&m->m_pkthdr.tags, t, m_tag, m_tag_link);
}
-struct mbuf *
-m_aux_find2(struct mbuf *m, int af, int type, void *p)
+/* Unlink and free a packet tag. */
+void
+m_tag_delete(struct mbuf *m, struct m_tag *t)
{
- struct mbuf *n;
- struct mauxtag *t;
+ KASSERT(m && t, ("m_tag_delete: null argument, m %p t %p", m, t));
+ m_tag_unlink(m, t);
+ m_tag_free(t);
+}
- if ((m->m_flags & M_PKTHDR) == 0)
- return NULL;
+/* Unlink and free a packet tag chain, starting from given tag. */
+void
+m_tag_delete_chain(struct mbuf *m, struct m_tag *t)
+{
+ struct m_tag *p, *q;
+
+ KASSERT(m, ("m_tag_delete_chain: null mbuf"));
+ if (t != NULL)
+ p = t;
+ else
+ p = SLIST_FIRST(&m->m_pkthdr.tags);
+ if (p == NULL)
+ return;
+ while ((q = SLIST_NEXT(p, m_tag_link)) != NULL)
+ m_tag_delete(m, q);
+ m_tag_delete(m, p);
+}
- for (n = m->m_pkthdr.aux; n; n = n->m_next) {
- t = (struct mauxtag *)n->m_dat;
- if (n->m_data != ((caddr_t)t) + sizeof(struct mauxtag)) {
- printf("m_aux_find: invalid m_data for mbuf=%p (%p %p)\n", n, t, n->m_data);
- continue;
- }
- if (t->af == af && t->type == type && t->p == p)
- return n;
+/* Find a tag, starting from a given position. */
+struct m_tag *
+m_tag_locate(struct mbuf *m, u_int32_t cookie, int type, struct m_tag *t)
+{
+ struct m_tag *p;
+
+ KASSERT(m, ("m_tag_find: null mbuf"));
+ if (t == NULL)
+ p = SLIST_FIRST(&m->m_pkthdr.tags);
+ else
+ p = SLIST_NEXT(t, m_tag_link);
+ while (p != NULL) {
+ if (p->m_tag_cookie == cookie && p->m_tag_id == type)
+ return p;
+ p = SLIST_NEXT(p, m_tag_link);
}
return NULL;
}
-struct mbuf *
-m_aux_find(struct mbuf *m, int af, int type)
+/* Copy a single tag. */
+struct m_tag *
+m_tag_copy(struct m_tag *t)
{
-
- return m_aux_find2(m, af, type, NULL);
+ struct m_tag *p;
+
+ KASSERT(t, ("m_tag_copy: null tag"));
+ p = m_tag_alloc(t->m_tag_cookie, t->m_tag_id, t->m_tag_len, M_NOWAIT);
+ if (p == NULL)
+ return (NULL);
+ bcopy(t + 1, p + 1, t->m_tag_len); /* Copy the data */
+ return p;
}
-struct mbuf *
-m_aux_add(struct mbuf *m, int af, int type)
+/*
+ * Copy two tag chains. The destination mbuf (to) loses any attached
+ * tags even if the operation fails. This should not be a problem, as
+ * m_tag_copy_chain() is typically called with a newly-allocated
+ * destination mbuf.
+ */
+int
+m_tag_copy_chain(struct mbuf *to, struct mbuf *from)
{
-
- return m_aux_add2(m, af, type, NULL);
+ struct m_tag *p, *t, *tprev = NULL;
+
+ KASSERT(to && from,
+ ("m_tag_copy: null argument, to %p from %p", to, from));
+ m_tag_delete_chain(to, NULL);
+ SLIST_FOREACH(p, &from->m_pkthdr.tags, m_tag_link) {
+ t = m_tag_copy(p);
+ if (t == NULL) {
+ m_tag_delete_chain(to, NULL);
+ return 0;
+ }
+ if (tprev == NULL)
+ SLIST_INSERT_HEAD(&to->m_pkthdr.tags, t, m_tag_link);
+ else {
+ SLIST_INSERT_AFTER(tprev, t, m_tag_link);
+ tprev = t;
+ }
+ }
+ return 1;
}
+/* Initialize tags on an mbuf. */
void
-m_aux_delete(struct mbuf *m, struct mbuf *victim)
+m_tag_init(struct mbuf *m)
{
- struct mbuf *n, *prev, *next;
- struct mauxtag *t;
+ SLIST_INIT(&m->m_pkthdr.tags);
+}
- if ((m->m_flags & M_PKTHDR) == 0)
- return;
+/* Get first tag in chain. */
+struct m_tag *
+m_tag_first(struct mbuf *m)
+{
+ return SLIST_FIRST(&m->m_pkthdr.tags);
+}
- prev = NULL;
- n = m->m_pkthdr.aux;
- while (n) {
- t = (struct mauxtag *)n->m_dat;
- next = n->m_next;
- if (n->m_data != ((caddr_t)t) + sizeof(struct mauxtag)) {
- printf("m_aux_delete: invalid m_data for mbuf=%p (%p %p)\n", n, t, n->m_data);
- prev = n;
- n = next;
- continue;
- }
- if (n == victim) {
- if (prev)
- prev->m_next = n->m_next;
- else
- m->m_pkthdr.aux = n->m_next;
- n->m_next = NULL;
- m_free(n);
- return;
- } else
- prev = n;
- n = next;
- }
+/* Get next tag in chain. */
+struct m_tag *
+m_tag_next(struct mbuf *m, struct m_tag *t)
+{
+ return SLIST_NEXT(t, m_tag_link);
}
diff --git a/sys/net/bridge.c b/sys/net/bridge.c
index e41d8c7..1a59cee 100644
--- a/sys/net/bridge.c
+++ b/sys/net/bridge.c
@@ -816,7 +816,7 @@ bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst)
args.rule = NULL; /* did we match a firewall rule ? */
/* Fetch state from dummynet tag, ignore others */
for (;m0->m_type == MT_TAG; m0 = m0->m_next)
- if (m0->m_tag_id == PACKET_TAG_DUMMYNET) {
+ if (m0->_m_tag_id == PACKET_TAG_DUMMYNET) {
args.rule = ((struct dn_pkt *)m0)->rule;
shared = 0; /* For sure this is our own mbuf. */
}
diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c
index dfa9ddb..a8231c0 100644
--- a/sys/net/if_gre.c
+++ b/sys/net/if_gre.c
@@ -384,7 +384,7 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
ifp->if_opackets++;
ifp->if_obytes += m->m_pkthdr.len;
/* send it off */
- error = ip_output(m, NULL, &sc->route, 0, NULL);
+ error = ip_output(m, NULL, &sc->route, 0, NULL, NULL);
end:
sc->called = 0;
if (error)
diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c
index 1184e9c..57571a8 100644
--- a/sys/net/if_loop.c
+++ b/sys/net/if_loop.c
@@ -224,8 +224,7 @@ looutput(ifp, m, dst, rt)
m_copydata(m, 0, m->m_pkthdr.len, mtod(n, caddr_t));
n->m_pkthdr = m->m_pkthdr;
n->m_len = m->m_pkthdr.len;
- n->m_pkthdr.aux = m->m_pkthdr.aux;
- m->m_pkthdr.aux = (struct mbuf *)NULL;
+ SLIST_INIT(&m->m_pkthdr.tags);
m_freem(m);
m = n;
}
diff --git a/sys/net/if_stf.c b/sys/net/if_stf.c
index dcbd14c..1acc0a6 100644
--- a/sys/net/if_stf.c
+++ b/sys/net/if_stf.c
@@ -471,7 +471,7 @@ stf_output(ifp, m, dst, rt)
}
ifp->if_opackets++;
- return ip_output(m, NULL, &sc->sc_ro, 0, NULL);
+ return ip_output(m, NULL, &sc->sc_ro, 0, NULL, NULL);
}
static int
diff --git a/sys/netinet/igmp.c b/sys/netinet/igmp.c
index 2cf1e7c..929d456 100644
--- a/sys/netinet/igmp.c
+++ b/sys/netinet/igmp.c
@@ -487,7 +487,7 @@ igmp_sendpkt(inm, type, addr)
* XXX
* Do we have to worry about reentrancy here? Don't think so.
*/
- ip_output(m, router_alert, &igmprt, 0, &imo);
+ ip_output(m, router_alert, &igmprt, 0, &imo, NULL);
++igmpstat.igps_snd_reports;
}
diff --git a/sys/netinet/in_gif.c b/sys/netinet/in_gif.c
index b7a1cec..ffd877b 100644
--- a/sys/netinet/in_gif.c
+++ b/sys/netinet/in_gif.c
@@ -197,7 +197,7 @@ in_gif_output(ifp, family, m, rt)
#endif
}
- error = ip_output(m, NULL, &sc->gif_ro, 0, NULL);
+ error = ip_output(m, NULL, &sc->gif_ro, 0, NULL, NULL);
return(error);
}
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
index ff246f9..c79ddfa 100644
--- a/sys/netinet/ip_divert.c
+++ b/sys/netinet/ip_divert.c
@@ -315,7 +315,7 @@ div_output(struct socket *so, struct mbuf *m,
inp->inp_options, &inp->inp_route,
(so->so_options & SO_DONTROUTE) |
IP_ALLOWBROADCAST | IP_RAWOUTPUT,
- inp->inp_moptions);
+ inp->inp_moptions, NULL);
} else {
if (m->m_pkthdr.rcvif == NULL) {
/*
diff --git a/sys/netinet/ip_dummynet.c b/sys/netinet/ip_dummynet.c
index 3c2ee99..0d3baa6 100644
--- a/sys/netinet/ip_dummynet.c
+++ b/sys/netinet/ip_dummynet.c
@@ -422,7 +422,7 @@ transmit_event(struct dn_pipe *pipe)
*/
switch (pkt->dn_dir) {
case DN_TO_IP_OUT:
- (void)ip_output((struct mbuf *)pkt, NULL, NULL, 0, NULL);
+ (void)ip_output((struct mbuf *)pkt, NULL, NULL, 0, NULL, NULL);
rt_unref (pkt->ro.ro_rt) ;
break ;
diff --git a/sys/netinet/ip_encap.c b/sys/netinet/ip_encap.c
index e12f50a..a547c66 100644
--- a/sys/netinet/ip_encap.c
+++ b/sys/netinet/ip_encap.c
@@ -485,38 +485,26 @@ encap_fillarg(m, ep)
struct mbuf *m;
const struct encaptab *ep;
{
-#if 0
- m->m_pkthdr.aux = ep->arg;
-#else
- struct mbuf *n;
+ struct m_tag *tag;
- n = m_aux_add(m, AF_INET, IPPROTO_IPV4);
- if (n) {
- *mtod(n, void **) = ep->arg;
- n->m_len = sizeof(void *);
+ tag = m_tag_get(PACKET_TAG_ENCAP, sizeof (void*), M_NOWAIT);
+ if (tag) {
+ *(void**)(tag+1) = 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);
+ void *p = NULL;
+ struct m_tag *tag;
+
+ tag = m_tag_find(m, PACKET_TAG_ENCAP, NULL);
+ if (tag) {
+ p = *(void**)(tag+1);
+ m_tag_delete(m, tag);
}
return p;
-#endif
}
diff --git a/sys/netinet/ip_fw2.c b/sys/netinet/ip_fw2.c
index ffbe9eb..3714d53 100644
--- a/sys/netinet/ip_fw2.c
+++ b/sys/netinet/ip_fw2.c
@@ -1124,7 +1124,7 @@ send_pkt(struct ipfw_flow_id *id, u_int32_t seq, u_int32_t ack, int flags)
bzero (&sro, sizeof (sro));
ip_rtaddr(ip->ip_dst, &sro);
m->m_flags |= M_SKIP_FIREWALL;
- ip_output(m, NULL, &sro, 0, NULL);
+ ip_output(m, NULL, &sro, 0, NULL, NULL);
if (sro.ro_rt)
RTFREE(sro.ro_rt);
}
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index af00849..5dd82ef 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -751,7 +751,7 @@ icmp_send(m, opts, rt)
buf, inet_ntoa(ip->ip_src));
}
#endif
- (void) ip_output(m, opts, rt, 0, NULL);
+ (void) ip_output(m, opts, rt, 0, NULL, NULL);
}
n_time
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 119021c..1feee4a 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -299,10 +299,10 @@ ip_input(struct mbuf *m)
/* Grab info from MT_TAG mbufs prepended to the chain. */
for (; m && m->m_type == MT_TAG; m = m->m_next) {
- switch(m->m_tag_id) {
+ switch(m->_m_tag_id) {
default:
printf("ip_input: unrecognised MT_TAG tag %d\n",
- m->m_tag_id);
+ m->_m_tag_id);
break;
case PACKET_TAG_DUMMYNET:
@@ -1750,7 +1750,7 @@ ip_forward(struct mbuf *m, int srcrt, struct sockaddr_in *next_hop)
m = (struct mbuf *)&tag;
}
error = ip_output(m, (struct mbuf *)0, &ipforward_rt,
- IP_FORWARDING, 0);
+ IP_FORWARDING, 0, NULL);
}
if (error)
ipstat.ips_cantforward++;
@@ -1788,10 +1788,7 @@ ip_forward(struct mbuf *m, int srcrt, struct sockaddr_in *next_hop)
case EMSGSIZE:
type = ICMP_UNREACH;
code = ICMP_UNREACH_NEEDFRAG;
-#ifndef IPSEC
- if (ipforward_rt.ro_rt)
- destifp = ipforward_rt.ro_rt->rt_ifp;
-#else
+#ifdef IPSEC
/*
* If the packet is routed over IPsec tunnel, tell the
* originator the tunnel MTU.
@@ -1842,6 +1839,9 @@ ip_forward(struct mbuf *m, int srcrt, struct sockaddr_in *next_hop)
key_freesp(sp);
}
}
+#else
+ if (ipforward_rt.ro_rt)
+ destifp = ipforward_rt.ro_rt->rt_ifp;
#endif /*IPSEC*/
ipstat.ips_cantfrag++;
break;
diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c
index b0f2eab..72772d3 100644
--- a/sys/netinet/ip_mroute.c
+++ b/sys/netinet/ip_mroute.c
@@ -1876,7 +1876,7 @@ tbf_send_packet(vifp, m)
if (vifp->v_flags & VIFF_TUNNEL) {
/* If tunnel options */
ip_output(m, (struct mbuf *)0, &vifp->v_route,
- IP_FORWARDING, (struct ip_moptions *)0);
+ IP_FORWARDING, (struct ip_moptions *)0, NULL);
} else {
imo.imo_multicast_ifp = vifp->v_ifp;
imo.imo_multicast_ttl = mtod(m, struct ip *)->ip_ttl - 1;
@@ -1890,7 +1890,7 @@ tbf_send_packet(vifp, m)
* the loopback interface, thus preventing looping.
*/
error = ip_output(m, (struct mbuf *)0, &ro,
- IP_FORWARDING, &imo);
+ IP_FORWARDING, &imo, NULL);
if (mrtdebug & DEBUG_XMIT)
log(LOG_DEBUG, "phyint_send on vif %d err %d\n",
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 2c765eb..e78ef26 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -112,12 +112,13 @@ extern struct protosw inetsw[];
* The mbuf opt, if present, will not be freed.
*/
int
-ip_output(m0, opt, ro, flags, imo)
+ip_output(m0, opt, ro, flags, imo, inp)
struct mbuf *m0;
struct mbuf *opt;
struct route *ro;
int flags;
struct ip_moptions *imo;
+ struct inpcb *inp;
{
struct ip *ip, *mhip;
struct ifnet *ifp = NULL; /* keep compiler happy */
@@ -130,8 +131,8 @@ ip_output(m0, opt, ro, flags, imo)
struct in_addr pkt_dst;
#ifdef IPSEC
struct route iproute;
- struct socket *so = NULL;
struct secpolicy *sp = NULL;
+ struct socket *so = inp ? inp->inp_socket : NULL;
#endif
struct ip_fw_args args;
int src_was_INADDR_ANY = 0; /* as the name says... */
@@ -148,10 +149,10 @@ ip_output(m0, opt, ro, flags, imo)
/* Grab info from MT_TAG mbufs prepended to the chain. */
for (; m0 && m0->m_type == MT_TAG; m0 = m0->m_next) {
- switch(m0->m_tag_id) {
+ switch(m0->_m_tag_id) {
default:
printf("ip_output: unrecognised MT_TAG tag %d\n",
- m0->m_tag_id);
+ m0->_m_tag_id);
break;
case PACKET_TAG_DUMMYNET:
@@ -182,13 +183,6 @@ ip_output(m0, opt, ro, flags, imo)
KASSERT(!m || (m->m_flags & M_PKTHDR) != 0, ("ip_output: no HDR"));
- KASSERT(ro != NULL, ("ip_output: no route, proto %d",
- mtod(m, struct ip *)->ip_p));
-
-#ifdef IPSEC
- so = ipsec_getsocket(m);
- (void)ipsec_setsocket(m, NULL);
-#endif
if (args.rule != NULL) { /* dummynet already saw us */
ip = mtod(m, struct ip *);
hlen = IP_VHL_HL(ip->ip_vhl) << 2 ;
diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h
index e1f8465..43eaa03 100644
--- a/sys/netinet/ip_var.h
+++ b/sys/netinet/ip_var.h
@@ -170,7 +170,8 @@ void ip_init(void);
extern int (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *,
struct ip_moptions *);
int ip_output(struct mbuf *,
- struct mbuf *, struct route *, int, struct ip_moptions *);
+ struct mbuf *, struct route *, int, struct ip_moptions *,
+ struct inpcb *);
struct in_ifaddr *
ip_rtaddr(struct in_addr, struct route *);
void ip_savecontrol(struct inpcb *, struct mbuf **, struct ip *,
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 76cdeb6..144554a 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -281,15 +281,8 @@ rip_output(m, so, dst)
ipstat.ips_rawout++;
}
-#ifdef IPSEC
- if (ipsec_setsocket(m, so) != 0) {
- m_freem(m);
- return ENOBUFS;
- }
-#endif /*IPSEC*/
-
return (ip_output(m, inp->inp_options, &inp->inp_route, flags,
- inp->inp_moptions));
+ inp->inp_moptions, inp));
}
/*
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 3e6f589..59cf6ae 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -369,7 +369,7 @@ tcp_input(m, off0)
/* Grab info from MT_TAG mbufs prepended to the chain. */
for (;m && m->m_type == MT_TAG; m = m->m_next) {
- if (m->m_tag_id == PACKET_TAG_IPFORWARD)
+ if (m->_m_tag_id == PACKET_TAG_IPFORWARD)
next_hop = (struct sockaddr_in *)m->m_hdr.mh_data;
}
#ifdef INET6
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
index 944e7ee..4128be5 100644
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -875,17 +875,11 @@ send:
: NULL);
/* TODO: IPv6 IP6TOS_ECT bit on */
-#ifdef IPSEC
- if (ipsec_setsocket(m, so) != 0) {
- m_freem(m);
- error = ENOBUFS;
- goto out;
- }
-#endif /*IPSEC*/
error = ip6_output(m,
tp->t_inpcb->in6p_outputopts,
&tp->t_inpcb->in6p_route,
- (so->so_options & SO_DONTROUTE), NULL, NULL);
+ (so->so_options & SO_DONTROUTE), NULL, NULL,
+ tp->t_inpcb);
} else
#endif /* INET6 */
{
@@ -914,11 +908,8 @@ send:
&& !(rt->rt_rmx.rmx_locks & RTV_MTU)) {
ip->ip_off |= IP_DF;
}
-#ifdef IPSEC
- ipsec_setsocket(m, so);
-#endif /*IPSEC*/
error = ip_output(m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route,
- (so->so_options & SO_DONTROUTE), 0);
+ (so->so_options & SO_DONTROUTE), 0, tp->t_inpcb);
}
if (error) {
diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c
index 3e6f589..59cf6ae 100644
--- a/sys/netinet/tcp_reass.c
+++ b/sys/netinet/tcp_reass.c
@@ -369,7 +369,7 @@ tcp_input(m, off0)
/* Grab info from MT_TAG mbufs prepended to the chain. */
for (;m && m->m_type == MT_TAG; m = m->m_next) {
- if (m->m_tag_id == PACKET_TAG_IPFORWARD)
+ if (m->_m_tag_id == PACKET_TAG_IPFORWARD)
next_hop = (struct sockaddr_in *)m->m_hdr.mh_data;
}
#ifdef INET6
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 181996c..d9b3ecf 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -515,15 +515,10 @@ tcp_respond(tp, ipgen, th, m, ack, seq, flags)
if (tp == NULL || (tp->t_inpcb->inp_socket->so_options & SO_DEBUG))
tcp_trace(TA_OUTPUT, 0, tp, mtod(m, void *), th, 0);
#endif
-#ifdef IPSEC
- if (ipsec_setsocket(m, tp ? tp->t_inpcb->inp_socket : NULL) != 0) {
- m_freem(m);
- return;
- }
-#endif
#ifdef INET6
if (isipv6) {
- (void)ip6_output(m, NULL, ro6, ipflags, NULL, NULL);
+ (void)ip6_output(m, NULL, ro6, ipflags, NULL, NULL,
+ tp ? tp->t_inpcb : NULL);
if (ro6 == &sro6 && ro6->ro_rt) {
RTFREE(ro6->ro_rt);
ro6->ro_rt = NULL;
@@ -531,7 +526,7 @@ tcp_respond(tp, ipgen, th, m, ack, seq, flags)
} else
#endif /* INET6 */
{
- (void) ip_output(m, NULL, ro, ipflags, NULL);
+ (void) ip_output(m, NULL, ro, ipflags, NULL, tp ? tp->t_inpcb : NULL);
if (ro == &sro && ro->ro_rt) {
RTFREE(ro->ro_rt);
ro->ro_rt = NULL;
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index d5cc9ad..49197bf 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -1104,14 +1104,6 @@ syncache_respond(sc, m)
mac_create_mbuf_from_socket(sc->sc_tp->t_inpcb->inp_socket, m);
#endif
-#ifdef IPSEC
- /* use IPsec policy on listening socket to send SYN,ACK */
- if (ipsec_setsocket(m, sc->sc_tp->t_inpcb->inp_socket) != 0) {
- m_freem(m);
- return (ENOBUFS);
- }
-#endif
-
#ifdef INET6
if (sc->sc_inc.inc_isipv6) {
ip6 = mtod(m, struct ip6_hdr *);
@@ -1213,7 +1205,8 @@ no_options:
th->th_sum = in6_cksum(m, IPPROTO_TCP, hlen, tlen - hlen);
ip6->ip6_hlim = in6_selecthlim(NULL,
ro6->ro_rt ? ro6->ro_rt->rt_ifp : NULL);
- error = ip6_output(m, NULL, ro6, 0, NULL, NULL);
+ error = ip6_output(m, NULL, ro6, 0, NULL, NULL,
+ sc->sc_tp->t_inpcb);
} else
#endif
{
@@ -1221,7 +1214,8 @@ no_options:
htons(tlen - hlen + IPPROTO_TCP));
m->m_pkthdr.csum_flags = CSUM_TCP;
m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum);
- error = ip_output(m, sc->sc_ipopts, &sc->sc_route, 0, NULL);
+ error = ip_output(m, sc->sc_ipopts, &sc->sc_route, 0, NULL,
+ sc->sc_tp->t_inpcb);
}
return (error);
}
diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c
index 181996c..d9b3ecf 100644
--- a/sys/netinet/tcp_timewait.c
+++ b/sys/netinet/tcp_timewait.c
@@ -515,15 +515,10 @@ tcp_respond(tp, ipgen, th, m, ack, seq, flags)
if (tp == NULL || (tp->t_inpcb->inp_socket->so_options & SO_DEBUG))
tcp_trace(TA_OUTPUT, 0, tp, mtod(m, void *), th, 0);
#endif
-#ifdef IPSEC
- if (ipsec_setsocket(m, tp ? tp->t_inpcb->inp_socket : NULL) != 0) {
- m_freem(m);
- return;
- }
-#endif
#ifdef INET6
if (isipv6) {
- (void)ip6_output(m, NULL, ro6, ipflags, NULL, NULL);
+ (void)ip6_output(m, NULL, ro6, ipflags, NULL, NULL,
+ tp ? tp->t_inpcb : NULL);
if (ro6 == &sro6 && ro6->ro_rt) {
RTFREE(ro6->ro_rt);
ro6->ro_rt = NULL;
@@ -531,7 +526,7 @@ tcp_respond(tp, ipgen, th, m, ack, seq, flags)
} else
#endif /* INET6 */
{
- (void) ip_output(m, NULL, ro, ipflags, NULL);
+ (void) ip_output(m, NULL, ro, ipflags, NULL, tp ? tp->t_inpcb : NULL);
if (ro == &sro && ro->ro_rt) {
RTFREE(ro->ro_rt);
ro->ro_rt = NULL;
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 188182f..1a07cea 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -816,15 +816,9 @@ udp_output(inp, m, addr, control, td)
((struct ip *)ui)->ip_tos = inp->inp_ip_tos; /* XXX */
udpstat.udps_opackets++;
-#ifdef IPSEC
- if (ipsec_setsocket(m, inp->inp_socket) != 0) {
- error = ENOBUFS;
- goto release;
- }
-#endif /*IPSEC*/
error = ip_output(m, inp->inp_options, &inp->inp_route,
(inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST)),
- inp->inp_moptions);
+ inp->inp_moptions, inp);
if (addr) {
in_pcbdisconnect(inp);
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index 38332b2..6c1c1c5 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -2158,15 +2158,11 @@ icmp6_reflect(m, off)
*/
m->m_flags &= ~(M_BCAST|M_MCAST);
-#ifdef IPSEC
- /* Don't lookup socket */
- (void)ipsec_setsocket(m, NULL);
-#endif /*IPSEC*/
#ifdef COMPAT_RFC1885
- ip6_output(m, NULL, &icmp6_reflect_rt, 0, NULL, &outif);
+ ip6_output(m, NULL, &icmp6_reflect_rt, 0, NULL, &outif, NULL);
#else
- ip6_output(m, NULL, NULL, 0, NULL, &outif);
+ ip6_output(m, NULL, NULL, 0, NULL, &outif, NULL);
#endif
if (outif)
icmp6_ifoutstat_inc(outif, type, code);
@@ -2666,11 +2662,7 @@ noredhdropt:;
= in6_cksum(m, IPPROTO_ICMPV6, sizeof(*ip6), ntohs(ip6->ip6_plen));
/* send the packet to outside... */
-#ifdef IPSEC
- /* Don't lookup socket */
- (void)ipsec_setsocket(m, NULL);
-#endif /*IPSEC*/
- ip6_output(m, NULL, NULL, 0, NULL, &outif);
+ ip6_output(m, NULL, NULL, 0, NULL, &outif, NULL);
if (outif) {
icmp6_ifstat_inc(outif, ifs6_out_msg);
icmp6_ifstat_inc(outif, ifs6_out_redirect);
diff --git a/sys/netinet6/in6_gif.c b/sys/netinet6/in6_gif.c
index e96a0bc..6d48afd 100644
--- a/sys/netinet6/in6_gif.c
+++ b/sys/netinet6/in6_gif.c
@@ -202,9 +202,9 @@ in6_gif_output(ifp, family, m, rt)
* it is too painful to ask for resend of inner packet, to achieve
* path MTU discovery for encapsulated packets.
*/
- return(ip6_output(m, 0, &sc->gif_ro6, IPV6_MINMTU, 0, NULL));
+ return(ip6_output(m, 0, &sc->gif_ro6, IPV6_MINMTU, 0, NULL, NULL));
#else
- return(ip6_output(m, 0, &sc->gif_ro6, 0, 0, NULL));
+ return(ip6_output(m, 0, &sc->gif_ro6, 0, 0, NULL, NULL));
#endif
}
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
index 0c401c8..3f5d7d5 100644
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -146,7 +146,7 @@ int ip6_fw_enable = 1;
struct ip6stat ip6stat;
static void ip6_init2 __P((void *));
-static struct mbuf *ip6_setdstifaddr __P((struct mbuf *, struct in6_ifaddr *));
+static struct ip6aux *ip6_setdstifaddr __P((struct mbuf *, struct in6_ifaddr *));
static int ip6_hopopts_input __P((u_int32_t *, u_int32_t *, struct mbuf **, int *));
#ifdef PULLDOWN_TEST
static struct mbuf *ip6_pullexthdr __P((struct mbuf *, size_t, int));
@@ -858,16 +858,16 @@ ip6_input(m)
* set/grab in6_ifaddr correspond to IPv6 destination address.
* XXX backward compatibility wrapper
*/
-static struct mbuf *
+static struct ip6aux *
ip6_setdstifaddr(m, ia6)
struct mbuf *m;
struct in6_ifaddr *ia6;
{
- struct mbuf *n;
+ struct ip6aux *n;
n = ip6_addaux(m);
if (n)
- mtod(n, struct ip6aux *)->ip6a_dstia6 = ia6;
+ n->ip6a_dstia6 = ia6;
return n; /* NULL if failed to set */
}
@@ -875,11 +875,11 @@ struct in6_ifaddr *
ip6_getdstifaddr(m)
struct mbuf *m;
{
- struct mbuf *n;
+ struct ip6aux *n;
n = ip6_findaux(m);
if (n)
- return mtod(n, struct ip6aux *)->ip6a_dstia6;
+ return n->ip6a_dstia6;
else
return NULL;
}
@@ -1609,53 +1609,38 @@ ip6_lasthdr(m, off, proto, nxtp)
}
}
-struct mbuf *
+struct ip6aux *
ip6_addaux(m)
struct mbuf *m;
{
- struct mbuf *n;
-
-#ifdef DIAGNOSTIC
- if (sizeof(struct ip6aux) > MHLEN)
- panic("assumption failed on sizeof(ip6aux)");
-#endif
- n = m_aux_find(m, AF_INET6, -1);
- if (n) {
- if (n->m_len < sizeof(struct ip6aux)) {
- printf("conflicting use of ip6aux");
- return NULL;
- }
- } else {
- n = m_aux_add(m, AF_INET6, -1);
- n->m_len = sizeof(struct ip6aux);
- bzero(mtod(n, caddr_t), n->m_len);
+ struct m_tag *tag = m_tag_find(m, PACKET_TAG_IPV6_INPUT, NULL);
+ if (!tag) {
+ tag = m_tag_get(PACKET_TAG_IPV6_INPUT,
+ sizeof (struct ip6aux),
+ M_NOWAIT);
+ if (tag)
+ m_tag_prepend(m, tag);
}
- return n;
+ if (tag)
+ bzero(tag+1, sizeof (struct ip6aux));
+ return tag ? (struct ip6aux*)(tag+1) : NULL;
}
-struct mbuf *
+struct ip6aux *
ip6_findaux(m)
struct mbuf *m;
{
- struct mbuf *n;
-
- n = m_aux_find(m, AF_INET6, -1);
- if (n && n->m_len < sizeof(struct ip6aux)) {
- printf("conflicting use of ip6aux");
- n = NULL;
- }
- return n;
+ struct m_tag *tag = m_tag_find(m, PACKET_TAG_IPV6_INPUT, NULL);
+ return tag ? (struct ip6aux*)(tag+1) : NULL;
}
void
ip6_delaux(m)
struct mbuf *m;
{
- struct mbuf *n;
-
- n = m_aux_find(m, AF_INET6, -1);
- if (n)
- m_aux_delete(m, n);
+ struct m_tag *tag = m_tag_find(m, PACKET_TAG_IPV6_INPUT, NULL);
+ if (tag)
+ m_tag_delete(m, tag);
}
/*
diff --git a/sys/netinet6/ip6_mroute.c b/sys/netinet6/ip6_mroute.c
index 786d088..ecb18c0 100644
--- a/sys/netinet6/ip6_mroute.c
+++ b/sys/netinet6/ip6_mroute.c
@@ -1449,7 +1449,7 @@ phyint_send(ip6, mifp, m)
im6o.im6o_multicast_hlim = ip6->ip6_hlim;
im6o.im6o_multicast_loop = 1;
error = ip6_output(mb_copy, NULL, &ro,
- IPV6_FORWARDING, &im6o, NULL);
+ IPV6_FORWARDING, &im6o, NULL, NULL);
#ifdef MRT6DEBUG
if (mrt6debug & DEBUG_XMIT)
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index bb3e079..63d676d 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -143,13 +143,14 @@ static int ip6_splithdr __P((struct mbuf *, struct ip6_exthdrs *));
* which is rt_rmx.rmx_mtu.
*/
int
-ip6_output(m0, opt, ro, flags, im6o, ifpp)
+ip6_output(m0, opt, ro, flags, im6o, ifpp, inp)
struct mbuf *m0;
struct ip6_pktopts *opt;
struct route_in6 *ro;
int flags;
struct ip6_moptions *im6o;
struct ifnet **ifpp; /* XXX: just for statistics */
+ struct inpcb *inp;
{
struct ip6_hdr *ip6, *mhip6;
struct ifnet *ifp, *origifp;
@@ -173,12 +174,9 @@ ip6_output(m0, opt, ro, flags, im6o, ifpp)
#endif /* PFIL_HOOKS */
#ifdef IPSEC
int needipsectun = 0;
- struct socket *so;
struct secpolicy *sp = NULL;
+ struct socket *so = inp ? inp->inp_socket : NULL;
- /* for AH processing. stupid to have "socket" variable in IP layer... */
- so = ipsec_getsocket(m);
- (void)ipsec_setsocket(m, NULL);
ip6 = mtod(m, struct ip6_hdr *);
#endif /* IPSEC */
diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h
index fdf709b..d16fd59 100644
--- a/sys/netinet6/ip6_var.h
+++ b/sys/netinet6/ip6_var.h
@@ -304,8 +304,8 @@ char * ip6_get_prevhdr __P((struct mbuf *, int));
int ip6_nexthdr __P((struct mbuf *, int, int, int *));
int ip6_lasthdr __P((struct mbuf *, int, int, int *));
-struct mbuf *ip6_addaux __P((struct mbuf *));
-struct mbuf *ip6_findaux __P((struct mbuf *));
+struct ip6aux *ip6_addaux __P((struct mbuf *));
+struct ip6aux *ip6_findaux __P((struct mbuf *));
void ip6_delaux __P((struct mbuf *));
int ip6_mforward __P((struct ip6_hdr *, struct ifnet *, struct mbuf *));
@@ -323,7 +323,8 @@ void ip6_mloopback __P((struct ifnet *, struct mbuf *, struct sockaddr_in6 *));
int ip6_output __P((struct mbuf *, struct ip6_pktopts *,
struct route_in6 *,
int,
- struct ip6_moptions *, struct ifnet **));
+ struct ip6_moptions *, struct ifnet **,
+ struct inpcb *));
int ip6_ctloutput __P((struct socket *, struct sockopt *sopt));
void init_ip6pktopts __P((struct ip6_pktopts *));
int ip6_setpktoptions __P((struct mbuf *, struct ip6_pktopts *, int, int));
diff --git a/sys/netinet6/ipsec.c b/sys/netinet6/ipsec.c
index 5a9e509..b91470e 100644
--- a/sys/netinet6/ipsec.c
+++ b/sys/netinet6/ipsec.c
@@ -221,9 +221,6 @@ static int ipsec4_encapsulate __P((struct mbuf *, struct secasvar *));
#ifdef INET6
static int ipsec6_encapsulate __P((struct mbuf *, struct secasvar *));
#endif
-static struct mbuf *ipsec_addaux __P((struct mbuf *));
-static struct mbuf *ipsec_findaux __P((struct mbuf *));
-static void ipsec_optaux __P((struct mbuf *, struct mbuf *));
/*
* For OUTBOUND packet having a socket. Searching SPD for packet,
@@ -3457,91 +3454,14 @@ ipsec_copypkt(m)
return(NULL);
}
-static struct mbuf *
-ipsec_addaux(m)
- struct mbuf *m;
-{
- struct mbuf *n;
-
- n = m_aux_find(m, AF_INET, IPPROTO_ESP);
- if (!n)
- n = m_aux_add(m, AF_INET, IPPROTO_ESP);
- if (!n)
- return n; /* ENOBUFS */
- n->m_len = sizeof(struct socket *);
- bzero(mtod(n, void *), n->m_len);
- return n;
-}
-
-static struct mbuf *
-ipsec_findaux(m)
- struct mbuf *m;
-{
- struct mbuf *n;
-
- n = m_aux_find(m, AF_INET, IPPROTO_ESP);
-#ifdef DIAGNOSTIC
- if (n && n->m_len < sizeof(struct socket *))
- panic("invalid ipsec m_aux");
-#endif
- return n;
-}
-
void
ipsec_delaux(m)
struct mbuf *m;
{
- struct mbuf *n;
-
- n = m_aux_find(m, AF_INET, IPPROTO_ESP);
- if (n)
- m_aux_delete(m, n);
-}
-
-/* if the aux buffer is unnecessary, nuke it. */
-static void
-ipsec_optaux(m, n)
- struct mbuf *m;
- struct mbuf *n;
-{
+ struct m_tag *tag;
- if (!n)
- return;
- if (n->m_len == sizeof(struct socket *) && !*mtod(n, struct socket **))
- ipsec_delaux(m);
-}
-
-int
-ipsec_setsocket(m, so)
- struct mbuf *m;
- struct socket *so;
-{
- struct mbuf *n;
-
- /* if so == NULL, don't insist on getting the aux mbuf */
- if (so) {
- n = ipsec_addaux(m);
- if (!n)
- return ENOBUFS;
- } else
- n = ipsec_findaux(m);
- if (n && n->m_len >= sizeof(struct socket *))
- *mtod(n, struct socket **) = so;
- ipsec_optaux(m, n);
- return 0;
-}
-
-struct socket *
-ipsec_getsocket(m)
- struct mbuf *m;
-{
- struct mbuf *n;
-
- n = ipsec_findaux(m);
- if (n && n->m_len >= sizeof(struct socket *))
- return *mtod(n, struct socket **);
- else
- return NULL;
+ while ((tag = m_tag_find(m, PACKET_TAG_IPSEC_HISTORY, NULL)) != NULL)
+ m_tag_delete(m, tag);
}
int
@@ -3550,19 +3470,18 @@ ipsec_addhist(m, proto, spi)
int proto;
u_int32_t spi;
{
- struct mbuf *n;
+ struct m_tag *tag;
struct ipsec_history *p;
- n = ipsec_addaux(m);
- if (!n)
+ tag = m_tag_get(PACKET_TAG_IPSEC_HISTORY,
+ sizeof (struct ipsec_history), M_NOWAIT);
+ if (tag == NULL)
return ENOBUFS;
- if (M_TRAILINGSPACE(n) < sizeof(*p))
- return ENOSPC; /* XXX */
- p = (struct ipsec_history *)(mtod(n, caddr_t) + n->m_len);
- n->m_len += sizeof(*p);
+ p = (struct ipsec_history *)(tag+1);
bzero(p, sizeof(*p));
p->ih_proto = proto;
p->ih_spi = spi;
+ m_tag_prepend(m, tag);
return 0;
}
@@ -3571,32 +3490,13 @@ ipsec_gethist(m, lenp)
struct mbuf *m;
int *lenp;
{
- struct mbuf *n;
- int l;
+ struct m_tag *tag;
- n = ipsec_findaux(m);
- if (!n)
+ tag = m_tag_find(m, PACKET_TAG_IPSEC_HISTORY, NULL);
+ if (tag == NULL)
return NULL;
- l = n->m_len;
- if (sizeof(struct socket *) > l)
- return NULL;
- if ((l - sizeof(struct socket *)) % sizeof(struct ipsec_history))
- return NULL;
- /* XXX does it make more sense to divide by sizeof(ipsec_history)? */
+ /* XXX NB: noone uses this so fake it */
if (lenp)
- *lenp = l - sizeof(struct socket *);
- return (struct ipsec_history *)
- (mtod(n, caddr_t) + sizeof(struct socket *));
-}
-
-void
-ipsec_clearhist(m)
- struct mbuf *m;
-{
- struct mbuf *n;
-
- n = ipsec_findaux(m);
- if ((n) && n->m_len > sizeof(struct socket *))
- n->m_len = sizeof(struct socket *);
- ipsec_optaux(m, n);
+ *lenp = sizeof (struct ipsec_history);
+ return ((struct ipsec_history *)(tag+1));
}
diff --git a/sys/netinet6/ipsec.h b/sys/netinet6/ipsec.h
index 20569a0..76790b8 100644
--- a/sys/netinet6/ipsec.h
+++ b/sys/netinet6/ipsec.h
@@ -336,11 +336,8 @@ extern int ipsec4_tunnel_validate __P((struct mbuf *, int, u_int,
struct secasvar *));
extern struct mbuf *ipsec_copypkt __P((struct mbuf *));
extern void ipsec_delaux __P((struct mbuf *));
-extern int ipsec_setsocket __P((struct mbuf *, struct socket *));
-extern struct socket *ipsec_getsocket __P((struct mbuf *));
extern int ipsec_addhist __P((struct mbuf *, int, u_int32_t));
extern struct ipsec_history *ipsec_gethist __P((struct mbuf *, int *));
-extern void ipsec_clearhist __P((struct mbuf *));
#endif /* _KERNEL */
#ifndef _KERNEL
diff --git a/sys/netinet6/mld6.c b/sys/netinet6/mld6.c
index b35d10d..61c0e0c 100644
--- a/sys/netinet6/mld6.c
+++ b/sys/netinet6/mld6.c
@@ -456,7 +456,7 @@ mld6_sendpkt(in6m, type, dst)
/* increment output statictics */
icmp6stat.icp6s_outhist[type]++;
- ip6_output(mh, &ip6_opts, NULL, 0, &im6o, &outif);
+ ip6_output(mh, &ip6_opts, NULL, 0, &im6o, &outif, NULL);
if (outif) {
icmp6_ifstat_inc(outif, ifs6_out_msg);
switch (type) {
diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c
index 1b1f7dc9..88af7ce 100644
--- a/sys/netinet6/nd6_nbr.c
+++ b/sys/netinet6/nd6_nbr.c
@@ -504,11 +504,7 @@ nd6_ns_output(ifp, daddr6, taddr6, ln, dad)
nd_ns->nd_ns_cksum
= in6_cksum(m, IPPROTO_ICMPV6, sizeof(*ip6), icmp6len);
-#ifdef IPSEC
- /* Don't lookup socket */
- (void)ipsec_setsocket(m, NULL);
-#endif
- ip6_output(m, NULL, NULL, dad ? IPV6_DADOUTPUT : 0, &im6o, &outif);
+ ip6_output(m, NULL, NULL, dad ? IPV6_DADOUTPUT : 0, &im6o, &outif, NULL);
if (outif) {
icmp6_ifstat_inc(outif, ifs6_out_msg);
icmp6_ifstat_inc(outif, ifs6_out_neighborsolicit);
@@ -952,11 +948,7 @@ nd6_na_output(ifp, daddr6, taddr6, flags, tlladdr, sdl0)
nd_na->nd_na_cksum =
in6_cksum(m, IPPROTO_ICMPV6, sizeof(struct ip6_hdr), icmp6len);
-#ifdef IPSEC
- /* Don't lookup socket */
- (void)ipsec_setsocket(m, NULL);
-#endif
- ip6_output(m, NULL, NULL, 0, &im6o, &outif);
+ ip6_output(m, NULL, NULL, 0, &im6o, &outif, NULL);
if (outif) {
icmp6_ifstat_inc(outif, ifs6_out_msg);
icmp6_ifstat_inc(outif, ifs6_out_neighboradvert);
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index c4652af..6d4cc22 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -445,15 +445,8 @@ rip6_output(m, va_alist)
*p = in6_cksum(m, ip6->ip6_nxt, sizeof(*ip6), plen);
}
-#ifdef IPSEC
- if (ipsec_setsocket(m, so) != 0) {
- error = ENOBUFS;
- goto bad;
- }
-#endif /*IPSEC*/
-
error = ip6_output(m, optp, &in6p->in6p_route, 0,
- in6p->in6p_moptions, &oifp);
+ in6p->in6p_moptions, &oifp, in6p);
if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) {
if (oifp)
icmp6_ifoutstat_inc(oifp, type, code);
diff --git a/sys/netinet6/route6.c b/sys/netinet6/route6.c
index f3fe83d..f2575bc 100644
--- a/sys/netinet6/route6.c
+++ b/sys/netinet6/route6.c
@@ -60,11 +60,10 @@ route6_input(mp, offp, proto)
struct mbuf *m = *mp;
struct ip6_rthdr *rh;
int off = *offp, rhlen;
- struct mbuf *n;
+ struct ip6aux *ip6a;
- n = ip6_findaux(m);
- if (n) {
- struct ip6aux *ip6a = mtod(n, struct ip6aux *);
+ ip6a = ip6_findaux(m);
+ if (ip6a) {
/* XXX reject home-address option before rthdr */
if (ip6a->ip6a_flags & IP6A_SWAP) {
ip6stat.ip6s_badoptions++;
diff --git a/sys/netinet6/udp6_output.c b/sys/netinet6/udp6_output.c
index 35597fd..1de45f0 100644
--- a/sys/netinet6/udp6_output.c
+++ b/sys/netinet6/udp6_output.c
@@ -290,14 +290,8 @@ udp6_output(in6p, m, addr6, control, td)
flags = 0;
udp6stat.udp6s_opackets++;
-#ifdef IPSEC
- if (ipsec_setsocket(m, in6p->in6p_socket) != 0) {
- error = ENOBUFS;
- goto release;
- }
-#endif /* IPSEC */
error = ip6_output(m, in6p->in6p_outputopts, &in6p->in6p_route,
- flags, in6p->in6p_moptions, NULL);
+ flags, in6p->in6p_moptions, NULL, in6p);
break;
case AF_INET:
error = EAFNOSUPPORT;
diff --git a/sys/netipx/ipx_ip.c b/sys/netipx/ipx_ip.c
index 0fb03f9..d306713 100644
--- a/sys/netipx/ipx_ip.c
+++ b/sys/netipx/ipx_ip.c
@@ -287,7 +287,7 @@ ipxipoutput(ifp, m, dst, rt)
/*
* Output final datagram.
*/
- error = (ip_output(m, (struct mbuf *)NULL, ro, SO_BROADCAST, NULL));
+ error = (ip_output(m, (struct mbuf *)NULL, ro, SO_BROADCAST, NULL, NULL));
if (error) {
ifn->ifen_ifnet.if_oerrors++;
ifn->ifen_ifnet.if_ierrors = error;
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
index e62bedd..ceca989 100644
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -38,6 +38,7 @@
#define _SYS_MBUF_H_
#include <sys/_label.h>
+#include <sys/queue.h>
/*
* Mbufs are of a single size, MSIZE (machine/param.h), which
@@ -76,6 +77,16 @@ struct m_hdr {
};
/*
+ * Packet tag structure (see below for details).
+ */
+struct m_tag {
+ SLIST_ENTRY(m_tag) m_tag_link; /* List of packet tags */
+ u_int16_t m_tag_id; /* Tag ID */
+ u_int16_t m_tag_len; /* Length of data */
+ u_int32_t m_tag_cookie; /* ABI/Module ID */
+};
+
+/*
* Record/packet header in first mbuf of chain; valid only if M_PKTHDR is set.
*/
struct pkthdr {
@@ -86,7 +97,7 @@ struct pkthdr {
/* variables for hardware checksum */
int csum_flags; /* flags regarding checksum */
int csum_data; /* data field used by csum routines */
- struct mbuf *aux; /* extra data buffer; ipsec/others */
+ SLIST_HEAD(packet_tags, m_tag) tags; /* list of packet tags */
struct label label; /* MAC label of data in packet */
};
@@ -392,62 +403,6 @@ struct mbstat {
/* Compatibility with 4.3. */
#define m_copy(m, o, l) m_copym((m), (o), (l), M_DONTWAIT)
-/*
- * pkthdr.aux type tags.
- */
-struct mauxtag {
- int af;
- int type;
- void *p;
-};
-
-/*-
- * Some packet tags to identify different mbuf annotations.
- *
- * Eventually, these annotations will end up in an appropriate chain
- * (struct m_tag or similar, e.g. as in NetBSD) properly managed by
- * the mbuf handling routines.
- *
- * As a temporary and low impact solution to replace the even uglier
- * approach used so far in some parts of the network stack (which relies
- * on global variables), these annotations are stored in MT_TAG
- * mbufs (or lookalikes) prepended to the actual mbuf chain.
- *
- * m_type = MT_TAG
- * m_flags = m_tag_id
- * m_next = next buffer in chain.
- *
- * BE VERY CAREFUL not to pass these blocks to the mbuf handling routines.
- */
-
-#define m_tag_id m_hdr.mh_flags
-
-/* Packet tag types -- first ones are from NetBSD */
-
-#define PACKET_TAG_NONE 0 /* Nadda */
-#define PACKET_TAG_IPSEC_IN_DONE 1 /* IPsec applied, in */
-#define PACKET_TAG_IPSEC_OUT_DONE 2 /* IPsec applied, out */
-#define PACKET_TAG_IPSEC_IN_CRYPTO_DONE 3 /* NIC IPsec crypto done */
-#define PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED 4 /* NIC IPsec crypto req'ed */
-#define PACKET_TAG_IPSEC_IN_COULD_DO_CRYPTO 5 /* NIC notifies IPsec */
-#define PACKET_TAG_IPSEC_PENDING_TDB 6 /* Reminder to do IPsec */
-#define PACKET_TAG_BRIDGE 7 /* Bridge processing done */
-#define PACKET_TAG_GIF 8 /* GIF processing done */
-#define PACKET_TAG_GRE 9 /* GRE processing done */
-#define PACKET_TAG_IN_PACKET_CHECKSUM 10 /* NIC checksumming done */
-#define PACKET_TAG_ENCAP 11 /* Encap. processing */
-#define PACKET_TAG_IPSEC_SOCKET 12 /* IPSEC socket ref */
-#define PACKET_TAG_IPSEC_HISTORY 13 /* IPSEC history */
-#define PACKET_TAG_IPV6_INPUT 14 /* IPV6 input processing */
-
-/* Packet tags used in the FreeBSD network stack */
-#define PACKET_TAG_DUMMYNET 15 /* dummynet info */
-#define PACKET_TAG_IPFW 16 /* ipfw classification */
-#define PACKET_TAG_DIVERT 17 /* divert info */
-#define PACKET_TAG_IPFORWARD 18 /* ipforward info */
-
-#define PACKET_TAG_MAX 19
-
extern int max_datalen; /* MHLEN - max_hdr */
extern int max_hdr; /* Largest link + protocol header */
extern int max_linkhdr; /* Largest link-level header */
@@ -461,11 +416,6 @@ extern int nsfbufs; /* Number of sendfile(2) bufs */
void _mext_free(struct mbuf *);
void m_adj(struct mbuf *, int);
-struct mbuf *m_aux_add(struct mbuf *, int, int);
-struct mbuf *m_aux_add2(struct mbuf *, int, int, void *);
-void m_aux_delete(struct mbuf *, struct mbuf *);
-struct mbuf *m_aux_find(struct mbuf *, int, int);
-struct mbuf *m_aux_find2(struct mbuf *, int, int, void *);
void m_cat(struct mbuf *, struct mbuf *);
void m_chtype(struct mbuf *, short);
void m_clget(struct mbuf *, int);
@@ -494,6 +444,111 @@ void m_print(const struct mbuf *);
struct mbuf *m_pulldown(struct mbuf *, int, int, int *);
struct mbuf *m_pullup(struct mbuf *, int);
struct mbuf *m_split(struct mbuf *, int, int);
+
+/*
+ * Packets may have annotations attached by affixing a list
+ * of "packet tags" to the pkthdr structure. Packet tags are
+ * dynamically allocated semi-opaque data structures that have
+ * a fixed header (struct m_tag) that specifies the size of the
+ * memory block and a <cookie,type> pair that identifies it.
+ * The cookie is a 32-bit unique unsigned value used to identify
+ * a module or ABI. By convention this value is chose as the
+ * date+time that the module is created, expressed as the number of
+ * seconds since the epoch (e.g. using date -u +'%s'). The type value
+ * is an ABI/module-specific value that identifies a particular annotation
+ * and is private to the module. For compatibility with systems
+ * like openbsd that define packet tags w/o an ABI/module cookie,
+ * the value PACKET_ABI_COMPAT is used to implement m_tag_get and
+ * m_tag_find compatibility shim functions and several tag types are
+ * defined below. Users that do not require compatibility should use
+ * a private cookie value so that packet tag-related definitions
+ * can be maintained privately.
+ *
+ * Note that the packet tag returned by m_tag_allocate has the default
+ * memory alignment implemented by malloc. To reference private data
+ * one can use a construct like:
+ *
+ * struct m_tag *mtag = m_tag_allocate(...);
+ * struct foo *p = (struct foo *)(mtag+1);
+ *
+ * if the alignment of struct m_tag is sufficient for referencing members
+ * of struct foo. Otherwise it is necessary to embed struct m_tag within
+ * the private data structure to insure proper alignment; e.g.
+ *
+ * struct foo {
+ * struct m_tag tag;
+ * ...
+ * };
+ * struct foo *p = (struct foo *) m_tag_allocate(...);
+ * struct m_tag *mtag = &p->tag;
+ */
+
+#define PACKET_TAG_NONE 0 /* Nadda */
+
+/* Packet tag for use with PACKET_ABI_COMPAT */
+#define PACKET_TAG_IPSEC_IN_DONE 1 /* IPsec applied, in */
+#define PACKET_TAG_IPSEC_OUT_DONE 2 /* IPsec applied, out */
+#define PACKET_TAG_IPSEC_IN_CRYPTO_DONE 3 /* NIC IPsec crypto done */
+#define PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED 4 /* NIC IPsec crypto req'ed */
+#define PACKET_TAG_IPSEC_IN_COULD_DO_CRYPTO 5 /* NIC notifies IPsec */
+#define PACKET_TAG_IPSEC_PENDING_TDB 6 /* Reminder to do IPsec */
+#define PACKET_TAG_BRIDGE 7 /* Bridge processing done */
+#define PACKET_TAG_GIF 8 /* GIF processing done */
+#define PACKET_TAG_GRE 9 /* GRE processing done */
+#define PACKET_TAG_IN_PACKET_CHECKSUM 10 /* NIC checksumming done */
+#define PACKET_TAG_ENCAP 11 /* Encap. processing */
+#define PACKET_TAG_IPSEC_SOCKET 12 /* IPSEC socket ref */
+#define PACKET_TAG_IPSEC_HISTORY 13 /* IPSEC history */
+#define PACKET_TAG_IPV6_INPUT 14 /* IPV6 input processing */
+
+/*
+ * As a temporary and low impact solution to replace the even uglier
+ * approach used so far in some parts of the network stack (which relies
+ * on global variables), packet tag-like annotations are stored in MT_TAG
+ * mbufs (or lookalikes) prepended to the actual mbuf chain.
+ *
+ * m_type = MT_TAG
+ * m_flags = m_tag_id
+ * m_next = next buffer in chain.
+ *
+ * BE VERY CAREFUL not to pass these blocks to the mbuf handling routines.
+ */
+#define _m_tag_id m_hdr.mh_flags
+
+/* Packet tags used in the FreeBSD network stack */
+#define PACKET_TAG_DUMMYNET 15 /* dummynet info */
+#define PACKET_TAG_IPFW 16 /* ipfw classification */
+#define PACKET_TAG_DIVERT 17 /* divert info */
+#define PACKET_TAG_IPFORWARD 18 /* ipforward info */
+
+/* Packet tag routines */
+struct m_tag *m_tag_alloc(u_int32_t, int, int, int);
+void m_tag_free(struct m_tag *);
+void m_tag_prepend(struct mbuf *, struct m_tag *);
+void m_tag_unlink(struct mbuf *, struct m_tag *);
+void m_tag_delete(struct mbuf *, struct m_tag *);
+void m_tag_delete_chain(struct mbuf *, struct m_tag *);
+struct m_tag *m_tag_locate(struct mbuf *, u_int32_t, int, struct m_tag *);
+struct m_tag *m_tag_copy(struct m_tag *);
+int m_tag_copy_chain(struct mbuf *, struct mbuf *);
+void m_tag_init(struct mbuf *);
+struct m_tag *m_tag_first(struct mbuf *);
+struct m_tag *m_tag_next(struct mbuf *, struct m_tag *);
+
+/* these are for openbsd compatibility */
+#define MTAG_ABI_COMPAT 0 /* compatibility ABI */
+
+static __inline struct m_tag *
+m_tag_get(int type, int length, int wait)
+{
+ return m_tag_alloc(MTAG_ABI_COMPAT, type, length, wait);
+}
+
+static __inline struct m_tag *
+m_tag_find(struct mbuf *m, int type, struct m_tag *start)
+{
+ return m_tag_locate(m, MTAG_ABI_COMPAT, type, start);
+}
#endif /* _KERNEL */
#endif /* !_SYS_MBUF_H_ */
OpenPOWER on IntegriCloud