78 lines
2.5 KiB
Nim
78 lines
2.5 KiB
Nim
# core/rumpk/core/netswitch.nim
|
|
# Phase 36.2: The Traffic Cop (Network Membrane Layer 2 Switch)
|
|
#
|
|
# Responsibilities:
|
|
# - Poll VirtIO-Net hardware for incoming packets
|
|
# - Route RX packets to s_net_rx ring (Kernel -> Userland)
|
|
# - Drain s_net_tx ring and transmit via VirtIO-Net (Userland -> Kernel)
|
|
# - Never yield during active traffic (War Mode latency optimization)
|
|
|
|
{.push stackTrace: off, lineTrace: off.}
|
|
|
|
import ion
|
|
|
|
# Forward declare fiber_yield to avoid circular import
|
|
proc fiber_yield*() {.importc, cdecl.}
|
|
|
|
# HAL Imports
|
|
proc virtio_net_poll() {.importc, cdecl.}
|
|
proc virtio_net_send(data: pointer, len: uint32) {.importc, cdecl.}
|
|
|
|
# Logging
|
|
proc kprintln(s: cstring) {.importc, cdecl.}
|
|
|
|
var netswitch_initialized: bool = false
|
|
|
|
proc netswitch_init*() =
|
|
## Initialize network channels and populate SysTable
|
|
## MUST be called before userland starts!
|
|
ion_init_network()
|
|
kprintln("[NetSwitch] Network Rings Initialized")
|
|
netswitch_initialized = true
|
|
|
|
proc netswitch_attach_systable*(sys: ptr SysTable) =
|
|
## Attach network ring pointers to SysTable for userland access
|
|
sys.s_net_rx = chan_net_rx.ring
|
|
sys.s_net_tx = chan_net_tx.ring
|
|
kprintln("[NetSwitch] SysTable Rings Attached")
|
|
|
|
proc fiber_netswitch_entry*() {.cdecl.} =
|
|
kprintln("[NetSwitch] Fiber Entry - The Traffic Cop is ON DUTY")
|
|
|
|
var rx_activity: bool = false
|
|
var tx_activity: bool = false
|
|
|
|
while true:
|
|
rx_activity = false
|
|
tx_activity = false
|
|
|
|
# ============================================
|
|
# RX PATH: Hardware -> chan_net_rx -> Userland
|
|
# ============================================
|
|
# virtio_net_poll() internally calls ion_ingress() which pushes
|
|
# received packets to the hardware driver's internal ring.
|
|
# We poll here to drive the RX path.
|
|
virtio_net_poll()
|
|
|
|
# ============================================
|
|
# TX PATH: Userland -> chan_net_tx -> Hardware
|
|
# ============================================
|
|
var tx_pkt: IonPacket
|
|
while chan_net_tx.recv(tx_pkt):
|
|
if tx_pkt.data != nil and tx_pkt.len > 0:
|
|
virtio_net_send(cast[pointer](tx_pkt.data), uint32(tx_pkt.len))
|
|
ion_free(tx_pkt)
|
|
tx_activity = true
|
|
|
|
# ============================================
|
|
# YIELD STRATEGY
|
|
# ============================================
|
|
if rx_activity or tx_activity:
|
|
# War Mode: Continue processing if we moved data
|
|
continue
|
|
else:
|
|
# Peace Mode: Yield to let other fibers run
|
|
fiber_yield()
|
|
|
|
{.pop.}
|