Haiku Network Stack Architecture================================The Haiku Network Stack is a modular and layered networking stack, verysimilar to what you may know as BONE.The entry point when talking to the stack is through a dedicated devicedriver that publish itself in /dev/net. The userland librarylibnetwork.so (which combines libsocket.so, and libbind.so) directlytalks to this driver, mostly via ioctl()\ `1 <#foot1>`__.The driver either creates sockets, or passes on every command to thesocket module\ `2 <#foot2>`__. Depending on the address family and typeof the sockets, the lower layers will be loaded and connected.For example, with a TCP/IP socket, the stack could look like this:+------------------+--------------------------------------------------------+| **Socket** |+------------------+--------------------------------------------------------+| TCP | Protocols defined by the socket (address family, type) |+------------------+ || IPv4 | (session, transport, network layers) |+------------------+--------------------------------------------------------+| **Datalink** |+------------------+--------------------------------------------------------+| ARP | Datalink Protocols defined by the interface || | (IP address, device) |+------------------+ || Ethernet framing | (datalink layer) |+------------------+--------------------------------------------------------+| Ethernet device | (physical layer) |+------------------+--------------------------------------------------------+Where TCP, and IPv4 are net_protocol modules, and ARP, and the Ethernetframing are net_datalink_protocol modules. All modules are connected ina chain, even though the datalink layer introduces more than one path(one for each interface).When sending data through a socket, a net_buffer is created in thesocket module, and passed on to the lower levels where each protocolprocesses it, before passing it on to the next protocol in the chain.The last protocol in the chain is always a domain protocol - it willdirectly forward the buffers to the datalink module. When the bufferreaches the datalink level, an accompanied net_route object willdetermine for which interface (which determines the datalink protocolsin the chain) the buffer is destined. The route has to be specified bythe upper protocols before the buffer gets into the datalink level - ifa buffer comes in without a valid route, it is discarded.The protocol modules are loaded and unloaded as needed. The stack itselfstays loaded as long as there are interfaces defined - as soon as thelast interface is removed, the stack gets unloaded (which is, of course,not yet implemented).The Structures and Classes~~~~~~~~~~~~~~~~~~~~~~~~~~net_domain^^^^^^^^^^Every supported address family gets its own domain. A domain comprisessuch a family, a net_protocol module that handles this domain, and alist of interfaces and routes. It also gets a name: for example, theIPv4 module registers the "internet" domain (AF_INET).The domain protocol module is responsible for managing the domain; ithas to register it when it's loaded, and it has to unregister it when itis unloaded by the networking stack.net_interface^^^^^^^^^^^^^An interface makes an underlying net_device accessible by the stack.When creating a new interface, you have to specify a domain, and adevice to be used. The stack will then look through the registereddatalink protocols, and builds a chain of them for that interface.The interface usually gets a network address, and a route that directsbuffers to be sent to it. If there is no route to an interface, it willnever be used for outgoing data, but may well receive data from otherhosts.An interface can be "up" (when ``IFF_UP`` is set in its ``flags``member) in which case it accepts data - when that flag is not set, itwill discard all data it gets. The interface also specifies the maximumbuffer size that can be sent over this interface (the ``mtu`` member,a.k.a. maximum transmission unit).Interfaces are configured via ioctl()s (SIOCAIFADDR, ...). You can usethe command line tool "ifconfig" to do this for you.net_device^^^^^^^^^^A networking device is used to actually send and receive the buffers. Iteither points to an actual hardware device (in case of ethernet), or toa virtual device (in case of loopback). Every device has a unique namethat identifies it. When creating a device, the name also decides whichnet_device module will be chosen; for example, everything that startswith "loop" will end up in the loopback device, while the ethernetdevice accepts names that start with "/dev/net/".A device can be shared by many interfaces at the same time. The deviceto be used by an interface is specified at the time an interface iscreated. It also has an ``mtu`` member that determines the upper limitof an interface's ``mtu`` as well.net_buffer^^^^^^^^^^A buffer holds exactly one packet, and has a source as well as adestination address. The addresses may be changed in every layer thebuffer passes through. For example, the datalink protocols usually usesockaddr_dl structures with family AF_DLI, while the upper levels mayuse sockaddr_in structures with family AF_INET. Every protocol onlysupports a small number of address types, and it's the requirement ofthe upper protocols to prepare the address for use in the lowerprotocols (and that's also a reason why it wouldn't work to arbitrarilystack protocols onto each other).The net_buffer module can be used to access the data within the buffer,append new data to the buffer, or remove chunks of data from it.Internally, the buffer consists of usually fixed size (2048 byte)buffers that can be shared or connected as needed.net_socket^^^^^^^^^^The socket is only of interest for the net_protocol modules, as itstores options that may have an effect on the protocol's performance.It's the direct counterpart to a socket file descriptor in userland, butit has only little logic bound to it.When a socket is created, the networking stack creates a chain ofnet_protocol modules for the socket that will then do the real work.When the socket is closed, the net_protocol chain is freed, and themodules are eventually unloaded (if they are no longer in use).net_protocol^^^^^^^^^^^^The protocols are bound to a specific socket, process the outgoingbuffers as needed (ie. add or remove headers, compute checksums, ...),and pass it on to the next protocol. The last protocol in the chain isalways a domain protocol that will forward the calls to the datalinkmodule directly, if needed.A domain protocol is a net_protocol that registered a domain, ie. IPv4.Other than usual protocols, domain protocols have some specialrequirements:- they need to be able to execute send_data(), and get_domain() withouta pointer to its net_protocol object, as those may be called outsideof the socket context.- as mentioned, they also don't talk to the next protocol in the chain(as they are always the last one), but to the datalink moduledirectly.Similar to the need to perform send_data() outside of the socketcontext, all protocols that can receive data need to handle incomingdata without the socket context: incoming data is always handled outsideof the socket context, as the actual target socket is unknown duringprocessing.Only the top-most protocol will be able to forward the packet to thetarget socket(s). To receive incoming data, a protocol must registeritself as receiving protocol with the networking stack. The domainprotocol is usually registered automatically by a net_datalink_protocolmodule that knows about both ends (for example, the ARP module is bothIPv4 and ethernet specific, and therefore registers the AF_INET domainto receive ethernet packets of type IP).net_datalink_protocol^^^^^^^^^^^^^^^^^^^^^The datalink protocols are bound to a specific net_interface, andtherefore to a specific net_device as well. Outgoing data is processedso that it can be sent via the net_device. For example, the ARP protocolwill replace sockaddr_in structures in the buffer with sockaddr_dlstructures describing the ethernet MAC address of the source anddestination hosts, the ethernet_frame protocol will add the usualethernet header, etc.The last protocol in the chain is also a special device interface bridgeprotocol, that redirects the calls to the underlying net_device.Incoming data is handled differently again; when you want to receivedata directly coming from a device, you can either register a deframingfunction for it, or a handler that will be called depending on what datatype the deframing module reported. For example, the ethernet_framemodule registers an ethernet deframing function, while the ARP moduleregisters a handler for ethernet ARP packets with the device. When thedeframing function reports a ``ETHER_TYPE_ARP`` packet, the ARPreceiving function will be called.net_route^^^^^^^^^A route determines the target interface of an outgoing packet. A routeis always owned by a specific domain, and the route is chosen bycomparing the networking address of the outgoing buffer with the maskand address of the route.A protocol will usually not use the routes directly, but use anet_route_info object (see below), that will make sure that the route isupdated automatically whenever the routing table is changed.net_route_info^^^^^^^^^^^^^^A routing helper for protocol usage: it stores the target address aswell as the route to be used, and has to be registered with thenetworking stack via ``register_route_info()``.Then, the stack will automatically update the route as needed, wheneverthe routing table of the domain changes; it will always matches theaddress specified there. When the routing is no longer needed, you mustunregister the net_route_info again.--------------| 1 You can find the definition of the driver interface in`headers/private/net/net_stack_interface.h <https://git.haiku-os.org/haiku/tree/headers/private/net>`__,as well as the driver itself at`src/add-ons/kernel/drivers/network <https://git.haiku-os.org/haiku/tree/src/add-ons/kernel/drivers/network>`__| 2\ `src/add-ons/kernel/network/stack/ <https://git.haiku-os.org/haiku/tree/src/add-ons/kernel/network/stack>`__