Skip to main content
The dev collector provides information about network devices, either from a struct net_device available in probe arguments or through a struct sk_buff and its device reference.

Overview

The dev collector extracts network device (interface) information as packets flow through the networking stack. This helps identify which interfaces packets are traversing and correlate events with specific network devices.

What Data is Retrieved

The dev collector retrieves:
  • Device name: Network interface name (e.g., “eth0”, “wlan0”)
  • Interface index (ifindex): Unique numeric identifier for the device
  • Rx interface index (rx_ifindex): Input interface for received packets (when available)

Probe Installation

The dev collector does not install any probes. It only retrieves data when network device information is available in probe arguments.
The collector activates automatically when probes have:
  • struct net_device * parameters
  • struct sk_buff * parameters (reads skb->dev)

Command-Line Options

The dev collector has no specific command-line options.

Event Sections Produced

The dev collector produces the dev event section. See dev event documentation for detailed format.

Event Format

if {ifindex} ({name})
With optional receive interface:
if {ifindex} ({name}) rxif {rx_ifindex}
Examples:
if 2 (eth0)
if 5 (veth1) rxif 4

Usage Examples

Basic Device Tracking

Track which interfaces packets use:
retis collect -c skb,dev

With Filtering

Monitor specific interface:
retis collect -c skb,dev -m 'sk_buff.dev.name == "eth0"'

Track Interface Path

See which interfaces a packet traverses:
retis collect -c skb,skb-tracking,dev -o events.json
retis sort events.json

With Other Context

Combine with other collectors:
# Device + namespace
retis collect -c skb,dev,ns

# Device + drops
retis collect -c skb,dev,skb-drop

# Device + conntrack
retis collect -c skb,dev,ct

Multi-Interface Debugging

Debug routing between interfaces:
retis collect -c skb,skb-tracking,dev -p 'net:*' -o events.json
retis sort events.json

Example Output

Basic Output

202389123456789 [ping] 12345 [tp] net:netif_receive_skb
  if 2 (eth0) 192.168.1.100 > 192.168.1.1 ttl 64 tos 0x0 id 12345 off 0 len 84 proto ICMP (1) type 8 code 0
Packet received on interface 2 (eth0).

With Receive Interface

202389123456789 [handler7] 3215286 [tp] net:netif_receive_skb
  if 5 (veth1) rxif 4 192.168.1.100 > 192.168.1.1 ttl 64 tos 0x0 id 12345 off 0 len 84 proto ICMP (1) type 8 code 0
Packet received on interface 4, currently on interface 5 (veth pair).

Tracking Across Interfaces

Using retis sort after collection:
202389123400000 [ping] 1234 [tp] net:net_dev_start_xmit #abc123 (skb 18446629157470561024) n 0
  if 2 (eth0) 192.168.1.100 > 10.0.0.1 ttl 64 tos 0x0 id 12345 off 0 len 84 proto ICMP (1) type 8 code 0
  + 202389123410000 [swapper/0] 0 [tp] net:netif_receive_skb #abc123 (skb 18446629157470561024) n 1
    if 3 (tun0) 192.168.1.100 > 10.0.0.1 ttl 64 tos 0x0 id 12345 off 0 len 84 proto ICMP (1) type 8 code 0
Packet moves from eth0 to tun0 (tracking shows it’s the same packet).

Integration with Other Collectors

skb

Essential combination:
retis collect -c skb,dev
Shows packet content and which interface it’s on.

skb-tracking

Track interface transitions:
retis collect -c skb,skb-tracking,dev -o events.json
retis sort events.json
See complete path including interface changes.

skb-drop

Identify where drops occur:
retis collect -c skb,dev,skb-drop
Shows on which interface packets are dropped.

ct (Conntrack)

Interface and connection state:
retis collect -c skb,dev,ct
Useful for debugging NAT and routing.

nft (Netfilter)

Interface-based firewall rules:
retis collect -c skb,dev,nft --allow-system-changes
See which rules match on which interfaces.

ovs (OpenVSwitch)

OVS port mapping:
retis collect -c skb,dev,ovs --ovs-track
Correlate OVS ports with kernel interfaces.

ns (Namespace)

Interface and namespace:
retis collect -c skb,dev,ns
Debug containerized networking.

Use Cases

Debug Routing

See which interface packets are routed to:
retis collect -c skb,skb-tracking,dev -f 'host 10.0.0.1' -o events.json
retis sort events.json

Multi-Interface Hosts

Track traffic on specific interfaces:
retis collect -c skb,dev -m 'sk_buff.dev.name == "eth0"'

Bridge Debugging

See packets crossing bridge interfaces:
retis collect -c skb,skb-tracking,dev -p 'net:*' -o events.json
retis sort events.json

VLAN Interfaces

Track VLAN interface handling:
retis collect -c skb,dev --skb-sections all -f 'vlan'

Tunnel Debugging

See packets entering/exiting tunnels:
retis collect -c skb,skb-tracking,dev -f 'host 10.0.0.1'
Watch for interface changes from physical to tunnel interfaces.

Container Networking

retis collect -c skb,dev,ns
Correlate interfaces with network namespaces.

Understanding Interface Information

Interface Index (ifindex)

Unique numeric identifier:
  • Assigned by kernel when interface is created
  • Persistent while interface exists
  • Can be reused after interface deletion
  • Use ip link show to see current mapping

Interface Name

Human-readable identifier:
  • Can be changed with ip link set name
  • Limited to 15 characters (IFNAMSIZ)
  • Common patterns: ethX, wlanX, vethX, tunX, brX

Receive Interface (rxif)

Original input interface:
  • Available in some contexts (e.g., forwarding, bridging)
  • Useful for tracking where packets entered the system
  • Not always present (depends on packet path)

Common Interface Types

  • Physical: eth0, ens33, eno1
  • Wireless: wlan0, wlp2s0
  • Virtual Ethernet: veth0, veth1 (usually in pairs)
  • Bridges: br0, docker0
  • Tunnels: tun0, gre0, vxlan0
  • VLANs: eth0.100, vlan100
  • Loopback: lo
  • Bonding: bond0

Technical Details

Kernel Types

The dev collector activates when these types appear in probe arguments:
  • struct net_device *
  • struct sk_buff * (reads skb->dev)

Data Extraction

The collector:
  1. Checks if struct net_device is directly available
  2. If not, checks if struct sk_buff is available
  3. Reads device information from skb->dev
  4. Extracts device name, ifindex, and rx_ifindex
  5. Validates data (device name must be valid UTF-8)

Union Considerations

skb->dev is in a union and isn’t always valid. The collector:
  • Validates device name is UTF-8
  • Returns empty section if data looks invalid
  • Avoids reporting garbage data

Source Code References

  • Collector: retis/src/collect/collector/dev/dev.rs
  • eBPF hook: retis/src/collect/collector/dev/bpf/dev_hook.bpf.c
  • Event factory: Inline in dev.rs

Best Practices

  1. Combine with skb: Always collect packet data alongside device info
  2. Use tracking: Enable skb-tracking to see interface transitions
  3. Filter by interface: Use metadata filters for specific interfaces
  4. Check both directions: Monitor both transmit and receive paths
  5. Correlate with namespace: Use ns collector in containerized environments

Performance Considerations

  • No probe overhead: Doesn’t install probes
  • Minimal extraction: Only reads when device info is available
  • Small data: Device info adds ~20 bytes per event
  • Efficient validation: Quick UTF-8 check
  • Works with any probe: Activates automatically

Troubleshooting

No Device Information

If device information is missing:
  1. Verify dev collector is enabled
  2. Check probes have appropriate arguments:
    • struct net_device * or
    • struct sk_buff *
  3. Some probe points may not have valid device info

Wrong Interface Name

If interface names seem wrong:
  1. Check interface exists: ip link show
  2. Verify index matches: ip link show dev <name>
  3. Interface might have been renamed
  4. Interface might be in different namespace

Missing rxif

The receive interface is only available in certain contexts:
  • Forwarding scenarios
  • Bridge processing
  • Some routing contexts
It’s normal for rxif to be absent in many cases.

Invalid Device Data

If seeing empty device sections:
  1. Device pointer might be NULL
  2. Device might be in invalid state
  3. Probe point might be before device assignment
  4. This is normal validation behavior

Filtering by Interface

By Name

retis collect -c skb,dev -m 'sk_buff.dev.name == "eth0"'

By Index

retis collect -c skb,dev -m 'sk_buff.dev.ifindex == 2'

Multiple Interfaces

retis collect -c skb,dev -m 'sk_buff.dev.name == "eth0" || sk_buff.dev.name == "eth1"'

See Also

Build docs developers (and LLMs) love