summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2002-10-16 01:54:46 +0000
committersam <sam@FreeBSD.org>2002-10-16 01:54:46 +0000
commit2a86be217a6aed33eda6628df2b175e49172cd9f (patch)
treeb26e1e9f49b40642051748bcd3961cc2a2b5ff1d /sys/netinet6
parent733bfbdd78ddb9efc129532b2c2239d0bacfaf1a (diff)
downloadFreeBSD-src-2a86be217a6aed33eda6628df2b175e49172cd9f.zip
FreeBSD-src-2a86be217a6aed33eda6628df2b175e49172cd9f.tar.gz
Replace aux mbufs with packet tags:
o instead of a list of mbufs use a list of m_tag structures a la openbsd o for netgraph et. al. extend the stock openbsd m_tag to include a 32-bit ABI/module number cookie o for openbsd compatibility define a well-known cookie MTAG_ABI_COMPAT and use this in defining openbsd-compatible m_tag_find and m_tag_get routines o rewrite KAME use of aux mbufs in terms of packet tags o eliminate the most heavily used aux mbufs by adding an additional struct inpcb parameter to ip_output and ip6_output to allow the IPsec code to locate the security policy to apply to outbound packets o bump __FreeBSD_version so code can be conditionalized o fixup ipfilter's call to ip_output based on __FreeBSD_version Reviewed by: julian, luigi (silent), -arch, -net, darren Approved by: julian, silence from everyone else Obtained from: openbsd (mostly) MFC after: 1 month
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/icmp6.c14
-rw-r--r--sys/netinet6/in6_gif.c4
-rw-r--r--sys/netinet6/ip6_input.c61
-rw-r--r--sys/netinet6/ip6_mroute.c2
-rw-r--r--sys/netinet6/ip6_output.c8
-rw-r--r--sys/netinet6/ip6_var.h7
-rw-r--r--sys/netinet6/ipsec.c130
-rw-r--r--sys/netinet6/ipsec.h3
-rw-r--r--sys/netinet6/mld6.c2
-rw-r--r--sys/netinet6/nd6_nbr.c12
-rw-r--r--sys/netinet6/raw_ip6.c9
-rw-r--r--sys/netinet6/route6.c7
-rw-r--r--sys/netinet6/udp6_output.c8
13 files changed, 59 insertions, 208 deletions
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index 38332b2..6c1c1c5 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -2158,15 +2158,11 @@ icmp6_reflect(m, off)
*/
m->m_flags &= ~(M_BCAST|M_MCAST);
-#ifdef IPSEC
- /* Don't lookup socket */
- (void)ipsec_setsocket(m, NULL);
-#endif /*IPSEC*/
#ifdef COMPAT_RFC1885
- ip6_output(m, NULL, &icmp6_reflect_rt, 0, NULL, &outif);
+ ip6_output(m, NULL, &icmp6_reflect_rt, 0, NULL, &outif, NULL);
#else
- ip6_output(m, NULL, NULL, 0, NULL, &outif);
+ ip6_output(m, NULL, NULL, 0, NULL, &outif, NULL);
#endif
if (outif)
icmp6_ifoutstat_inc(outif, type, code);
@@ -2666,11 +2662,7 @@ noredhdropt:;
= in6_cksum(m, IPPROTO_ICMPV6, sizeof(*ip6), ntohs(ip6->ip6_plen));
/* send the packet to outside... */
-#ifdef IPSEC
- /* Don't lookup socket */
- (void)ipsec_setsocket(m, NULL);
-#endif /*IPSEC*/
- ip6_output(m, NULL, NULL, 0, NULL, &outif);
+ ip6_output(m, NULL, NULL, 0, NULL, &outif, NULL);
if (outif) {
icmp6_ifstat_inc(outif, ifs6_out_msg);
icmp6_ifstat_inc(outif, ifs6_out_redirect);
diff --git a/sys/netinet6/in6_gif.c b/sys/netinet6/in6_gif.c
index e96a0bc..6d48afd 100644
--- a/sys/netinet6/in6_gif.c
+++ b/sys/netinet6/in6_gif.c
@@ -202,9 +202,9 @@ in6_gif_output(ifp, family, m, rt)
* it is too painful to ask for resend of inner packet, to achieve
* path MTU discovery for encapsulated packets.
*/
- return(ip6_output(m, 0, &sc->gif_ro6, IPV6_MINMTU, 0, NULL));
+ return(ip6_output(m, 0, &sc->gif_ro6, IPV6_MINMTU, 0, NULL, NULL));
#else
- return(ip6_output(m, 0, &sc->gif_ro6, 0, 0, NULL));
+ return(ip6_output(m, 0, &sc->gif_ro6, 0, 0, NULL, NULL));
#endif
}
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
index 0c401c8..3f5d7d5 100644
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -146,7 +146,7 @@ int ip6_fw_enable = 1;
struct ip6stat ip6stat;
static void ip6_init2 __P((void *));
-static struct mbuf *ip6_setdstifaddr __P((struct mbuf *, struct in6_ifaddr *));
+static struct ip6aux *ip6_setdstifaddr __P((struct mbuf *, struct in6_ifaddr *));
static int ip6_hopopts_input __P((u_int32_t *, u_int32_t *, struct mbuf **, int *));
#ifdef PULLDOWN_TEST
static struct mbuf *ip6_pullexthdr __P((struct mbuf *, size_t, int));
@@ -858,16 +858,16 @@ ip6_input(m)
* set/grab in6_ifaddr correspond to IPv6 destination address.
* XXX backward compatibility wrapper
*/
-static struct mbuf *
+static struct ip6aux *
ip6_setdstifaddr(m, ia6)
struct mbuf *m;
struct in6_ifaddr *ia6;
{
- struct mbuf *n;
+ struct ip6aux *n;
n = ip6_addaux(m);
if (n)
- mtod(n, struct ip6aux *)->ip6a_dstia6 = ia6;
+ n->ip6a_dstia6 = ia6;
return n; /* NULL if failed to set */
}
@@ -875,11 +875,11 @@ struct in6_ifaddr *
ip6_getdstifaddr(m)
struct mbuf *m;
{
- struct mbuf *n;
+ struct ip6aux *n;
n = ip6_findaux(m);
if (n)
- return mtod(n, struct ip6aux *)->ip6a_dstia6;
+ return n->ip6a_dstia6;
else
return NULL;
}
@@ -1609,53 +1609,38 @@ ip6_lasthdr(m, off, proto, nxtp)
}
}
-struct mbuf *
+struct ip6aux *
ip6_addaux(m)
struct mbuf *m;
{
- struct mbuf *n;
-
-#ifdef DIAGNOSTIC
- if (sizeof(struct ip6aux) > MHLEN)
- panic("assumption failed on sizeof(ip6aux)");
-#endif
- n = m_aux_find(m, AF_INET6, -1);
- if (n) {
- if (n->m_len < sizeof(struct ip6aux)) {
- printf("conflicting use of ip6aux");
- return NULL;
- }
- } else {
- n = m_aux_add(m, AF_INET6, -1);
- n->m_len = sizeof(struct ip6aux);
- bzero(mtod(n, caddr_t), n->m_len);
+ struct m_tag *tag = m_tag_find(m, PACKET_TAG_IPV6_INPUT, NULL);
+ if (!tag) {
+ tag = m_tag_get(PACKET_TAG_IPV6_INPUT,
+ sizeof (struct ip6aux),
+ M_NOWAIT);
+ if (tag)
+ m_tag_prepend(m, tag);
}
- return n;
+ if (tag)
+ bzero(tag+1, sizeof (struct ip6aux));
+ return tag ? (struct ip6aux*)(tag+1) : NULL;
}
-struct mbuf *
+struct ip6aux *
ip6_findaux(m)
struct mbuf *m;
{
- struct mbuf *n;
-
- n = m_aux_find(m, AF_INET6, -1);
- if (n && n->m_len < sizeof(struct ip6aux)) {
- printf("conflicting use of ip6aux");
- n = NULL;
- }
- return n;
+ struct m_tag *tag = m_tag_find(m, PACKET_TAG_IPV6_INPUT, NULL);
+ return tag ? (struct ip6aux*)(tag+1) : NULL;
}
void
ip6_delaux(m)
struct mbuf *m;
{
- struct mbuf *n;
-
- n = m_aux_find(m, AF_INET6, -1);
- if (n)
- m_aux_delete(m, n);
+ struct m_tag *tag = m_tag_find(m, PACKET_TAG_IPV6_INPUT, NULL);
+ if (tag)
+ m_tag_delete(m, tag);
}
/*
diff --git a/sys/netinet6/ip6_mroute.c b/sys/netinet6/ip6_mroute.c
index 786d088..ecb18c0 100644
--- a/sys/netinet6/ip6_mroute.c
+++ b/sys/netinet6/ip6_mroute.c
@@ -1449,7 +1449,7 @@ phyint_send(ip6, mifp, m)
im6o.im6o_multicast_hlim = ip6->ip6_hlim;
im6o.im6o_multicast_loop = 1;
error = ip6_output(mb_copy, NULL, &ro,
- IPV6_FORWARDING, &im6o, NULL);
+ IPV6_FORWARDING, &im6o, NULL, NULL);
#ifdef MRT6DEBUG
if (mrt6debug & DEBUG_XMIT)
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index bb3e079..63d676d 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -143,13 +143,14 @@ static int ip6_splithdr __P((struct mbuf *, struct ip6_exthdrs *));
* which is rt_rmx.rmx_mtu.
*/
int
-ip6_output(m0, opt, ro, flags, im6o, ifpp)
+ip6_output(m0, opt, ro, flags, im6o, ifpp, inp)
struct mbuf *m0;
struct ip6_pktopts *opt;
struct route_in6 *ro;
int flags;
struct ip6_moptions *im6o;
struct ifnet **ifpp; /* XXX: just for statistics */
+ struct inpcb *inp;
{
struct ip6_hdr *ip6, *mhip6;
struct ifnet *ifp, *origifp;
@@ -173,12 +174,9 @@ ip6_output(m0, opt, ro, flags, im6o, ifpp)
#endif /* PFIL_HOOKS */
#ifdef IPSEC
int needipsectun = 0;
- struct socket *so;
struct secpolicy *sp = NULL;
+ struct socket *so = inp ? inp->inp_socket : NULL;
- /* for AH processing. stupid to have "socket" variable in IP layer... */
- so = ipsec_getsocket(m);
- (void)ipsec_setsocket(m, NULL);
ip6 = mtod(m, struct ip6_hdr *);
#endif /* IPSEC */
diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h
index fdf709b..d16fd59 100644
--- a/sys/netinet6/ip6_var.h
+++ b/sys/netinet6/ip6_var.h
@@ -304,8 +304,8 @@ char * ip6_get_prevhdr __P((struct mbuf *, int));
int ip6_nexthdr __P((struct mbuf *, int, int, int *));
int ip6_lasthdr __P((struct mbuf *, int, int, int *));
-struct mbuf *ip6_addaux __P((struct mbuf *));
-struct mbuf *ip6_findaux __P((struct mbuf *));
+struct ip6aux *ip6_addaux __P((struct mbuf *));
+struct ip6aux *ip6_findaux __P((struct mbuf *));
void ip6_delaux __P((struct mbuf *));
int ip6_mforward __P((struct ip6_hdr *, struct ifnet *, struct mbuf *));
@@ -323,7 +323,8 @@ void ip6_mloopback __P((struct ifnet *, struct mbuf *, struct sockaddr_in6 *));
int ip6_output __P((struct mbuf *, struct ip6_pktopts *,
struct route_in6 *,
int,
- struct ip6_moptions *, struct ifnet **));
+ struct ip6_moptions *, struct ifnet **,
+ struct inpcb *));
int ip6_ctloutput __P((struct socket *, struct sockopt *sopt));
void init_ip6pktopts __P((struct ip6_pktopts *));
int ip6_setpktoptions __P((struct mbuf *, struct ip6_pktopts *, int, int));
diff --git a/sys/netinet6/ipsec.c b/sys/netinet6/ipsec.c
index 5a9e509..b91470e 100644
--- a/sys/netinet6/ipsec.c
+++ b/sys/netinet6/ipsec.c
@@ -221,9 +221,6 @@ static int ipsec4_encapsulate __P((struct mbuf *, struct secasvar *));
#ifdef INET6
static int ipsec6_encapsulate __P((struct mbuf *, struct secasvar *));
#endif
-static struct mbuf *ipsec_addaux __P((struct mbuf *));
-static struct mbuf *ipsec_findaux __P((struct mbuf *));
-static void ipsec_optaux __P((struct mbuf *, struct mbuf *));
/*
* For OUTBOUND packet having a socket. Searching SPD for packet,
@@ -3457,91 +3454,14 @@ ipsec_copypkt(m)
return(NULL);
}
-static struct mbuf *
-ipsec_addaux(m)
- struct mbuf *m;
-{
- struct mbuf *n;
-
- n = m_aux_find(m, AF_INET, IPPROTO_ESP);
- if (!n)
- n = m_aux_add(m, AF_INET, IPPROTO_ESP);
- if (!n)
- return n; /* ENOBUFS */
- n->m_len = sizeof(struct socket *);
- bzero(mtod(n, void *), n->m_len);
- return n;
-}
-
-static struct mbuf *
-ipsec_findaux(m)
- struct mbuf *m;
-{
- struct mbuf *n;
-
- n = m_aux_find(m, AF_INET, IPPROTO_ESP);
-#ifdef DIAGNOSTIC
- if (n && n->m_len < sizeof(struct socket *))
- panic("invalid ipsec m_aux");
-#endif
- return n;
-}
-
void
ipsec_delaux(m)
struct mbuf *m;
{
- struct mbuf *n;
-
- n = m_aux_find(m, AF_INET, IPPROTO_ESP);
- if (n)
- m_aux_delete(m, n);
-}
-
-/* if the aux buffer is unnecessary, nuke it. */
-static void
-ipsec_optaux(m, n)
- struct mbuf *m;
- struct mbuf *n;
-{
+ struct m_tag *tag;
- if (!n)
- return;
- if (n->m_len == sizeof(struct socket *) && !*mtod(n, struct socket **))
- ipsec_delaux(m);
-}
-
-int
-ipsec_setsocket(m, so)
- struct mbuf *m;
- struct socket *so;
-{
- struct mbuf *n;
-
- /* if so == NULL, don't insist on getting the aux mbuf */
- if (so) {
- n = ipsec_addaux(m);
- if (!n)
- return ENOBUFS;
- } else
- n = ipsec_findaux(m);
- if (n && n->m_len >= sizeof(struct socket *))
- *mtod(n, struct socket **) = so;
- ipsec_optaux(m, n);
- return 0;
-}
-
-struct socket *
-ipsec_getsocket(m)
- struct mbuf *m;
-{
- struct mbuf *n;
-
- n = ipsec_findaux(m);
- if (n && n->m_len >= sizeof(struct socket *))
- return *mtod(n, struct socket **);
- else
- return NULL;
+ while ((tag = m_tag_find(m, PACKET_TAG_IPSEC_HISTORY, NULL)) != NULL)
+ m_tag_delete(m, tag);
}
int
@@ -3550,19 +3470,18 @@ ipsec_addhist(m, proto, spi)
int proto;
u_int32_t spi;
{
- struct mbuf *n;
+ struct m_tag *tag;
struct ipsec_history *p;
- n = ipsec_addaux(m);
- if (!n)
+ tag = m_tag_get(PACKET_TAG_IPSEC_HISTORY,
+ sizeof (struct ipsec_history), M_NOWAIT);
+ if (tag == NULL)
return ENOBUFS;
- if (M_TRAILINGSPACE(n) < sizeof(*p))
- return ENOSPC; /* XXX */
- p = (struct ipsec_history *)(mtod(n, caddr_t) + n->m_len);
- n->m_len += sizeof(*p);
+ p = (struct ipsec_history *)(tag+1);
bzero(p, sizeof(*p));
p->ih_proto = proto;
p->ih_spi = spi;
+ m_tag_prepend(m, tag);
return 0;
}
@@ -3571,32 +3490,13 @@ ipsec_gethist(m, lenp)
struct mbuf *m;
int *lenp;
{
- struct mbuf *n;
- int l;
+ struct m_tag *tag;
- n = ipsec_findaux(m);
- if (!n)
+ tag = m_tag_find(m, PACKET_TAG_IPSEC_HISTORY, NULL);
+ if (tag == NULL)
return NULL;
- l = n->m_len;
- if (sizeof(struct socket *) > l)
- return NULL;
- if ((l - sizeof(struct socket *)) % sizeof(struct ipsec_history))
- return NULL;
- /* XXX does it make more sense to divide by sizeof(ipsec_history)? */
+ /* XXX NB: noone uses this so fake it */
if (lenp)
- *lenp = l - sizeof(struct socket *);
- return (struct ipsec_history *)
- (mtod(n, caddr_t) + sizeof(struct socket *));
-}
-
-void
-ipsec_clearhist(m)
- struct mbuf *m;
-{
- struct mbuf *n;
-
- n = ipsec_findaux(m);
- if ((n) && n->m_len > sizeof(struct socket *))
- n->m_len = sizeof(struct socket *);
- ipsec_optaux(m, n);
+ *lenp = sizeof (struct ipsec_history);
+ return ((struct ipsec_history *)(tag+1));
}
diff --git a/sys/netinet6/ipsec.h b/sys/netinet6/ipsec.h
index 20569a0..76790b8 100644
--- a/sys/netinet6/ipsec.h
+++ b/sys/netinet6/ipsec.h
@@ -336,11 +336,8 @@ extern int ipsec4_tunnel_validate __P((struct mbuf *, int, u_int,
struct secasvar *));
extern struct mbuf *ipsec_copypkt __P((struct mbuf *));
extern void ipsec_delaux __P((struct mbuf *));
-extern int ipsec_setsocket __P((struct mbuf *, struct socket *));
-extern struct socket *ipsec_getsocket __P((struct mbuf *));
extern int ipsec_addhist __P((struct mbuf *, int, u_int32_t));
extern struct ipsec_history *ipsec_gethist __P((struct mbuf *, int *));
-extern void ipsec_clearhist __P((struct mbuf *));
#endif /* _KERNEL */
#ifndef _KERNEL
diff --git a/sys/netinet6/mld6.c b/sys/netinet6/mld6.c
index b35d10d..61c0e0c 100644
--- a/sys/netinet6/mld6.c
+++ b/sys/netinet6/mld6.c
@@ -456,7 +456,7 @@ mld6_sendpkt(in6m, type, dst)
/* increment output statictics */
icmp6stat.icp6s_outhist[type]++;
- ip6_output(mh, &ip6_opts, NULL, 0, &im6o, &outif);
+ ip6_output(mh, &ip6_opts, NULL, 0, &im6o, &outif, NULL);
if (outif) {
icmp6_ifstat_inc(outif, ifs6_out_msg);
switch (type) {
diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c
index 1b1f7dc9..88af7ce 100644
--- a/sys/netinet6/nd6_nbr.c
+++ b/sys/netinet6/nd6_nbr.c
@@ -504,11 +504,7 @@ nd6_ns_output(ifp, daddr6, taddr6, ln, dad)
nd_ns->nd_ns_cksum
= in6_cksum(m, IPPROTO_ICMPV6, sizeof(*ip6), icmp6len);
-#ifdef IPSEC
- /* Don't lookup socket */
- (void)ipsec_setsocket(m, NULL);
-#endif
- ip6_output(m, NULL, NULL, dad ? IPV6_DADOUTPUT : 0, &im6o, &outif);
+ ip6_output(m, NULL, NULL, dad ? IPV6_DADOUTPUT : 0, &im6o, &outif, NULL);
if (outif) {
icmp6_ifstat_inc(outif, ifs6_out_msg);
icmp6_ifstat_inc(outif, ifs6_out_neighborsolicit);
@@ -952,11 +948,7 @@ nd6_na_output(ifp, daddr6, taddr6, flags, tlladdr, sdl0)
nd_na->nd_na_cksum =
in6_cksum(m, IPPROTO_ICMPV6, sizeof(struct ip6_hdr), icmp6len);
-#ifdef IPSEC
- /* Don't lookup socket */
- (void)ipsec_setsocket(m, NULL);
-#endif
- ip6_output(m, NULL, NULL, 0, &im6o, &outif);
+ ip6_output(m, NULL, NULL, 0, &im6o, &outif, NULL);
if (outif) {
icmp6_ifstat_inc(outif, ifs6_out_msg);
icmp6_ifstat_inc(outif, ifs6_out_neighboradvert);
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index c4652af..6d4cc22 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -445,15 +445,8 @@ rip6_output(m, va_alist)
*p = in6_cksum(m, ip6->ip6_nxt, sizeof(*ip6), plen);
}
-#ifdef IPSEC
- if (ipsec_setsocket(m, so) != 0) {
- error = ENOBUFS;
- goto bad;
- }
-#endif /*IPSEC*/
-
error = ip6_output(m, optp, &in6p->in6p_route, 0,
- in6p->in6p_moptions, &oifp);
+ in6p->in6p_moptions, &oifp, in6p);
if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) {
if (oifp)
icmp6_ifoutstat_inc(oifp, type, code);
diff --git a/sys/netinet6/route6.c b/sys/netinet6/route6.c
index f3fe83d..f2575bc 100644
--- a/sys/netinet6/route6.c
+++ b/sys/netinet6/route6.c
@@ -60,11 +60,10 @@ route6_input(mp, offp, proto)
struct mbuf *m = *mp;
struct ip6_rthdr *rh;
int off = *offp, rhlen;
- struct mbuf *n;
+ struct ip6aux *ip6a;
- n = ip6_findaux(m);
- if (n) {
- struct ip6aux *ip6a = mtod(n, struct ip6aux *);
+ ip6a = ip6_findaux(m);
+ if (ip6a) {
/* XXX reject home-address option before rthdr */
if (ip6a->ip6a_flags & IP6A_SWAP) {
ip6stat.ip6s_badoptions++;
diff --git a/sys/netinet6/udp6_output.c b/sys/netinet6/udp6_output.c
index 35597fd..1de45f0 100644
--- a/sys/netinet6/udp6_output.c
+++ b/sys/netinet6/udp6_output.c
@@ -290,14 +290,8 @@ udp6_output(in6p, m, addr6, control, td)
flags = 0;
udp6stat.udp6s_opackets++;
-#ifdef IPSEC
- if (ipsec_setsocket(m, in6p->in6p_socket) != 0) {
- error = ENOBUFS;
- goto release;
- }
-#endif /* IPSEC */
error = ip6_output(m, in6p->in6p_outputopts, &in6p->in6p_route,
- flags, in6p->in6p_moptions, NULL);
+ flags, in6p->in6p_moptions, NULL, in6p);
break;
case AF_INET:
error = EAFNOSUPPORT;
OpenPOWER on IntegriCloud