Scope of Nano-P4
This section describes what Nano-P4 includes and what it leaves out. For a complete grammar reference, see Appendix A: Nano-P4 Grammar.
What Nano-P4 includes
Types
Nano-P4 supports the following types:
- Boolean :
bool - Fixed-width integers :
bit<N>andint<N>whereNis a compile-time constant match_kind: the built-in kind used to annotate table key fields- Struct types : declared with
struct - Header types : declared with
header
Named types (structs and headers) can be used anywhere a type is expected.
Expressions
Nano-P4 supports a standard set of expressions:
- Boolean and integer literals
- Variable references
- Unary operators:
!,~,-,+ - Binary operators: arithmetic (
*,+,-), comparison (<,<=,>,>=,==,!=), and bitwise/logical (&,|,^,&&,||) - Member access:
expr.field - Function and extern calls:
f(args) - Parenthesized expressions
Statements
Inside parser states, control apply blocks, and action bodies, the following statements are available:
- Empty statement (
;) - Variable declaration with mandatory initializer:
type name = expr; - Assignment:
lvalue = expr; - Call statement:
lvalue(args); - Block:
{ ... } - Conditional:
if (expr) { ... } else { ... }: both branches are required
Actions
Top-level action declarations are supported:
action drop(inout Header hdr) {
hdr.nanonet.drop = true;
}
Actions must be declared at the top level of the program. Action declarations inside a control block are not supported.
Tables
Tables are supported in a limited form. A table must have a key property and
an actions property, and may optionally have a const entries property:
table t {
key = { hdr.nanonet.drop : exact; }
actions = { drop(hdr); }
const entries = {
(true) : drop(hdr);
}
}
Restrictions compared to full P4:
- Exactly one key field (the key block takes a single
expr : match_kindentry) - Control plane operations are not supported, so table entries cannot be extended at runtime.
- No
default_action,size, or other table properties - Tables can only be declared inside a control block as a local declaration, not at the top level
Parser block
Parser declarations are fully supported, including multiple named states and
select expressions for branching:
parser MyParser(packet_in pkt, out Header hdr) {
state start {
pkt.extract(hdr.nanonet);
transition select(hdr.nanonet.drop) {
true : drop_state;
false : accept;
}
}
state drop_state {
transition accept;
}
}
A parser state body consists of zero or more variable declarations followed by a
transition statement.
Control block
Control declarations are supported. A control may contain local variable
declarations and table declarations, followed by an apply block:
control MyControl(inout Header hdr, out bool pass) {
table t { ... }
apply {
t.apply();
}
}
Extern declarations
Extern object types (used to declare things like packet_in) can be declared
with method prototypes, but not constructors:
extern packet_in {
void extract(out Nanonet hdr);
}
This is how the architecture model exposes built-in operations to the program.
Instantiation
Top-level instantiation is supported and is how the main package is assembled:
NanoSwitch(MyParser(), MyControl()) main;
What Nano-P4 excludes
These features are absent to keep the spec tractable and the type-checking rules focused. The following P4 features are intentionally absent from Nano-P4.
Types
- Header stacks (
header[N]) enumtypesheader_unionlistandtupletypes- Generic types
- Arbitrary-width integer literals
Statements and control flow
forloopsswitchstatementifwithout anelse
Declarations and scoping
- Type aliases (
typedef,type) - Constructor parameters on parsers/controls
- Nested action declarations
Expressions and operators
- Implicit type casting
- Explicit type casting (
(T) expr) - Method overloading
- Dot-prefix notation (
.fieldwithout a receiver)
Table features
- The return value of
table.apply()(.hit,.action_run) default_actionsizeand other table properties- Multiple key fields
Header built-in methods
isValid(),setValid(),setInvalid(), and similar header methods