{"id":1930,"date":"2016-01-21T19:02:32","date_gmt":"2016-01-22T03:02:32","guid":{"rendered":"https:\/\/www.privateinternetaccess.com\/blog\/?p=1930"},"modified":"2024-01-31T09:29:39","modified_gmt":"2024-01-31T17:29:39","slug":"linux-networking-stack-from-the-ground-up-part-1","status":"publish","type":"post","link":"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-1\/","title":{"rendered":"Linux networking stack from the ground up, part 1"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-1\/\">part 1<\/a> | <a href=\"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-2\/\">part 2<\/a> | <a href=\"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-3\/\">part 3<\/a> | <a href=\"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-4\/\">part 4<\/a> | <a href=\"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-4-2\/\">part 5<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-purpose\">Purpose<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This multi-part blog series\u00a0aims to outline the path of a packet from the wire through the network driver and kernel until it reaches the receive queue for a socket. This information pertains to the Linux kernel, release 3.13.0. Links to source code on GitHub are provided throughout to help with context.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This document will describe code throughout the Linux networking stack as well as some code from the following Ethernet device drivers:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>e1000e: Intel PRO\/1000 Linux driver<\/li>\n\n\n\n<li>igb: Intel Gigabit Linux driver<\/li>\n\n\n\n<li>ixgbe: Intel 10 Gigabit PCI Express Linux driver<\/li>\n\n\n\n<li>tg3: Broadcom Tigon3 ethernet driver<\/li>\n\n\n\n<li>be2net: HP Emulex 10 Gigabit PCI Express Linux Driver<\/li>\n\n\n\n<li>bnx2: Broadcom NX2 network driver<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Other kernels or drivers will likely be similar, but line numbers and detailed inner workings will likely be different.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-data-sheets-programmer-s-reference-manuals\">Data sheets \/ Programmer\u2019s Reference Manuals<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Driver code can be cryptic, especially when trying to understand the meanings of stastistics counters that the driver reads from the device. In many cases, referring to the documentation about the device can help clear things up.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><b>WARNING<\/b>: All of these PDFs are large. You may or may not want to download these on mobile devices.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>e1000e:\n<ol class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.intel.com\/content\/www\/us\/en\/my-intel\/developer-sign-in.html?redirect=\/content\/www\/us\/en\/design\/resource-design-center.html&amp;TYPE=33554433&amp;REALMOID=06-384e112f-284a-40b5-923f-e57891a2be39&amp;GUID=&amp;SMAUTHREASON=0&amp;METHOD=GET&amp;SMAGENTNAME=9IyroXSoMF7kVVITXzYzIESBjH6eFkyv3kC3z6rcWCrL6oJOa3iddh8NL5Fe3ago&amp;TARGET=%24SM%24HTTPS%3A%2F%2Fsfederation.intel.com%2Ffederation2%2Fsp%2FCDRv2%2FR1JEQ0NEUlYyUFJPREFURUFN%3FSAMLRequest%3DnVNdb5swFP0ryO%24%2FhKy2drCQVg2Rr1Q9GoNL2MjnmpkUzNvM1afbv55Cw8tDloU9I5577cc4xs%24%2Bt9I5wdaKyVnJPA9cn1YoasES2NO%24%2FMic%24%2FjdARrH0iTSvjAnnZZUMayRStYAUsPpOr6%24%2Fo6Hr01Yro7gSxLlJ5%24%2BTnZcA3n8JLfxtVAXB%24%2BccUiIM7TsNB2WCJiBzcSDZPGQn4YTPxoElwVwZReRHTqu9Mg%24%2BkGc7DT6cy2rWj6fv2NzJCH9WhTZJHtcF8SJEUEbuzhRErsG9Br0ruZQ5ndz8mJMi9TzeKWrXejW0oBwuWo8oZ5r6XEmxIbxX8RJrR%24%2B1ZKYXMHThFirQPThqfQNDD1svSfNd6OXB7fKb%24%2F7Asxfc%24%2F5eo2y5erMi9XD%24%2BRoPO3t0CPHzwtlgyiy%24%2BJKnid3xFGb5YxoXy%24%2Fh%24%2B5o1GDsGeMoWqT9h6YWD%24%2FoYQT1bRM13gwAvaMm0HCeHAi7IU5bD8i6CyNU34YbeHMfl6Vrg4PBLgVVmgmsVXanPS%24%2Fd8%24%2FiWPuPHf%24%2Bq479g8Rc%24%3D%26RelayState%3DL3YxL2RsL2dldGNvbnRlbnQvMzE3Njk0\">Intel 82574 Gigabit Ethernet Controller<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.intel.com\/content\/www\/us\/en\/my-intel\/developer-sign-in.html?redirect=\/content\/www\/us\/en\/design\/resource-design-center.html&amp;TYPE=33554433&amp;REALMOID=06-384e112f-284a-40b5-923f-e57891a2be39&amp;GUID=&amp;SMAUTHREASON=0&amp;METHOD=GET&amp;SMAGENTNAME=%24SM%24QnJMmP%2BN6gMN%2FVVnfgk5wOmI3XqRSADYbdE9VPLR1oGltLZwYJ6CRfT8RxFdy4HV&amp;TARGET=%24SM%24HTTPS%3A%2F%2Fsfederation.intel.com%2Ffederation2%2Fsp%2FCDRv2%2FR1JEQ0NEUlYyUFJPREFURUFN%3FSAMLRequest%3DnVPLbtswEPwVgXfrQQdOQdgOVMluE%24%2BSh0lKA9lLQ1DoRKpEql3Lcvy8tW60OrQ85CZidfcwMNb85NLW3B4OVVgsS%24%2BSG5Wc5RNHXL4s6%24%2BKg4%24%2FO0DrOZpC1hcWpDOKaYEVMiUaQGYl28QP94z6IWuNtlrqmni36YJ8%24%2F0BLIbeCzihEMpzCbLujxHseFroOR0Ts4FahFco6KKTRJJxNous8mrKrGZuGPr26%24%2Fka87Dz6Y6XKSr1cvmN7IiH7nOfZJHva5MSLEcFYtzjRCrsGzAbMvpJQ8PsFebW2RRYEsjTlnvqVslD7UjdBrV8qFUhR11shfxAvdX5USthewNCFOyjB9OCo9S9IA2yDJOV7GvDobvUlfFwV9ddfxfou46t1wYv1IzkZz3o7zMjxy0LFIIosP%24%2FE0cTueacaf0jhfxQ%24%2FzYDRyCPacKZR9ws4LC4d3JZzophWmwqMRcBDSDhLGg5PaXchh9x5BF2mSyeNoB2fu86ZNeXwgIJ2w3AiFrTb2rP9f9yxPtf%24%2FY8ac6%24%2FguWvwE%24%3D%26RelayState%3DL3YxL2RsL2dldENvbnRlbnQvNjEzNDU2\">Intel 82579 Gigabit Ethernet Controller<\/a><\/li>\n<\/ol>\n<\/li>\n\n\n\n<li>igb:\n<ol class=\"wp-block-list\">\n<li>Intel Ethernet Server Adapter i350<\/li>\n\n\n\n<li>Intel Ethernet Server Adapter i210<\/li>\n<\/ol>\n<\/li>\n\n\n\n<li>ixgbe:\n<ol class=\"wp-block-list\">\n<li>Intel Ethernet Controller X540<\/li>\n<\/ol>\n<\/li>\n\n\n\n<li>tg3:\n<ol class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.broadcom.com\/support\/download-search\">Broadcom NetXtreme \/ NetLink BCM5717 BCM5718 BCM5719 BCM5720<\/a><\/li>\n<\/ol>\n<\/li>\n\n\n\n<li>be2net:\n<ol class=\"wp-block-list\">\n<li>Emulex\u00ae OneConnect\u2122 UCNAs and LightPulse\u00ae Fibre Channel HBAs<\/li>\n<\/ol>\n<\/li>\n\n\n\n<li>bnx2:\n<ol class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.broadcom.com\/support\/download-search\">Broadcom NetXtreme II BCM5706 BCM5708C BCM5708S BCM5709C BCM5709S BCM5716<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.broadcom.com\/support\/download-search\">Broadcom BCM57XX<\/a><\/li>\n<\/ol>\n<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-overview\">Overview<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">High level overview of the path of a packet:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Driver is loaded and initialized.<\/li>\n\n\n\n<li>Packet arrives at the NIC from the network.<\/li>\n\n\n\n<li>Packet is copied (via DMA) to a ring buffer in kernel memory.<\/li>\n\n\n\n<li>Hardware interrupt is generated to let the system know a packet is in memory.<\/li>\n\n\n\n<li>Driver calls into <a href=\"https:\/\/wiki.linuxfoundation.org\/networking\/napi\">NAPI<\/a> to start a poll loop if one was not running already.<\/li>\n\n\n\n<li>ksoftirqd processes run on each CPU on the system. They are registered at boot time. The ksoftirqd processes pull packets off the ring buffer by calling the NAPI poll function that the device driver registered during initialization.<\/li>\n\n\n\n<li>Memory regions in the ring buffer that have had network data written to them are unmapped.<\/li>\n\n\n\n<li>Data that was DMA\u2019d into memory is passed up the networking layer as an \u2018skb\u2019 for more processing.<\/li>\n\n\n\n<li>Packet steering happens to distribute packet processing load to multiple CPUs (in leu of a NIC with multiple receive queues), if enabled.<\/li>\n\n\n\n<li>Packets are handed to the protocol layers from the queues.<\/li>\n\n\n\n<li>Protocol layers add them to receive buffers attached to sockets.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-detailed-look\">Detailed look<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-driver-loading-pci\">Driver loading \/ PCI<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">PCI devices identify themselves with a series of registers in the <a href=\"https:\/\/en.wikipedia.org\/wiki\/PCI_configuration_space#Standardized_registers\">PCI configuration space<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When a device driver is compiled, a macro named <code>MODULE_DEVICE_TABLE<\/code> is used to export a table of PCI device IDs identifying devices that the device driver can control. The kernel uses this table to determine which device driver to load to control the device.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When the driver is loaded, a function named <code>pci_register_driver<\/code> is called in the initialization function.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This function registers a structure of function pointers that the kernel can use to initialize the PCI device.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-e1000e\">e1000e<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In the e1000e driver, this structure can be found in <code>drivers\/net\/ethernet\/intel\/e1000e\/netdev.c<\/code> <a href=\"https:\/\/github.com\/torvalds\/linux\/blob\/v3.13\/drivers\/net\/ethernet\/intel\/e1000e\/netdev.c#L7024-L7035\">around line 7035<\/a>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\nstatic struct pci_driver e1000_driver = {\n  .name     = e1000e_driver_name,\n  .id_table = e1000_pci_tbl,\n  .probe    = e1000_probe,\n\n  \/* more stuff  *\/\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">It is registered in <code>e1000_init_module<\/code> in the same file <a href=\"https:\/\/github.com\/torvalds\/linux\/blob\/v3.13\/drivers\/net\/ethernet\/intel\/e1000e\/netdev.c#L7037-L7053\">around line 7043<\/a>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\n\/**\n* e1000_init_module - Driver Registration Routine\n*\n* e1000_init_module is the first routine called when the driver is\n* loaded. All it does is register with the PCI subsystem.\n**\/\n\nstatic int __init e1000_init_module(void)\n{\n  int ret;\n  pr_info(\"Intel(R) PRO\/1000 Network Driver - %s\\n\",\n  e1000e_driver_version);\n  pr_info(\"Copyright(c) 1999 - 2013 Intel Corporation.\\n\");\n  ret = pci_register_driver(&amp;e1000_driver);\n\n  return ret;\n}\nmodule_init(e1000_init_module);\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-igb\">igb<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In the igb driver, this structure can be found in <code>drivers\/net\/ethernet\/intel\/igb\/igb_main.c<\/code> <a href=\"https:\/\/github.com\/torvalds\/linux\/blob\/v3.13\/drivers\/net\/ethernet\/intel\/igb\/igb_main.c#L238-L249\">around line 238<\/a>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\nstatic struct pci_driver igb_driver = {\n  .name = igb_driver_name,\n  .id_table = igb_pci_tbl,\n  .probe = igb_probe,\n  .remove = igb_remove,\n#ifdef CONFIG_PM\n  .driver.pm = &amp;igb_pm_ops,\n#endif\n  .shutdown = igb_shutdown,\n  .sriov_configure = igb_pci_sriov_configure,\n  .err_handler = &amp;igb_err_handler\n};\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">It is registered in <code>igb_init_module<\/code> in the same file <a href=\"https:\/\/github.com\/torvalds\/linux\/blob\/v3.13\/drivers\/net\/ethernet\/intel\/igb\/igb_main.c#L676-L695\">around line 682<\/a>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\nstatic int __init igb_init_module(void)\n{\n  int ret;\n  pr_info(\"%s - version %s\\n\",\n  igb_driver_string, igb_driver_version);\n\n  pr_info(\"%s\\n\", igb_copyright);\n\n#ifdef CONFIG_IGB_DCA\n  dca_register_notify(&amp;dca_notifier);\n#endif\n  ret = pci_register_driver(&amp;igb_driver);\n  return ret;\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-ixgbe\">ixgbe<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In the ixgbe driver, this structure can be found in <code>drivers\/net\/ethernet\/intel\/ixgbe\/ixgbe_main.c<\/code> <a href=\"https:\/\/github.com\/torvalds\/linux\/blob\/v3.13\/drivers\/net\/ethernet\/intel\/ixgbe\/ixgbe_main.c#L8448-L8460\">around line 8448<\/a>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\nstatic struct pci_driver ixgbe_driver = {\n  .name = ixgbe_driver_name,\n  .id_table = ixgbe_pci_tbl,\n  .probe = ixgbe_probe,\n  .remove = ixgbe_remove,\n#ifdef CONFIG_PM\n  .suspend = ixgbe_suspend,\n  .resume = ixgbe_resume,\n#endif\n  .shutdown = ixgbe_shutdown,\n  .sriov_configure = ixgbe_pci_sriov_configure,\n  .err_handler = &amp;ixgbe_err_handler\n};\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">It is registered in <code>ixgbe_init_module<\/code> in the same file <a href=\"https:\/\/github.com\/torvalds\/linux\/blob\/v3.13\/drivers\/net\/ethernet\/intel\/ixgbe\/ixgbe_main.c#L8462-L8487\">around line 8468<\/a>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\nstatic int __init ixgbe_init_module(void)\n{\n  int ret;\n  pr_info(\"%s - version %s\\n\", ixgbe_driver_string, ixgbe_driver_version);\n  pr_info(\"%s\\n\", ixgbe_copyright);\n\n  ixgbe_dbg_init();\n\n  ret = pci_register_driver(&amp;ixgbe_driver);\n  if (ret) {\n    ixgbe_dbg_exit();\n    return ret;\n  }\n\n#ifdef CONFIG_IXGBE_DCA\n  dca_register_notify(&amp;dca_notifier);\n#endif\n\n  return 0;\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-tg3\">tg3<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In the tg3 driver, this structure can be found in <code>drivers\/net\/ethernet\/broadcom\/tg3.c<\/code> <a href=\"https:\/\/github.com\/torvalds\/linux\/blob\/v3.13\/drivers\/net\/ethernet\/broadcom\/tg3.c#L17999-L18007\">around line 17999<\/a>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\nstatic struct pci_driver tg3_driver = {\n  .name = DRV_MODULE_NAME,\n  .id_table = tg3_pci_tbl,\n  .probe = tg3_init_one,\n  .remove = tg3_remove_one,\n  .err_handler = &amp;tg3_err_handler,\n  .driver.pm = &amp;tg3_pm_ops,\n  .shutdown = tg3_shutdown,\n};\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">It is registered in the same file, using a macro <code>module_pci_driver<\/code> (defined in <code>include\/linux\/pci.h<\/code>:1104) just below the structure definition:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\nmodule_pci_driver(tg3_driver);\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-be2net\">be2net<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In the be2net driver, this structure can be found in <code>drivers\/net\/ethernet\/emulex\/benet\/be_main.c<\/code> <a href=\"https:\/\/github.com\/torvalds\/linux\/blob\/v3.13\/drivers\/net\/ethernet\/emulex\/benet\/be_main.c#L4819-L4828\">around line 4819<\/a>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\nstatic struct pci_driver be_driver = {\n  .name = DRV_NAME,\n  .id_table = be_dev_ids,\n  .probe = be_probe,\n  .remove = be_remove,\n  .suspend = be_suspend,\n  .resume = be_resume,\n  .shutdown = be_shutdown,\n  .err_handler = &amp;be_eeh_handlers\n};\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">It is registered in <code>be_init_module<\/code> in the same file <a href=\"https:\/\/github.com\/torvalds\/linux\/blob\/v3.13\/drivers\/net\/ethernet\/emulex\/benet\/be_main.c#L4830-L4842\">around line 4764<\/a>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\nstatic int __init be_init_module(void)\n{\n  if (rx_frag_size != 8192 &amp;&amp; rx_frag_size != 4096 &amp;&amp;\n      rx_frag_size != 2048) {\n    printk(KERN_WARNING DRV_NAME\n    \" : Module param rx_frag_size must be 2048\/4096\/8192.\"\n    \" Using 2048\\n\");\n    rx_frag_size = 2048;\n  }\n\n  return pci_register_driver(&amp;be_driver);\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-bnx2\">bnx2<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In the bnx2 driver, this structure can be found in <code>drivers\/net\/ethernet\/broadcom\/bnx2.c<\/code> <a href=\"https:\/\/github.com\/torvalds\/linux\/blob\/v3.13\/drivers\/net\/ethernet\/broadcom\/bnx2.c#L8759-L8769\">around line 8788<\/a>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\nstatic struct pci_driver bnx2_pci_driver = {\n  .name = DRV_MODULE_NAME,\n  .id_table = bnx2_pci_tbl,\n  .probe = bnx2_init_one,\n  .remove = bnx2_remove_one,\n  .driver.pm = BNX2_PM_OPS,\n  .err_handler = &amp;bnx2_err_handler,\n  .shutdown = bnx2_shutdown,\n};\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">It is registered in the same file just below the structure definition using the <code>module_pci_driver<\/code> macro (from <a href=\"https:\/\/github.com\/torvalds\/linux\/blob\/v3.13\/include\/linux\/pci.h\">include\/linux\/pci.h<\/a>):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\nmodule_pci_driver(bnx2_pci_driver);\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-pci-probe\">PCI probe<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Each driver registers a <code>probe<\/code> function with the PCI system in the kernel.<br>The kernel calls this function to do early initialization of the device.<br>Most drivers have a lot of code that runs to get the device ready for use. The<br>exact things done vary from driver to driver.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The name of the function registered as the <code>probe<\/code> function and a very (very) high level<br>overview of what it does is provided below for each of the drivers.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Generally speaking, the drivers are quite similar in terms of what they do at this stage:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>The <code>ethtool<\/code> (described more in the next parts of this series) functions the driver supports<\/li>\n\n\n\n<li>The NAPI poll function (described more in the next parts of this series) for harvesting incoming packets<\/li>\n\n\n\n<li>The NIC\u2019s MAC address<\/li>\n\n\n\n<li>The higher level <code>net_device<\/code> structure<\/li>\n\n\n\n<li>The hardware IRQ number that will be used by the device when interrupts are (eventually) enabled<\/li>\n\n\n\n<li>Any watchdog tasks needed (for example, <code>e1000e<\/code> has a watchdog task to check if the hardware is hung)<\/li>\n\n\n\n<li>Other device specific stuff like workarounds or dealing with quirks or similar<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">To dig deeper into what each driver\u2019s probe function does, see:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>e1000_probe<\/code> (<a href=\"https:\/\/github.com\/torvalds\/linux\/blob\/v3.13\/drivers\/net\/ethernet\/intel\/e1000e\/netdev.c#L6517-L6854\">drivers\/net\/ethernet\/intel\/e1000e\/netdev.c:6517<\/a>) for <code>e1000e<\/code><\/li>\n\n\n\n<li><code>igb_probe<\/code> (<a href=\"https:\/\/github.com\/torvalds\/linux\/blob\/v3.13\/drivers\/net\/ethernet\/intel\/igb\/igb_main.c#L2005-L2429\">drivers\/net\/ethernet\/intel\/igb\/igb_main.c:2005<\/a>) for <code>igb<\/code><\/li>\n\n\n\n<li><code>ixgbe_probe<\/code> (<a href=\"https:\/\/github.com\/torvalds\/linux\/blob\/v3.13\/drivers\/net\/ethernet\/intel\/ixgbe\/ixgbe_main.c#L7785-L8195\">drivers\/net\/ethernet\/intel\/ixgbe\/ixgbe_main.c:7796<\/a>) for <code>ixgbe<\/code><\/li>\n\n\n\n<li><code>tg3_init_one<\/code> (<a href=\"https:\/\/github.com\/torvalds\/linux\/blob\/v3.13\/drivers\/net\/ethernet\/broadcom\/tg3.c#L17315-L17697\">drivers\/net\/ethernet\/broadcom\/tg3.c:17315<\/a>) for <code>tg3<\/code><\/li>\n\n\n\n<li><code>be_probe<\/code> (<a href=\"https:\/\/github.com\/torvalds\/linux\/blob\/v3.13\/drivers\/net\/ethernet\/emulex\/benet\/be_main.c#L4501-L4621\">drivers\/net\/ethernet\/emulex\/benet\/be_main.c:4501<\/a>) for <code>be2net<\/code><\/li>\n\n\n\n<li><code>bnx2_init_one<\/code> (<a href=\"https:\/\/github.com\/torvalds\/linux\/blob\/v3.13\/drivers\/net\/ethernet\/broadcom\/bnx2.c#L8487-L8551\">drivers\/net\/ethernet\/broadcom\/bnx2.c:8517<\/a>) for <code>bnx2<\/code><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>part 1 | part 2 | part 3 | part 4 | part 5 Purpose This multi-part blog series\u00a0aims to outline the path of a packet from the wire through the network driver and kernel until it reaches the receive queue for a socket. This information pertains to the Linux kernel, release 3.13.0. Links to &hellip; <a href=\"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-1\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Linux networking stack from the ground up, part 1&#8221;<\/span><\/a><\/p>\n","protected":false},"author":9,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_stopmodifiedupdate":true,"_modified_date":"","footnotes":""},"categories":[1],"tags":[],"class_list":["post-1930","post","type-post","status-publish","format-standard","hentry","category-news"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.9 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Linux networking stack from the ground up, part 1<\/title>\n<meta name=\"description\" content=\"part 1 | part 2 | part 3 | part 4 | part 5 Purpose This multi-part blog series&nbsp;aims to outline the path of a packet from the wire through the network\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-1\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Linux networking stack from the ground up, part 1\" \/>\n<meta property=\"og:description\" content=\"part 1 | part 2 | part 3 | part 4 | part 5 Purpose This multi-part blog series&nbsp;aims to outline the path of a packet from the wire through the network\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-1\/\" \/>\n<meta property=\"og:site_name\" content=\"PIA\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/privateinternetaccess\/\" \/>\n<meta property=\"article:published_time\" content=\"2016-01-22T03:02:32+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-01-31T17:29:39+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.privateinternetaccess.com\/blog\/wp-content\/uploads\/2018\/07\/ogimage.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"PIA Research\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@buyvpnservice\" \/>\n<meta name=\"twitter:site\" content=\"@buyvpnservice\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"PIA Research\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-1\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-1\/\"},\"author\":{\"name\":\"PIA Research\",\"@id\":\"https:\/\/www.privateinternetaccess.com\/blog\/#\/schema\/person\/867d81a36eafaf83e91f6528aca0ba29\"},\"headline\":\"Linux networking stack from the ground up, part 1\",\"datePublished\":\"2016-01-22T03:02:32+00:00\",\"dateModified\":\"2024-01-31T17:29:39+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-1\/\"},\"wordCount\":934,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.privateinternetaccess.com\/blog\/#organization\"},\"articleSection\":[\"General Privacy News\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-1\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-1\/\",\"url\":\"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-1\/\",\"name\":\"Linux networking stack from the ground up, part 1\",\"isPartOf\":{\"@id\":\"https:\/\/www.privateinternetaccess.com\/blog\/#website\"},\"datePublished\":\"2016-01-22T03:02:32+00:00\",\"dateModified\":\"2024-01-31T17:29:39+00:00\",\"description\":\"part 1 | part 2 | part 3 | part 4 | part 5 Purpose This multi-part blog series&nbsp;aims to outline the path of a packet from the wire through the network\",\"breadcrumb\":{\"@id\":\"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-1\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-1\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-1\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.privateinternetaccess.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Linux networking stack from the ground up, part 1\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.privateinternetaccess.com\/blog\/#website\",\"url\":\"https:\/\/www.privateinternetaccess.com\/blog\/\",\"name\":\"PIA\",\"description\":\"Online privacy news from around the world.\",\"publisher\":{\"@id\":\"https:\/\/www.privateinternetaccess.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.privateinternetaccess.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.privateinternetaccess.com\/blog\/#organization\",\"name\":\"Private Internet Access\",\"url\":\"https:\/\/www.privateinternetaccess.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.privateinternetaccess.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.privateinternetaccess.com\/blog\/wp-content\/uploads\/2018\/07\/pialogowhitekglogo.png\",\"contentUrl\":\"https:\/\/www.privateinternetaccess.com\/blog\/wp-content\/uploads\/2018\/07\/pialogowhitekglogo.png\",\"width\":1200,\"height\":1200,\"caption\":\"Private Internet Access\"},\"image\":{\"@id\":\"https:\/\/www.privateinternetaccess.com\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/privateinternetaccess\/\",\"https:\/\/x.com\/buyvpnservice\",\"https:\/\/www.instagram.com\/piavpn\/\",\"https:\/\/www.youtube.com\/channel\/UClyJZ47Rizb1xnwuKXDI0_w\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.privateinternetaccess.com\/blog\/#\/schema\/person\/867d81a36eafaf83e91f6528aca0ba29\",\"name\":\"PIA Research\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.privateinternetaccess.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/717a02042be28ce22f2ae82923cdaa82551205b8768e3cd4a8fce14988ed0ccd?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/717a02042be28ce22f2ae82923cdaa82551205b8768e3cd4a8fce14988ed0ccd?s=96&d=mm&r=g\",\"caption\":\"PIA Research\"},\"sameAs\":[\"https:\/\/www.privateinternetaccess.com\"],\"url\":\"https:\/\/www.privateinternetaccess.com\/blog\/author\/piaresearch\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Linux networking stack from the ground up, part 1","description":"part 1 | part 2 | part 3 | part 4 | part 5 Purpose This multi-part blog series&nbsp;aims to outline the path of a packet from the wire through the network","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-1\/","og_locale":"en_US","og_type":"article","og_title":"Linux networking stack from the ground up, part 1","og_description":"part 1 | part 2 | part 3 | part 4 | part 5 Purpose This multi-part blog series&nbsp;aims to outline the path of a packet from the wire through the network","og_url":"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-1\/","og_site_name":"PIA","article_publisher":"https:\/\/www.facebook.com\/privateinternetaccess\/","article_published_time":"2016-01-22T03:02:32+00:00","article_modified_time":"2024-01-31T17:29:39+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.privateinternetaccess.com\/blog\/wp-content\/uploads\/2018\/07\/ogimage.png","type":"image\/png"}],"author":"PIA Research","twitter_card":"summary_large_image","twitter_creator":"@buyvpnservice","twitter_site":"@buyvpnservice","twitter_misc":{"Written by":"PIA Research","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-1\/#article","isPartOf":{"@id":"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-1\/"},"author":{"name":"PIA Research","@id":"https:\/\/www.privateinternetaccess.com\/blog\/#\/schema\/person\/867d81a36eafaf83e91f6528aca0ba29"},"headline":"Linux networking stack from the ground up, part 1","datePublished":"2016-01-22T03:02:32+00:00","dateModified":"2024-01-31T17:29:39+00:00","mainEntityOfPage":{"@id":"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-1\/"},"wordCount":934,"commentCount":0,"publisher":{"@id":"https:\/\/www.privateinternetaccess.com\/blog\/#organization"},"articleSection":["General Privacy News"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-1\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-1\/","url":"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-1\/","name":"Linux networking stack from the ground up, part 1","isPartOf":{"@id":"https:\/\/www.privateinternetaccess.com\/blog\/#website"},"datePublished":"2016-01-22T03:02:32+00:00","dateModified":"2024-01-31T17:29:39+00:00","description":"part 1 | part 2 | part 3 | part 4 | part 5 Purpose This multi-part blog series&nbsp;aims to outline the path of a packet from the wire through the network","breadcrumb":{"@id":"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-1\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-1\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.privateinternetaccess.com\/blog\/linux-networking-stack-from-the-ground-up-part-1\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.privateinternetaccess.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Linux networking stack from the ground up, part 1"}]},{"@type":"WebSite","@id":"https:\/\/www.privateinternetaccess.com\/blog\/#website","url":"https:\/\/www.privateinternetaccess.com\/blog\/","name":"PIA","description":"Online privacy news from around the world.","publisher":{"@id":"https:\/\/www.privateinternetaccess.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.privateinternetaccess.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.privateinternetaccess.com\/blog\/#organization","name":"Private Internet Access","url":"https:\/\/www.privateinternetaccess.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.privateinternetaccess.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.privateinternetaccess.com\/blog\/wp-content\/uploads\/2018\/07\/pialogowhitekglogo.png","contentUrl":"https:\/\/www.privateinternetaccess.com\/blog\/wp-content\/uploads\/2018\/07\/pialogowhitekglogo.png","width":1200,"height":1200,"caption":"Private Internet Access"},"image":{"@id":"https:\/\/www.privateinternetaccess.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/privateinternetaccess\/","https:\/\/x.com\/buyvpnservice","https:\/\/www.instagram.com\/piavpn\/","https:\/\/www.youtube.com\/channel\/UClyJZ47Rizb1xnwuKXDI0_w"]},{"@type":"Person","@id":"https:\/\/www.privateinternetaccess.com\/blog\/#\/schema\/person\/867d81a36eafaf83e91f6528aca0ba29","name":"PIA Research","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.privateinternetaccess.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/717a02042be28ce22f2ae82923cdaa82551205b8768e3cd4a8fce14988ed0ccd?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/717a02042be28ce22f2ae82923cdaa82551205b8768e3cd4a8fce14988ed0ccd?s=96&d=mm&r=g","caption":"PIA Research"},"sameAs":["https:\/\/www.privateinternetaccess.com"],"url":"https:\/\/www.privateinternetaccess.com\/blog\/author\/piaresearch\/"}]}},"_links":{"self":[{"href":"https:\/\/www.privateinternetaccess.com\/blog\/wp-json\/wp\/v2\/posts\/1930","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.privateinternetaccess.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.privateinternetaccess.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.privateinternetaccess.com\/blog\/wp-json\/wp\/v2\/users\/9"}],"replies":[{"embeddable":true,"href":"https:\/\/www.privateinternetaccess.com\/blog\/wp-json\/wp\/v2\/comments?post=1930"}],"version-history":[{"count":18,"href":"https:\/\/www.privateinternetaccess.com\/blog\/wp-json\/wp\/v2\/posts\/1930\/revisions"}],"predecessor-version":[{"id":29809,"href":"https:\/\/www.privateinternetaccess.com\/blog\/wp-json\/wp\/v2\/posts\/1930\/revisions\/29809"}],"wp:attachment":[{"href":"https:\/\/www.privateinternetaccess.com\/blog\/wp-json\/wp\/v2\/media?parent=1930"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.privateinternetaccess.com\/blog\/wp-json\/wp\/v2\/categories?post=1930"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.privateinternetaccess.com\/blog\/wp-json\/wp\/v2\/tags?post=1930"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}