Subject: Re: patch: handle shared/read-only ipv6+icmp6 mbuf storage
To: None <tech-net@netbsd.org>
From: Manuel Bouyer <bouyer@antioche.eu.org>
List: tech-net
Date: 04/04/2006 21:28:59
On Thu, Mar 30, 2006 at 02:37:03PM -0600, David Young wrote:
> [...]
> Index: ip6_input.c
> ===================================================================
> RCS file: /cvsroot/src/sys/netinet6/ip6_input.c,v
> retrieving revision 1.83
> diff -u -p -u -p -r1.83 ip6_input.c
> --- ip6_input.c 5 Mar 2006 23:47:08 -0000 1.83
> +++ ip6_input.c 30 Mar 2006 19:27:16 -0000
> @@ -234,7 +234,7 @@ void
> ip6_input(m)
> struct mbuf *m;
> {
> - struct ip6_hdr *ip6;
> + struct ip6_hdr *ip6, *tmp;
> int off = sizeof(struct ip6_hdr), nest;
> u_int32_t plen;
> u_int32_t rtalert = ~0;
> @@ -305,7 +305,27 @@ ip6_input(m)
> }
> }
>
> - ip6 = mtod(m, struct ip6_hdr *);
> + /* If we will embed a scope identifier in either the source or
> + * destination address or both, then make them both writable.
> + * We have to do this to avoid scribbling over read-only/shared
> + * mbuf storage.
> + *
> + * XXX It may be possible to do this nearer to the place
> + * XXX where the src & dst are rewritten, per Manuel Bouyer's
> + * XXX suggestion on tech-net.
> + */
> + tmp = mtod(m, struct ip6_hdr *);
> + if (!(IN6_IS_SCOPE_EMBEDDABLE(&tmp->ip6_src) ||
> + IN6_IS_SCOPE_EMBEDDABLE(&tmp->ip6_dst)))
> + ip6 = tmp;
> + else if (m_makewritable(&m, 0, sizeof(struct ip6_hdr),
> + M_DONTWAIT) != 0) {
> + struct ifnet *inifp = m->m_pkthdr.rcvif;
> + ip6stat.ip6s_toosmall++; /* XXXDCY new stat */
> + in6_ifstat_inc(inifp, ifs6_in_hdrerr); /* XXXDCY new stat */
> + goto bad;
As I already said, I think you should move this check later in the code,
when we're actually going to the mbuf (i.e. just before the call to
in6_setscope). The packet may actually be dropped before reaching
in6_setscope() and copying it in this case would be a waste of ressources.
--
Manuel Bouyer <bouyer@antioche.eu.org>
NetBSD: 26 ans d'experience feront toujours la difference
--