This section outlines the P4-16 language features supported by the DOCA Pipeline Language (DPL) and notes any known deviations or limitations. All references are based on the P4 Language Specification version v1.2.5.
Introduction
NVIDIA® BlueField® networking platforms (DPU or SuperNIC) are designed to accelerate data center workloads by offloading and isolating key infrastructure tasks, including networking, storage, and security. BlueField-3 combines ASIC performance with programmable flexibility, supporting up to 400G connectivity—ideal for AI and HPC environments.
To optimize for high-performance hardware, the P4 implementation on BlueField differs from generic software targets. As a result, DOCA Pipeline Language (DPL) selectively supports P4 features that align with its target architecture. This section details which P4 features are currently supported, restricted, or unsupported.
A feature labeled as “unsupported” is either not implemented or has not been validated. The compiler may explicitly reject such usage or accept it only if resolved at compile time (e.g., via constant folding). However, acceptance does not mean the feature is supported; do not rely on accepted, unsupported features.
P4 Language Features
The DPL compiler implements a performance-oriented subset of P4-16, aligned with the capabilities of the BlueField hardware. Unsupported features are typically those that require runtime flexibility (e.g., dynamic parsing or general-purpose control logic) which are not efficient in ASIC-based systems. Developers should reference this section during development to ensure compatibility and portability of P4 programs targeting DPL.
Identifiers
-
Identifiers starting with
__are reserved for internal compiler use -
All other identifiers conform to P4 spec §6.4.1
Data Types
|
Type |
Support Level |
Notes |
|---|---|---|
|
|
Supported |
Fully supported |
|
Arbitrary-precision int |
Limited |
Only for literals (see spec §7.1.6.5 ) |
|
|
Unsupported |
|
|
String literals |
Unsupported |
Accepted, but no operations or validity checks (see spec §6.4.3.3 ). Only supported in annotations. |
|
Bit strings |
Supported |
Subject to hardware resource limits |
Refer to section "P4 Language Support in DPL | Operators" for support of operations on values with these types.
Derived Types
|
Type |
Support Level |
Notes |
|---|---|---|
|
|
Supported |
As per spec §7.2.1 , with restrictions based on target-supported types |
|
|
Supported |
All field types except §7.2.2 . |
|
|
Unsupported |
|
|
|
Supported |
Must use only supported field types. See spec §7.2.5 . |
|
|
Unsupported |
|
|
|
Supported |
As per spec §7.2.6 |
|
|
Limited |
Only the externs provided with the DPL compiler are allowed; no custom externs. See spec §7.2.9 . |
|
Type specialization |
Supported |
As per spec §7.2.10 |
Statements and Expressions
|
Feature |
Support Level |
Notes |
|---|---|---|
|
|
Limited |
L-values are restricted. Cannot assign to method calls, |
|
|
Supported |
See DLP Expressions, Header Field Support for details. |
|
|
Limited |
Only within control |
|
|
Limited |
Only within control Fall-through, default, and empty |
Operators
The P4-16 language specification lists a wide variety of operations that the language accepts for the supported data types (see Section 8). The table below lists the operators that are officially supported by the NVIDIA P4 compiler:
|
Operator |
Compile-time value |
P4 action parameter value |
Runtime value |
Spec section |
|---|---|---|---|---|
|
bool && bool
|
✔ |
✔ |
✔ |
8.5 |
|
bool || bool
|
✔ |
✔ |
✔ |
8.5 |
|
! bool
|
✔ |
✔ |
✔ |
8.5 |
|
bool == bool
|
✔ |
✘ |
✘ |
8.5 |
|
bool != bool
|
✔ |
✘ |
✘ |
8.5 |
|
bit<W> == bit<W> |
✔ |
✔ |
✔ |
8.6 |
|
bit<W> != bit<W> |
✔ |
✔ |
✔
|
8.6 |
|
bit<W> << integer |
✔ |
✔
|
✔
|
8.6 |
|
bit<W> >> integer |
✔ |
✔
|
✔
|
8.6 |
|
bit<W>[H:L] |
✔ |
✔ |
✔ |
8.6 |
|
bit<W> > bit<W> |
✔ |
✔ |
✔ |
8.6 |
|
bit<W> >= bit<W> |
✔ |
✔ |
✔ |
8.6 |
|
bit<W> < bit<W> |
✔ |
✔ |
✔ |
8.6 |
|
bit<W> <= bit<W> |
✔ |
✔ |
✔ |
8.6 |
|
All explicit casts between supported types |
✔ |
✔ |
✔ |
8.11.1 |
|
All implicit casts between supported types |
✔ |
✔ |
✔ |
8.11.2 |
|
bit<W>..bit<W> |
✔ |
✔ |
✘ |
8.15.4 |
|
Assignment to user struct fields |
✔ |
✔ |
✔ |
8.16 |
|
Assignment to packet-in struct fields |
✔ |
✔ |
✔ |
8.16 |
|
All operations on header fields |
✔ |
✔ |
✔ |
8.17 |
|
Method calls |
✔ |
✔ |
✘ |
8.20 |
|
Function calls with positional args |
✔ |
✔ |
✔ |
8.20 |
|
Extern constructor invocations |
✔ |
✘ |
✘ |
8.21 |
|
Parser constructor invocations |
✔ |
✘ |
✘ |
8.21 |
|
Control constructor invocations |
✔ |
✘ |
✘ |
8.21 |
|
Package constructor invocations |
✔ |
✘ |
✘ |
8.21 |
|
Decrement (-=) |
✔ |
✔ |
✔ |
- |
|
Increment (+=) |
✔ |
✔ |
✔ |
- |
Variables
Variables are supported in accordance with the following spec items:
-
Constants (spec 11.1)
-
"Compile-time known values" are evaluated on a best-effort basis. It is possible that a compile-time known value may not be recognized by the compiler as such.
-
-
Variables (spec 11.2)
-
Instantiations (spec 11.3)
-
Instantiations with abstract methods (spec 11.3.1) are allowed in BlueField Target Architecture
-
Named arguments are not supported
-
Variables may be declared in any of the locations described in (spec 11.2) and follow the scope rules described there.
The compiler will emit errors for uninitialized values. In some cases where a struct is partially initialized, only a warning may be produced. In some cases there may be no error emitted when an uninitialized struct field is accessed. The accessed field will then contain an undefined value.
On BlueField-3 the maximum amount of user metadata is 256 bits at any single point in the program. The remaining register space is utilized internally by the firmware.
Control Apply Block
The apply block within a control logic supports a specific subset of P4 statements to ensure deterministic execution and hardware compatibility.
Supported Statements
The following statements are supported within the control flow:
-
table.apply()calls -
if/elsestatements -
switchstatements -
Extern function and method calls
-
Assignment statements (using supported operators)
-
The empty statement (
;) -
returnstatements
The exit statement is not supported in this target architecture.
Loop Constructs
The for loop is supported, provided it adheres to strict structural restrictions. These constraints are necessary to ensure the compiler can statically verify loop termination (preventing infinite loops in the hardware pipeline).
Both break and continue statements are supported within the loop body.
Loop Constraints
To ensure validity, the loop must follow this specific decrementing pattern:
-
Init Clause: Must be a single assignment defining the loop variable.
-
Condition Clause: Must test that the loop variable is not equal to zero (
!= 0). -
Update Clause: Must be a single operation-assignment that decrements the variable by 1 (
-= 1). -
Body Constraint: The loop body must not modify the loop control variable.
Example Implementation
bit<32> sum = 1;
/* Valid Decrementing Loop */
for (
bit<8> i = headers.ipv4.ttl; // Init statement
i != 0; // Condition
i -= 1 // Update statement
) {
if (i == 64) {
continue;
} else if (i == 1) {
break;
} else {
sum += 1;
}
}
Hardware Constraints: Steering Hop Limits
The BlueField hardware enforces a global limit on the absolute number of steering hops in the pipeline. This acts as a safety mechanism to prevent infinite loops in the data path.
-
Scope: This "TTL" (Time To Live) or hop limit is managed by the firmware. It is an accumulation over all steering domains (not just the DPL program).
-
Validation: Because this is a runtime hardware state dependent on the total system configuration, it is out of the scope of DPL to validate at compile time.
-
Behavior: Once the limit is exceeded, the packet is immediately dropped.
Troubleshooting Steering Violations
Violations of this limit can be detected by monitoring specific steering failure counters exposed to the kernel.
Relevant counters:
-
generated_pkt_steering_fail -
handled_pkt_steering_fail
These can be inspected using the devlink health reporter. See the command devlink health diagnose in the Linux Kernel Documentation.
Table Apply
Calling the apply method on a table produces a result object that can return specific attributes about the table lookup outcome:
-
bool hit
-
bool miss
-
enum action_run
Actions
Actions support the same statements as controls except for the following:
-
table.apply()calls are not supported -
Conditional statements -
ifandswitch- are not allowed
Actions support the same expressions as controls except for the following:
-
Boolean logical operators -
&&,||, ternary operator are not supported -
Comparisons (
==,!=, etc.) are not supported
P4Runtime Features
The DPL compiler generates a p4info file compliant with the P4Runtime Specification (v1.4.1) for all supported DPL features.
Supported Annotations
The compiler supports the following package annotations as outlined in the P4Runtime PkgInfo Message. These allow for better documentation and versioning of the P4 program.
-
@pkginfowith the following fields:-
name -
version -
doc -
arch
-
-
@brief -
@description
Limitations and Unsupported Features
The following P4Runtime features are not supported in this target architecture:
Unsupported P4Info Objects
-
ValueSet
-
Register
-
Digest
Unsupported P4 Entity Messages
The following runtime entities cannot be manipulated via P4Runtime on this target:
-
Packet Replication:
-
PacketReplicationEngineEntry -
MulticastGroupEntry -
CloneSessionEntry
-
-
State and Metadata:
-
ValueSetEntry -
RegisterEntry -
DigestEntry
-
Last updated: