Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 3 Feb 2012 06:34:57 +0900
From:      rozhuk.im@gmail.com
To:        "'Navdeep Parhar'" <nparhar@gmail.com>
Cc:        freebsd-net@freebsd.org
Subject:   RE: m_pullup - fail
Message-ID:  <4f2b0188.82b7cc0a.2dad.ffff88e9@mx.google.com>
In-Reply-To: <CAPFoGT_6Qp-_qtQ4bDM6VMwG8D4P6m5JYjy5zoUXAZ1aFQBTdQ@mail.gmail.com>
References:  <4f298d95.82b7cc0a.49b2.5d24@mx.google.com> <CAPFoGT_6Qp-_qtQ4bDM6VMwG8D4P6m5JYjy5zoUXAZ1aFQBTdQ@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help

The function does not allow access to data if m_flags & M_EXT size and more
MHLEN, although the data is actually available.

Why if there is no m_flags & M_PKTHDR size anyway MHLEN instead MLEN?

As an improvement, you can try to copy the data from the current m in
m_next, if m is not enough space and enough m_next (case m_flags & M_EXT).


If I figured out MBUF then m_pullup should take maximum length according to
this macro

#define	M_PULLUP_MAX(m)							\
	((m)->m_flags & M_EXT ?						\
	    (M_WRITABLE(m) ? (m)->m_ext.ext_size : 0) :			\
	    (m)->m_flags & M_PKTHDR ? MHLEN : MLEN )



/usr/src/sys/sys/param.h:#define MSIZE          256             /* size of
an mbuf */
/usr/src/sys/sys/mbuf.h:#define MLEN            (MSIZE - sizeof(struct
m_hdr))  /* normal data len */
/usr/src/sys/sys/mbuf.h:#define MHLEN           (MLEN - sizeof(struct
pkthdr))  /* data len w/pkthdr */ 

#define	M_EXT		0x00000001 /* has associated external storage */

	/*
	 * If first mbuf has no cluster, and has room for len bytes
	 * without shifting current data, pullup into it,
	 * otherwise allocate a new mbuf to prepend to the chain.
	 */
	if ((n->m_flags & M_EXT) == 0 &&
	    n->m_data + len < &n->m_dat[MLEN] && n->m_next) {
		if (n->m_len >= len)
			return (n);
		m = n;
		n = n->m_next;
		len -= m->m_len;
	} else {
		if (len > MHLEN)
			goto bad;
		MGET(m, M_DONTWAIT, n->m_type);
		if (m == NULL)
			goto bad;
		m->m_len = 0;
		if (n->m_flags & M_PKTHDR)
			M_MOVE_PKTHDR(m, n);
	}



> -----Original Message-----
> From: Navdeep Parhar [mailto:nparhar@gmail.com]
> Sent: Thursday, February 02, 2012 3:54 PM
> To: Rozhuk.IM@gmail.com
> Cc: freebsd-net@freebsd.org
> Subject: Re: m_pullup - fail
> 
> On Wed, Feb 1, 2012 at 11:07 AM,  <rozhuk.im@gmail.com> wrote:
> > Hello!
> >
> >
> > The function always returns an error and remove the chain MBUF for
> two
> > or more generated on the same host.
> > If the pre-call m_defrag no error occurs.
> > This is normal behavior?
> > How to know in advance the maximum size for MBUF that does not cause
> a
> > failure in m_pullup?
> 
> You can't pullup more than MHLEN bytes into a pkthdr mbuf if it's not
> associated with an external cluster.  See the last sentence in this
> excerpt from mbuf(9):
> 
>            m_pullup(mbuf, len)
>            Arrange that the first len bytes of an mbuf chain are
> contiguous
>            and lay in the data area of mbuf, so they are accessible
> with
>            mtod(mbuf, type).  It is important to remember that this may
>            involve reallocating some mbufs and moving data so all
> pointers
>            referencing data within the old mbuf chain must be
> recalculated or
>            made invalid.  Return the new mbuf chain on success, NULL on
> fail-
>            ure (the mbuf chain is freed in this case).  Note: It does
> not
>            allocate any mbuf clusters, so len must be less than MHLEN.
> 
> Regards,
> Navdeep
> >
> >
> > mbuf: 0xfffffe0074fc0600 len: 42, next: 0xfffffe0073a45800, 2<pkthdr>
> > mbuf: 0xfffffe0073a45800 len: 210, next: 0, 1<ext>
> > FAIL: m_pullup: m_pkthdr.len = 252, m_len = 42, pullup_len = 252
> >
> >
> >
> > _______________________________________________
> > freebsd-net@freebsd.org mailing list
> > http://lists.freebsd.org/mailman/listinfo/freebsd-net
> > To unsubscribe, send any mail to "freebsd-net-
> unsubscribe@freebsd.org"




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4f2b0188.82b7cc0a.2dad.ffff88e9>