blob: 1b3b1b740708b3f7814fc6807a6750e80a71b49d [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mbufs &mdash; Apache Mynewt latest documentation</title>
<link rel="shortcut icon" href="../../../_static/mynewt-logo-only-newt32x32.png"/>
<link rel="stylesheet" href="../../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/css/sphinx_theme.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/css/bootstrap-3.0.3.min.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/css/v2.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/css/custom.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/css/restructuredtext.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/css/overrides.css" type="text/css" />
<link rel="index" title="Index"
href="../../../genindex.html"/>
<link rel="search" title="Search" href="../../../search.html"/>
<link rel="top" title="Apache Mynewt latest documentation" href="../../../index.html"/>
<link rel="up" title="Apache Mynewt Operating System Kernel" href="../mynewt_os.html"/>
<link rel="next" title="CPU Time" href="../cputime/os_cputime.html"/>
<link rel="prev" title="Memory Pools" href="../memory_pool/memory_pool.html"/>
<script src="../../../_static/js/modernizr.min.js"></script>
<script>
(function(i, s, o, g, r, a, m) {
i["GoogleAnalyticsObject"] = r;
(i[r] =
i[r] ||
function() {
(i[r].q = i[r].q || []).push(arguments);
}),
(i[r].l = 1 * new Date());
(a = s.createElement(o)), (m = s.getElementsByTagName(o)[0]);
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m);
})(window, document, "script", "//www.google-analytics.com/analytics.js", "ga");
ga("create", "UA-72162311-1", "auto");
ga("send", "pageview");
</script>
</head>
<body class="not-front page-documentation" role="document" >
<div id="wrapper">
<div class="container">
<div id="banner" class="row v2-main-banner">
<a class="logo-cell" href="/">
<img class="logo" src="../../../_static/img/logo.png">
</a>
<div class="tagline-cell">
<h4 class="tagline">An OS to build, deploy and securely manage billions of devices</h4>
</div>
<div class="news-cell">
<div class="well">
<h4>Latest News:</h4> <a href="/download">Apache Mynewt 1.11.0, Apache NimBLE 1.6.0 </a> released September 7, 2023)
</div>
</div>
</div>
</div>
<header>
<nav id="navbar" class="navbar navbar-inverse" role="navigation">
<div class="container">
<!-- Collapsed navigation -->
<div class="navbar-header">
<!-- Expander button -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<!-- Expanded navigation -->
<div class="navbar-collapse collapse">
<!-- Main navigation -->
<ul class="nav navbar-nav navbar-right">
<li>
<a href="/"><i class="fa fa-home" style="font-size: larger;"></i></a>
</li>
<li class="important">
<a href="/quick-start/">Quick Start</a>
</li>
<li>
<a href="/about/">About</a>
</li>
<li>
<a href="/talks/">Talks</a>
</li>
<li class="active">
<a href="/documentation/">Documentation</a>
</li>
<li>
<a href="/download/">Download</a>
</li>
<li>
<a href="/community/">Community</a>
</li>
<li>
<a href="/events/">Events</a>
</li>
</ul>
<!-- Search, Navigation and Repo links -->
<ul class="nav navbar-nav navbar-right">
</ul>
</div>
</div>
</nav>
</header>
<!-- STARTS MAIN CONTENT -->
<div id="main-content">
<div id="breadcrumb">
<div class="container">
<a href="/documentation/">Docs</a> /
<a href="../../os_user_guide.html">OS User Guide</a> /
<a href="../mynewt_os.html">Apache Mynewt Operating System Kernel</a> /
Mbufs
<div class="sourcelink">
<a href="https://github.com/apache/mynewt-core/edit/master/docs/os/core_os/mbuf/mbuf.rst" class="icon icon-github"
rel="nofollow"> Edit on GitHub</a>
</div>
</div>
</div>
<!-- STARTS CONTAINER -->
<div class="container">
<!-- STARTS .content -->
<div id="content" class="row">
<!-- STARTS .container-sidebar -->
<div class="container-sidebar col-xs-12 col-sm-3">
<div id="docSidebar" class="sticky-container">
<div role="search" class="sphinx-search">
<form id="rtd-search-form" class="wy-form" action="../../../search.html" method="get">
<input type="text" name="q" placeholder="Search documentation" class="search-documentation" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
<!-- Note: only works when deployed -->
<select class="form-control" onchange="if (this.value) window.location.href=this.value">
<option value="/latest" selected>
Version: latest
</option>
<option value="/v1_11_0" >
Version: 1.11.0
</option>
<option value="/v1_10_0" >
Version: 1.10.0
</option>
<option value="/v1_9_0" >
Version: 1.9.0
</option>
<option value="/v1_8_0" >
Version: 1.8.0
</option>
<option value="/v1_7_0" selected="selected" >
Version: 1.7.0
</option>
<option value="/v1_6_0" >
Version: 1.6.0
</option>
<option value="/v1_5_0" >
Version: 1.5.0
</option>
<option value="/v1_4_0" >
Version: 1.4.0
</option>
<option value="/v1_3_0/os/introduction" >
Version: 1.3.0
</option>
<option value="/v1_2_0/os/introduction" >
Version: 1.2.0
</option>
<option value="/v1_1_0/os/introduction" >
Version: 1.1.0
</option>
<option value="/v1_0_0/os/introduction" >
Version: 1.0.0
</option>
<option value="/v0_9_0/os/introduction" >
Version: 0.9.0
</option>
</select>
<div class="region region-sidebar">
<div class="docs-menu">
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../../index.html">Introduction</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../get_started/index.html">Setup &amp; Get Started</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../concepts.html">Concepts</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../tutorials/tutorials.html">Tutorials</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../external_links.html">Third-party Resources</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../../os_user_guide.html">OS User Guide</a><ul class="current">
<li class="toctree-l2 current"><a class="reference internal" href="../mynewt_os.html">Kernel</a><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="../context_switch/context_switch.html">Scheduler</a></li>
<li class="toctree-l3"><a class="reference internal" href="../task/task.html">Task</a></li>
<li class="toctree-l3"><a class="reference internal" href="../mutex/mutex.html">Mutex</a></li>
<li class="toctree-l3"><a class="reference internal" href="../semaphore/semaphore.html">Semaphore</a></li>
<li class="toctree-l3"><a class="reference internal" href="../event_queue/event_queue.html">Event Queues</a></li>
<li class="toctree-l3"><a class="reference internal" href="../callout/callout.html">Callout</a></li>
<li class="toctree-l3"><a class="reference internal" href="../heap/heap.html">Heap</a></li>
<li class="toctree-l3"><a class="reference internal" href="../memory_pool/memory_pool.html">Memory Pools</a></li>
<li class="toctree-l3 current"><a class="current reference internal" href="#">Mbufs</a></li>
<li class="toctree-l3"><a class="reference internal" href="../cputime/os_cputime.html">CPU Time</a></li>
<li class="toctree-l3"><a class="reference internal" href="../time/os_time.html">OS Time</a></li>
<li class="toctree-l3"><a class="reference internal" href="../sanity/sanity.html">Sanity</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/system_modules.html">System</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/hal/hal.html">Hardware Abstraction</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/bootloader/bootloader.html">Secure Bootloader</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/split/split.html">Split Images</a></li>
<li class="toctree-l2"><a class="reference internal" href="../porting/port_os.html">Porting Guide</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/baselibc.html">Baselibc</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/drivers/driver.html">Drivers</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/devmgmt/newtmgr.html">Device Management with Newt Manager</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/mcumgr/mcumgr.html">Device Management with MCUmgr</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/imgmgr/imgmgr.html">Image Manager</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/sysinitconfig/sysinitconfig.html">Compile-Time Configuration</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/fs/fs.html">File System</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/fcb/fcb.html">Flash Circular Buffer</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/sensor_framework/sensor_framework.html">Sensor Framework</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/testutil/testutil.html">Test Utilities</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/json/json.html">JSON</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../modules/mfg/mfg.html">Manufacturing support</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../../network/index.html">BLE User Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../newt/index.html">Newt Tool Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../newtmgr/index.html">Newt Manager Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../mynewt_faq/index.html">Mynewt FAQ</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../misc/index.html">Appendix</a></li>
</ul>
</div>
</div>
</div>
<!-- ENDS STICKY CONTAINER -->
</div>
<!-- ENDS .container-sidebar -->
<div class="col-xs-12 col-sm-9">
<div class="alert alert-warning">
<p>
Version 1.7.0 is not the most recent version of the
Apache Mynewt documentation. Click <a href="/latest">here</a> to
read the latest version.
</p>
</div>
<div class="">
<div class="rst-content">
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="mbufs">
<h1>Mbufs<a class="headerlink" href="#mbufs" title="Permalink to this headline"></a></h1>
<p>The mbuf (short for memory buffer) is a common concept in networking
stacks. The mbuf is used to hold packet data as it traverses the stack.
The mbuf also generally stores header information or other networking
stack information that is carried around with the packet. The mbuf and
its associated library of functions were developed to make common
networking stack operations (like stripping and adding protocol headers)
efficient and as copy-free as possible.</p>
<p>In its simplest form, an mbuf is a memory block with some space reserved
for internal information and a pointer which is used to “chain” memory
blocks together in order to create a “packet”. This is a very important
aspect of the mbuf: the ability to chain mbufs together to create larger
“packets” (chains of mbufs).</p>
<div class="section" id="why-use-mbufs">
<h2>Why use mbufs?<a class="headerlink" href="#why-use-mbufs" title="Permalink to this headline"></a></h2>
<p>The main reason is to conserve memory. Consider a networking protocol
that generally sends small packets but occasionally sends large ones.
The Bluetooth Low Energy (BLE) protocol is one such example. A flat
buffer would need to be sized so that the maximum packet size could be
contained by the buffer. With the mbuf, a number of mbufs can be chained
together so that the occasional large packet can be handled while
leaving more packet buffers available to the networking stack for
smaller packets.</p>
</div>
<div class="section" id="packet-header-mbuf">
<h2>Packet Header mbuf<a class="headerlink" href="#packet-header-mbuf" title="Permalink to this headline"></a></h2>
<p>Not all mbufs are created equal. The first mbuf in a chain of mbufs is a
special mbuf called a “packet header mbuf”. The reason that this mbuf is
special is that it contains the length of all the data contained by the
chain of mbufs (the packet length, in other words). The packet header
mbuf may also contain a user defined structure (called a “user header”)
so that networking protocol specific information can be conveyed to
various layers of the networking stack. Any mbufs that are part of the
packet (i.e. in the mbuf chain but not the first one) are “normal” (i.e.
non-packet header) mbufs. A normal mbuf does not have any packet header
or user packet header structures in them; they only contain the basic
mbuf header (<code class="xref c c-type docutils literal notranslate"><span class="pre">struct</span> <span class="pre">os_mbuf</span></code>). Figure 1 illustrates these two types
of mbufs. Note that the numbers/text in parentheses denote the size of
the structures/elements (in bytes) and that MBLEN is the memory block
length of the memory pool used by the mbuf pool.</p>
<div class="figure align-default" id="id1">
<img alt="Packet header mbuf" src="../../../_images/mbuf_fig1.png" />
<p class="caption"><span class="caption-text">Packet header mbuf</span><a class="headerlink" href="#id1" title="Permalink to this image"></a></p>
</div>
</div>
<div class="section" id="normal-mbuf">
<h2>Normal mbuf<a class="headerlink" href="#normal-mbuf" title="Permalink to this headline"></a></h2>
<p>Now let’s take a deeper dive into the mbuf structure. Figure 2
illustrates a normal mbuf and breaks out the various fields in the
c:type:<cite>os_mbuf</cite> structure.</p>
<ul class="simple">
<li><p>The <code class="xref c c-member docutils literal notranslate"><span class="pre">om_data</span></code> field is a pointer to where the data starts inside the
data buffer. Typically, mbufs that are allocated from the mbuf pool
(discussed later) have their <code class="xref c c-member docutils literal notranslate"><span class="pre">om_data</span></code> pointer set to the start of the
data buffer but there are cases where this may not be desirable
(added a protocol header to a packet, for example).</p></li>
<li><p>The <code class="xref c c-member docutils literal notranslate"><span class="pre">om_flags</span></code> field is a set of flags used internally by the mbuf
library. Currently, no flags have been defined.</p></li>
<li><p>The <code class="xref c c-member docutils literal notranslate"><span class="pre">om_pkthdr_len</span></code> field is the total length of all packet headers
in the mbuf. For normal mbufs this is set to 0 as there is no packet
or user packet headers. For packet header mbufs, this would be set to
the length of the packet header structure (16) plus the size of the
user packet header (if any). Note that it is this field which
differentiates packet header mbufs from normal mbufs (i.e. if
<code class="xref c c-member docutils literal notranslate"><span class="pre">om_pkthdr_len</span></code> is zero, this is a normal mbuf; otherwise it is a
packet header mbuf).</p></li>
<li><p>The <code class="xref c c-member docutils literal notranslate"><span class="pre">om_len</span></code> field contains the amount of user data in the data
buffer. When initially allocated, this field is 0 as there is no user
data in the mbuf.</p></li>
<li><p>The <code class="xref c c-member docutils literal notranslate"><span class="pre">omp_pool</span></code> field is a pointer to the pool from which this mbuf
has been allocated. This is used internally by the mbuf library.</p></li>
<li><p>The <code class="xref c c-member docutils literal notranslate"><span class="pre">omp_next</span></code> field is a linked list element which is used to chain
mbufs.</p></li>
</ul>
<p>Figure 2 also shows a normal mbuf with actual values in the <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><code class="xref c c-type docutils literal notranslate"><span class="pre">os_mbuf</span></code></a>
structure. This mbuf starts at address 0x1000 and is 256 bytes in total
length. In this example, the user has copied 33 bytes into the data
buffer starting at address 0x1010 (this is where <code class="xref c c-member docutils literal notranslate"><span class="pre">om_data</span></code> points). Note
that the packet header length in this mbuf is 0 as it is not a packet
header mbuf.</p>
<div class="figure align-default" id="id2">
<img alt="OS mbuf structure" src="../../../_images/mbuf_fig2.png" />
<p class="caption"><span class="caption-text">OS mbuf structure</span><a class="headerlink" href="#id2" title="Permalink to this image"></a></p>
</div>
<p>Figure 3 illustrates the packet header mbuf along with some chained
mbufs (i.e a “packet”). In this example, the user header structure is
defined to be 8 bytes. Note that in figure 3 we show a number of
different mbufs with varying <code class="xref c c-member docutils literal notranslate"><span class="pre">om_data</span></code> pointers and lengths since we
want to show various examples of valid mbufs. For all the mbufs (both
packet header and normal ones) the total length of the memory block is
128 bytes.</p>
<div class="figure align-default" id="id3">
<img alt="Packet" src="../../../_images/mbuf_fig3.png" />
<p class="caption"><span class="caption-text">Packet</span><a class="headerlink" href="#id3" title="Permalink to this image"></a></p>
</div>
</div>
<div class="section" id="mbuf-pools">
<h2>Mbuf pools<a class="headerlink" href="#mbuf-pools" title="Permalink to this headline"></a></h2>
<p>Mbufs are collected into “mbuf pools” much like memory blocks. The mbuf
pool itself contains a pointer to a memory pool. The memory blocks in
this memory pool are the actual mbufs; both normal and packet header
mbufs. Thus, the memory block (and corresponding memory pool) must be
sized correctly. In other words, the memory blocks which make up the
memory pool used by the mbuf pool must be at least: sizeof(struct
os_mbuf) + sizeof(struct os_mbuf_pkthdr) + sizeof(struct
user_defined_header) + desired minimum data buffer length. For
example, if the developer wants mbufs to contain at least 64 bytes of
user data and they have a user header of 12 bytes, the size of the
memory block would be (at least): 64 + 12 + 16 + 8, or 100 bytes. Yes,
this is a fair amount of overhead. However, the flexibility provided by
the mbuf library usually outweighs overhead concerns.</p>
</div>
<div class="section" id="create-mbuf-pool">
<h2>Create mbuf pool<a class="headerlink" href="#create-mbuf-pool" title="Permalink to this headline"></a></h2>
<p>Creating an mbuf pool is fairly simple: create a memory pool and then
create the mbuf pool using that memory pool. Once the developer has
determined the size of the user data needed per mbuf (this is based on
the application/networking stack and is outside the scope of this
discussion) and the size of the user header (if any), the memory blocks
can be sized. In the example shown below, the application requires 64
bytes of user data per mbuf and also allocates a user header (called
struct user_hdr). Note that we do not show the user header data
structure as there really is no need; all we need to do is to account
for it when creating the memory pool. In the example, we use the macro
<em>MBUF_PKTHDR_OVERHEAD</em> to denote the amount of packet header overhead
per mbuf and <em>MBUF_MEMBLOCK_OVERHEAD</em> to denote the total amount of
overhead required per memory block. The macro <em>MBUF_BUF_SIZE</em> is used
to denote the amount of payload that the application requires (aligned
on a 32-bit boundary in this case). All this leads to the total memory
block size required, denoted by the macro <em>MBUF_MEMBLOCK_OVERHEAD</em>.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#define MBUF_PKTHDR_OVERHEAD sizeof(struct os_mbuf_pkthdr) + sizeof(struct user_hdr)</span>
<span class="cp">#define MBUF_MEMBLOCK_OVERHEAD sizeof(struct os_mbuf) + MBUF_PKTHDR_OVERHEAD</span>
<span class="cp">#define MBUF_NUM_MBUFS (32)</span>
<span class="cp">#define MBUF_PAYLOAD_SIZE (64)</span>
<span class="cp">#define MBUF_BUF_SIZE OS_ALIGN(MBUF_PAYLOAD_SIZE, 4)</span>
<span class="cp">#define MBUF_MEMBLOCK_SIZE (MBUF_BUF_SIZE + MBUF_MEMBLOCK_OVERHEAD)</span>
<span class="cp">#define MBUF_MEMPOOL_SIZE OS_MEMPOOL_SIZE(MBUF_NUM_MBUFS, MBUF_MEMBLOCK_SIZE)</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">os_mbuf_pool</span><span class="w"> </span><span class="n">g_mbuf_pool</span><span class="p">;</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">os_mempool</span><span class="w"> </span><span class="n">g_mbuf_mempool</span><span class="p">;</span>
<span class="n">os_membuf_t</span><span class="w"> </span><span class="n">g_mbuf_buffer</span><span class="p">[</span><span class="n">MBUF_MEMPOOL_SIZE</span><span class="p">];</span>
<span class="kt">void</span>
<span class="nf">create_mbuf_pool</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">rc</span><span class="p">;</span>
<span class="w"> </span><span class="n">rc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">os_mempool_init</span><span class="p">(</span><span class="o">&amp;</span><span class="n">g_mbuf_mempool</span><span class="p">,</span><span class="w"> </span><span class="n">MBUF_NUM_MBUFS</span><span class="p">,</span>
<span class="w"> </span><span class="n">MBUF_MEMBLOCK_SIZE</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">g_mbuf_buffer</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span><span class="w"> </span><span class="s">&quot;mbuf_pool&quot;</span><span class="p">);</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">rc</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
<span class="w"> </span><span class="n">rc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">os_mbuf_pool_init</span><span class="p">(</span><span class="o">&amp;</span><span class="n">g_mbuf_pool</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">g_mbuf_mempool</span><span class="p">,</span><span class="w"> </span><span class="n">MBUF_MEMBLOCK_SIZE</span><span class="p">,</span>
<span class="w"> </span><span class="n">MBUF_NUM_MBUFS</span><span class="p">);</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">rc</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="msys">
<h2>Msys<a class="headerlink" href="#msys" title="Permalink to this headline"></a></h2>
<p>Msys stands for “system mbufs” and is a set of API built on top of the
mbuf code. The basic idea behind msys is the following. The developer
can create different size mbuf pools and register them with msys. The
application then allocates mbufs using the msys API (as opposed to the
mbuf API). The msys code will choose the mbuf pool with the smallest
mbufs that can accommodate the requested size.</p>
<p>Let us walk through an example where the user registers three mbuf pools
with msys: one with 32 byte mbufs, one with 256 and one with 2048. If
the user requests an mbuf with 10 bytes, the 32-byte mbuf pool is used.
If the request is for 33 bytes the 256 byte mbuf pool is used. If an
mbuf data size is requested that is larger than any of the pools (say,
4000 bytes) the largest pool is used. While this behaviour may not be
optimal in all cases that is the currently implemented behaviour. All
this means is that the user is not guaranteed that a single mbuf can
hold the requested data.</p>
<p>The msys code will not allocate an mbuf from a larger pool if the chosen
mbuf pool is empty. Similarly, the msys code will not chain together a
number of smaller mbufs to accommodate the requested size. While this
behaviour may change in future implementations the current code will
simply return NULL. Using the above example, say the user requests 250
bytes. The msys code chooses the appropriate pool (i.e. the 256 byte
mbuf pool) and attempts to allocate an mbuf from that pool. If that pool
is empty, NULL is returned even though the 32 and 2048 byte pools are
not empty.</p>
<p>Note that no added descriptions on how to use the msys API are presented
here (other than in the API descriptions themselves) as the msys API is
used in exactly the same manner as the mbuf API. The only difference is
that mbuf pools are added to msys by calling <code class="docutils literal notranslate"><span class="pre">os_msys_register().</span></code></p>
</div>
<div class="section" id="using-mbufs">
<h2>Using mbufs<a class="headerlink" href="#using-mbufs" title="Permalink to this headline"></a></h2>
<p>The following examples illustrate typical mbuf usage. There are two
basic mbuf allocation API: c:func:<cite>os_mbuf_get()</cite> and
<a class="reference internal" href="#c.os_mbuf_get_pkthdr" title="os_mbuf_get_pkthdr"><code class="xref c c-func docutils literal notranslate"><span class="pre">os_mbuf_get_pkthdr()</span></code></a>. The first API obtains a normal mbuf whereas
the latter obtains a packet header mbuf. Typically, application
developers use <a class="reference internal" href="#c.os_mbuf_get_pkthdr" title="os_mbuf_get_pkthdr"><code class="xref c c-func docutils literal notranslate"><span class="pre">os_mbuf_get_pkthdr()</span></code></a> and rarely, if ever, need to
call <a class="reference internal" href="#c.os_mbuf_get" title="os_mbuf_get"><code class="xref c c-func docutils literal notranslate"><span class="pre">os_mbuf_get()</span></code></a> as the rest of the mbuf API (e.g.
<a class="reference internal" href="#c.os_mbuf_append" title="os_mbuf_append"><code class="xref c c-func docutils literal notranslate"><span class="pre">os_mbuf_append()</span></code></a>, <a class="reference internal" href="#c.os_mbuf_copyinto" title="os_mbuf_copyinto"><code class="xref c c-func docutils literal notranslate"><span class="pre">os_mbuf_copyinto()</span></code></a>, etc.) typically
deal with allocating and chaining mbufs. It is recommended to use the
provided API to copy data into/out of mbuf chains and/or manipulate mbufs.</p>
<p>In <code class="docutils literal notranslate"><span class="pre">example1</span></code>, the developer creates a packet and then sends the
packet to a networking interface. The code sample also provides an
example of copying data out of an mbuf as well as use of the “pullup”
api (another very common mbuf api).</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span>
<span class="nf">mbuf_usage_example1</span><span class="p">(</span><span class="kt">uint8_t</span><span class="w"> </span><span class="o">*</span><span class="n">mydata</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">mydata_length</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">rc</span><span class="p">;</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">os_mbuf</span><span class="w"> </span><span class="o">*</span><span class="n">om</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/* get a packet header mbuf */</span>
<span class="w"> </span><span class="n">om</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">os_mbuf_get_pkthdr</span><span class="p">(</span><span class="o">&amp;</span><span class="n">g_mbuf_pool</span><span class="p">,</span><span class="w"> </span><span class="k">sizeof</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">user_hdr</span><span class="p">));</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">om</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="cm">/*</span>
<span class="cm"> * Copy user data into mbuf. NOTE: if mydata_length is greater than the</span>
<span class="cm"> * mbuf payload size (64 bytes using above example), mbufs are allocated</span>
<span class="cm"> * and chained together to accommodate the total packet length.</span>
<span class="cm"> */</span>
<span class="w"> </span><span class="n">rc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">os_mbuf_copyinto</span><span class="p">(</span><span class="n">om</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">mydata</span><span class="p">,</span><span class="w"> </span><span class="n">len</span><span class="p">);</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">rc</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="cm">/* Error! Could not allocate enough mbufs for total packet length */</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">-1</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="cm">/* Send packet to networking interface */</span>
<span class="w"> </span><span class="n">send_pkt</span><span class="p">(</span><span class="n">om</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>In <code class="docutils literal notranslate"><span class="pre">example2</span></code> we show use of the pullup api as this illustrates some
of the typical pitfalls developers encounter when using mbufs. The first
pitfall is one of alignment/padding. Depending on the processor and/or
compiler, the sizeof() a structure may vary. Thus, the size of
<em>my_protocol_header</em> may be different inside the packet data of the
mbuf than the size of the structure on the stack or as a global
variable, for instance. While some networking protcols may align
protocol information on convenient processor boundaries many others try
to conserve bytes “on the air” (i.e inside the packet data). Typical
methods used to deal with this are “packing” the structure (i.e. force
compiler to not pad) or creating protocol headers that do not require
padding. <code class="docutils literal notranslate"><span class="pre">example2</span></code> assumes that one of these methods was used when
defining the <em>my_protocol_header</em> structure.</p>
<p>Another common pitfall occurs around endianness. A network protocol may
be little endian or big endian; it all depends on the protocol
specification. Processors also have an endianness; this means that the
developer has to be careful that the processor endianness and the
protocol endianness are handled correctly. In <code class="docutils literal notranslate"><span class="pre">example2</span></code>, some common
networking functions are used: <code class="docutils literal notranslate"><span class="pre">ntohs()</span></code> and <code class="docutils literal notranslate"><span class="pre">ntohl()</span></code>. These are
shorthand for “network order to host order, short” and “network order to
host order, long”. Basically, these functions convert data of a certain
size (i.e. 16 bits, 32 bits, etc) to the endianness of the host. Network
byte order is big-endian (most significant byte first), so these
functions convert big-endian byte order to host order (thus, the
implementation of these functions is host dependent). Note that the BLE
networking stack “on the air” format is least signigicant byte first
(i.e. little endian), so a “bletoh” function would have to take little
endian format and convert to host format.</p>
<p>A long story short: the developer must take care when copying structure
data to/from mbufs and flat buffers!</p>
<p>A final note: these examples assume the same mbuf struture and
definitions used in the first example.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span>
<span class="nf">mbuf_usage_example2</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">mbuf</span><span class="w"> </span><span class="o">*</span><span class="n">rxpkt</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">rc</span><span class="p">;</span>
<span class="w"> </span><span class="kt">uint8_t</span><span class="w"> </span><span class="n">packet_data</span><span class="p">[</span><span class="mi">16</span><span class="p">];</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">mbuf</span><span class="w"> </span><span class="o">*</span><span class="n">om</span><span class="p">;</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">my_protocol_header</span><span class="w"> </span><span class="o">*</span><span class="n">phdr</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/* Make sure that &quot;my_protocol_header&quot; bytes are contiguous in mbuf */</span>
<span class="w"> </span><span class="n">om</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">os_mbuf_pullup</span><span class="p">(</span><span class="o">&amp;</span><span class="n">g_mbuf_pool</span><span class="p">,</span><span class="w"> </span><span class="k">sizeof</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">my_protocol_header</span><span class="p">));</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">om</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="cm">/* Not able to pull up data into contiguous area */</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">-1</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="cm">/*</span>
<span class="cm"> * Get the protocol information from the packet. In this example we presume that we</span>
<span class="cm"> * are interested in protocol types that are equal to MY_PROTOCOL_TYPE, are not zero</span>
<span class="cm"> * length, and have had some time in flight.</span>
<span class="cm"> */</span>
<span class="w"> </span><span class="n">phdr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">OS_MBUF_DATA</span><span class="p">(</span><span class="n">om</span><span class="p">,</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">my_protocol_header</span><span class="w"> </span><span class="o">*</span><span class="p">);</span>
<span class="w"> </span><span class="n">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ntohs</span><span class="p">(</span><span class="n">phdr</span><span class="o">-&gt;</span><span class="n">prot_type</span><span class="p">);</span>
<span class="w"> </span><span class="n">length</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ntohs</span><span class="p">(</span><span class="n">phdr</span><span class="o">-&gt;</span><span class="n">prot_length</span><span class="p">);</span>
<span class="w"> </span><span class="n">time_in_flight</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ntohl</span><span class="p">(</span><span class="n">phdr</span><span class="o">-&gt;</span><span class="n">prot_tif</span><span class="p">);</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">((</span><span class="n">type</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">MY_PROTOCOL_TYPE</span><span class="p">)</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="p">(</span><span class="n">length</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="p">(</span><span class="n">time_in_flight</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="mi">0</span><span class="p">))</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">rc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">os_mbuf_copydata</span><span class="p">(</span><span class="n">rxpkt</span><span class="p">,</span><span class="w"> </span><span class="k">sizeof</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">my_protocol_header</span><span class="p">),</span><span class="w"> </span><span class="mi">16</span><span class="p">,</span><span class="w"> </span><span class="n">packet_data</span><span class="p">);</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">rc</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="cm">/* Success! Perform operations on packet data */</span>
<span class="w"> </span><span class="o">&lt;</span><span class="p">...</span><span class="w"> </span><span class="n">user</span><span class="w"> </span><span class="n">code</span><span class="w"> </span><span class="n">here</span><span class="w"> </span><span class="p">...</span><span class="o">&gt;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="cm">/* Free passed in packet (mbuf chain) since we don&#39;t need it anymore */</span>
<span class="w"> </span><span class="n">os_mbuf_free_chain</span><span class="p">(</span><span class="n">om</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="mqueue">
<h2>Mqueue<a class="headerlink" href="#mqueue" title="Permalink to this headline"></a></h2>
<p>The mqueue construct allows a task to wake up when it receives data.
Typically, this data is in the form of packets received over a network.
A common networking stack operation is to put a packet on a queue and
post an event to the task monitoring that queue. When the task handles
the event, it processes each packet on the packet queue.</p>
</div>
<div class="section" id="using-mqueue">
<h2>Using Mqueue<a class="headerlink" href="#using-mqueue" title="Permalink to this headline"></a></h2>
<p>The following code sample demonstrates how to use an mqueue. In this
example:</p>
<ul class="simple">
<li><p>packets are put on a receive queue</p></li>
<li><p>a task processes each packet on the queue (increments a receive
counter)</p></li>
</ul>
<p>Not shown in the code example is a call <code class="docutils literal notranslate"><span class="pre">my_task_rx_data_func</span></code>.
Presumably, some other code will call this API.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">uint32_t</span><span class="w"> </span><span class="n">pkts_rxd</span><span class="p">;</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">os_mqueue</span><span class="w"> </span><span class="n">rxpkt_q</span><span class="p">;</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">os_eventq</span><span class="w"> </span><span class="n">my_task_evq</span><span class="p">;</span>
<span class="cm">/**</span>
<span class="cm"> * Removes each packet from the receive queue and processes it.</span>
<span class="cm"> */</span>
<span class="kt">void</span>
<span class="nf">process_rx_data_queue</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">os_mbuf</span><span class="w"> </span><span class="o">*</span><span class="n">om</span><span class="p">;</span>
<span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">((</span><span class="n">om</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">os_mqueue_get</span><span class="p">(</span><span class="o">&amp;</span><span class="n">rxpkt_q</span><span class="p">))</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="nb">NULL</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="o">++</span><span class="n">pkts_rxd</span><span class="p">;</span>
<span class="w"> </span><span class="n">os_mbuf_free_chain</span><span class="p">(</span><span class="n">om</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
<span class="cm">/**</span>
<span class="cm"> * Called when a packet is received.</span>
<span class="cm"> */</span>
<span class="kt">int</span>
<span class="nf">my_task_rx_data_func</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">os_mbuf</span><span class="w"> </span><span class="o">*</span><span class="n">om</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">rc</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/* Enqueue the received packet and wake up the listening task. */</span>
<span class="w"> </span><span class="n">rc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">os_mqueue_put</span><span class="p">(</span><span class="o">&amp;</span><span class="n">rxpkt_q</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">my_task_evq</span><span class="p">,</span><span class="w"> </span><span class="n">om</span><span class="p">);</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">rc</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">-1</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">void</span>
<span class="nf">my_task_handler</span><span class="p">(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">arg</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">os_event</span><span class="w"> </span><span class="o">*</span><span class="n">ev</span><span class="p">;</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">os_callout_func</span><span class="w"> </span><span class="o">*</span><span class="n">cf</span><span class="p">;</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">rc</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/* Initialize eventq */</span>
<span class="w"> </span><span class="n">os_eventq_init</span><span class="p">(</span><span class="o">&amp;</span><span class="n">my_task_evq</span><span class="p">);</span>
<span class="w"> </span><span class="cm">/* Initialize mqueue */</span>
<span class="w"> </span><span class="n">os_mqueue_init</span><span class="p">(</span><span class="o">&amp;</span><span class="n">rxpkt_q</span><span class="p">,</span><span class="w"> </span><span class="nb">NULL</span><span class="p">);</span>
<span class="w"> </span><span class="cm">/* Process each event posted to our eventq. When there are no events to</span>
<span class="cm"> * process, sleep until one arrives.</span>
<span class="cm"> */</span>
<span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">os_eventq_run</span><span class="p">(</span><span class="o">&amp;</span><span class="n">my_task_evq</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="api">
<h2>API<a class="headerlink" href="#api" title="Permalink to this headline"></a></h2>
<dl class="c function">
<dt id="c.os_mqueue_init">
<span class="target" id="group___o_s_mbuf_1ga9763522ccbaeb6844dab335f6ee91342"></span><span class="pre">int</span> <code class="sig-name descname"><span class="pre">os_mqueue_init</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mqueue" title="os_mqueue"><span class="pre">os_mqueue</span></a> <span class="pre">*</span><em><span class="pre">mq</span></em>, <a class="reference internal" href="../event_queue/event_queue.html#c.os_event_fn" title="os_event_fn"><span class="pre">os_event_fn</span></a> <span class="pre">*</span><em><span class="pre">ev_cb</span></em>, <span class="pre">void</span> <span class="pre">*</span><em><span class="pre">arg</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_mqueue_init" title="Permalink to this definition"></a><br /></dt>
<dd><p>Initializes an mqueue. </p>
<p>An mqueue is a queue of mbufs that ties to a particular task’s event queue. Mqueues form a helper API around a common paradigm: wait on an event queue until at least one packet is available, then process a queue of packets.</p>
<p>When mbufs are available on the queue, an event OS_EVENT_T_MQUEUE_DATA will be posted to the task’s mbuf queue.</p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>0 on success, non-zero on failure. </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">mq</span></code>: The mqueue to initialize </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">ev_cb</span></code>: The callback to associate with the mqeueue event. Typically, this callback pulls each packet off the mqueue and processes them. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">arg</span></code>: The argument to associate with the mqueue event.</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_mqueue_get">
<span class="target" id="group___o_s_mbuf_1ga32306d7188418fdde8d0be121844b291"></span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><code class="sig-name descname"><span class="pre">os_mqueue_get</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mqueue" title="os_mqueue"><span class="pre">os_mqueue</span></a><span class="pre">*</span><span class="sig-paren">)</span><a class="headerlink" href="#c.os_mqueue_get" title="Permalink to this definition"></a><br /></dt>
<dd><p>Remove and return a single mbuf from the mbuf queue. </p>
<p>Does not block.</p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>The next mbuf in the queue, or NULL if queue has no mbufs. </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">mq</span></code>: The mbuf queue to pull an element off of.</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_mqueue_put">
<span class="target" id="group___o_s_mbuf_1ga39221c77178f12af8bd4b2c24cad07b6"></span><span class="pre">int</span> <code class="sig-name descname"><span class="pre">os_mqueue_put</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mqueue" title="os_mqueue"><span class="pre">os_mqueue</span></a><span class="pre">*</span>, <em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="../event_queue/event_queue.html#c.os_eventq" title="os_eventq"><span class="pre">os_eventq</span></a><span class="pre">*</span>, <em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a><span class="pre">*</span><span class="sig-paren">)</span><a class="headerlink" href="#c.os_mqueue_put" title="Permalink to this definition"></a><br /></dt>
<dd><p>Adds a packet (i.e. </p>
<p>packet header mbuf) to an mqueue. The event associated with the mqueue gets posted to the specified eventq.</p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>0 on success, non-zero on failure. </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">mq</span></code>: The mbuf queue to append the mbuf to. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">evq</span></code>: The event queue to post an event to. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">m</span></code>: The mbuf to append to the mbuf queue.</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_msys_register">
<span class="target" id="group___o_s_mbuf_1ga164e3f90cdee2692a85c249761ba001e"></span><span class="pre">int</span> <code class="sig-name descname"><span class="pre">os_msys_register</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf_pool" title="os_mbuf_pool"><span class="pre">os_mbuf_pool</span></a><span class="pre">*</span><span class="sig-paren">)</span><a class="headerlink" href="#c.os_msys_register" title="Permalink to this definition"></a><br /></dt>
<dd><p>MSYS is a system level mbuf registry. </p>
<p>Allows the system to share packet buffers amongst the various networking stacks that can be running simultaeneously.</p>
<p>Mbuf pools are created in the system initialization code, and then when a mbuf is allocated out of msys, it will try and find the best fit based upon estimated mbuf size.</p>
<p><a class="reference internal" href="#group___o_s_mbuf_1ga164e3f90cdee2692a85c249761ba001e"><span class="std std-ref">os_msys_register()</span></a> registers a mbuf pool with MSYS, and allows MSYS to allocate mbufs out of it.</p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>0 on success, non-zero on failure </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">new_pool</span></code>: The pool to register with MSYS</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_msys_get">
<span class="target" id="group___o_s_mbuf_1ga0e887615518be2d1fc721815dfd157c5"></span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><code class="sig-name descname"><span class="pre">os_msys_get</span></code><span class="sig-paren">(</span><span class="pre">uint16_t</span> <em><span class="pre">dsize</span></em>, <span class="pre">uint16_t</span> <em><span class="pre">leadingspace</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_msys_get" title="Permalink to this definition"></a><br /></dt>
<dd><p>Allocate a mbuf from msys. </p>
<p>Based upon the data size requested, <a class="reference internal" href="#group___o_s_mbuf_1ga0e887615518be2d1fc721815dfd157c5"><span class="std std-ref">os_msys_get()</span></a> will choose the mbuf pool that has the best fit.</p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>A freshly allocated mbuf on success, NULL on failure. </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">dsize</span></code>: The estimated size of the data being stored in the mbuf </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">leadingspace</span></code>: The amount of leadingspace to allocate in the mbuf</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_msys_reset">
<span class="target" id="group___o_s_mbuf_1gaa984a74000da6f436912a99821baeb9a"></span><span class="pre">void</span> <code class="sig-name descname"><span class="pre">os_msys_reset</span></code><span class="sig-paren">(</span><span class="pre">void</span><span class="sig-paren">)</span><a class="headerlink" href="#c.os_msys_reset" title="Permalink to this definition"></a><br /></dt>
<dd><p>De-registers all mbuf pools from msys. </p>
</dd></dl>
<dl class="c function">
<dt id="c.os_msys_get_pkthdr">
<span class="target" id="group___o_s_mbuf_1ga841e0b4f77115ec9df4b5becc252f03e"></span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><code class="sig-name descname"><span class="pre">os_msys_get_pkthdr</span></code><span class="sig-paren">(</span><span class="pre">uint16_t</span> <em><span class="pre">dsize</span></em>, <span class="pre">uint16_t</span> <em><span class="pre">user_hdr_len</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_msys_get_pkthdr" title="Permalink to this definition"></a><br /></dt>
<dd><p>Allocate a packet header structure from the MSYS pool. </p>
<p>See <a class="reference internal" href="#group___o_s_mbuf_1ga164e3f90cdee2692a85c249761ba001e"><span class="std std-ref">os_msys_register()</span></a> for a description of MSYS.</p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>A freshly allocated mbuf on success, NULL on failure. </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">dsize</span></code>: The estimated size of the data being stored in the mbuf </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">user_hdr_len</span></code>: The length to allocate for the packet header structure</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_msys_count">
<span class="target" id="group___o_s_mbuf_1ga82ba13b28a45ee54405dd7c4d6ea013b"></span><span class="pre">int</span> <code class="sig-name descname"><span class="pre">os_msys_count</span></code><span class="sig-paren">(</span><span class="pre">void</span><span class="sig-paren">)</span><a class="headerlink" href="#c.os_msys_count" title="Permalink to this definition"></a><br /></dt>
<dd><p>Count the number of blocks in all the mbuf pools that are allocated. </p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>total number of blocks allocated in Msys </p>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_msys_num_free">
<span class="target" id="group___o_s_mbuf_1gadf2b97336a5ab02260a304188374d345"></span><span class="pre">int</span> <code class="sig-name descname"><span class="pre">os_msys_num_free</span></code><span class="sig-paren">(</span><span class="pre">void</span><span class="sig-paren">)</span><a class="headerlink" href="#c.os_msys_num_free" title="Permalink to this definition"></a><br /></dt>
<dd><p>Return the number of free blocks in Msys. </p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>Number of free blocks available in Msys </p>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_mbuf_pool_init">
<span class="target" id="group___o_s_mbuf_1ga2895885c2f34a9582d2490558e782ff5"></span><span class="pre">int</span> <code class="sig-name descname"><span class="pre">os_mbuf_pool_init</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf_pool" title="os_mbuf_pool"><span class="pre">os_mbuf_pool</span></a><span class="pre">*</span>, <em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="../memory_pool/memory_pool.html#c.os_mempool" title="os_mempool"><span class="pre">os_mempool</span></a> <span class="pre">*</span><em><span class="pre">mp</span></em>, <span class="pre">uint16_t</span>, <span class="pre">uint16_t</span><span class="sig-paren">)</span><a class="headerlink" href="#c.os_mbuf_pool_init" title="Permalink to this definition"></a><br /></dt>
<dd><p>Initialize a pool of mbufs. </p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>0 on success, error code on failure. </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">omp</span></code>: The mbuf pool to initialize </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">mp</span></code>: The memory pool that will hold this mbuf pool </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">buf_len</span></code>: The length of the buffer itself. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">nbufs</span></code>: The number of buffers in the pool</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_mbuf_get">
<span class="target" id="group___o_s_mbuf_1gabf3bb711c79f3435c1da86f533e50296"></span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><code class="sig-name descname"><span class="pre">os_mbuf_get</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf_pool" title="os_mbuf_pool"><span class="pre">os_mbuf_pool</span></a> <span class="pre">*</span><em><span class="pre">omp</span></em>, <span class="pre">uint16_t</span><span class="sig-paren">)</span><a class="headerlink" href="#c.os_mbuf_get" title="Permalink to this definition"></a><br /></dt>
<dd><p>Get an mbuf from the mbuf pool. </p>
<p>The mbuf is allocated, and initialized prior to being returned.</p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>An initialized mbuf on success, and NULL on failure. </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">omp</span></code>: The mbuf pool to return the packet from </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">leadingspace</span></code>: The amount of leadingspace to put before the data section by default.</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_mbuf_get_pkthdr">
<span class="target" id="group___o_s_mbuf_1ga717bd3c356c7555d5b93245d6e0e1b47"></span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><code class="sig-name descname"><span class="pre">os_mbuf_get_pkthdr</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf_pool" title="os_mbuf_pool"><span class="pre">os_mbuf_pool</span></a> <span class="pre">*</span><em><span class="pre">omp</span></em>, <span class="pre">uint8_t</span> <em><span class="pre">pkthdr_len</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_mbuf_get_pkthdr" title="Permalink to this definition"></a><br /></dt>
<dd><p>Allocate a new packet header mbuf out of the <a class="reference internal" href="#structos__mbuf__pool"><span class="std std-ref">os_mbuf_pool</span></a>. </p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>A freshly allocated mbuf on success, NULL on failure. </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">omp</span></code>: The mbuf pool to allocate out of </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">user_pkthdr_len</span></code>: The packet header length to reserve for the caller.</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_mbuf_dup">
<span class="target" id="group___o_s_mbuf_1ga69b900ec646d9251fac4050ff49c3ab6"></span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><code class="sig-name descname"><span class="pre">os_mbuf_dup</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><em><span class="pre">m</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_mbuf_dup" title="Permalink to this definition"></a><br /></dt>
<dd><p>Duplicate a chain of mbufs. </p>
<p>Return the start of the duplicated chain.</p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>A pointer to the new chain of mbufs </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">omp</span></code>: The mbuf pool to duplicate out of </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">om</span></code>: The mbuf chain to duplicate</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_mbuf_off">
<span class="target" id="group___o_s_mbuf_1gabbd3dd2b8880a323c70478f8988902af"></span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><code class="sig-name descname"><span class="pre">os_mbuf_off</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">const</span></em> <em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><em><span class="pre">om</span></em>, <span class="pre">int</span> <em><span class="pre">off</span></em>, <span class="pre">uint16_t</span> <span class="pre">*</span><em><span class="pre">out_off</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_mbuf_off" title="Permalink to this definition"></a><br /></dt>
<dd><p>Locates the specified absolute offset within an mbuf chain. </p>
<p>The offset can be one past than the total length of the chain, but no greater.</p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>The mbuf containing the specified offset on success. NULL if the specified offset is out of bounds. </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">om</span></code>: The start of the mbuf chain to seek within. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">off</span></code>: The absolute address to find. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">out_off</span></code>: On success, this points to the relative offset within the returned mbuf.</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_mbuf_copydata">
<span class="target" id="group___o_s_mbuf_1ga31d793aa91e9c7ae5b5002b10f95dd64"></span><span class="pre">int</span> <code class="sig-name descname"><span class="pre">os_mbuf_copydata</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">const</span></em> <em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><em><span class="pre">m</span></em>, <span class="pre">int</span> <em><span class="pre">off</span></em>, <span class="pre">int</span> <em><span class="pre">len</span></em>, <span class="pre">void</span> <span class="pre">*</span><em><span class="pre">dst</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_mbuf_copydata" title="Permalink to this definition"></a><br /></dt>
<dd></dd></dl>
<dl class="c function">
<dt id="c.os_mbuf_len">
<span class="target" id="group___o_s_mbuf_1ga71a365a381016fb89b7b5d4acef5ddb3"></span><span class="pre">uint16_t</span> <code class="sig-name descname"><span class="pre">os_mbuf_len</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">const</span></em> <em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><em><span class="pre">om</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_mbuf_len" title="Permalink to this definition"></a><br /></dt>
<dd><p>Calculates the length of an mbuf chain. </p>
<p>Calculates the length of an mbuf chain. If the mbuf contains a packet header, you should use <code class="docutils literal notranslate"><a class="reference internal" href="#group___o_s_mbuf_1gae286e94341ed58ac3be7b7a3cd0f1c25"><span class="std std-ref"><span class="pre">OS_MBUF_PKTLEN()</span></span></a></code> as a more efficient alternative to this function.</p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>The length, in bytes, of the provided mbuf chain. </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">om</span></code>: The mbuf to measure.</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_mbuf_append">
<span class="target" id="group___o_s_mbuf_1ga672d3e6990c4d8fe60046ee6cde32ac1"></span><span class="pre">int</span> <code class="sig-name descname"><span class="pre">os_mbuf_append</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><em><span class="pre">m</span></em>, <em class="property"><span class="pre">const</span></em> <span class="pre">void</span><span class="pre">*</span>, <span class="pre">uint16_t</span><span class="sig-paren">)</span><a class="headerlink" href="#c.os_mbuf_append" title="Permalink to this definition"></a><br /></dt>
<dd><p>Append data onto a mbuf. </p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>0 on success, and an error code on failure </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">om</span></code>: The mbuf to append the data onto </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">data</span></code>: The data to append onto the mbuf </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">len</span></code>: The length of the data to append</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_mbuf_appendfrom">
<span class="target" id="group___o_s_mbuf_1ga66da7f4e54d6dbf4dc2d7531b68d7db0"></span><span class="pre">int</span> <code class="sig-name descname"><span class="pre">os_mbuf_appendfrom</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><em><span class="pre">dst</span></em>, <em class="property"><span class="pre">const</span></em> <em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><em><span class="pre">src</span></em>, <span class="pre">uint16_t</span> <em><span class="pre">src_off</span></em>, <span class="pre">uint16_t</span> <em><span class="pre">len</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_mbuf_appendfrom" title="Permalink to this definition"></a><br /></dt>
<dd><p>Reads data from one mbuf and appends it to another. </p>
<p>On error, the specified data range may be partially appended. Neither mbuf is required to contain an mbuf packet header.</p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>0 on success; OS_EINVAL if the specified range extends beyond the end of the source mbuf chain. </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">dst</span></code>: The mbuf to append to. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">src</span></code>: The mbuf to copy data from. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">src_off</span></code>: The absolute offset within the source mbuf chain to read from. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">len</span></code>: The number of bytes to append.</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_mbuf_free">
<span class="target" id="group___o_s_mbuf_1ga2bcbfe183bd88962d78017cc51c59ed2"></span><span class="pre">int</span> <code class="sig-name descname"><span class="pre">os_mbuf_free</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><em><span class="pre">mb</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_mbuf_free" title="Permalink to this definition"></a><br /></dt>
<dd><p>Release a mbuf back to the pool. </p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>0 on success, -1 on failure </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">omp</span></code>: The Mbuf pool to release back to </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">om</span></code>: The Mbuf to release back to the pool</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_mbuf_free_chain">
<span class="target" id="group___o_s_mbuf_1ga66de6a0a042c35435547a1df9534cc3f"></span><span class="pre">int</span> <code class="sig-name descname"><span class="pre">os_mbuf_free_chain</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><em><span class="pre">om</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_mbuf_free_chain" title="Permalink to this definition"></a><br /></dt>
<dd><p>Free a chain of mbufs. </p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>0 on success, -1 on failure </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">omp</span></code>: The mbuf pool to free the chain of mbufs into </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">om</span></code>: The starting mbuf of the chain to free back into the pool</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_mbuf_adj">
<span class="target" id="group___o_s_mbuf_1gad1379ba25e8dc203a84ad6fc21f2880e"></span><span class="pre">void</span> <code class="sig-name descname"><span class="pre">os_mbuf_adj</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><em><span class="pre">mp</span></em>, <span class="pre">int</span> <em><span class="pre">req_len</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_mbuf_adj" title="Permalink to this definition"></a><br /></dt>
<dd><p>Adjust the length of a mbuf, trimming either from the head or the tail of the mbuf. </p>
<p><dl class="simple">
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">mp</span></code>: The mbuf chain to adjust </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">req_len</span></code>: The length to trim from the mbuf. If positive, trims from the head of the mbuf, if negative, trims from the tail of the mbuf. </p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_mbuf_cmpf">
<span class="target" id="group___o_s_mbuf_1gac5d238e8abd1a459c2daf8fe814e13d4"></span><span class="pre">int</span> <code class="sig-name descname"><span class="pre">os_mbuf_cmpf</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">const</span></em> <em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><em><span class="pre">om</span></em>, <span class="pre">int</span> <em><span class="pre">off</span></em>, <em class="property"><span class="pre">const</span></em> <span class="pre">void</span> <span class="pre">*</span><em><span class="pre">data</span></em>, <span class="pre">int</span> <em><span class="pre">len</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_mbuf_cmpf" title="Permalink to this definition"></a><br /></dt>
<dd><p>Performs a memory compare of the specified region of an mbuf chain against a flat buffer. </p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>0 if both memory regions are identical; A memcmp return code if there is a mismatch; INT_MAX if the mbuf is too short. </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">om</span></code>: The start of the mbuf chain to compare. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">off</span></code>: The offset within the mbuf chain to start the comparison. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">data</span></code>: The flat buffer to compare. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">len</span></code>: The length of the flat buffer.</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_mbuf_cmpm">
<span class="target" id="group___o_s_mbuf_1ga11d6f4ce57b2c5c7b619831689f519f1"></span><span class="pre">int</span> <code class="sig-name descname"><span class="pre">os_mbuf_cmpm</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">const</span></em> <em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><em><span class="pre">om1</span></em>, <span class="pre">uint16_t</span> <em><span class="pre">offset1</span></em>, <em class="property"><span class="pre">const</span></em> <em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><em><span class="pre">om2</span></em>, <span class="pre">uint16_t</span> <em><span class="pre">offset2</span></em>, <span class="pre">uint16_t</span> <em><span class="pre">len</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_mbuf_cmpm" title="Permalink to this definition"></a><br /></dt>
<dd><p>Compares the contents of two mbuf chains. </p>
<p>The ranges of the two chains to be compared are specified via the two offset parameters and the len parameter. Neither mbuf chain is required to contain a packet header.</p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>0 if both mbuf segments are identical; A memcmp() return code if the segment contents differ; INT_MAX if a specified range extends beyond the end of its corresponding mbuf chain. </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">om1</span></code>: The first mbuf chain to compare. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">offset1</span></code>: The absolute offset within om1 at which to start the comparison. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">om2</span></code>: The second mbuf chain to compare. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">offset2</span></code>: The absolute offset within om2 at which to start the comparison. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">len</span></code>: The number of bytes to compare.</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_mbuf_prepend">
<span class="target" id="group___o_s_mbuf_1gac16c27c68f35e4647823ae020411763f"></span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><code class="sig-name descname"><span class="pre">os_mbuf_prepend</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><em><span class="pre">om</span></em>, <span class="pre">int</span> <em><span class="pre">len</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_mbuf_prepend" title="Permalink to this definition"></a><br /></dt>
<dd><p>Increases the length of an mbuf chain by adding data to the front. </p>
<p>If there is insufficient room in the leading mbuf, additional mbufs are allocated and prepended as necessary. If this function fails to allocate an mbuf, the entire chain is freed.</p>
<p>The specified mbuf chain does not need to contain a packet header.</p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>The new head of the chain on success; NULL on failure. </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">omp</span></code>: The mbuf pool to allocate from. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">om</span></code>: The head of the mbuf chain. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">len</span></code>: The number of bytes to prepend.</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_mbuf_prepend_pullup">
<span class="target" id="group___o_s_mbuf_1gac6e76dec13d44abd6032eb293aa1b63a"></span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><code class="sig-name descname"><span class="pre">os_mbuf_prepend_pullup</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><em><span class="pre">om</span></em>, <span class="pre">uint16_t</span> <em><span class="pre">len</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_mbuf_prepend_pullup" title="Permalink to this definition"></a><br /></dt>
<dd><p>Prepends a chunk of empty data to the specified mbuf chain and ensures the chunk is contiguous. </p>
<p>If either operation fails, the specified mbuf chain is freed and NULL is returned.</p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>The modified mbuf on success; NULL on failure (and the mbuf chain is freed). </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">om</span></code>: The mbuf chain to prepend to. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">len</span></code>: The number of bytes to prepend and pullup.</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_mbuf_copyinto">
<span class="target" id="group___o_s_mbuf_1ga5e87037857c05e8a9379bb2889947854"></span><span class="pre">int</span> <code class="sig-name descname"><span class="pre">os_mbuf_copyinto</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><em><span class="pre">om</span></em>, <span class="pre">int</span> <em><span class="pre">off</span></em>, <em class="property"><span class="pre">const</span></em> <span class="pre">void</span> <span class="pre">*</span><em><span class="pre">src</span></em>, <span class="pre">int</span> <em><span class="pre">len</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_mbuf_copyinto" title="Permalink to this definition"></a><br /></dt>
<dd><p>Copies the contents of a flat buffer into an mbuf chain, starting at the specified destination offset. </p>
<p>If the mbuf is too small for the source data, it is extended as necessary. If the destination mbuf contains a packet header, the header length is updated.</p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>0 on success; nonzero on failure. </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">omp</span></code>: The mbuf pool to allocate from. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">om</span></code>: The mbuf chain to copy into. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">off</span></code>: The offset within the chain to copy to. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">src</span></code>: The source buffer to copy from. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">len</span></code>: The number of bytes to copy.</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_mbuf_concat">
<span class="target" id="group___o_s_mbuf_1ga65ab8ccc2730629ca0dd8c5190575213"></span><span class="pre">void</span> <code class="sig-name descname"><span class="pre">os_mbuf_concat</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><em><span class="pre">first</span></em>, <em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><em><span class="pre">second</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_mbuf_concat" title="Permalink to this definition"></a><br /></dt>
<dd><p>Attaches a second mbuf chain onto the end of the first. </p>
<p>If the first chain contains a packet header, the header’s length is updated. If the second chain has a packet header, its header is cleared.</p>
<p><dl class="simple">
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">first</span></code>: The mbuf chain being attached to. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">second</span></code>: The mbuf chain that gets attached. </p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_mbuf_extend">
<span class="target" id="group___o_s_mbuf_1ga67d81c50479c67444fd1a9449d4241ed"></span><span class="pre">void</span> <span class="pre">*</span><code class="sig-name descname"><span class="pre">os_mbuf_extend</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><em><span class="pre">om</span></em>, <span class="pre">uint16_t</span> <em><span class="pre">len</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_mbuf_extend" title="Permalink to this definition"></a><br /></dt>
<dd><p>Increases the length of an mbuf chain by the specified amount. </p>
<p>If there is not sufficient room in the last buffer, a new buffer is allocated and appended to the chain. It is an error to request more data than can fit in a single buffer.</p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>A pointer to the new data on success; NULL on failure. </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">omp</span></code>: </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">om</span></code>: The head of the chain to extend. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">len</span></code>: The number of bytes to extend by.</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_mbuf_pullup">
<span class="target" id="group___o_s_mbuf_1ga3afad6750be6e7647ff0a19112ea36f7"></span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><code class="sig-name descname"><span class="pre">os_mbuf_pullup</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><em><span class="pre">om</span></em>, <span class="pre">uint16_t</span> <em><span class="pre">len</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_mbuf_pullup" title="Permalink to this definition"></a><br /></dt>
<dd><p>Rearrange a mbuf chain so that len bytes are contiguous, and in the data area of an mbuf (so that <a class="reference internal" href="#group___o_s_mbuf_1ga4bf84d7b323b20131da17c8bfed65674"><span class="std std-ref">OS_MBUF_DATA()</span></a> will work on a structure of size len.) Returns the resulting mbuf chain on success, free’s it and returns NULL on failure. </p>
<p>If there is room, it will add up to “max_protohdr - len” extra bytes to the contiguous region, in an attempt to avoid being called next time.</p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>The contiguous mbuf chain on success, NULL on failure. </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">omp</span></code>: The mbuf pool to take the mbufs out of </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">om</span></code>: The mbuf chain to make contiguous </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">len</span></code>: The number of bytes in the chain to make contiguous</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_mbuf_trim_front">
<span class="target" id="group___o_s_mbuf_1ga76d87394f85361c8a72d7ec0f0416bd6"></span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><code class="sig-name descname"><span class="pre">os_mbuf_trim_front</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><em><span class="pre">om</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_mbuf_trim_front" title="Permalink to this definition"></a><br /></dt>
<dd><p>Removes and frees empty mbufs from the front of a chain. </p>
<p>If the chain contains a packet header, it is preserved.</p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>The head of the trimmed mbuf chain. </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">om</span></code>: The mbuf chain to trim.</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c function">
<dt id="c.os_mbuf_widen">
<span class="target" id="group___o_s_mbuf_1gaa5e6acfb8702f5333567f758f620e1f3"></span><span class="pre">int</span> <code class="sig-name descname"><span class="pre">os_mbuf_widen</span></code><span class="sig-paren">(</span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf" title="os_mbuf"><span class="pre">os_mbuf</span></a> <span class="pre">*</span><em><span class="pre">om</span></em>, <span class="pre">uint16_t</span> <em><span class="pre">off</span></em>, <span class="pre">uint16_t</span> <em><span class="pre">len</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.os_mbuf_widen" title="Permalink to this definition"></a><br /></dt>
<dd><p>Increases the length of an mbuf chain by inserting a gap at the specified offset. </p>
<p>The contents of the gap are indeterminate. If the mbuf chain contains a packet header, its total length is increased accordingly.</p>
<p>This function never frees the provided mbuf chain.</p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>0 on success; SYS_[…] error code on failure. </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">om</span></code>: The mbuf chain to widen. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">off</span></code>: The offset at which to insert the gap. </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">len</span></code>: The size of the gap to insert.</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c macro">
<dt id="c.OS_MBUF_F_MASK">
<span class="target" id="group___o_s_mbuf_1gafc8811efeca97f3c412416bb01ed746e"></span><code class="sig-name descname"><span class="pre">OS_MBUF_F_MASK</span></code><span class="sig-paren">(</span><em><span class="pre">__n</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.OS_MBUF_F_MASK" title="Permalink to this definition"></a><br /></dt>
<dd></dd></dl>
<dl class="c macro">
<dt id="c.OS_MBUF_IS_PKTHDR">
<span class="target" id="group___o_s_mbuf_1ga44478552b659f6780f750528b8345577"></span><code class="sig-name descname"><span class="pre">OS_MBUF_IS_PKTHDR</span></code><span class="sig-paren">(</span><em><span class="pre">__om</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.OS_MBUF_IS_PKTHDR" title="Permalink to this definition"></a><br /></dt>
<dd></dd></dl>
<dl class="c macro">
<dt id="c.OS_MBUF_PKTHDR">
<span class="target" id="group___o_s_mbuf_1ga6cac59130516e8c8bc98f27bb1d18a9e"></span><code class="sig-name descname"><span class="pre">OS_MBUF_PKTHDR</span></code><span class="sig-paren">(</span><em><span class="pre">__om</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.OS_MBUF_PKTHDR" title="Permalink to this definition"></a><br /></dt>
<dd><p>Get a packet header pointer given an mbuf pointer. </p>
</dd></dl>
<dl class="c macro">
<dt id="c.OS_MBUF_PKTHDR_TO_MBUF">
<span class="target" id="group___o_s_mbuf_1ga753a06f73d0b8dc916969e9ae490c0ce"></span><code class="sig-name descname"><span class="pre">OS_MBUF_PKTHDR_TO_MBUF</span></code><span class="sig-paren">(</span><em><span class="pre">__hdr</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.OS_MBUF_PKTHDR_TO_MBUF" title="Permalink to this definition"></a><br /></dt>
<dd><p>Given a mbuf packet header pointer, return a pointer to the mbuf. </p>
</dd></dl>
<dl class="c macro">
<dt id="c.OS_MBUF_PKTLEN">
<span class="target" id="group___o_s_mbuf_1gae286e94341ed58ac3be7b7a3cd0f1c25"></span><code class="sig-name descname"><span class="pre">OS_MBUF_PKTLEN</span></code><span class="sig-paren">(</span><em><span class="pre">__om</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.OS_MBUF_PKTLEN" title="Permalink to this definition"></a><br /></dt>
<dd><p>Gets the length of an entire mbuf chain. </p>
<p>The specified mbuf must have a packet header. </p>
</dd></dl>
<dl class="c macro">
<dt id="c.OS_MBUF_DATA">
<span class="target" id="group___o_s_mbuf_1ga4bf84d7b323b20131da17c8bfed65674"></span><code class="sig-name descname"><span class="pre">OS_MBUF_DATA</span></code><span class="sig-paren">(</span><em><span class="pre">__om</span></em>, <em><span class="pre">__type</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.OS_MBUF_DATA" title="Permalink to this definition"></a><br /></dt>
<dd><p>Access the data of a mbuf, and cast it to type. </p>
<p><dl class="simple">
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">__om</span></code>: The mbuf to access, and cast </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">__type</span></code>: The type to cast it to </p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c macro">
<dt id="c.OS_MBUF_USRHDR">
<span class="target" id="group___o_s_mbuf_1ga6a70c33b992b2c96ddbbea7a8e13ac4c"></span><code class="sig-name descname"><span class="pre">OS_MBUF_USRHDR</span></code><span class="sig-paren">(</span><em><span class="pre">om</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.OS_MBUF_USRHDR" title="Permalink to this definition"></a><br /></dt>
<dd><p>Access the “user header” in the head of an mbuf chain. </p>
<p><dl class="simple">
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">om</span></code>: Pointer to the head of an mbuf chain. </p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c macro">
<dt id="c.OS_MBUF_USRHDR_LEN">
<span class="target" id="group___o_s_mbuf_1gab603a13e3de7d579605bce345e3c5101"></span><code class="sig-name descname"><span class="pre">OS_MBUF_USRHDR_LEN</span></code><span class="sig-paren">(</span><em><span class="pre">om</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.OS_MBUF_USRHDR_LEN" title="Permalink to this definition"></a><br /></dt>
<dd><p>Retrieves the length of the user header in an mbuf. </p>
<p><dl class="simple">
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">om</span></code>: Pointer to the mbuf to query. </p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c macro">
<dt id="c.OS_MBUF_LEADINGSPACE">
<span class="target" id="group___o_s_mbuf_1gafa645aa091541bcc590e1f7091a35a7d"></span><code class="sig-name descname"><span class="pre">OS_MBUF_LEADINGSPACE</span></code><span class="sig-paren">(</span><em><span class="pre">__om</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.OS_MBUF_LEADINGSPACE" title="Permalink to this definition"></a><br /></dt>
<dd><p>Returns the leading space (space at the beginning) of the mbuf. </p>
<p>Works on both packet header, and regular mbufs, as it accounts for the additional space allocated to the packet header.</p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>Amount of leading space available in the mbuf </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">__omp</span></code>: Is the mbuf pool (which contains packet header length.) </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">__om</span></code>: Is the mbuf in that pool to get the leadingspace for</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c macro">
<dt id="c.OS_MBUF_TRAILINGSPACE">
<span class="target" id="group___o_s_mbuf_1ga6bed008283a020a38886e68997b99239"></span><code class="sig-name descname"><span class="pre">OS_MBUF_TRAILINGSPACE</span></code><span class="sig-paren">(</span><em><span class="pre">__om</span></em><span class="sig-paren">)</span><a class="headerlink" href="#c.OS_MBUF_TRAILINGSPACE" title="Permalink to this definition"></a><br /></dt>
<dd><p>Returns the trailing space (space at the end) of the mbuf. </p>
<p>Works on both packet header and regular mbufs.</p>
<p><dl class="simple">
<dt><strong>Return</strong></dt><dd><p>The amount of trailing space available in the mbuf </p>
</dd>
<dt><strong>Parameters</strong></dt><dd><ul class="breatheparameterlist simple">
<li><p><code class="docutils literal notranslate"><span class="pre">__omp</span></code>: The mbuf pool for this mbuf </p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">__om</span></code>: Is the mbuf in that pool to get trailing space for</p></li>
</ul>
</dd>
</dl>
</p>
</dd></dl>
<dl class="c struct">
<dt id="c.os_mbuf_pool">
<span class="target" id="structos__mbuf__pool"></span><em class="property"><span class="pre">struct</span> </em><code class="sig-name descname"><span class="pre">os_mbuf_pool</span></code><a class="headerlink" href="#c.os_mbuf_pool" title="Permalink to this definition"></a><br /></dt>
<dd><em>#include &lt;os_mbuf.h&gt;</em><p>A mbuf pool from which to allocate mbufs. </p>
<p>This contains a pointer to the os mempool to allocate mbufs out of, the total number of elements in the pool, and the amount of “user” data in a non-packet header mbuf. The total pool size, in bytes, should be: os_mbuf_count * (omp_databuf_len + sizeof(struct os_mbuf)) </p>
<div class="breathe-sectiondef docutils container">
<p class="breathe-sectiondef-title rubric" id="breathe-section-title-public-members">Public Members</p>
<dl class="c var">
<dt id="c.os_mbuf_pool.omp_databuf_len">
<span class="target" id="structos__mbuf__pool_1a4ec5eeea1727efc7765dd95d60f5c1df"></span><span class="pre">uint16_t</span> <code class="sig-name descname"><span class="pre">omp_databuf_len</span></code><a class="headerlink" href="#c.os_mbuf_pool.omp_databuf_len" title="Permalink to this definition"></a><br /></dt>
<dd><p>Total length of the databuf in each mbuf. </p>
<p>This is the size of the mempool block, minus the mbuf header </p>
</dd></dl>
<dl class="c var">
<dt id="c.os_mbuf_pool.omp_pool">
<span class="target" id="structos__mbuf__pool_1a883d0c3aa305284ebd19bd3c62037430"></span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="../memory_pool/memory_pool.html#c.os_mempool" title="os_mempool"><span class="pre">os_mempool</span></a> <span class="pre">*</span><code class="sig-name descname"><span class="pre">omp_pool</span></code><a class="headerlink" href="#c.os_mbuf_pool.omp_pool" title="Permalink to this definition"></a><br /></dt>
<dd><p>The memory pool which to allocate mbufs out of. </p>
</dd></dl>
</div>
</dd></dl>
<dl class="c struct">
<dt id="c.os_mbuf_pkthdr">
<span class="target" id="structos__mbuf__pkthdr"></span><em class="property"><span class="pre">struct</span> </em><code class="sig-name descname"><span class="pre">os_mbuf_pkthdr</span></code><a class="headerlink" href="#c.os_mbuf_pkthdr" title="Permalink to this definition"></a><br /></dt>
<dd><em>#include &lt;os_mbuf.h&gt;</em><p>A packet header structure that preceeds the mbuf packet headers. </p>
<div class="breathe-sectiondef docutils container">
<p class="breathe-sectiondef-title rubric" id="breathe-section-title-public-members">Public Members</p>
<dl class="c var">
<dt id="c.os_mbuf_pkthdr.omp_len">
<span class="target" id="structos__mbuf__pkthdr_1aeb48e54eaea9964c2cd4e856722def7f"></span><span class="pre">uint16_t</span> <code class="sig-name descname"><span class="pre">omp_len</span></code><a class="headerlink" href="#c.os_mbuf_pkthdr.omp_len" title="Permalink to this definition"></a><br /></dt>
<dd><p>Overall length of the packet. </p>
</dd></dl>
<dl class="c var">
<dt id="c.os_mbuf_pkthdr.omp_flags">
<span class="target" id="structos__mbuf__pkthdr_1aee78ee1e9d30477e0253d9ed5245c36b"></span><span class="pre">uint16_t</span> <code class="sig-name descname"><span class="pre">omp_flags</span></code><a class="headerlink" href="#c.os_mbuf_pkthdr.omp_flags" title="Permalink to this definition"></a><br /></dt>
<dd><p>Flags. </p>
</dd></dl>
</div>
</dd></dl>
<dl class="c struct">
<dt id="c.os_mbuf">
<span class="target" id="structos__mbuf"></span><em class="property"><span class="pre">struct</span> </em><code class="sig-name descname"><span class="pre">os_mbuf</span></code><a class="headerlink" href="#c.os_mbuf" title="Permalink to this definition"></a><br /></dt>
<dd><em>#include &lt;os_mbuf.h&gt;</em><p>Chained memory buffer. </p>
<div class="breathe-sectiondef docutils container">
<p class="breathe-sectiondef-title rubric" id="breathe-section-title-public-members">Public Members</p>
<dl class="c var">
<dt id="c.os_mbuf.om_data">
<span class="target" id="structos__mbuf_1a26c2267833d75b8af52f511c431e07de"></span><span class="pre">uint8_t</span> <span class="pre">*</span><code class="sig-name descname"><span class="pre">om_data</span></code><a class="headerlink" href="#c.os_mbuf.om_data" title="Permalink to this definition"></a><br /></dt>
<dd><p>Current pointer to data in the structure. </p>
</dd></dl>
<dl class="c var">
<dt id="c.os_mbuf.om_flags">
<span class="target" id="structos__mbuf_1a534559bde8149d283cf8571164a5fcfc"></span><span class="pre">uint8_t</span> <code class="sig-name descname"><span class="pre">om_flags</span></code><a class="headerlink" href="#c.os_mbuf.om_flags" title="Permalink to this definition"></a><br /></dt>
<dd><p>Flags associated with this buffer, see OS_MBUF_F_* defintions. </p>
</dd></dl>
<dl class="c var">
<dt id="c.os_mbuf.om_pkthdr_len">
<span class="target" id="structos__mbuf_1a809d8377b268edeb774cdc37be654130"></span><span class="pre">uint8_t</span> <code class="sig-name descname"><span class="pre">om_pkthdr_len</span></code><a class="headerlink" href="#c.os_mbuf.om_pkthdr_len" title="Permalink to this definition"></a><br /></dt>
<dd><p>Length of packet header. </p>
</dd></dl>
<dl class="c var">
<dt id="c.os_mbuf.om_len">
<span class="target" id="structos__mbuf_1a685a98624cf0d8ad353967e18eb3506a"></span><span class="pre">uint16_t</span> <code class="sig-name descname"><span class="pre">om_len</span></code><a class="headerlink" href="#c.os_mbuf.om_len" title="Permalink to this definition"></a><br /></dt>
<dd><p>Length of data in this buffer. </p>
</dd></dl>
<dl class="c var">
<dt id="c.os_mbuf.om_omp">
<span class="target" id="structos__mbuf_1a06b4de9c818acdf09241b0cbe3d6a207"></span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="#c.os_mbuf_pool" title="os_mbuf_pool"><span class="pre">os_mbuf_pool</span></a> <span class="pre">*</span><code class="sig-name descname"><span class="pre">om_omp</span></code><a class="headerlink" href="#c.os_mbuf.om_omp" title="Permalink to this definition"></a><br /></dt>
<dd><p>The mbuf pool this mbuf was allocated out of. </p>
</dd></dl>
<dl class="c var">
<dt id="c.os_mbuf.om_databuf">
<span class="target" id="structos__mbuf_1a3928b4bdc7b67b9bbb6ef8f1f3133b01"></span><span class="pre">uint8_t</span> <code class="sig-name descname"><span class="pre">om_databuf</span></code><span class="pre">[</span><span class="pre">0</span><span class="pre">]</span><a class="headerlink" href="#c.os_mbuf.om_databuf" title="Permalink to this definition"></a><br /></dt>
<dd><p>Pointer to the beginning of the data, after this buffer. </p>
</dd></dl>
</div>
</dd></dl>
<dl class="c struct">
<dt id="c.os_mqueue">
<span class="target" id="structos__mqueue"></span><em class="property"><span class="pre">struct</span> </em><code class="sig-name descname"><span class="pre">os_mqueue</span></code><a class="headerlink" href="#c.os_mqueue" title="Permalink to this definition"></a><br /></dt>
<dd><em>#include &lt;os_mbuf.h&gt;</em><p>Structure representing a queue of mbufs. </p>
<div class="breathe-sectiondef docutils container">
<p class="breathe-sectiondef-title rubric" id="breathe-section-title-public-members">Public Members</p>
<dl class="c var">
<dt id="c.os_mqueue.mq_ev">
<span class="target" id="structos__mqueue_1a30ed7b555fcb87d7829dd6a1f34540db"></span><em class="property"><span class="pre">struct</span></em> <a class="reference internal" href="../event_queue/event_queue.html#c.os_event" title="os_event"><span class="pre">os_event</span></a> <code class="sig-name descname"><span class="pre">mq_ev</span></code><a class="headerlink" href="#c.os_mqueue.mq_ev" title="Permalink to this definition"></a><br /></dt>
<dd><p>Event to post when new buffers are available on the queue. </p>
</dd></dl>
</div>
</dd></dl>
</div>
</div>
</div>
</div>
<div class="rst-footer-buttons row" role="navigation" aria-label="footer navigation">
<a href="../cputime/os_cputime.html" class="btn btn-neutral float-right" title="CPU Time" accesskey="n">Next: CPU Time <span class="fa fa-arrow-circle-right"></span></a>
<a href="../memory_pool/memory_pool.html" class="btn btn-neutral" title="Memory Pools" accesskey="p"><span class="fa fa-arrow-circle-left"></span> Previous: Memory Pools</a>
</div>
</div>
</div>
</div>
<!-- ENDS CONTENT SECTION -->
</div>
<!-- ENDS .content -->
</div>
</div>
<footer>
<div class="container">
<div class="row">
<div class="col-xs-12">
<p class="copyright">Apache Mynewt is available under Apache License, version 2.0.</p>
</div>
<div class="col-xs-12">
<div class="logos">
<img src="../../../_static/img/asf_logo_wide_small.png" alt="Apache" title="Apache">
<small class="footnote">
Apache Mynewt, Mynewt, Apache, the Apache feather logo, and the Apache Mynewt project logo are either
registered trademarks or trademarks of the Apache Software Foundation in the United States and other countries.
</small>
<a href="">
<img src="../../../_static/img/add_to_slack.png" alt="Slack Icon" title="Join our Slack Community" />
</a>
</div>
</div>
</div>
</div>
</footer>
</div>
<!-- ENDS #wrapper -->
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../../',
VERSION:'latest',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt',
LINK_SUFFIX: '.html'
};
</script>
<script type="text/javascript" src="../../../_static/jquery.js"></script>
<script type="text/javascript" src="../../../_static/underscore.js"></script>
<script type="text/javascript" src="../../../_static/doctools.js"></script>
<script type="text/javascript" src="../../../_static/js/bootstrap-3.0.3.min.js"></script>
<script type="text/javascript" src="../../../_static/js/affix.js"></script>
<script type="text/javascript" src="../../../_static/js/main.js"></script>
</body>
</html>