diff options
author | sam <sam@FreeBSD.org> | 2002-10-16 01:54:46 +0000 |
---|---|---|
committer | sam <sam@FreeBSD.org> | 2002-10-16 01:54:46 +0000 |
commit | 2a86be217a6aed33eda6628df2b175e49172cd9f (patch) | |
tree | b26e1e9f49b40642051748bcd3961cc2a2b5ff1d /sys/netinet6 | |
parent | 733bfbdd78ddb9efc129532b2c2239d0bacfaf1a (diff) | |
download | FreeBSD-src-2a86be217a6aed33eda6628df2b175e49172cd9f.zip FreeBSD-src-2a86be217a6aed33eda6628df2b175e49172cd9f.tar.gz |
Replace aux mbufs with packet tags:
o instead of a list of mbufs use a list of m_tag structures a la openbsd
o for netgraph et. al. extend the stock openbsd m_tag to include a 32-bit
ABI/module number cookie
o for openbsd compatibility define a well-known cookie MTAG_ABI_COMPAT and
use this in defining openbsd-compatible m_tag_find and m_tag_get routines
o rewrite KAME use of aux mbufs in terms of packet tags
o eliminate the most heavily used aux mbufs by adding an additional struct
inpcb parameter to ip_output and ip6_output to allow the IPsec code to
locate the security policy to apply to outbound packets
o bump __FreeBSD_version so code can be conditionalized
o fixup ipfilter's call to ip_output based on __FreeBSD_version
Reviewed by: julian, luigi (silent), -arch, -net, darren
Approved by: julian, silence from everyone else
Obtained from: openbsd (mostly)
MFC after: 1 month
Diffstat (limited to 'sys/netinet6')
-rw-r--r-- | sys/netinet6/icmp6.c | 14 | ||||
-rw-r--r-- | sys/netinet6/in6_gif.c | 4 | ||||
-rw-r--r-- | sys/netinet6/ip6_input.c | 61 | ||||
-rw-r--r-- | sys/netinet6/ip6_mroute.c | 2 | ||||
-rw-r--r-- | sys/netinet6/ip6_output.c | 8 | ||||
-rw-r--r-- | sys/netinet6/ip6_var.h | 7 | ||||
-rw-r--r-- | sys/netinet6/ipsec.c | 130 | ||||
-rw-r--r-- | sys/netinet6/ipsec.h | 3 | ||||
-rw-r--r-- | sys/netinet6/mld6.c | 2 | ||||
-rw-r--r-- | sys/netinet6/nd6_nbr.c | 12 | ||||
-rw-r--r-- | sys/netinet6/raw_ip6.c | 9 | ||||
-rw-r--r-- | sys/netinet6/route6.c | 7 | ||||
-rw-r--r-- | sys/netinet6/udp6_output.c | 8 |
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; |