P4 Language Support in DPL
This section contains information on the P4 language features that are supported, known issues and deviations from the P4 Language Specification. All references to the spec refer to P416 language specification version v1.2.4.
The NVIDIA BlueField networking platform (DPU or SuperNIC) is a specialized Data Processing Unit engineered to significantly enhance data center performance. It achieves this by efficiently offloading, accelerating, and isolating critical tasks related to networking, storage, and security. BlueField-3 merges the advantages of dedicated accelerators with the versatility of general-purpose processors, all within an ASIC-based system-on-a-chip architecture. It boasts impressive connectivity speeds of up to 400G, making it an ideal choice for environments demanding high levels of AI and high-performance computing capabilities.
To ensure BlueField delivers on its promise of optimized functionality, its P4 language implementation has been tailored to leverage the strengths of high-performance ASIC hardware. This strategic focus on performance and efficiency, however, means that BlueField supports DOCA Pipeline Language (DPL), which does not include every feature outlined in the P4 language specification. This is primarily due to the inherent differences in flexibility and programmability between ASICs and other types of hardware, such as CPUs and FPGAs, and the unique pipeline model of the BlueField DPU. This section outlines the P4 Language features that are currently supported in this release of the NVIDIA DPL compiler.
This document refers to features as being supported
or unsupported
. Supported features have been tested and should work according to the P416 language specification, subject to any caveats described in this document. Unsupported features have not been fully tested and should not be relied upon. In most cases, the compiler will reject programs that use unsupported features. However, in some cases the compiler may accept a program that uses unsupported features if the feature is not necessary to implement the program. For example, if a program contains an expression that uses an unsupported operator but its operands can be computed at compile-time, the compiler may choose to compute the value of the expression at compile-time and accept the program. This behavior should not be used as an indicator of whether the feature is supported.
Identifiers
Identifiers starting with __
are reserved for internal compiler use. Otherwise, identifiers described in the P4 language spec section 6.4.1. Identifiers are allowed.
Data Types
See Operators section for support of operations on values with these types.
Bool
Supported
Arbitrary-precision Integer
Supported only for literals. See spec 7.1.6.5. Arbitrary-precision integers.
Signed integer
Unsupported
Strings literals
No operations are allowed or validity checks performed. See spec 6.4.3.3.
Bit strings
Supported, limited by available hardware resources
Derived Types
Enum
Enumeration types are supported as described in section 7.2.1 of the P416 spec, allowing the P4 programmer to either specify an underlying representation or allow the compiler to choose the representation. Note that the set of allowed types for the underlying representation is limited to those otherwise supported by the DPL compiler.
Header
Header types are supported as described in section 7.2.2 of the P416 spec using field types otherwise supported by the DPL compiler with the exception of
varbit<>
fields. Variable-length header types are supported only using theNvOptionParser
extern type.
Header stacks
Unsupported
Structs
Struct types are supported as described in section 7.2.5 of the P416 spec using field types otherwise supported by the DPL compiler.
Unions
Unsupported
Tuple/List
Tuple types are supported as described in section 7.2.6 of the P416 spec using component types otherwise supported by the DPL compiler.
Extern types
Extern types, including both extern functions and extern objects, as described in section 7.2.9 of the P416 spec are supported only for those declared in the P4 headers distributed with the DPL compiler. P4 programs cannot declare additional extern types.
Type specialization
Type specialization is supported as described in section 7.2.10 of the P416 spec.
Statements and Expressions
Assignment
An L-value cannot be used in a method call expression, packet out metadata, flex-header field, standard metadata field, or as an action parameter. Not all fixed header fields can be an L-value of an assignment statement. Please refer to the chart below.
Conditional
Conditional statements are only supported within control apply blocks. Its expression must evaluate to a bit or bool type.
switch statement
The switch statement is only supported within control apply block. Its expression must evaluate to a bool type.
The compiler supports empty switch statement, fall through, default case, and non-default cases. See spec section 11.7 Switch statement for details.
The following tables describe the compiler support for expressions using the built in header fields and standard metadata as L-values and R-values. Note, this is separate of header fields that can be used as match keys.
In the default hardware parser, some fields that are mutually exclusive are extracted to the same buffer location (referred to in the table as an alias). Assignments to and copy from these fields can use either of the aliased field names.
Fixed Header Fields | Assignable | Copyable | Notes |
| ✔ | ✔ | |
| ✔ | ✔ | |
| ✘ | ✘ |
Last extracted outer |
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✔ | ✔ | |
| ✘ | ✘ |
Last extracted outer |
| ✘ | ✔ | |
| ✘ | ✔ | |
| ✘ | ✘ |
Last extracted inner |
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
Last extracted inner |
Alias with headers.ipv6.version | ✘ | ✘ |
|
| ✘ | ✘ |
|
Alias with | ✘ | ✔ | Can be set through |
Alias with | ✘ | ✔ | Can be set through |
| ✘ | ✘ | Value is write only by hardware |
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
Alias with | ✘ | ✔ | Can be set through |
Alias with | ✘ | ✘ |
|
| ✘ | ✘ | Value is write only by hardware |
| ✔ | ✔ | |
| ✔ | ✔ |
|
Alias with | ✘ | ✘ |
|
| ✘ | ✘ |
|
Alias with | ✘ | ✔ | |
Alias with | ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
Alias with | ✘ | ✔ | |
Alias with | ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✔ | |
| ✘ | ✔ | |
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✔ | ✔ | |
| ✔ | ✔ | |
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✔ | |
| ✘ | ✔ | |
| ✔ | ✔ | |
| ✔ | ✔ | |
| ✔ | ✔ | |
| ✔ | ✔ | |
| ✘ | ✔ | |
| ✘ | ✔ | |
| ✘ | ✔ | |
| ✘ | ✔ | |
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
Alias with | ✘ | ✔ | Can be set through |
Alias with | ✘ | ✔ | Can be set through |
| ✔ | ✔ | |
| ✔ | ✔ | |
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✔ | ✔ | |
| ✔ | ✔ | |
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
Alias with | ✘ | ✔ | |
Alias with | ✘ | ✔ | |
| ✘ | ✔ | |
| ✘ | ✔ | |
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✔ | |
| ✘ | ✔ | |
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ | Value set by hardware after decryption |
| ✘ | ✘ | Value set by hardware after decryption |
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✔ | ✔ | |
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✔ | ✔ | |
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✘ | ✘ |
|
| ✔ | ✔ | |
| ✘ | ✘ |
|
All the fields of BlueField standard metadata are read only. The following table outlines the current support for using a standard metadata field as an R-value in an expression.
Standard Metadata Fields | Copyable | Notes |
| ✔ |
|
| ✘ |
|
| ✘ |
|
| ✘ |
|
| ✔ | Last extracted value of etherType within ethernet header or VLAN tags |
| ✘ |
|
| ✘ |
|
| ✘ |
|
| ✘ |
|
| ✘ |
|
| ✘ |
|
| ✘ |
|
| ✘ |
|
| ✘ |
|
| ✘ |
|
| ✘ |
|
| ✘ | ROCE not currently supported |
| ✘ |
|
| ✘ | Valid only after hardware encrypt/decrypt |
| ✘ | Valid only after hardware encrypt/decrypt |
| ✘ |
|
| ✘ |
|
| ✔ | Last extracted value of etherType within inner ethernet header or VLAN tags |
| ✘ |
|
| ✘ |
|
| ✘ |
|
| ✘ |
|
| ✘ |
|
| ✘ |
|
| ✘ |
|
| ✘ |
|
| ✘ |
|
| ✘ |
|
| ✘ |
|
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 | P4Runtime value | Runtime value | Spec section |
Bool && Bool | ✔ | ✔ | ✔ | 8.5 |
Bool || Bool | ✔ | ✔ | ✔ | 8.5 |
Bool == Bool | ✔ | ✔ 1 | ✔ 1 | 8.5 |
Bool != Bool | ✔ | ✔ 1 | ✔ 1 | 8.5 |
Bit<W> == Bit<W> | ✔ | ✔ 1 | ✔ 1 | 8.6 |
Bit<W> != Bit<W> | ✔ | ✔ 1 | ✔ 1 | 8.6 |
Bit<W> << integer | ✔ 2 | ✔ 2 | ✔ 2 | 8.6 |
Bit<W> >> integer | ✔ 2 | ✔ 2 | ✔ 2 | 8.6 |
Bit<W>[H:L] | ✔ 3 | ✔ 3 | ✔ 3 | 8.6 |
All explicit casts between supported types | ✔ | ✔ | ✔ | 8.11.1 |
All implicit casts between supported types | ✔ | ✔ | ✔ | 8.11.2 |
Bit<W>..Bit<W> | ✔ 4 | ✔ 4 | ✘ | 8.15.4 |
Assignment to user struct fields | ✔ | ✔ | ✔ | 8.16 |
Assignment to packet-in struct fields | ✔ | ✔ | ✔ | 8.16 |
All operations on header fields | ✔ | ✔ | ✔ 5 | 8.17 |
Method calls | ✔ | ✔ | ✘ | 8.20 |
Function calls with positional args | ✔ | ✔ 6 | ✔ 6 | 8.20 |
Extern constructor invocations | ✔ | ✘ | ✘ | 8.21 |
Parser constructor invocations | ✔ | ✘ | ✘ | 8.21 |
Control constructor invocations | ✔ | ✘ | ✘ | 8.21 |
Package constructor invocations | ✔ | ✘ | ✘ | 8.21 |
H and L are subject to the restrictions described in the spec 8.6. Assigning to slices (slices as L-values) is not supported. Additionally, slices as R-values are only supported as P4 table keys.
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.
Control Apply Block
The following statements are supported in a control's apply block:
table.apply()
callsif
statementswitch
statementextern function and method calls
assignment statements with the supported operators
the empty statement
return
statements
The exit
statement is not supported.
All supported expressions are allowed within these statements, where applicable.
Actions
Actions support the same statements as controls except for the following:
table.apply()
callsConditional statements -
if
andswitch
Actions support the same expressions as controls except for the following:
Boolean logical operators -
&&
,||
, ternary operatorComparisons (
==
,!=
, etc.)