net — Network Device Models
The net sub-module provides a complete Ethernet networking stack for gem5: multiple NIC models (NsGigE, IGbE, Sinic), link and bus topologies, Ethernet switches, packet capture, and distributed simulation support for multi-node network experiments.
📚 What is this?
The net module simulates Ethernet networking so that guest operating systems can send and receive network packets inside gem5. It models the full path from NIC hardware registers and DMA engines to Ethernet wires and switches, enabling researchers to study network I/O performance, driver behavior, and protocol stacks under realistic conditions.
💡 Analogy: A Postal System
Think of gem5's network sub-module as a model postal system. Each NIC is a post office in a building (the simulated machine) — it has outgoing/incoming mailboxes (descriptor rings), a mail truck (DMA engine), and a sorting room (packet FIFO). The EtherLink is the road between two post offices — it has a speed limit (bandwidth) and travel time (latency). The EtherSwitch is a central sorting facility that reads the address label (MAC address) on each envelope (packet) and routes it to the right road. The EtherBus is like a shared megaphone line — everyone hears everything (broadcast domain). And EtherDump is a mail inspector that photographs every envelope passing by (pcap capture).
📜 Table of Contents
Network Architecture
The network simulation layer has three tiers: NIC devices (connecting to the PCI bus), the interconnect (links, buses, switches), and the external interface (TAP devices, distributed simulation):
flowchart LR
subgraph Machine1["Simulated Machine 1"]
CPU1["CPU"] -->|"PIO/DMA"| NIC1["NsGigE / IGbE\n(PCI NIC)"]
NIC1 --> IF1["EtherInt\n(interface)"]
end
subgraph Interconnect["Network Fabric"]
IF1 --> LINK1["EtherLink\n(bandwidth + delay)"]
LINK1 --> SW["EtherSwitch\n(MAC learning)"]
SW --> LINK2["EtherLink"]
SW --> LINK3["EtherLink"]
end
subgraph Machine2["Simulated Machine 2"]
LINK2 --> IF2["EtherInt"]
IF2 --> NIC2["IGbE\n(PCI NIC)"]
NIC2 -->|"PIO/DMA"| CPU2["CPU"]
end
subgraph External["External"]
LINK3 --> TAP["EtherTap\n(host TAP device)"]
TAP --> HOST["Host Network"]
end
DUMP["EtherDump\n(pcap capture)"] -.->|"monitors"| LINK1
NIC Models
gem5 includes three Ethernet NIC models, each implementing different real-world hardware:
NsGigE — National Semiconductor DP83820
A model of the National Semiconductor DP83820 Gigabit Ethernet controller. It implements the full register set, transmit/receive descriptor rings, and DMA engine. This is one of the most mature NIC models in gem5.
| Feature | Details |
|---|---|
| Registers | Full NS DP83820 register map in ns_gige_reg.h |
| Descriptor Rings | TX and RX descriptor rings with DMA-based descriptor fetch |
| Interrupts | PCI legacy (INTx) interrupt support |
| PCI Device | Inherits from PciEndpoint (was EtherDevBase) |
IGbE — Intel 8254x Gigabit Ethernet
A model of the Intel 82574L Gigabit Ethernet NIC. Supports advanced features including multiple TX/RX queues, interrupt coalescing, TCP/IP checksum offload, and detailed register-level emulation defined in i8254xGBe_defs.hh.
| Feature | Details |
|---|---|
| Registers | Detailed Intel 8254x register definitions in i8254xGBe_defs.hh |
| DMA Engine | Full descriptor DMA with completion writeback |
| Offloads | Checksum offload, interrupt throttling |
| PCI Device | Inherits from PciEndpoint |
Sinic — gem5-Native NIC
A simplified, gem5-native Ethernet NIC designed for simulation efficiency. It reduces the complexity of real NIC emulation while still providing accurate timing. Defined in sinic.hh with register layout in sinicreg.hh.
Interconnect Components
EtherLink — Point-to-Point Link
Models a fixed-bandwidth, full-duplex Ethernet link with configurable delay. Internally it contains two unidirectional Link objects and two Interface endpoints:
// EtherLink internals
class EtherLink : public SimObject {
protected:
class Link {
const double ticksPerByte; // bandwidth model
const Tick linkDelay; // propagation delay
const Tick delayVar; // delay jitter
EtherDump *const dump; // optional packet capture
std::deque<std::pair<Tick, EthPacketPtr>> txQueue;
bool transmit(EthPacketPtr packet);
};
class Interface : public EtherInt {
Link *txlink;
bool recvPacket(EthPacketPtr pkt) {
return txlink->transmit(pkt);
}
};
Link *link[2]; // two directions
Interface *interface[2]; // two endpoints
};
EtherBus — Shared Medium
EtherBus models a shared Ethernet segment (like a hub or classic coaxial Ethernet). All connected interfaces receive every packet — it implements a broadcast domain with configurable speed.
EtherSwitch — Learning Switch
EtherSwitch implements a basic L2 learning switch. It maintains a MAC address table and forwards packets only to the appropriate port, reducing unnecessary traffic compared to EtherBus.
EtherInt — Interface Base Class
EtherInt is the abstract interface class that all network endpoints implement. It defines the recvPacket() and sendDone() contract for passing Ethernet frames between components.
Packet Handling
EthPacketPtr
Ethernet frames are represented by EthPacketPtr (a shared pointer to EthPacketData). The packet contains raw frame bytes including Ethernet header, payload, and (optionally) CRC.
PktFifo
NICs use PktFifo as an internal packet buffer. It provides a FIFO queue with a maximum size in bytes, supporting push/pop operations and serialization for checkpointing.
EtherDump — Packet Capture
EtherDump captures packets traversing a link and writes them in pcap format, enabling analysis with tools like Wireshark or tcpdump:
// Configuration example
dump = EtherDump(file='network_trace.pcap')
link = EtherLink(speed='1Gbps', delay='1us', dump=dump)
Distributed Simulation
gem5 supports multi-process distributed simulation where separate gem5 instances communicate over a real network. This enables simulating multi-node clusters:
DistIface — Distribution Interface
DistIface is the abstract base class for distributed simulation. It manages:
- Synchronization — barrier-based sync across all gem5 processes
- Packet forwarding — sending/receiving Ethernet frames between processes
- Time coordination — ensuring consistent simulation time across nodes
TcpIface
TcpIface implements DistIface using TCP sockets for inter-process communication. It provides the concrete transport layer for distributed simulation.
DistEtherLink
DistEtherLink replaces EtherLink in distributed setups. It connects a local NIC to a DistIface that forwards packets to remote gem5 instances over the network.
flowchart TD
subgraph Process1["gem5 Process 1"]
NIC1["NIC Model"] --> DLINK1["DistEtherLink"]
DLINK1 --> DIFACE1["DistIface\n(TcpIface)"]
end
subgraph Process2["gem5 Process 2"]
DIFACE2["DistIface\n(TcpIface)"] --> DLINK2["DistEtherLink"]
DLINK2 --> NIC2["NIC Model"]
end
subgraph Sync["Synchronization"]
DIFACE1 <-->|"TCP socket\n+ barrier sync"| DIFACE2
end
EtherTap — Host Network Bridge
EtherTap bridges simulated Ethernet to the host machine's network via a TAP device. This allows the simulated machine to communicate with real network hosts:
// Python configuration for host bridging
tap = EtherTap(tun_clone_device='/dev/net/tun',
tap_device_name='gem5-tap0')
link = EtherLink(speed='1Gbps')
link.int0 = nic.interface
link.int1 = tap.interface
Key Classes Reference
| Class | File | Inherits | Role |
|---|---|---|---|
EtherDevice | etherdevice.hh | PciEndpoint | Abstract base for PCI Ethernet NICs |
NsGigE | ns_gige.hh | EtherDevice | National Semiconductor DP83820 NIC model |
IGbE | i8254xGBe.hh | PciEndpoint | Intel 8254x Gigabit Ethernet NIC model |
Sinic::Device | sinic.hh | PciEndpoint | gem5-native simplified NIC |
EtherLink | etherlink.hh | SimObject | Fixed-bandwidth full-duplex Ethernet link |
EtherBus | etherbus.hh | SimObject | Shared broadcast Ethernet segment |
EtherSwitch | etherswitch.hh | SimObject | L2 learning Ethernet switch |
EtherInt | etherint.hh | — | Abstract Ethernet interface endpoint |
EthPacketData | etherpkt.hh | — | Raw Ethernet frame data container |
PacketFifo | pktfifo.hh | — | Byte-limited FIFO buffer for Ethernet packets |
EtherDump | etherdump.hh | SimObject | Pcap packet capture for debugging/analysis |
EtherTap | ethertap.hh | SimObject | Bridge to host TAP device for real-network access |
DistIface | dist_iface.hh | Drainable | Abstract distributed simulation interface |
TcpIface | tcp_iface.hh | DistIface | TCP-based transport for distributed simulation |
DistEtherLink | dist_etherlink.hh | SimObject | EtherLink replacement for distributed setups |
Configuration Reference
| Parameter | Python Class | Default | Description |
|---|---|---|---|
speed | EtherLink | '1Gbps' | Link bandwidth |
delay | EtherLink | '0us' | Propagation delay per packet |
delay_var | EtherLink | '0ns' | Random delay jitter |
dump | EtherLink | NULL | EtherDump object for packet capture |
output_buffers | EtherSwitch | 16 | Per-port output buffer count |
delay | EtherSwitch | '0us' | Switch forwarding delay |
fabric_speed | EtherSwitch | '10Gbps' | Internal switching fabric bandwidth |
hardware_address | EtherDevice | '00:90:00:00:00:01' | NIC MAC address |
rx_fifo_size | EtherDevice | '512KiB' | Receive FIFO size |
tx_fifo_size | EtherDevice | '512KiB' | Transmit FIFO size |
file | EtherDump | — | Pcap output file path |
sync_repeat | DistEtherLink | '10us' | Distributed sync interval |
dist_rank | DistEtherLink | 0 | Process rank for distributed sim |
dist_size | DistEtherLink | 1 | Total number of distributed processes |
Example Configuration
A typical two-machine network setup in gem5 Python configuration:
// Python config (shown as pseudo-C++ for highlighting)
// Create NICs
nic0 = IGbE(pci_bus=0, pci_dev=2, pci_func=0)
nic1 = IGbE(pci_bus=0, pci_dev=2, pci_func=0)
// Create link with 1Gbps bandwidth and 1us delay
link = EtherLink(speed='1Gbps', delay='1us')
// Connect NIC interfaces to link endpoints
link.int0 = nic0.interface
link.int1 = nic1.interface
// Attach NICs to their respective systems
system0.pci_host.attach(nic0)
system1.pci_host.attach(nic1)
File Map
net/ directory structure
src/dev/net/
├── etherdevice.hh/cc ← EtherDevice base (PCI NIC with descriptor rings)
├── ns_gige.hh/cc ← NsGigE NIC model (National Semiconductor DP83820)
├── ns_gige_reg.h ← NS DP83820 register definitions
├── i8254xGBe.hh/cc ← IGbE NIC model (Intel 8254x)
├── i8254xGBe_defs.hh ← Intel 8254x register definitions
├── sinic.hh/cc ← Sinic NIC model (gem5-native simplified NIC)
├── sinicreg.hh ← Sinic register definitions
├── etherlink.hh/cc ← EtherLink (point-to-point link model)
├── etherbus.hh/cc ← EtherBus (shared broadcast medium)
├── etherswitch.hh/cc ← EtherSwitch (L2 learning switch)
├── etherint.hh/cc ← EtherInt (abstract interface endpoint)
├── etherpkt.hh/cc ← EthPacketData (Ethernet frame container)
├── pktfifo.hh/cc ← PacketFifo (byte-limited packet FIFO)
├── etherdump.hh/cc ← EtherDump (pcap packet capture)
├── ethertap.hh/cc ← EtherTap (host TAP device bridge)
├── dist_iface.hh/cc ← DistIface (distributed simulation base)
├── dist_etherlink.hh/cc ← DistEtherLink (distributed EtherLink)
├── dist_packet.hh ← DistPacket (serialization for dist. sim)
├── tcp_iface.hh/cc ← TcpIface (TCP transport for dist. sim)
├── Ethernet.py ← Python config bindings
├── Kconfig ← Build configuration options
├── SConscript ← Build definitions
└── SConsopts ← Build option definitions
Glossary
| Term | Definition |
|---|---|
| NIC | Network Interface Card — hardware that sends/receives Ethernet frames |
| Descriptor Ring | Circular buffer in host memory shared between NIC and driver for DMA transfers |
| EtherInt | Abstract interface for connecting network components (NIC↔Link↔Switch) |
| TAP | TUN/TAP virtual network device allowing userspace programs to inject packets |
| pcap | Packet capture format used by tcpdump/Wireshark for network analysis |
| MAC Learning | Switch process of observing source MAC addresses to build forwarding table |
| Broadcast Domain | Network segment where all frames are visible to all members (EtherBus) |