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
This commit is contained in:
Sam Leffler 2002-10-16 01:54:46 +00:00
parent 86aeb27fa2
commit 5d84645305
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=105194
43 changed files with 373 additions and 477 deletions

View File

@ -458,7 +458,8 @@ frentry_t *fr, **frptr;
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

View File

@ -443,7 +443,7 @@ fore_recv_drain(fup)
*/
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;

View File

@ -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,

View File

@ -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);
}
/*

View File

@ -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;
n = m_aux_find(m, af, type);
if (n)
return n;
MGET(n, M_DONTWAIT, m->m_type);
if (n == NULL)
t = malloc(len + sizeof(struct m_tag), M_PACKET_TAGS, wait);
if (t == NULL)
return NULL;
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;
t->m_tag_id = type;
t->m_tag_len = len;
t->m_tag_cookie = cookie;
return t;
}
struct mbuf *
m_aux_find2(struct mbuf *m, int af, int type, void *p)
/* Free a packet tag. */
void
m_tag_free(struct m_tag *t)
{
struct mbuf *n;
struct mauxtag *t;
free(t, M_PACKET_TAGS);
}
if ((m->m_flags & M_PKTHDR) == 0)
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);
}
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;
/* 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);
}
/* Unlink and free a packet tag. */
void
m_tag_delete(struct mbuf *m, struct m_tag *t)
{
KASSERT(m && t, ("m_tag_delete: null argument, m %p t %p", m, t));
m_tag_unlink(m, t);
m_tag_free(t);
}
/* 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);
}
/* 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)
{
struct m_tag *p;
return m_aux_find2(m, af, type, NULL);
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)
{
struct m_tag *p, *t, *tprev = NULL;
return m_aux_add2(m, af, type, NULL);
}
void
m_aux_delete(struct mbuf *m, struct mbuf *victim)
{
struct mbuf *n, *prev, *next;
struct mauxtag *t;
if ((m->m_flags & M_PKTHDR) == 0)
return;
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;
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;
}
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;
}
return 1;
}
/* Initialize tags on an mbuf. */
void
m_tag_init(struct mbuf *m)
{
SLIST_INIT(&m->m_pkthdr.tags);
}
/* Get first tag in chain. */
struct m_tag *
m_tag_first(struct mbuf *m)
{
return SLIST_FIRST(&m->m_pkthdr.tags);
}
/* 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);
}

View File

@ -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. */
}

View File

@ -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)

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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) {
/*

View File

@ -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 ;

View File

@ -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;
void *p = NULL;
struct m_tag *tag;
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);
tag = m_tag_find(m, PACKET_TAG_ENCAP, NULL);
if (tag) {
p = *(void**)(tag+1);
m_tag_delete(m, tag);
}
return p;
#endif
}

View File

@ -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);
}

View File

@ -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

View File

@ -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;

View File

@ -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",

View File

@ -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 ;

View File

@ -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 *,

View File

@ -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));
}
/*

View File

@ -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

View File

@ -875,17 +875,11 @@ tcp_output(struct tcpcb *tp)
: 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 @@ tcp_output(struct tcpcb *tp)
&& !(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) {

View File

@ -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

View File

@ -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;

View File

@ -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 @@ syncache_respond(sc, m)
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 @@ syncache_respond(sc, m)
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);
}

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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
}

View File

@ -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);
}
/*

View File

@ -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)

View File

@ -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 */

View File

@ -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));

View File

@ -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;
struct m_tag *tag;
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;
{
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));
}

View File

@ -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

View File

@ -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) {

View File

@ -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);

View File

@ -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);

View File

@ -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++;

View File

@ -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;

View File

@ -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;

View File

@ -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
@ -75,6 +76,16 @@ struct m_hdr {
short mh_type; /* type of data in this mbuf */
};
/*
* 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.
*/
@ -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_ */