CLI reference¶
The p4net command starts a topology and opens an interactive shell. From the shell you can run host commands, test connectivity, program switch tables, read counters, and manage multicast groups. The command is included when you install p4net.
Starting the shell¶
The topology file must define a module-level topology variable containing a Topology instance. It may also define setup(net), which runs after the network starts and before the shell opens. The IPv4 forwarding example shows both definitions.
Each file is loaded as a separate Python module. It can define helper classes and dataclasses for use when constructing the topology or running setup(net).
Run either entry point with the Python environment where p4net is installed:
Both accept the same arguments:
usage: p4net [-h] [--no-shell] [--unsafe] [--log-dir LOG_DIR]
[--pcap-dir PCAP_DIR] [--extra-compile-arg ARG] [-v]
topology_file
| Option | Behavior |
|---|---|
-h, --help |
Print startup help and exit. |
--no-shell |
Start the network, run setup(net) if present, and wait for SIGINT or SIGTERM to shut down. |
--unsafe |
Skip Topology.validate() before startup. |
--log-dir DIR |
Store BMv2 logs in DIR. Defaults to a new temporary directory. |
--pcap-dir DIR |
Save per-port BMv2 captures in DIR. Captures are disabled when omitted. |
--extra-compile-arg ARG |
Forward an argument to p4c. Repeat for multiple arguments. For a value starting with -, use the form --extra-compile-arg=-DDEBUG. |
-v, --verbose |
Set logging to INFO. Use -vv for DEBUG. The default is WARNING. |
With --pcap-dir set, pcap_enabled=False in Topology.add_switch() excludes that switch from capture.
Using sudo with a virtual environment¶
On systems where sudo replaces PATH with secure_path, it may not find the active environment's p4net, Python, or external tools. The commands above pass the current PATH through env, so both entry points use that environment.
The examples below use hosts h1, h2 and switch s1. IPv6 commands use hosts configured with IPv6 addresses. Table names, actions, counters, and controller metadata come from the loaded P4 program. Enter each p4net> command on one line.
Top-level commands¶
help and help <command>¶
help lists available commands. Give a topic to see its syntax and description:
Help topics for node commands use the literal placeholders, for example help <host> ping or help <switch> table add.
exit, quit¶
Leave the shell and shut down the network. Ctrl-D on an empty input line does the same.
status¶
Show whether the network is running, the host and switch counts, and the BMv2 log directory.
hosts¶
List each host's first configured IPv4 and IPv6 addresses, followed by its interfaces. Addresses retain their prefix lengths. An unconfigured address is shown as -.
p4net> hosts
name primary_ip primary_ip6 interfaces
h1 10.0.0.1/24 fd00::1/64 h1-eth0
h2 10.0.0.2/24 fd00::2/64 h2-eth0
switches¶
List each switch's gRPC address, BMv2 process PID, and log file path.
pingall [count] [timeout]¶
Run IPv4 ping between hosts with a configured primary IPv4 address, in both directions. The matrix includes all hosts, with the row as source and column as destination. count defaults to 1 and timeout to 2.0 seconds. Both follow the ping argument rules. Cells show 1 for success, X for failure, - for the same host, and ? for an untested pair involving a host without IPv4.
pingall6 [count] [timeout]¶
Run IPv6 ping between hosts with a configured primary IPv6 address. Hosts without one are excluded. The argument rules and output format match pingall. If no host has IPv6 configured, the result is (no IPv6-equipped hosts in topology).
topology graph [path] [layout=LR|TB|BT|RL] [format=png|svg|pdf|dot]¶
Validate the topology and render its graph. Without path, print DOT source. With a path, write the selected format and return the absolute output path. layout sets Graphviz's rankdir and defaults to LR; format defaults to png.
format=dot writes the source directly. Other formats require the system dot executable.
Host commands¶
<host> ping <target> [count] [timeout]¶
Ping from the named host. A target host name resolves to that host's primary IPv4 address. Other targets are passed to ping; a string containing : selects IPv6. Use ping6 to resolve a host name to IPv6.
The defaults are count=1 and timeout=2.0 seconds. count must be a positive integer and limits the number of echo requests. timeout must be finite and non-negative. It accepts fractional seconds, such as 0.25, and is passed to ping -W. A timeout of 0 relies on the overall process wait limit.
p4net calculates the overall wait from the count, timeout, and default one-second send interval. This wait must not exceed 2,147,483 seconds. The result is OK if at least one reply arrives, including under partial packet loss. No replies or an execution failure produces FAIL.
<host> ping6 <target> [count] [timeout]¶
Run IPv6 ping with the same defaults as ping. A host name resolves to its primary IPv6 address; a host without one produces an error. You can also give an IPv6 address directly.
<host> xterm¶
Open an xterm running bash in the host's namespace. This requires xterm and a graphical session reachable through DISPLAY. The process is tracked and terminated when the network stops.
The PID varies between runs.
<host> cmd <argv>...¶
Run a command in the host's namespace, with a 30-second timeout. Quotes group arguments using shlex; the command is executed directly. Use sh -c '...' when you need shell features such as pipes or redirection.
Stdout is printed first, then stderr with [stderr] before each line. A nonzero exit status adds [exit N].
<host> ifconfig¶
Run ip -br addr in the host's namespace and display its stdout.
Switch commands¶
<switch> log¶
Show the path of the switch's BMv2 log file. A relative --log-dir produces a relative path here.
<switch> table list¶
List the tables in the loaded P4Info. Each line contains the table name and its match-field types and names:
<switch> table dump <table>¶
Show entries in the named table. Values are formatted by field width: 32-bit values as IPv4 addresses, 128-bit values as IPv6 addresses, 48-bit values as MAC addresses, and other widths as decimal numbers. Match types add the prefix length, mask, or range. Action parameters use the same width-based formatting.
For a table containing one IPv4 forwarding entry:
p4net> s1 table dump MyIngress.ipv4_lpm
#0
table: MyIngress.ipv4_lpm
match: {'hdr.ipv4.dstAddr': '10.0.0.1/32'}
action: MyIngress.set_egress_port
params: {'port': '1'}
An empty table returns (table 'MyIngress.ipv4_lpm' is empty).
<switch> table add <table> match: <kv>... action: <name> [params: <kv>...] [priority: <n>]¶
Insert an entry. match:, action:, params:, and priority: start separate sections. Match fields and action parameters use key=value pairs, separated by spaces or commas.
p4net> s1 table add MyIngress.ipv4_lpm match: hdr.ipv4.dstAddr=10.0.0.5/32 action: MyIngress.set_egress_port params: port=2
ok
Match values follow the field types in the target switch's P4Info:
| Match type | Example |
|---|---|
| exact, optional | key=123 |
| lpm | key=10.0.0.0/24 |
| ternary | key=0x1200&&&0xff00 |
| range | key=100..200 |
Each component accepts the field's supported value formats, including decimal or hexadecimal integers, IP addresses, and MAC addresses. Write composite values without spaces, or quote the whole value when including spaces.
For a nonzero LPM prefix, bits outside the prefix must be zero. 10.0.0.5/24 reports an EncodingError. Use 10.0.0.0/24. Prefix /0 is a wildcard: its value is checked for format and width before the matching field is omitted.
For a nonzero ternary mask, value bits must be zero wherever the mask is zero. 0xab&&&0xf0 reports an EncodingError. Use 0xa0&&&0xf0. A zero mask is a wildcard: both parts are checked for format and width before the matching field is omitted, even when the value is nonzero.
Range bounds must satisfy low <= high. Equal bounds match one value. Reversed bounds report an EncodingError.
For a 16-bit range field, key=0..65535 matches every value. Such wildcard fields are omitted from entries shown by table dump; the table still requires a priority.
For exact/LPM-only tables, omit priority:. Tables with optional, ternary or range keys require it when inserting entries, including entries that omit an optional field as a wildcard. The priority must be an integer from 1 to 2147483647. Zero, negative and out-of-range values report an EncodingError before sending the request. For a table with an exact destination MAC, a ternary source MAC, and a range of EtherTypes:
p4net> s1 table add MyIngress.l2_match match: hdr.ethernet.dstAddr=00:00:00:00:00:02,hdr.ethernet.srcAddr=00:00:00:00:00:00&&&ff:ff:ff:ff:ff:00,hdr.ethernet.etherType=0x88b0..0x88bf action: MyIngress.set_egress_port params: port=2 priority: 17
ok
<switch> table del <table> match: <kv>... [priority: <n>]¶
Delete an entry using its match key. Use the same match-value formats as table add, including value&&&mask and low..high. For tables with optional, ternary or range keys, supply the entry's original priority as priority: N, including for wildcard entries. It must be an integer from 1 to 2147483647. Omitting a required priority reports an EncodingError. For exact/LPM-only tables, omit priority:.
<switch> table clear <table>¶
Delete all entries from the table and return cleared N entries.
<switch> counter [reset] <name> [<index>]¶
Read an indirect counter cell, or use reset to clear it. With an index, reading returns pkts=N bytes=M. Without an index, it returns a table of cells, or (no populated cells) if the switch returns none. The P4 counter type determines which counts are recorded. Resetting without an index clears all returned cells.
p4net> s1 counter reset MyIngress.ingress_pkts 1
ok
p4net> s1 counter MyIngress.ingress_pkts 1
pkts=0 bytes=0
<switch> mcast list¶
List multicast groups in group-ID order, in the form <id>: [<port>, ...]. An empty result is (no multicast groups).
<switch> mcast add <id> <port,port,...>¶
Create a group with the specified replication ports.
<switch> mcast del <id>¶
Delete the specified multicast group.
<switch> packet send <hex_payload> [metadata: <k>=<v>[,<k>=<v>...]]¶
Queue a PacketOut on the P4Runtime StreamChannel. The payload is the complete packet, expressed as a hex string. Metadata names and widths come from the P4Info packet_out header; omitted fields are filled with zero.
The CPU punt example provides a pipeline with controller packet headers and a CPU port. Its PacketOut command is:
<switch> packet listen [count=N] [timeout=T]¶
Collect new PacketIn messages while the command runs. Return when count packets arrive or the total timeout elapses. Defaults are count=1 and timeout=10.0 seconds. count must be a positive integer. timeout must be finite, non-negative, and within the system wait limit; 0 means no waiting. At timeout, any packets already collected are displayed.
Each output line contains metadata as [name=value] fields followed by the packet's hex contents. Metadata fields are sorted by name. Hex contents longer than 64 characters are truncated with .... If no packet arrives, the result is (no packets within 3.0s).
Keyboard shortcuts¶
Ctrl-C: cancel the input line being edited.Ctrl-Don an empty line: leave the shell and shut down the network.↑/↓: browse history, stored in~/.p4net_history.Tab: complete top-level commands, host and switch names, and node verbs such aspingortable.