diff options
author | sam <sam@FreeBSD.org> | 2002-10-16 01:54:46 +0000 |
---|---|---|
committer | sam <sam@FreeBSD.org> | 2002-10-16 01:54:46 +0000 |
commit | 2a86be217a6aed33eda6628df2b175e49172cd9f (patch) | |
tree | b26e1e9f49b40642051748bcd3961cc2a2b5ff1d /sys | |
parent | 733bfbdd78ddb9efc129532b2c2239d0bacfaf1a (diff) | |
download | FreeBSD-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
Diffstat (limited to 'sys')
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_ */ |