net — Network Device Models

Ethernet NIC, Link, and Switch Simulation

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.

3 NIC Models EtherLink EtherSwitch Distributed Sim

📚 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.

FeatureDetails
RegistersFull NS DP83820 register map in ns_gige_reg.h
Descriptor RingsTX and RX descriptor rings with DMA-based descriptor fetch
InterruptsPCI legacy (INTx) interrupt support
PCI DeviceInherits 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.

FeatureDetails
RegistersDetailed Intel 8254x register definitions in i8254xGBe_defs.hh
DMA EngineFull descriptor DMA with completion writeback
OffloadsChecksum offload, interrupt throttling
PCI DeviceInherits 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

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:

TcpIface

TcpIface implements DistIface using TCP sockets for inter-process communication. It provides the concrete transport layer for distributed simulation.

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

ClassFileInheritsRole
EtherDeviceetherdevice.hhPciEndpointAbstract base for PCI Ethernet NICs
NsGigEns_gige.hhEtherDeviceNational Semiconductor DP83820 NIC model
IGbEi8254xGBe.hhPciEndpointIntel 8254x Gigabit Ethernet NIC model
Sinic::Devicesinic.hhPciEndpointgem5-native simplified NIC
EtherLinketherlink.hhSimObjectFixed-bandwidth full-duplex Ethernet link
EtherBusetherbus.hhSimObjectShared broadcast Ethernet segment
EtherSwitchetherswitch.hhSimObjectL2 learning Ethernet switch
EtherIntetherint.hh—Abstract Ethernet interface endpoint
EthPacketDataetherpkt.hh—Raw Ethernet frame data container
PacketFifopktfifo.hh—Byte-limited FIFO buffer for Ethernet packets
EtherDumpetherdump.hhSimObjectPcap packet capture for debugging/analysis
EtherTapethertap.hhSimObjectBridge to host TAP device for real-network access
DistIfacedist_iface.hhDrainableAbstract distributed simulation interface
TcpIfacetcp_iface.hhDistIfaceTCP-based transport for distributed simulation
DistEtherLinkdist_etherlink.hhSimObjectEtherLink replacement for distributed setups

Configuration Reference

ParameterPython ClassDefaultDescription
speedEtherLink'1Gbps'Link bandwidth
delayEtherLink'0us'Propagation delay per packet
delay_varEtherLink'0ns'Random delay jitter
dumpEtherLinkNULLEtherDump object for packet capture
output_buffersEtherSwitch16Per-port output buffer count
delayEtherSwitch'0us'Switch forwarding delay
fabric_speedEtherSwitch'10Gbps'Internal switching fabric bandwidth
hardware_addressEtherDevice'00:90:00:00:00:01'NIC MAC address
rx_fifo_sizeEtherDevice'512KiB'Receive FIFO size
tx_fifo_sizeEtherDevice'512KiB'Transmit FIFO size
fileEtherDump—Pcap output file path
sync_repeatDistEtherLink'10us'Distributed sync interval
dist_rankDistEtherLink0Process rank for distributed sim
dist_sizeDistEtherLink1Total 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

TermDefinition
NICNetwork Interface Card — hardware that sends/receives Ethernet frames
Descriptor RingCircular buffer in host memory shared between NIC and driver for DMA transfers
EtherIntAbstract interface for connecting network components (NIC↔Link↔Switch)
TAPTUN/TAP virtual network device allowing userspace programs to inject packets
pcapPacket capture format used by tcpdump/Wireshark for network analysis
MAC LearningSwitch process of observing source MAC addresses to build forwarding table
Broadcast DomainNetwork segment where all frames are visible to all members (EtherBus)