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:npar...@gmail.com]
> Sent: Thursday, February 02, 2012 3:54 PM
> To: rozhuk...@gmail.com
> Cc: freebsd-net@freebsd.org
> Subject: Re: m_pullup - fail
> 
> On Wed, Feb 1, 2012 at 11:07 AM,  <rozhuk...@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-
> unsubscr...@freebsd.org"

_______________________________________________
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"

Reply via email to