The new API (mptr, mptr_rw, m_datarange and m_datarange_rw) was implemented, together with the new concept of guaranteed contiguous regions (parts of a mbuf which were once made contiguous and need to remain so). The existing m_pullup, m_pulldown, m_makewritable and m_copyback_cow functions were changed to respect guaranteed contiguous regions. m_copyback_cow was also taught to extend the mbuf, making easier to replace m_copyback with it.

The IPv4, IPv6 and link-layer protocols are converted to use the new API and constified where possible. As a result, they should be read-only mbuf safe. This was tested in a Xen 2 domU, where the xennet driver produces mbufs marked as read-only. With a patch from Manuel Bouyer it is possible to map the external storage read-only and catch any writes to the read-only area. I've tested TCP, UDP and ICMP for both IPv4 and IPv6 ad they work with this patch. I've tested some common cases which need to write to the mbufs: IP options (source-routing and record route), IPv6 link-local adresses (where the KAME implementation stores the scope ID in the address), fragmentation and reassembly, and TCP. This will hopefully enable a more efficient implementation of a Xen 3 backend driver.

IPv4 and IPv6 were also converted to the convention that the input routines make the packet contiguous for such a length to include all the protocol headers.

A documentation of the new API has been added to the mbuf(9) man page, and a summary of its limitations has been written.

A possibly interesting result of this project is the ability of testing the kernel code in userland, see here for details. I'm not aware for any previous work in this area for NetBSD. During the project it proved very convenient for finding and fixing bugs in the implementation of the new API, maybe it could find more applications in the future.

Due to the lack of time (converting such a large volume of code was more difficult than I suspected), I haven't finished any of the optional parts of the projects. For m_tags, I did an analysis of current uses of this API, which could serve as a guideline for converting the code later.

For IPFilter, I also did a summary of its current use of mbuf routines. Unfortunately, IPFilter assumes that the variables in the IP header are in host byte order, so it is a question how much benefit is from making it read-only mbuf safe, if the mbuf must be made writable at the entry to IPFilter code (fr_check_wrapper function) anyway.

Some ideas about making struct mbuf opaque are here.