Small patch to multicast code...
gnn at freebsd.org
gnn at freebsd.org
Thu Aug 21 21:59:51 UTC 2008
At Thu, 21 Aug 2008 22:35:19 +0200,
Luigi Rizzo wrote:
>
> On Thu, Aug 21, 2008 at 03:11:56PM -0400, gnn at freebsd.org wrote:
> > Hi,
> >
> > Turns out there is a bug in the code that loops back multicast
> > packets. If the underlying device driver supports checksum offloading
> > then the packet that is looped back, when it is transmitted on the
> > wire, is incorrect, due to the fact that the packet is not fully
> > copied.
> >
> > Here is a patch. Comments welcome.
> >
> > Best,
> > George
> >
> > Index: ip_output.c
> > ===================================================================
> > --- ip_output.c (revision 181731)
> > +++ ip_output.c (working copy)
> > @@ -1135,7 +1135,7 @@
> > register struct ip *ip;
> > struct mbuf *copym;
> >
> > - copym = m_copy(m, 0, M_COPYALL);
> > + copym = m_dup(m, M_DONTWAIT);
> > if (copym != NULL && (copym->m_flags & M_EXT || copym->m_len < hlen))
> > copym = m_pullup(copym, hlen);
> > if (copym != NULL) {
>
> I am slightly puzzled -- what is exactly the problem, i.e. what part
> of the packet on the wire is incorrect ? The IP header is within hlen so
> the m_pullup() should be enough to leave the original content intact.
>
> The only thing i can think of is that it's the UDP checksum,
> residing beyond hlen, which is overwritten somewhere in the
> call to if_simloop -- in which case perhaps a better fix is
> to m_pullup() the udp header as well ?
It is the checksum that gets trashed, yes.
> (in any case, it is worthwhile to add a comment to explain
> what should be done -- the code paths using m_*() have become
> quite fragile with these hw support enhancements that now
> require selective modifications on previously shared, readonly buffers).
The m_*() routines actually have reasonable comments, it just seems
the wrong one was used here.
Best,
Gerge
More information about the freebsd-net
mailing list