EthernetEthernet frame handling.
This module implements the lowest layer of the Mnet network stack. It manages reading and writing Ethernet frames on a network device, decoding the protocol field to dispatch incoming frames to the appropriate upper-layer handler (ARP, IPv4, or IPv6).
create spawns a background daemon that continuously reads frames from the network device. Each incoming frame is decoded and dispatched to a handler function. The handler runs synchronously within the daemon's task — it does not run as a separate Miou task. This means the handler must not perform I/O that would write back to the same device (which would cause a deadlock). Upper-layer responses should be written from a different Miou task.
Multiple handlers can be registered using set_handler and extend_handler_with. When a handler does not know how to process a packet, it calls uninteresting_packet to pass control to the next handler in the chain.
module Packet : sig ... endtype 'net hypercalls = {device : 'net;swr : 'net -> ?off:int -> ?len:int -> Bstr.t -> unit;srd : 'net -> ?off:int -> ?len:int -> Bstr.t -> int;}Low-level I/O operations for a network device. This abstracts over the underlying platform (Solo5, Unikraft, or a custom backend):
device: the network device handleswr: write (send) a frame to the devicesrd: read (receive) a frame from the device, returning the number of bytes readAn existentially-typed wrapper around hypercalls, allowing the Ethernet layer to work with any device type.
The Ethernet layer state. Provides access to the MAC address, MTU, and frame-writing capabilities.
The background task that reads frames from the device and dispatches them to registered handlers. Must be terminated with kill.
A packet ready to be dispatched to a handler. The payload is polymorphic: for incoming packets it is a Slice_bstr.t pointing into the received frame. src is None for frames originating from the local device.
type handler = Slice_bstr.t packet -> unitThe type of a function that processes incoming Ethernet frames. A handler receives the decoded packet (with its payload as a slice of the original frame) and should process it or call uninteresting_packet to pass it along.
set_handler t handler replaces the current handler with handler. This is typically called once during initialization to install the combined ARP + IPv4 + IPv6 handler.
extend_handler_with t handler adds handler to the handler chain. If handler calls uninteresting_packet, the previously installed handler gets a chance to process the packet.
Call this from within a handler when the packet is not relevant to the handler. This transfers control to the next handler in the chain (if any). This function does not return.
val write_directly_into :
t ->
?len:int ->
?src:Macaddr.t ->
dst:Macaddr.t ->
protocol:protocol ->
(Bstr.t -> int) ->
unitwrite_directly_into t ~dst ~protocol fn allocates a frame buffer, writes the Ethernet header (source MAC, dst, and protocol), then calls fn buf where buf starts after the Ethernet header. fn should write the payload and return the number of payload bytes written.
?len is a hint for the total frame size (including the Ethernet header).?src overrides the source MAC address (defaults to the device's own MAC address).This is the low-level frame writing primitive used by IPv4 and IPv6 to send packets.
val create :
?mtu:int ->
?handler:(Slice_bstr.t packet -> unit) ->
?hypercalls:extern ->
Macaddr.t ->
Mkernel.Net.t ->
(daemon * t, [> `MTU_too_small ]) resultcreate ?mtu ?handler ?hypercalls mac net creates an Ethernet layer for the given network device net with MAC address mac.
?mtu overrides the device MTU. Returns `MTU_too_small if the MTU is too small to carry even the smallest valid frame.?handler is the initial frame handler (can be set later via set_handler).?hypercalls provides custom I/O operations. If omitted, the default Mkernel network device operations are used.Note: The handler runs within the daemon's read loop, not in a separate Miou task. It must not attempt to write frames on the same device or a deadlock will occur.
val kill : daemon -> unitkill daemon terminates the background frame-reading task. After calling kill, no more frames will be received.
val mtu : t -> intmtu t returns the Maximum Transmission Unit (in bytes) of the underlying network device. This is the maximum payload size for a single Ethernet frame (typically 1500 bytes).
macaddr t returns the MAC address of the underlying device. Same as mac.
val tags : t -> Logs.Tag.settags t returns logging tags containing the MAC address of the device. Useful for structured logging output with Logs.