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:
parent
733bfbdd78
commit
2a86be217a
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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. */
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
/*
|
||||
|
@ -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 ;
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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",
|
||||
|
@ -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 ;
|
||||
|
@ -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 *,
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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++;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
179
sys/sys/mbuf.h
179
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
|
||||
@ -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_ */
|
||||
|
Loading…
Reference in New Issue
Block a user