xdptap - Basic Usage
 
 

xdptap - Basic Usage

May 30, 2025
development, projects, HOWTO
xdptap, IXDP, AF_XDP, libxdp, RPCL
Updated to include latest additions and the --xdp_skb and --xdp_drv command line options.

xdptap #

xdptap is an XDP based Ethernet analysis and monitoring security tool which allows to obtain insight and to record selected (or all) traffic for further analysis and evaluation.

Linux XDP in zero-copy mode allows packet processing at wire-speed up to 100GbE full duplex with specific drivers.

The Layers #

The xdptap application consists - somewhat simplified - of three layers:

flowchart TD a("xdptap") --- b("IXDP") --- c("libxdp/eBPF/NIC drivers")

xdptap #

The top layer, xdptap consists basically of command line option parsing, some RPCL initial processing (as loading /etc/xdptap.rpcl with load-if-present and inserting some variables like version.xdptap).

The functionality of xdptap itself is represented by the IXDP callback function IXDPCallback() and is simple and short:

1
2
3
4
5
6
7
8
int IXDPCallback(uint8_t* address, uint32_t* length_ptr, int interface) {
  if (interface == 0)
    return (1);
  else if (interface == 1)
    return (0);
  else
    return (-1);
}

IXDP #

The IXDP layer is responsible for XDP ring management operating with a set of interfaces in promiscuous mode. IXDP registers its specific set of RPCL functions (words) which allow to control and configure the IXDP packet processing layer.

All RPCL control mechanisms that are available with xdptap are in fact part of the IXDP layer.

Further information:

libxdp/eBPF/NIC drivers #

libxdp is a lightweight library that allows attaching multiple XDP programs to network interfaces and using AF_XDP sockets. It relies on libbpf to process eBPF object files and supports freplace and kernel features for the XDP dispatcher.

The xdptap Command #

The general usage information of the xdptap command is this:

$ xdptap -h 
usage: xdptap [options] interface0 [interface1]
       options:
       -q|--queues <q>         specify number of queues (default 1)
       -r|--ringsize <r>       specify ringsize (default 4096)
       -i|--initfile <file>    load specific initial RPCL file
       -d|--daemon             detach and run in background
       -h|--help               show usage
       -v|--version            show version
       -c|--copyright          show copyright
       --xdp_skb               force XDP_SKB mode
       --xdp_drv               force XDP_SKB mode
$

xdptap Options #

-q|–queues #

This option controls the number of queues that the IXDP layer operates withi over all interfaces. This parameter is equivalent to the number of threads, since IXDP runs with one thread per queue. The default is 1, which is fully sufficient to process packets bridging between two 10GbE interfaces.

-r|–ringsize #

The ringsize defaults to 4096 and can be changed with this option to another value. The NIC ring parameters are set to this value for RX and TX, also this value influences the IXDP ring and FIFO buffer dimensioning. There’s currently no NIC driver known which requires a different value, but it might be important for 40GbE and 100GbE NICs.

-i|–initfile #

Per default xdptap loads /etc/xdptap.rpcl with load-if-present. A different RPCL init file can be specified with this option if desired.

-d|–daemon #

With this option specified, xdptap detaches itself and runs in background, registering with xdptap as identifier for the control utility. When this option is not specified, the xdptap command ends in its RPCL main loop (with no line editing capabilities).

–xdp_skb #

Forces IXDP to operate AF_XDP in XDP_SKB mode.

–xdp_drv #

Forces IXDP to operate AF_XDP in XDP_DRV mode.

xdptap Modes #

Bridging Mode #

When xdptap is invoked with two interfaces, it runs in bridging mode, acting as a promiscuous mode bridge between those two interfaces.

Example:

$ sudo xdptap enp1s0f0 enp1s0f1 --daemon 
xdptap going to background ...
$

Mirroring Mode #

When xdptap is invoked with just one interface, it runs in mirroring mode (sometimes this is also called “SPAN” by other software and vendors). When the provided interface is connected to a switch port, that has been configured for port mirroring it allows to inspect the traffic visible this way. xdptap ’s fault injection is not able to inject faults in this mode.

Example:

$ sudo xdptap enp1s0f0 --daemon 
xdptap going to background ...
$

Control #

$ control -h 
usage: control <identifier>           control background process
       control <identifier> status    show background process status
       control <identifier> stop      terminate background process
       control -h|--help              show usage
       control -v|--version           show version
       control -c|--copyright         show copyright
$

Control Tasks #

control background process #

Invoking control with an identifier connects to a running background daemon which has registered itself with that identifier name. As soon as connected, stdin/stdout/stderr of the background process are connected to the control frontend which offers some line editing capabilities.

Any output that has been sent to stdout and stderr by the background process on startup is shown first as it would have appeared on screen.

Since xdptap runs RPCL as its main thread, this connects to the RPCL main loop indicated by the ok prompt.

Ctrl-D and Ctrl-C exit the control frontend, additionally there’s and inactivity timeout of 10 minutes.

Example:

$ sudo xdptap enp1s0f0 enp1s0f1 --daemon 
xdptap going to background ...
$ sudo control xdptap
connected to xdptap PID 6617
IXDPSetup() SUCCESS ifc:2 nqueues:1 ringsize:4096 XDP_DEFAULT
IXDPStart() SUCCESS
ok

show background process status #

This shows the background status and PID (if there’s a background process running with the specified identifier).

Example:

$ sudo control xdptap status
xdptap PID 6617 running
$ sudo control unknown status
unknown not running
$

terminate background process #

This allows to shutdown a running background process with increasing “force” in terms of signals.

Example:

$ sudo control xdptap stop 
shutdown of xdptap PID 6617 complete
$ sudo control unknown stop 
unknown not running
$

xdptap and RPCL #

Show Uptime #

The RPCL built-in word uptime-hr allows to display the uptime of the RPCL interpreter in a “human readable” format. With xdptap running in background, this looks like this (effectively displaying the uptime of the xdptap background process):

$ sudo control xdptap 
ok uptime-hr .
1d 22h 24m 52s
ok

Show RPCL Variables #

Example: xdptap in Bridging Mode #

$ sudo control xdptap 
ok .d 
ixdp.configured_interfaces       2
ixdp.configured_queues           1
ixdp.configured_ringsize         4096
ixdp.interface.0.driver          ixgbe
ixdp.interface.0.name            enp1s0f0
ixdp.interface.1.driver          ixgbe
ixdp.interface.1.name            enp1s0f1
ixdp.version                     1.97
rpcl.platform                    Debian12-amd64
rpcl.version                     1.138
xdptap.version                   1.4
ok

Example: xdptap in Mirroring Mode #

$ sudo control xtptap 
ok .d 
ixdp.configured_interfaces       1
ixdp.configured_queues           1
ixdp.configured_ringsize         4096
ixdp.interface.0.driver          ixgbe
ixdp.interface.0.name            enp1s0f0
ixdp.version                     1.97
rpcl.platform                    Debian12-amd64
rpcl.version                     1.138
xdptap.version                   1.4
ok

The Drop Machash #

IXDP supports lockless hashtables of MAC addresses, defining just a set of MAC addresses (a specific MAC address is either a member of such a set - or not). One instance of this is the “Drop Machash”. which defines a set of MAC addresses that cause a packet to be dropped when either the source MAC address or the destination MAC address of an Ethernet packet is a member of the Drop Machash.

This question (member of the Drop Machash or not) is asked when the IXDP callback function decides to forward the packet to another or the same interface it has been received from. With xdptap , this functionality makes therefore only sense in bridging mode, where xdptap acts as a bridge between two interfaces.

drop.hash.insert #

add specific MAC address to drop ( mac - )

Example:

$ sudo control xdptap 
ok a0:36:9f:21:4b:90 drop.hash.insert 
ok f0:b2:b9:15:07:ca drop.hash.insert 
ok drop.hash.show
a0:36:9f:21:4b:90 Intel Corporate
f0:b2:b9:15:07:ca Intel Corporate
ok
To specify addresses always to be dropped, just include the desired drop.hash.insert commands in /etc/xdptap.rpcl.

drop.hash.reset #

reset drop machash to 0 elements ( - )

This clears the drop machash.

Example:

$ sudo control xdptap 
ok drop.hash.show
a0:36:9f:21:4b:90 Intel Corporate
f0:b2:b9:15:07:ca Intel Corporate
ok drop.hash.reset 
ok drop.hash.show
ok

drop.hash.show #

show user defined drop machash ( - )

Example:

$ sudo control xdptap 
ok drop.hash.show
a0:36:9f:21:4b:90 Intel Corporate
f0:b2:b9:15:07:ca Intel Corporate
ok

Interface Statistics and Counters #

if.drivers #

show interfaces and drivers ( - )

Example:

ok if.drivers 
0 enp1s0f0         ixgbe
1 enp1s0f1         ixgbe
ok
Here xdptap is operating in bridging mode since it has been started with two interfaces.

if.etype.show #

show rx Ethertype and VLAN statistics for interface ( i - )

Example:

ok if.drivers
0 enp2s0           igc
1 enp3s0           igc
ok 0 if.etype.show 
0 0x0008 802.3 size       e8:fd:f8:5d:fe:4a                    1 Shanghai High-Flying Electronics Technology Co., Ltd
0 0x0800 IPv4             32:3a:fd:84:56:64                12866 Locally Administered Address (LAA)
0 0x0806 ARP              00:e2:69:89:51:e4                  935
0 0x8100 802.1q           00:3e:e1:c0:f0:9c                   24 Apple, Inc.
      10 VID              00:3e:e1:c0:f0:9c                   24 Apple, Inc.
0 0x86dd IPv6             00:3e:e1:c0:f0:9c                 2881 Apple, Inc.
0 0x8899 RRCP             24:d7:9c:e4:3e:e9                  700 Cisco Systems, Inc
0 0x88cc LLDP             56:e6:36:5f:17:a8                   92 Locally Administered Address (LAA)
1 0x0800 IPv4             00:3e:e1:c0:f0:9c                   12 Apple, Inc.
1 0x86dd IPv6             00:3e:e1:c0:f0:9c                   12 Apple, Inc.
ok

There are six columns in a if.etype.show output:

  • The first column is the VLAN level, where IXDP descends up to 4 levels for 0x8100 and 0x88a8 type of VLANs.
  • The second column is the Ethertype that has been seen (or the VLAN Id (VID) for 0x8100 and 0x88a8).
  • The third column is a textual desciption of the Ethertype.
  • The fourth column is the Ethernet address that has most recently encountered sending a packet. This may be helpful to determine MAC addresses that are communicating in wrong or unexpected VLANs.
  • The fifth column is the atomic counter counting the occurences of packets of that type.
  • The sixth column is the manufacturer information of the MAC address in column four.

if.mac.show #

show rx mac statistics for interface ( i - )

Example:

ok if.drivers
0 enp2s0           igc
1 enp3s0           igc
ok 0 if.mac.show 
9a:88:c6:d1:3d:4a                   97 Locally Administered Address (LAA)
3e:10:d5:14:22:7e                   66 Locally Administered Address (LAA)
24:d7:9c:e4:3e:e9                   21 Cisco Systems, Inc
00:11:32:d5:11:11                    1 Synology Incorporated
52:54:00:9c:53:c1                    1 Locally Administered Address (LAA)
00:3e:e1:c0:f0:9c                  295 Apple, Inc.
56:e6:36:5f:17:a8                    8 Locally Administered Address (LAA)
32:3a:fd:84:56:64                   94 Locally Administered Address (LAA)
00:e2:69:89:51:e4                   23
a0:52:72:1a:ca:41                    1 Apple, Inc.
00:23:7d:86:71:ff                    3 Hewlett Packard
ce:0e:14:15:67:bc                   95 Locally Administered Address (LAA)
50:1e:2d:49:c2:24                  206 StreamUnlimited Engineering GmbH
06:b6:2b:f1:08:fa                    1 Locally Administered Address (LAA)
ee:0c:92:fe:f1:1c                    1 Locally Administered Address (LAA)
32:3a:fd:86:36:3f                   39 Locally Administered Address (LAA)
4e:3a:fd:86:36:41                    1 Locally Administered Address (LAA)
38:10:d5:14:22:7c                    1 AVM Audiovisuelles Marketing und Computersysteme GmbH
3c:2a:f4:07:f0:4b                    1 Brother Industries, LTD.
00:11:32:d5:11:12                   56 Synology Incorporated
ok
This is from a freshly started xdptap in bridging mode, showing the MAC addresses and packet counts on RX of interface 0. Since RPCL has the recent manufacturer database compiled in, the manufacturer information is also shown. Locally administered addresses are additionally shown as such. If the manufacturer is not known, the information field stays blank (as for 00:e2:69:89:51:e4 above).

if.qstats #

show detailed queue/interface statistics ( queue interface - )

Example:

$ sudo control xdptap
$ 0 0 if.qstats 
queue 0 interface 0 enp1s0f0 ixgbe fd 3
  rx_packets_ctr            1
  tx_packets_ctr            24
  refill_packets_ctr        1
  drop_packets_ctr          0
  drop_fi_ctr               0
  bitflip_injected_ctr      0
  dup_injected_ctr          0
  noif_packets_ctr          0
  tap_packets_ctr           0
  txbuffer_full_packets_ctr 0
  txring_full_packets_ctr   0
  completed_packets_ctr     24
  xdp_options_zerocopy      ACTIVE
  rx_dropped                0
  rx_invalid_descs          0
  tx_invalid_descs          0
  rx_ring_full              0
  rx_fill_ring_empty_descs  2
  tx_ring_empty_descs       6236833
$
The XDP statistic counters rx_fill_ring_empty_descs and tx_ring_empty_descs are shown as they are, but we regard both values as meaningless (they aren’t documented, but existent).

if.stats #

show summary statistics of all interfaces ( - )

Example:

ok if.drivers
0 enp1s0f0         ixgbe
1 enp1s0f1         ixgbe
ok if.stats
0 enp1s0f0 ixgbe queues:1 ZEROCOPY
  rx                    1
  tx                    19
  drop                  0
  noif                  0
  err                   0
  RX tap                enabled
  TX tap                disabled
  fault injection       disabled
    drop probability    0 (0.000%)
    bitflip probability 0 (0.000%)
    dup probability     0 (0.000%)
    dropped by FI       0
    bitflipped by FI    0
    duplicated by FI    0
1 enp1s0f1 ixgbe queues:1 ZEROCOPY
  rx                    38
  tx                    1
  drop                  19
  noif                  0
  err                   0
  RX tap                enabled
  TX tap                disabled
  fault injection       disabled
    drop probability    0 (0.000%)
    bitflip probability 0 (0.000%)
    dup probability     0 (0.000%)
    dropped by FI       0
    bitflipped by FI    0
    duplicated by FI    0
ok

/etc/xdptap.rpcl #

/etc/xdptap.rpcl is the default xdptap configuration file which is loaded at startup if present (the location can be different as specified with -i|--initfile).

One thing that is useful in many cases is to change the RPCL interpreter prompt, see the description here: Changing the Prompt.