| .. _network_stack_architecture: |
| |
| Network Stack Architecture |
| ########################## |
| |
| .. toctree:: |
| :maxdepth: 1 |
| :hidden: |
| |
| net_pkt_processing_stats.rst |
| |
| The Zephyr network stack is a native network stack specifically designed |
| for Zephyr OS. It consists of layers, each meant to provide certain services |
| to other layers. Network stack functionality is highly configurable via Kconfig |
| options. |
| |
| .. contents:: |
| :local: |
| :depth: 2 |
| |
| High level overview of the network stack |
| **************************************** |
| |
| .. figure:: zephyr_netstack_overview.svg |
| :alt: Overview of the network stack architecture |
| :figclass: align-center |
| |
| Network stack overview |
| |
| The network stack is layered and consists of the following parts: |
| |
| * **Network Application.** The network application can either use the provided |
| application-level protocol libraries or access the |
| :ref:`BSD socket API <bsd_sockets_interface>` directly to create a network |
| connection, send or receive data, and close a connection. The application can |
| also use the :ref:`network management API <net_mgmt_interface>` to configure |
| the network and set related parameters such as network link options, |
| starting a scan (when applicable), listen network configuration events, etc. |
| The :ref:`network interface API <net_if_interface>` can be used to set IP |
| address to a network interface, taking the network interface down, etc. |
| |
| * **Network Protocols.** This provides implementations for |
| various protocols such as |
| |
| * Application-level network protocols like CoAP, LWM2M, and MQTT. |
| See :ref:`application protocols chapter <net_protocols>` for information |
| about them. |
| * Core network protocols like IPv6, IPv4, UDP, TCP, ICMPv4, and ICMPv6. |
| You access these protocols by using the |
| :ref:`BSD socket API <bsd_sockets_interface>`. |
| |
| * **Network Interface Abstraction.** This provides functionality |
| that is common in all the network interfaces, such as setting network |
| interface down, etc. There can be multiple network interfaces in the system. |
| See :ref:`network interface overview <net_if_interface>` for more details. |
| |
| * **L2 Network Technologies.** This provides a common API for sending and |
| receiving data to and from an actual network device. |
| See :ref:`L2 overview <net_l2_interface>` for more details. |
| These network technologies include :ref:`Ethernet <ethernet_interface>`, |
| :ref:`IEEE 802.15.4 <ieee802154_interface>`, |
| :ref:`Bluetooth <bluetooth_api>`, :ref:`CANBUS <can_api>`, etc. |
| Some of these technologies support IPv6 header compression (6Lo), |
| see `RFC 6282 <https://tools.ietf.org/html/rfc6282>`_ for details. |
| For example `ARP <https://tools.ietf.org/html/rfc826>`_ for IPv4 is done by |
| the :ref:`Ethernet component <ethernet_interface>`. |
| |
| * **Network Device Drivers.** The actual low-level device drivers handle the |
| physical sending or receiving of network packets. |
| |
| Network data flow |
| ***************** |
| |
| An application typically consists of one or more :ref:`threads <threads_v2>` |
| that execute the application logic. When using the |
| :ref:`BSD socket API <bsd_sockets_interface>`, the following things will |
| happen. |
| |
| .. figure:: zephyr_netstack_overview-rx_sequence.svg |
| :alt: Network RX data flow |
| :figclass: align-center |
| |
| Network RX data flow |
| |
| Data receiving (RX) |
| ------------------- |
| |
| 1. A network data packet is received by a device driver. |
| |
| 2. The device driver allocates enough network buffers to store the received |
| data. The network packet is placed in the proper RX queue (implemented by |
| :ref:`k_fifo <fifos_v2>`). By default there is only one receive queue in |
| the system, but it is possible to have up to 8 receive queues. |
| These queues will process incoming packets with different priority. |
| See :ref:`traffic-class-support` for more details. The receive queues also |
| act as a way to separate the data processing pipeline (bottom-half) as |
| the device driver is running in an interrupt context and it must do its |
| processing as fast as possible. |
| |
| 3. The network packet is then passed to the correct L2 driver. The L2 driver |
| can check if the packet is proper and modify it if needed, e.g. strip L2 |
| header and frame check sequence, etc. |
| |
| 4. The packet is processed by a network interface. The network statistics are |
| collected if enabled by :kconfig:option:`CONFIG_NET_STATISTICS`. |
| |
| 5. The packet is then passed to L3 processing. If the packet is IP based, |
| then the L3 layer checks if the packet is a proper IPv6 or IPv4 packet. |
| |
| 6. A socket handler then finds an active socket to which the network packet |
| belongs and puts it in a queue for that socket, in order to separate the |
| networking code from the application. Typically the application is run in |
| userspace context and the network stack is run in kernel context. |
| |
| 7. The application will then receive the data and can process it as needed. |
| The application should have used the |
| :ref:`BSD socket API <bsd_sockets_interface>` to create a socket |
| that will receive the data. |
| |
| |
| .. figure:: zephyr_netstack_overview-tx_sequence.svg |
| :alt: Network TX data flow |
| :figclass: align-center |
| |
| Network TX data flow |
| |
| Data sending (TX) |
| ----------------- |
| |
| 1. The application should use the |
| :ref:`BSD socket API <bsd_sockets_interface>` when sending the data. |
| |
| 2. The application data is prepared for sending to kernel space and then |
| copied to internal net_buf structures. |
| |
| 3. Depending on the socket type, a protocol header is added in front of the |
| data. For example, if the socket is a UDP socket, then a UDP header is |
| constructed and placed in front of the data. |
| |
| 4. An IP header is added to the network packet for a UDP or TCP packet. |
| |
| 5. The network stack will check that the network interface is properly set |
| for the network packet, and also will make sure that the network interface |
| is enabled before the data is queued to be sent. |
| |
| 6. The network packet is then classified and placed to the proper transmit |
| queue (implemented by :ref:`k_fifo <fifos_v2>`). By default there is only |
| one transmit queue in the system, but it is possible to have up to 8 |
| transmit queues. These queues will process the sent packets with different |
| priority. See :ref:`traffic-class-support` for more details. |
| After the transmit packet classification, the packet is checked by the |
| correct L2 layer module. The L2 module will do additional checks for the |
| data and it will also create any L2 headers for the network packet. |
| If everything is ok, the data is given to the network device driver to be |
| sent out. |
| |
| 7. The device driver will send the packet to the network. |
| |
| Note that in both the TX and RX data paths, the queues |
| (:ref:`k_fifo's <fifos_v2>`) form separation points where data is passed from |
| one :ref:`thread <threads_v2>` to another. |
| These :ref:`threads <threads_v2>` might run in different contexts |
| (:ref:`kernel <kernel_api>` vs. :ref:`userspace <usermode_api>`) and with different |
| :ref:`priorities <scheduling_v2>`. |
| |
| |
| Network packet processing statistics |
| ************************************ |
| |
| See information about network processing statistics |
| :ref:`here <net_pkt_processing_stats>`. |