DOCA Documentation v2.9.1 LTS

DOCA P4 Developer Tools

This section descries the NVIDIA DOCA P4 Developer Tools, used to inspect and debug P4 programs that have been loaded to the NVIDIA® BlueField®.

Developers that develop P4 (Programming Protocol-independent Packet Processors) applications require tools to validate and debug their work.

NVIDIA P4 contains the following developer tools:

  • P4nspect

  • P4Debugger

The developer tools interact with a P4 program running on BlueField.

This technical document outlines the usage and options available in the P4 developer tools, including commands, options, and their descriptions.

  1. The P4 Agent (nvp4agent) daemon must be up and running on BlueField (which is the host machine). The nvp4agent loads the p4nspect-server required by the tools.

  2. Compiling the P4 program using NVIDIA's P4 Compiler with debug enabled (nvp4c -g).

  3. Loading the nvp4c compilation output to the nvp4agent.

    Info

    For more, refer to section Compiling P4 Applications.

The tools provided are packed in a single python wheel package (e.g., p4devtools-1.0.whl).

Installing the package requires pip and can be done easily using:

Copy
Copied!
            

pip install p4devtools-1.0.whl

After installation the tools will be available through the p4nspect and p4debugger commands in the python environment.

P4Nspect is a Command-Line Interface (CLI) with many use cases, some of which are:

  • Viewing the dynamic state of a P4 program components - tables, entries, keys and actions, counters and values.

  • Recording of a debug session and generating an archive that can be opened by the P4Debugger.

  • Dumping the state of a P4 program to an archive for offline analysis.

Running p4nspect with no additional arguments will show the basic usage of the CLI tool.

To see a more detailed usage use the -h/--help argument, this argument is also used to get detailed usage of commands. e.g, p4nspect [command] -h

Running commands requires a connection to the local/remote host where p4nspect-server is running, the address host and port are configurable and are 127.0.0.1:9560 by default.

The executed command's output format varies between executed commands and can sometimes be modified by providing additional arguments.

A common use case for modifying a command output is to be able use it as part of some automatic scripting.

The P4nspect offers various commands for interacting with the P4 program and BlueField:

  • system-info – Displays BlueField system information, including HW Model, OS name and version, OFED version. Retrieve information regarding the system specifications such as the OS version, OFED version, etc.

  • devices – Display information about all the configured devices on BlueField: ID, name, virtual devices, loaded P4 program name, etc.

Note

Software abstractions representing real or emulated hardware devices. They provide a standardized interface for applications to interact with BlueField's resources, regardless of underlying physical hardware.

Examples include:

    • Virtual Network Interfaces (VNIs) – Logical representations of physical NICs, allowing multiple virtual networks to share a single physical interface

    • Virtual Processing Units (VPUs) – Software-defined processing units within BlueField that can be allocated to applications for tasks like packet processing or security offloading

    • Virtual Storage Devices – Software-defined representations of physical storage, offering flexibility in managing and allocating storage resources

  • counters – Display P4 counters details and values. The details included are the table, offset and value.

  • tables – Lists tables of P4 programs loaded on BlueField. each table will detail its keys, actions, counters and a reference to its (program’s) source location

  • query – Lists P4 table entries, keys, and actions with the priority of each set of keys.

  • graph – Displays a graph of the P4 pipeline using DOT language. This graph can be graphically rendered using DOT renderers.

  • hw-steering – Displays HW Steering rules dump.

  • debug – Starts a debug session.

Help Flags

To display details of p4nspect options usage:

  • help, -h, --help – Displays the help message and exits.

Output Control Flags

The following flags are optional and can be used independently:

  • -ll, --low-level – Display low level internal information (DOCA HAL Implementation) . (default: False)

  • -ni, --non-interactive – Disable interactive output mode. (default: False).

    Interactive output mode dumps chunks of the output just as Linux's less , designed for easier analysis of the output.

    Disabling may be required when running p4nspect commands from an automated script.

  • -nh, --no-hints – Disable hints for further information.

  • --csv – Set command output to use CSV format. (default: False)

  • --json – Set command output to use JSON format. (default: False)

  • p4nspect counters command specific:

    • --top-packets TOP_PACKETS – Show TOP_PACKETS entries with the highest counter packets values (default: None)

    • --top-bytes TOP_BYTES – Show TOP_PACKETS entries with the highest counter bytes values (default: None)

  • p4nspect graph command specific:

    • --url – Encode the output as a URL that can be directly pasted in a web browser. This is useful for quick rendering using online render websites (default: False).

    • --parser – Display a graph of the P4 pipeline or the Flex Parser (default: False)

Filter Control Flags

  • -d DEVICE_IDS, --device_ids DEVICE_IDS – Specifies a comma separated list of device ID's to be used, e.g. 1000,2000. Retrieves data for all devices if not specified. (default: None)

  • --table_ids TABLE_IDS – Specify which table IDs to filter by. (default: [])

  • --table_names TABLE_NAMES – Specify which table names to filter by (default: [])

  • --counter-names COUNTER_NAMES – Specify which counter names to filter by (default: [])

  • --indices INDICES – Specify which entries indices to filter by (default: [])

Control Flags for Connecting to BlueField

  • -a ADDRESS, --address ADDRESS

    Specifies the p4nspect-server socket address of the form IPv4/IPv6* [address][:port]

    IPv6*: To use with a port the address must be enclosed in literal square brackets.

    Example: ipv6:[2607:f8b0:400e:c00::ef]:443 or ipv6:[::]:1234

    Not specifying an address/port will result in using the default address and port. (default: `127.0.0.1:9560`)

  • --timeout TIMEOUT – [Optional] Connectivity timeout. (default: 0)

Misc Flags

  • --version, -V – Displays the program's version number and exits.

System-info

Copy
Copied!
            

p4nspect system-info

DESCRIPTION

VALUE

DOCA HAL version

TODO

Linux OS version

Ubuntu 22.04 LTS

OFED Version

MLNX_OFED_LINUX-24.01-0.1.7.0:

P4 Agent version

TODO


Devices

Copy
Copied!
            

p4nspect devices

ID

NAME

PCI ADDRESS

PORT ID

NAME

NUMBER

P4 PROGRAM

FW VERSION

HW MODEL

1000

br9

0000:65:00.0

0

enp101s0f0np0

50

alpha2_d2

32.38.0588

BlueField-3 integrated ConnectX-7 network controller

4

eth3

5

1

eth0

2

2

eth1

3

3

eth2

4


Counters

Copy
Copied!
            

p4nspect counters

DEVICE: 1000, NV_COUNTER: alpha2_drop2.decap.decap_counter, SCOPE: alpha2_drop2, TYPE: Pkts/Bts, SIZE: 4, IN USE: 3

IDX

P4

ENTRY OFFSET

VALUE

0

decap_table

1

(2, 140)

1

decap_table

2

(0, 0)

2

decap_table

0

(0, 0)

DEVICE: 1000, NV_COUNTER: alpha2_drop2.encap.encap_counter, SCOPE: alpha2_drop2, TYPE: Pkts/Bts, SIZE: 4, IN USE: 3

IDX

P4

ENTRY OFFSET

VALUE

0

encap_table

0

(0, 0)

1

encap_table

2

(0, 0)

2

encap_table

1

(0, 0)

DEVICE: 1000, NV_DIRECT_COUNTER: alpha2_drop2.gtp.gtp_counter, SCOPE: alpha2_drop2, TYPE: Pkts/Bts, SIZE: 128, IN USE: 3

IDX

P4

ENTRY OFFSET

VALUE

0

gtp_table

2

(0, 0)

1

gtp_table

1

(0, 0)

2

gtp_table

0

(0, 0)

The value is in the following format: (number of packets, number of bytes)

Tables

Copy
Copied!
            

p4nspect tables

DEVICE: 1000

ID

TABLE

KEYS

ACTIONS

COUNTER

ENTRIES

SOURCE

44963766

alpha2_drop2.decap.decap_table

std_meta.ingress_port

headers.gre.$valid$

headers.vxlan.$valid$

alpha2_drop2.decap.send_to_port

alpha2_drop2.decap.decap_gre

alpha2_drop2.decap.decap_vxlan

NoAction

4

alpha2_d2.p4:235

41521446

alpha2_drop2.encap.encap_table

std_meta.ingress_port

headers.ipv4.src_addr

alpha2_drop2.encap.send_to_port

alpha2_drop2.encap.encap_gre

alpha2_drop2.encap.encap_vxlan

NoAction

4

alpha2_d2.p4:173

34318161

alpha2_drop2.gtp.gtp_table

std_meta.ingress_port

headers.gtpv1.teid

alpha2_drop2.gtp.send_to_port

alpha2_drop2.gtp.drop

alpha2_drop2.gtp.gtp_counter

3

alpha2_d2.p4:102


Query

Copy
Copied!
            

p4nspect query

DEVICE: 1000, TABLE: alpha2_drop2.gtp.gtp_table, ID: 34318161, SOURCE: alpha2_d2.p4:102

PRIO

P4 KEY

VALUE

MASK

TYPE

P4 ACTION

0

std_meta.ingress_port

headers.gtpv1.teid

0x0

0x1

exact

exact

alpha2_drop2.gtp.send_to_port(

port=0x1)

0

std_meta.ingress_port

headers.gtpv1.teid

0x1

0x1

exact

exact

alpha2_drop2.gtp.send_to_port(

port=0x0)

0

ALWAYS_HIT

alpha2_drop2.gtp.drop()

DEVICE: 1000, TABLE: alpha2_drop2.encap.encap_table, ID: 41521446, SOURCE: alpha2_d2.p4:173

PRIO

P4 KEY

VALUE

MASK

TYPE

P4 ACTION

3

std_meta.ingress_port

headers.ipv4.src_addr

0x0

0x10000000

0xff000000

exact

ternary

alpha2_drop2.encap.send_to_port(

port=0x4)

2

std_meta.ingress_port

headers.ipv4.src_addr

0x0

0x20000000

0xff000000

exact

ternary

alpha2_drop2.encap.encap_gre(

port=0x2,

src_mac=0x112233445566,

dst_mac=0x10203040506,

sip=0x1010101,

dip=0x2020202,

key=0xabcd)

1

std_meta.ingress_port

headers.ipv4.src_addr

0x0

0x20000000

0xff000000

exact

ternary

alpha2_drop2.encap.encap_vxlan(

port=0x3,

src_mac=0x112233445566,

dst_mac=0x10203040506,

sip=0x1010101,

dip=0x2020202,

vni=0xabcd)

0

ALWAYS_HIT

NoAction()

DEVICE: 1000, TABLE: alpha2_drop2.decap.decap_table, ID: 44963766, SOURCE: alpha2_d2.p4:235

PRIO

P4 KEY

VALUE

MASK

TYPE

P4 ACTION

0

std_meta.ingress_port

headers.gre.$valid$

headers.vxlan.$valid$

0x3

0x0

0x1

exact

exact

exact

alpha2_drop2.decap.decap_vxlan(

port=0x0,

src_mac=0xaabbccddeeff,

dst_mac=0x112233445566)

0

std_meta.ingress_port

headers.gre.$valid$

headers.vxlan.$valid$

0x4

0x0

0x0

exact

exact

exact

alpha2_drop2.decap.send_to_port(

port=0x0)

0

std_meta.ingress_port

headers.gre.$valid$

headers.vxlan.$valid$

0x2

0x1

0x0

exact

exact

exact

alpha2_drop2.decap.decap_gre(

port=0x0)

0

ALWAYS_HIT

NoAction()

Different Output Option Flags

  • --cvs

    Copy
    Copied!
                

    p4nspect --csv tables

    Copy
    Copied!
                

    "DEVICE: 1000" "ID","TABLE","KEYS","ACTIONS","COUNTER","ENTRIES","SOURCE" "44963766","alpha2_drop2.decap.decap_table","std_meta.ingress_port headers.gre.$valid$ headers.vxlan.$valid$","alpha2_drop2.decap.send_to_port alpha2_drop2.decap.decap_gre alpha2_drop2.decap.decap_vxlan NoAction","","4","alpha2_d2.p4:235" "41521446","alpha2_drop2.encap.encap_table","std_meta.ingress_port headers.ipv4.src_addr","alpha2_drop2.encap.send_to_port alpha2_drop2.encap.encap_gre alpha2_drop2.encap.encap_vxlan NoAction","","4","alpha2_d2.p4:173" "34318161","alpha2_drop2.gtp.gtp_table","std_meta.ingress_port headers.gtpv1.teid","alpha2_drop2.gtp.send_to_port alpha2_drop2.gtp.drop","alpha2_drop2.gtp.gtp_counter","3","alpha2_d2.p4:102"

  • --json

    Copy
    Copied!
                

    p4nspect --json tables

    Copy
    Copied!
                

    [ [ { "DEVICE": 1000 }, { "ID": 44963766, "TABLE": "alpha2_drop2.decap.decap_table", "KEYS": [ "std_meta.ingress_port", "headers.gre.$valid$", "headers.vxlan.$valid$" ], "ACTIONS": [ "alpha2_drop2.decap.send_to_port", "alpha2_drop2.decap.decap_gre", "alpha2_drop2.decap.decap_vxlan", "NoAction" ], "COUNTER": "", "ENTRIES": 4, "SOURCE": { "filename": "/tmp/p4src/alpha2_d2.p4", "line": 235, "column": 11 } }, { "ID": 41521446, "TABLE": "alpha2_drop2.encap.encap_table", "KEYS": [ "std_meta.ingress_port", "headers.ipv4.src_addr" ], "ACTIONS": [ "alpha2_drop2.encap.send_to_port", "alpha2_drop2.encap.encap_gre", "alpha2_drop2.encap.encap_vxlan", "NoAction" ], "COUNTER": "", "ENTRIES": 4, "SOURCE": { "filename": "/tmp/p4src/alpha2_d2.p4", "line": 173, "column": 11 } }, { "ID": 34318161, "TABLE": "alpha2_drop2.gtp.gtp_table", "KEYS": [ "std_meta.ingress_port", "headers.gtpv1.teid" ], "ACTIONS": [ "alpha2_drop2.gtp.send_to_port", "alpha2_drop2.gtp.drop" ], "COUNTER": "alpha2_drop2.gtp.gtp_counter", "ENTRIES": 3, "SOURCE": { "filename": "/tmp/p4src/alpha2_d2.p4", "line": 102, "column": 11 } } ] ]

Graph (requires the --low-level flag)

  • No extra flags

    Copy
    Copied!
                

    p4nspect -ll graph

    Copy
    Copied!
                

    Device 1000: digraph hybrid_pipeline { graph [compound=true] // Legend subgraph cluster_legend { hal_table [label=<<B>HAL Table ID</B><BR/>[Implements P4 Objects]> shape=diamond] legend_invis [label=legend_invis shape=point style=invis width=0] p4_control [label="P4 Control" color=blue shape=rectangle] } alpha2_drop2_start [label=start color=green shape=none] legend_invis -> alpha2_drop2_start [style=invis] // Pipeline Stage: main subgraph cluster_alpha2_drop2 { graph [color=blue label=alpha2_drop2 shape=rectangle] 24 [label=<<B>24</B><BR/>[alpha2_drop2]> shape=diamond] alpha2_drop2_start -> 24 48 [label=<<B>48</B><BR/>[alpha2_drop2.gtp.gtp_table]> shape=diamond] DROP [label=DROP fontcolor=red shape=box] 48 -> DROP alpha2_drop2_end [label=end color=red shape=none] 48 -> alpha2_drop2_end 36 [label=<<B>36</B><BR/>[alpha2_drop2]> shape=diamond] 36 -> 48 56 [label=<<B>56</B><BR/>[alpha2_drop2.decap.decap_table]> shape=diamond] 56 -> alpha2_drop2_end 44 [label=<<B>44</B><BR/>[alpha2_drop2]> shape=diamond] 44 -> 56 44 -> alpha2_drop2_end 32 [label=<<B>32</B><BR/>[alpha2_drop2]> shape=diamond] 32 -> 44 32 -> alpha2_drop2_end 52 [label=<<B>52</B><BR/>[alpha2_drop2.encap.encap_table]> shape=diamond] 52 -> 32 52 -> alpha2_drop2_end 40 [label=<<B>40</B><BR/>[alpha2_drop2]> shape=diamond] 55 [label=<<B>55</B><BR/>[alpha2_drop2.encap.encap_table]> shape=diamond] 40 -> 55 40 -> 32 40 -> alpha2_drop2_end 28 [label=<<B>28</B><BR/>[alpha2_drop2]> shape=diamond] 28 -> 40 28 -> alpha2_drop2_end 36 -> 28 36 -> alpha2_drop2_end 24 -> 36 24 -> alpha2_drop2_end } }

  • --url – generates an HTTP URL link to the program's control flow graph, in dot format, rendered using https://dreampuf.github.io/GraphvizOnline/.

    Copy
    Copied!
                

    p4nspect -ll graph --url

    image-2024-4-24_9-24-0-version-1-modificationdate-1717077529903-api-v2.png

  • --parser – generates output of the program's parser graph in dot format

    Copy
    Copied!
                

    p4nspect -ll graph --parser

    Copy
    Copied!
                

    Device 1000: // Parser packet_parser digraph packet_parser { graph [concentrate=true splines=compound] // Legend subgraph cluster_legend { fixed_state [label="Fixed State" style=filled] legend_invis [label=legend_invis shape=point style=invis width=0] flex_state [label="Flex State"] default_transition_note [label="All states have an hidden transition to accept\nEdges are annotated with their match value." shape=none] legend_invis -> default_transition_note [style=invis] } start [label=start color=green shape=point] default_transition_note -> start [style=invis] nv_parse_ethernet [label=ethernet id=nv_parse_ethernet style=filled] start -> nv_parse_ethernet nv_parse_vlan [label=vlan id=nv_parse_vlan style=filled] nv_parse_ethernet -> nv_parse_vlan [label="0x8100" color=gray id="nv_parse_ethernet-nv_parse_vlan"] nv_parse_ipv4 [label=ipv4 id=nv_parse_ipv4 style=filled] nv_parse_ethernet -> nv_parse_ipv4 [label="0x800" color=gray id="nv_parse_ethernet-nv_parse_ipv4"] nv_parse_ipv6 [label=ipv6 id=nv_parse_ipv6 style=filled] nv_parse_ethernet -> nv_parse_ipv6 [label="0x86dd" color=gray id="nv_parse_ethernet-nv_parse_ipv6"] nv_parse_mpls [label=mpls id=nv_parse_mpls style=filled] nv_parse_ethernet -> nv_parse_mpls [label="0x8847" color=gray id="nv_parse_ethernet-nv_parse_mpls"] nv_parse_geneve [label=geneve id=nv_parse_geneve style=filled] nv_parse_inner_ipv4 [label=inner_ipv4 id=nv_parse_inner_ipv4 style=filled] nv_parse_geneve -> nv_parse_inner_ipv4 [label="0x800" color=gray id="nv_parse_geneve-nv_parse_inner_ipv4"] nv_parse_inner_ipv6 [label=inner_ipv6 id=nv_parse_inner_ipv6 style=filled] nv_parse_geneve -> nv_parse_inner_ipv6 [label="0x86dd" color=gray id="nv_parse_geneve-nv_parse_inner_ipv6"] nv_parse_inner_mpls [label=inner_mpls id=nv_parse_inner_mpls style=filled] nv_parse_geneve -> nv_parse_inner_mpls [label="0x8847" color=gray id="nv_parse_geneve-nv_parse_inner_mpls"] nv_parse_inner_ethernet [label=inner_ethernet id=nv_parse_inner_ethernet style=filled] nv_parse_geneve -> nv_parse_inner_ethernet [label="0x6558" color=gray id="nv_parse_geneve-nv_parse_inner_ethernet"] nv_parse_gre [label=gre id=nv_parse_gre style=filled] nv_parse_gre -> nv_parse_inner_ipv4 [label="0x800" color=gray id="nv_parse_gre-nv_parse_inner_ipv4"] nv_parse_gre -> nv_parse_inner_ipv6 [label="0x86dd" color=gray id="nv_parse_gre-nv_parse_inner_ipv6"] nv_parse_gre -> nv_parse_inner_mpls [label="0x8847" color=gray id="nv_parse_gre-nv_parse_inner_mpls"] nv_parse_nvgre_vsid [label=nvgre_vsid id=nv_parse_nvgre_vsid style=filled] nv_parse_gre -> nv_parse_nvgre_vsid [label="0x6558" color=gray id="nv_parse_gre-nv_parse_nvgre_vsid"] nv_parse_icmp [label=icmp id=nv_parse_icmp style=filled] nv_parse_icmpv6 [label=icmpv6 id=nv_parse_icmpv6 style=filled] nv_parse_inner_vlan [label=inner_vlan id=nv_parse_inner_vlan style=filled] nv_parse_inner_ethernet -> nv_parse_inner_vlan [label="0x8100" color=gray id="nv_parse_inner_ethernet-nv_parse_inner_vlan"] nv_parse_inner_ethernet -> nv_parse_inner_ipv4 [label="0x800" color=gray id="nv_parse_inner_ethernet-nv_parse_inner_ipv4"] nv_parse_inner_ethernet -> nv_parse_inner_ipv6 [label="0x86dd" color=gray id="nv_parse_inner_ethernet-nv_parse_inner_ipv6"] nv_parse_inner_ethernet -> nv_parse_inner_mpls [label="0x8847" color=gray id="nv_parse_inner_ethernet-nv_parse_inner_mpls"] nv_parse_inner_icmp [label=inner_icmp id=nv_parse_inner_icmp style=filled] nv_parse_inner_icmpv6 [label=inner_icmpv6 id=nv_parse_inner_icmpv6 style=filled] nv_parse_inner_ipv4 -> nv_parse_inner_icmp [label="0x1" color=gray id="nv_parse_inner_ipv4-nv_parse_inner_icmp"] nv_parse_inner_tcp [label=inner_tcp id=nv_parse_inner_tcp style=filled] nv_parse_inner_ipv4 -> nv_parse_inner_tcp [label="0x6" color=gray id="nv_parse_inner_ipv4-nv_parse_inner_tcp"] nv_parse_inner_udp [label=inner_udp id=nv_parse_inner_udp style=filled] nv_parse_inner_ipv4 -> nv_parse_inner_udp [label="0x11" color=gray id="nv_parse_inner_ipv4-nv_parse_inner_udp"] nv_parse_inner_ipv6 -> nv_parse_inner_icmpv6 [label="0x3a" color=gray id="nv_parse_inner_ipv6-nv_parse_inner_icmpv6"] nv_parse_inner_ipv6 -> nv_parse_inner_tcp [label="0x6" color=gray id="nv_parse_inner_ipv6-nv_parse_inner_tcp"] nv_parse_inner_ipv6 -> nv_parse_inner_udp [label="0x11" color=gray id="nv_parse_inner_ipv6-nv_parse_inner_udp"] nv_parse_inner_mpls1 [label=inner_mpls1 id=nv_parse_inner_mpls1 style=filled] nv_parse_inner_mpls -> nv_parse_inner_mpls1 [label="0x0" color=gray id="nv_parse_inner_mpls-nv_parse_inner_mpls1"] nv_parse_inner_mpls_next_header [label=nv_parse_inner_mpls_next_header id=nv_parse_inner_mpls_next_header style=filled] nv_parse_inner_mpls -> nv_parse_inner_mpls_next_header [label="0x1" color=gray id="nv_parse_inner_mpls-nv_parse_inner_mpls_next_header"] nv_parse_inner_mpls2 [label=inner_mpls2 id=nv_parse_inner_mpls2 style=filled] nv_parse_inner_mpls1 -> nv_parse_inner_mpls2 [label="0x0" color=gray id="nv_parse_inner_mpls1-nv_parse_inner_mpls2"] nv_parse_inner_mpls1 -> nv_parse_inner_mpls_next_header [label="0x1" color=gray id="nv_parse_inner_mpls1-nv_parse_inner_mpls_next_header"] nv_parse_inner_mpls3 [label=inner_mpls3 id=nv_parse_inner_mpls3 style=filled] nv_parse_inner_mpls2 -> nv_parse_inner_mpls3 [label="0x0" color=gray id="nv_parse_inner_mpls2-nv_parse_inner_mpls3"] nv_parse_inner_mpls2 -> nv_parse_inner_mpls_next_header [label="0x1" color=gray id="nv_parse_inner_mpls2-nv_parse_inner_mpls_next_header"] nv_parse_inner_mpls4 [label=inner_mpls4 id=nv_parse_inner_mpls4 style=filled] nv_parse_inner_mpls3 -> nv_parse_inner_mpls4 [label="0x0" color=gray id="nv_parse_inner_mpls3-nv_parse_inner_mpls4"] nv_parse_inner_mpls3 -> nv_parse_inner_mpls_next_header [label="0x1" color=gray id="nv_parse_inner_mpls3-nv_parse_inner_mpls_next_header"] nv_parse_inner_mpls4 -> nv_parse_inner_mpls_next_header [label="0x1" color=gray id="nv_parse_inner_mpls4-nv_parse_inner_mpls_next_header"] nv_parse_inner_mpls_next_header -> nv_parse_inner_ipv4 [label="0x4" color=gray id="nv_parse_inner_mpls_next_header-nv_parse_inner_ipv4"] nv_parse_inner_mpls_next_header -> nv_parse_inner_ipv6 [label="0x6" color=gray id="nv_parse_inner_mpls_next_header-nv_parse_inner_ipv6"] nv_parse_inner_vlan -> nv_parse_inner_ipv4 [label="0x800" color=gray id="nv_parse_inner_vlan-nv_parse_inner_ipv4"] nv_parse_inner_vlan -> nv_parse_inner_ipv6 [label="0x86dd" color=gray id="nv_parse_inner_vlan-nv_parse_inner_ipv6"] nv_parse_inner_vlan -> nv_parse_inner_mpls [label="0x8847" color=gray id="nv_parse_inner_vlan-nv_parse_inner_mpls"] nv_parse_ipsec_esp [label=esp id=nv_parse_ipsec_esp style=filled] nv_parse_ipv4 -> nv_parse_inner_ipv4 [label="0x4" color=gray id="nv_parse_ipv4-nv_parse_inner_ipv4"] nv_parse_ipv4 -> nv_parse_inner_ipv6 [label="0x29" color=gray id="nv_parse_ipv4-nv_parse_inner_ipv6"] nv_parse_ipv4 -> nv_parse_icmp [label="0x1" color=gray id="nv_parse_ipv4-nv_parse_icmp"] nv_parse_tcp [label=tcp id=nv_parse_tcp style=filled] nv_parse_ipv4 -> nv_parse_tcp [label="0x6" color=gray id="nv_parse_ipv4-nv_parse_tcp"] nv_parse_udp [label=udp id=nv_parse_udp style=filled] nv_parse_ipv4 -> nv_parse_udp [label="0x11" color=gray id="nv_parse_ipv4-nv_parse_udp"] nv_parse_ipv4 -> nv_parse_gre [label="0x2f" color=gray id="nv_parse_ipv4-nv_parse_gre"] nv_parse_ipv4 -> nv_parse_ipsec_esp [label="0x32" color=gray id="nv_parse_ipv4-nv_parse_ipsec_esp"] nv_parse_ipv6 -> nv_parse_inner_ipv4 [label="0x4" color=gray id="nv_parse_ipv6-nv_parse_inner_ipv4"] nv_parse_ipv6 -> nv_parse_inner_ipv6 [label="0x29" color=gray id="nv_parse_ipv6-nv_parse_inner_ipv6"] nv_parse_ipv6 -> nv_parse_icmpv6 [label="0x3a" color=gray id="nv_parse_ipv6-nv_parse_icmpv6"] nv_parse_ipv6 -> nv_parse_tcp [label="0x6" color=gray id="nv_parse_ipv6-nv_parse_tcp"] nv_parse_ipv6 -> nv_parse_udp [label="0x11" color=gray id="nv_parse_ipv6-nv_parse_udp"] nv_parse_ipv6 -> nv_parse_gre [label="0x2f" color=gray id="nv_parse_ipv6-nv_parse_gre"] nv_parse_ipv6 -> nv_parse_ipsec_esp [label="0x32" color=gray id="nv_parse_ipv6-nv_parse_ipsec_esp"] nv_parse_mpls1 [label=mpls1 id=nv_parse_mpls1 style=filled] nv_parse_mpls -> nv_parse_mpls1 [label="0x0" color=gray id="nv_parse_mpls-nv_parse_mpls1"] nv_parse_mpls_next_header [label=nv_parse_mpls_next_header id=nv_parse_mpls_next_header style=filled] nv_parse_mpls -> nv_parse_mpls_next_header [label="0x1" color=gray id="nv_parse_mpls-nv_parse_mpls_next_header"] nv_parse_mpls2 [label=mpls2 id=nv_parse_mpls2 style=filled] nv_parse_mpls1 -> nv_parse_mpls2 [label="0x0" color=gray id="nv_parse_mpls1-nv_parse_mpls2"] nv_parse_mpls1 -> nv_parse_mpls_next_header [label="0x1" color=gray id="nv_parse_mpls1-nv_parse_mpls_next_header"] nv_parse_mpls3 [label=mpls3 id=nv_parse_mpls3 style=filled] nv_parse_mpls2 -> nv_parse_mpls3 [label="0x0" color=gray id="nv_parse_mpls2-nv_parse_mpls3"] nv_parse_mpls2 -> nv_parse_mpls_next_header [label="0x1" color=gray id="nv_parse_mpls2-nv_parse_mpls_next_header"] nv_parse_mpls4 [label=mpls4 id=nv_parse_mpls4 style=filled] nv_parse_mpls3 -> nv_parse_mpls4 [label="0x0" color=gray id="nv_parse_mpls3-nv_parse_mpls4"] nv_parse_mpls3 -> nv_parse_mpls_next_header [label="0x1" color=gray id="nv_parse_mpls3-nv_parse_mpls_next_header"] nv_parse_mpls4 -> nv_parse_mpls_next_header [label="0x1" color=gray id="nv_parse_mpls4-nv_parse_mpls_next_header"] nv_parse_mpls_next_header -> nv_parse_ipv4 [label="0x4" color=gray id="nv_parse_mpls_next_header-nv_parse_ipv4"] nv_parse_mpls_next_header -> nv_parse_ipv6 [label="0x6" color=gray id="nv_parse_mpls_next_header-nv_parse_ipv6"] nv_parse_nvgre_vsid -> nv_parse_inner_ethernet [label="0x0" color=gray id="nv_parse_nvgre_vsid-nv_parse_inner_ethernet"] nv_parse_psp [label=psp id=nv_parse_psp style=filled] parse_gtp [label=gtpv1 id=parse_gtp style=""] nv_parse_udp -> parse_gtp [label="0x868" color=black id="nv_parse_udp-parse_gtp"] nv_parse_vxlan [label=vxlan id=nv_parse_vxlan style=filled] nv_parse_udp -> nv_parse_vxlan [label="0x12b5" color=gray id="nv_parse_udp-nv_parse_vxlan"] nv_parse_vxlan_gpe [label=vxlan_gpe id=nv_parse_vxlan_gpe style=filled] nv_parse_udp -> nv_parse_vxlan_gpe [label="0x12b6" color=gray id="nv_parse_udp-nv_parse_vxlan_gpe"] nv_parse_udp -> nv_parse_geneve [label="0x17c1" color=gray id="nv_parse_udp-nv_parse_geneve"] nv_parse_udp -> nv_parse_inner_mpls [label="0x19eb" color=gray id="nv_parse_udp-nv_parse_inner_mpls"] nv_parse_udp -> nv_parse_ipsec_esp [label="0x1194" color=gray id="nv_parse_udp-nv_parse_ipsec_esp"] nv_parse_udp -> nv_parse_psp [label="0x3e8" color=gray id="nv_parse_udp-nv_parse_psp"] nv_parse_vlan -> nv_parse_ipv4 [label="0x800" color=gray id="nv_parse_vlan-nv_parse_ipv4"] nv_parse_vlan -> nv_parse_ipv6 [label="0x86dd" color=gray id="nv_parse_vlan-nv_parse_ipv6"] nv_parse_vlan -> nv_parse_mpls [label="0x8847" color=gray id="nv_parse_vlan-nv_parse_mpls"] nv_parse_vxlan -> nv_parse_inner_ethernet [label="0x0" color=gray id="nv_parse_vxlan-nv_parse_inner_ethernet"] nv_parse_vxlan_gpe -> nv_parse_inner_ipv4 [label="0x1" color=gray id="nv_parse_vxlan_gpe-nv_parse_inner_ipv4"] nv_parse_vxlan_gpe -> nv_parse_inner_ipv6 [label="0x2" color=gray id="nv_parse_vxlan_gpe-nv_parse_inner_ipv6"] nv_parse_vxlan_gpe -> nv_parse_inner_ethernet [label="0x3" color=gray id="nv_parse_vxlan_gpe-nv_parse_inner_ethernet"] }

  • --url --parser

    Copy
    Copied!
                

    p4nspect -ll graph --url --parser

    image-2024-4-24_9-28-19-version-1-modificationdate-1717077529410-api-v2.png

Illustration

It is possible to render the graph to get the following picture:

Picture1-version-1-modificationdate-1717077530437-api-v2.png

Some of the flags are universally applicable to all of the commands, but some are applicable to only specific commands.

The following table outlines which commands and which flags relate

system-info

devices

counters

tables

query

graph

hw-steering

debug

--address

--time-out

--non-interactive

--no-hints

--csv

--json

--device-ids

--low-level

--table-ids

--table_names

--counter-names

--indices

--top-packets

--top-bytes

--url

--parser

--output-file

--debug-device-id

The P4Debugger is a GUI application that can run a debug session or open a pre recorded (through p4nspect debug ) debug session file.

Debug session shows the passage of traffic packets throughout a P4 program's pipeline and lets the developer trace the details of each packet's course.

Running p4debugger with no additional arguments will open the GUI application.

Opening and debugging a pre recorded debug session can be done using the File menu of by specifying the debug session file in the program execution command as follows:

Copy
Copied!
            

p4debugger my-debug-archive.tar.gz

Open Debug Session File

image-2024-4-19_11-52-15-version-1-modificationdate-1717077530837-api-v2.png

Select the File → Open Debug Session File and choose the appropriate <p4-debug-file>.tar.gz in this example hello_packet.tar.gz.

The tar.gz archive should be the output of a recorded debug session created with p4nspect debug.

image-2024-4-19_11-52-56-version-1-modificationdate-1717077531613-api-v2.png

Packet List

On the left pane users can see the Packets list. The packet list exposes the following fields:

  • ID – this is the packet's unique identifier.

  • Date Time – the time it entered the p4 pipeline.

  • Time Since Start – time since the first packet entered the p4 pipeline.

  • Size – packet size

  • Ingress Port

image-2024-4-19_11-53-34-version-1-modificationdate-1717077543257-api-v2.png

Filter

To filter out packets use the fields at the bottom left of the screen.

For example: "packet ID is not 0".

Press the + button and then the Apply button

image-2024-4-19_11-54-15-version-1-modificationdate-1717077532007-api-v2.png

Press the "Clear All" button.

A converse filter example: "packet ID is 0" again pressing the + and then the Apply buttons

image-2024-4-19_11-54-51-version-1-modificationdate-1717077533507-api-v2.png

Parser Graph

The middle section of the screen there is the parser graph

image-2024-4-19_11-55-32-version-1-modificationdate-1717077534060-api-v2.png

It outlines the route a packet can take. The purple nodes (such as "ethernet" above) indicate the node it traversed. It consists of both flex nodes which the p4 programmer instigated and static (fixed) nodes which are inherent part of the hardware.

Pipeline Stages

Selecting a packet from the Packets list will display the selected packet's pipeline stages.

Each row in the pipeline stages correlates to a single source location point in the P4 program code.

Cells in the table are interactable, selecting a cell will mark the relevant source location when applicable.

image-2024-4-19_11-56-4-version-1-modificationdate-1717077535417-api-v2.png

Variables

Selecting a pipeline stage (a single cell or the whole row) will display variable information in two different tabs.

  • The "Variables" tab shows P4 variables defined in the program and their values in the current pipeline stage.

  • The "Raw" tab shows a deeper dive into the low level variables (e.g., registers, samplers, etc.)

image-2024-4-19_11-56-30-version-1-modificationdate-1717077536890-api-v2.png

Source Code

Selecting a cell in a pipeline stage will open the P4 program in a new tab, marking the relevant source location when applicable.

The debugger seeks the P4 source file using the search paths defined in the Settings or by browsing manually for the file.

image-2024-4-19_11-56-52-version-1-modificationdate-1717077537567-api-v2.png

Log

The log window pane is on the left side. It shows the internal logs of the P4 agent.

image-2024-4-19_12-27-16-version-1-modificationdate-1717077538547-api-v2.png

System Info

image-2024-4-19_12-27-37-version-1-modificationdate-1717077539403-api-v2.png

Packet Dissector

Selecting a pipeline stage will dissect the packet.

image-2024-4-19_12-28-0-version-1-modificationdate-1717077540500-api-v2.png

Hex Dump

Selecting a pipeline stage will show a raw hex dump of the packet.

image-2024-4-19_12-28-29-version-1-modificationdate-1717077540977-api-v2.png

Options

The File->Preferences menu will open the Preferences window.

Here you can set different settings related to the debugger and the debug session.

image-2024-4-19_12-29-0-version-1-modificationdate-1717077542037-api-v2.png

© Copyright 2025, NVIDIA. Last updated on Feb 10, 2025.