zephyr/doc/subsystems/networking/ip-stack-architecture.rst

107 lines
4.6 KiB
ReStructuredText

.. _ip_stack_architecture:
IP Stack Architecture
#####################
High level overview of the IP stack
***********************************
.. figure:: ip-stack-architecture.svg
:align: center
:alt: Overview of the IP stack architecture
:figclass: align-center
Network stack overview
*The IP stack is layered and it consists of the following parts:*
* **Networking Application.** This application uses the connectivity API to
manipulate a network connection, and management API to set network
related parameters such as starting a scan (when applicable),
setting IP address to a network interface, etc.
* **Core IP stack.** This provides implementations for
various protocols such as IPv6, IPv4, UDP, TCP, ICMPv4 and ICMPv6.
* **Network interface abstraction layer.** This provides functionality
that is common in all the network interfaces, such as acquiring
an IP address, etc.
* **Generic L2 layer.** This provides common API for sending and receiving
data to and from an actual network device.
* **L2 network technology component.** These components include Ethernet,
IEEE 802.15.4, Bluetooth, etc. Some of these technologies support IPv6
header compression (6LoWPAN), which is done in its own layer. For
example ARP for IPv4 is done in the Ethernet component.
* **Network device driver.** The actual low-level device driver handles the
physical sending or receiving of a network packet.
Network data flow
*****************
.. figure:: ip-stack-data-flow.svg
:align: center
:alt: Network data flow
:figclass: align-center
Network data flow
The application typically consists of one or more tasks or threads
that execute the application logic. When using the network
connectivity APIs, following things will happen.
*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 buffers are then passed to the RX FIFO
for further processing. The RX FIFO is used as a way to separate
the data processing pipeline (bottom-half) as the device driver is
running in interrupt context and it must do its processing very fast.
3) The RX thread reads the RX FIFO and passes the data to the correct
L2 driver. After the L2 driver has checked the packet, the packet is
passed to L3 processing. The L3 layer checks if the packet is a proper
IPv6 or IPv4 packet. If the packet contains UDP or TCP data, it
is then sent to correct application via a function callback.
This also means that the application data processing in that callback
is run in thread context even if the actual application is running
in task context. The data processing in the application callback should
be done fast in order not to block the system too long.
There is only one RX thread in the system. The stack size of the RX
thread can be tweaked via Kconfig option but it should be kept as
small as possible. This also means that stack utilization in the
data processing callback should be minimized in order to avoid stack
overflow.
4) The application will then receive the data, which is stored inside a chain
of net_bufs. The application now owns the data. After it has finished working
with it, the application should release the net_bufs data by calling
:cpp:func:`net_pkt_unref()`.
*Data sending (TX):*
1) The application should use the connectivity API when the application is
ready to send data. The sent data is checked by the correct L2 layer module
and if everything is ok, the data is placed into the network interface TX
queue. The network interface is typically selected to be the same interface
for reply data packets or the interface is selected according to the routing
algorithm. The application should not free the data packet if it was
correctly placed into TX queue; the network driver will release the packet
after it is sent. If the connectivity API sending function returns an error
to the application, that means the packet was not sent correctly and the
application needs to free the packet.
2) Each network interface has a dedicated TX queue used to send data to that
interface. A TX thread in the system reads all the TX queues and passes
that data to the correct L2 driver, for sending via the device driver.
3) If the device driver is able to inject the network packet into the
network, then it will release the packet. Typically there are no
retransmits at this lower level so usually the packet is released
even if not sent correctly. This depends on the technology being used.