Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for adding GenericTable #419

Closed
wants to merge 13 commits into from
318 changes: 318 additions & 0 deletions docs/v1/P4Runtime-Spec.mdk
Original file line number Diff line number Diff line change
Expand Up @@ -2007,6 +2007,9 @@ The `Digest` message defines the following fields:
notification using a `P4DataTypeSpec` message (see section on [Representation
of Arbitrary P4 Types](#sec-representation-of-arbitrary-p4-types)).

### `GenericTable` { #sec-p4info-generic-table}
See section [GenericTable p4info](#sec-p4info-generic-table) for more info

### `Extern` { #sec-p4info-extern}

`Extern` messages are used to specify all extern instances across all extern
Expand Down Expand Up @@ -2933,6 +2936,10 @@ tables {
}
~ End Prototext

### GenericData
See section [GenericData p4types](#sec-p4data-generic-data) for more info on the info type.
See section [GenericData p4data](#sec-p4types-generic-data) for more info on the runtime type.

# P4 Entity Messages { #sec-p4-entity-msgs}

P4Runtime covers P4 entities that are either part of the P4~16~ language, or
Expand Down Expand Up @@ -4787,6 +4794,9 @@ message should be defined in a separate architecture-specific Protobuf file. See
section on [Extending P4Runtime for non-PSA
Architectures](#sec-extending-p4runtime) for more information.

## `GenericTableEntry`
See section [GenericTableEntry p4runtime](#sec-p4runtime-generic-table-entry) for more info

# Error Reporting Messages { #sec-error-reporting-messages}

P4Runtime is based on gRPC and all RPCs return a status to indicate success or
Expand Down Expand Up @@ -6269,6 +6279,314 @@ field [@ProtoAny]. At the moment, there is not any mechanism to extend the
`p4.v1.TableEntry` message based on the value of architecture-specific table
properties, but we may include on in future versions of the API.

# GenericTable { #sec-generic-table}

## GenericTable p4info { #sec-p4info-generic-table}

`GenericTable` messages are used to map non-PSA P4-externs or non-P4 target-
specific "fixed" features to their implementation in a generic way. The same can be achieved
via `Extern`, but GenericTable provides a structured way in which every feature is
represented as a set of match-fields and data-fields. The data consists of unions
wihch are similar to actions. One use of GenericTable in a server backend is
with TDI [Table Driven Interface](https://github.com/p4lang/tdi), but targets
can use Generic table to map to their own specific feature implementations as
well.
It defines the following fields

* `generic_table_type_id`, a 8-bit unsigned integer which uniquely identifies the
generic_table_type in the context of the architecture.
This value is in the range of `[0x00, 0xff]`.
The ID in the preamble is created as `0x18` `generic_table_type_id` `16 bits of
genereted ID`.
Note that this value does not need
to be unique across all architectures from all organizations, since at any
given time every device managed by a P4Runtime server maps to a single P4Info
message and a single architecture.

* `generic_table_type_name`, which specifies the fully-qualified P4 name of the
generic_table in case of P4 entities. In cases of non-P4 entities, it is a
name which uniquely identifies this entity in the entire space including P4
objects

* `generic_table_category_type`, please check section [GenericTable categories](#sec-generic-table-categories) for more details


* `preamble`, a `Preamble` message with the ID, name, and alias of this
GenericTable.

* `match_fields`, a repeated field of type `MatchField` representing the data to
be used to construct the lookup key matched in this table. For information check
the match_fields info in the [Table section](#sec-table)

* `union_refs`, a repeated `UnionRef` field representing the set of possible
unions for this table. Functionally, it behaves same as that of ActionRefs.
Hence it has been kept as ActionRefs itself.
Please check the action_refs info in the [Table section](#sec-table)

* `const_default_union_id`, if this table has a constant default union, this
field will carry the `uint32` identifier of that action, otherwise its value
will be 0. A default union is the data when the key is null. It is similar to
a default action for Match Tables.
Being constant means that the control plane cannot
set a different default union at runtime or change the default union's
arguments.

* `size`, an `int64` describing the desired number of table entries that the
target should support for the table. See the "Size" subsection within the
"Table Properties" section of the P4~16~ language specification for details
[@P4TableProperties].

* `is_const_table`, a boolean flag indicating that the table cannot be modified
by the control plane at runtime.

* `other_properties`, an `Any` Protobuf message [@ProtoAny] to embed
architecture-specific or target-specific table properties [@P4TableProperties]
that the target wants to convey.

## `GenericData` { #sec-p4data-generic-data}

`GenericData` is an addition to p4data.proto- which aims at adding support for
data types which aren't covered by P4Data. This incorporates all the data types
used as primitive data types like bytes, float, strings. It contains P

* bitstring : Bytes type used for simple unsigned integers or bytes
* float : Floating type values
* bool : Boolean type values
* generic_struct : Used to define a structure that can contain
one or more of the other members as named. One structure can contain
different members of different types in GenericData.
* generic_bag : Unordered collection of members of same type. Duplicates
are allowed.
* generic_list : Used to define a list of same types. Only allows for a
collection of the same type. It can also be a list of generic_structs.
Members are ordered and duplicates are allowed.
* generic_set : Used to define a set of same types. It can also be a set
of generic_structs. Members are unordered and duplicates are not allowed.
* generic_ordered_set : Used to define an ordered set of same types.
It can also be a set of generic_structs. Members are ordered and
duplicates are not allowed.
* string : Used to define control plane strings. The max string length is
defined by the size
* enum : String representation with which safe enums are realized
* enum_val : bytes value with which unsafe/serializable enums are defined
* p4_type : This is the same type as P4DataTypeSpec. This helps in achieving
parity with P4 types if the GenericTable is being generated from a P4 extern.
There are a few overlaps like bool, enums, new_type, bitstring. If the
entity is from a P4 extern and a P4 data type exists, then the p4_type is
used. Otherwise, the GenericDataType is used

## `GenericTableEntry` { #sec-generic-table-entry}
See section [GenericTableEntry p4runtime](#sec-p4runtime-generic-table-entry) for more info

GenericTableEntry can be used to program non-PSA externs or non-P4 target-specific
"fixed" features to their implementation in a generic way. This provides an alternative
to `Extern` in a structured way and within p4runtime guidelines and semantics.
The idea has been borrowed from TDI [Table Driven Interface](https://github.com/p4lang/tdi),
that every state can be representated as a table or multiple tables. A table here is any
data structure with one or more entries and each entry can be represented as a set of
key fields and data fields.
Actions in P4 tables behave like unions and that has been borrowed here in GenericTable.
This can be potentially used targets to map to either TDI based backends, or even non-TDI
based backends. If using TDI, then potentially, for every new feature to be added, only
TDI backend support and remote client code will be required to make use of that function.
All other middle layers should theoretically remain unchanged.

P4Runtime supports inserting, modifying, deleting and reading GenericTable entries with
the `GenericTableEntry` entity, which has the following fields:

* `table_id`, which identifies the table instance; the `table_id` is determined
by the P4Info message.

* `match`, a repeated field of `GenericFieldMatch` messages. Each element in the
repeated field is used to provide a value for the corresponding element in the
p4info.

* `union`, which indicates which of the table's unions to execute in case of

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I have a concern about the use to the word union by itself. I understand this is a C union type; but union is also a set operation. When I first read this spec, I wasn't sure if the GenericTableEntry's data could support a set of actions -- more than one action (like OpenFlow).

GenericTableEntry's data is in the form of a variant record. Each GenericTableEntry can execute exactly one variant. I feel that the word variant is an improvement on union in this context.

match and with which argument values.

* `priority`, a 32-bit integer used to order entries when the table's match key
includes an optional, ternary or range match.

* `is_default_entry`, a boolean flag which indicates whether the table entry is
the default entry for the table. See [Default entry](#sec-default-entry)
section for more information.

* `metadata`, an arbitrary `bytes` value which is opaque to the
target. There is no requirement of where this is stored, but it must be
returned by the server along with the rest of the entry when the client
performs a read on the entry.

The `priority` field must be set to a non-zero value if the match key includes a
ternary match (&ie; in the case of PSA if the P4Info entry for the table
indicates that one or more of its match fields has an `OPTIONAL`, `TERNARY` or
`RANGE` match
type) or to zero otherwise. A higher priority number indicates that the entry
must be given higher priority when performing a table lookup. Clients must allow
multiple entries to be added with the same priority value. If a packet can
match multiple entries with the same priority, it is not deterministic in the
data plane which entry a packet will match. If a client wishes to make the
matching behavior deterministic, it must use different priority values for any
pair of table entries that the same packet matches.

The `match` and `priority` fields are used to uniquely identify an entry within
a table. Therefore, these fields cannot be modified after the entry has been
inserted and must be provided for `MODIFY` and `DELETE` updates. When deleting
an entry, these key fields (along with `is_default_action`) are the only fields
considered by the server. All other fields must be ignored, even if they have
nonsensical values (such as an invalid action field). In the case of a *keyless*
table (the table has an empty match key), the server must reject all attempts to
`INSERT` a match entry and return an `INVALID_ARGUMENT` error.

The number of match entries that a table *should* support is indicated in P4Info
(`size` field of `Table` message). The guarantees provided to the P4Runtime
client are the same as the ones described in the P4~16~ specification for the
`size` property [@P4TableProperties]. In particular, some implementations may
not be able to always accommodate an arbitrary set of entries up to the
requested size, and other implementations may provide the P4Runtime client with
more entries than requested. The P4Runtime server must return
`RESOURCE_EXHAUSTED` when a table entry cannot be inserted because of a size
limitation. It is recommended that, for the sake of portability, P4Runtime
clients do not try to insert additional entries once the size indicated in
P4Info has been reached.

## GenericTable Categories

All tables fall into certain "categories" which define what APIs are
applicable on the table and the APIs.

* Regular tables: Read, INSERT, MODIFY, DELETE work as intended. Entries in
a table can be inserted, modified and deleted.
* `INSERT` : The union field must be set for every `INSERT` update. If
another entry with same match key exists, then `ALREADY_EXISTS` is
returned.
If `default_entry` is true, then it is treated as a MODIFY. Const
default union rules apply. Match fields and priority should not be set.
* `MODIFY` : Union field must be set since all data fields are under a
union. Modifies the union spec to new union or new field values if
same union.
If `default_entry` is true, then the default entry is modified. Match
fields and priority should not be set. Const default union rules apply.
* `DELETE` : Only Match fields must be set. `NOT_FOUND` is returned if
the entry isn't found. If no Match fields are given, then all entries
are deleted (wildcard delete). If the table contained init entries, they
are restored to initial state with their original union and union field
values.
If `default_entry` is true, then the default entry is reset to initial
values. Const union rules apply.
Wildcard doesn't apply to default_entry.
* `READ` : The Read RPC. All entries can be read. If no entities are
provided in request, then all entries are read, AKA wildcard read.
If `default_entry` is true, then the default entry is returned. Match
fields should not be set in this case.
Wildcard read does NOT return default entry.

* Modify-only tables: Entries exists from the time of initialization. Entries
cannot be inserted but only modified. Delete resets the entry to init time.
Read works as intended.
* `INSERT` : Not supported. Returns `NOT_SUPPORTED` error.
* `MODIFY` : Union field must be set since all data fields are under a
union. Modifies the union spec to new union or new field values if
same union.
If `default_entry` is true, then the default entry is modified. Match
fields and priority should not be set. Const default union rules apply.
* `DELETE` : Instead of deleting, this operation resets the entry with
default values for every field. The union field values are changed
but the union itself isn't changed.
Only Match fields must be set. `NOT_FOUND` is returned if
the entry isn't found. If no Match fields are given, then all entries
are reset (wildcard reset). If the table contained init entries, they
are restored to initial state with their original union and union field
values.
If `default_entry` is true, then the default entry is reset to initial
values. Const union rules apply.
Wildcard doesn't apply to default_entry.
* `READ` : The Read RPC. All entries can be read. If no entities are
provided in request, then all entries are read, AKA wildcard read.
If `default_entry` is true, then the default entry is returned. Match
fields should not be set in this case.
Wildcard read does NOT return default entry.

* Read-only tables: Entries can only be read. Write RPC doesn't work.
* `READ` : The Read RPC. All entries can be read. If no entities are
provided in request, then all entries are read, AKA wildcard read.
If `default_entry` is true, then the default entry is returned. Match
fields should not be set in this case.
Wildcard read does NOT return default entry.

* Reset-only tables :
* `INSERT` : Not supported. Returns `NOT_SUPPORTED` error
* `MODIFY` : Not supported. Returns `NOT_SUPPORTED` error
* `DELETE` : Instead of deleting, this operation resets the entry with
saynb marked this conversation as resolved.
Show resolved Hide resolved
default values for every field.
Only Match fields must be set. `NOT_FOUND` is returned if
the entry isn't found. If no Match fields are given, then all entries
are reset (wildcard reset). If the table contained init entries, they
are restored to initial state with their original union and union field
values.
If `default_entry` is true, then the default entry is reset to initial
values. Const union rules apply.
Wildcard doesn't apply to default_entry.
* `READ` : The Read RPC. All entries can be read. If no entities are
provided in request, then all entries are read, AKA wildcard read.
If `default_entry` is true, then the default entry is returned. Match
fields should not be set in this case.
Wildcard read does NOT return default entry.

* Calculation tables: Entries can only be read. However different from
Read-only in the sense that there is no defined size of the table since
the possible range of matchfields can be immense. For example, hash
calculation tables where matchfields are the field values and the union
data contains the hash value. There is no default_entry for such tables.
* `READ` : The Read RPC. Wildcard read doesn't exist for this table.
Match fields should always be set

* Indexed tables : Entries are ordered.


## GenericTable properties

Properties exist at 3 different levels - Table, entry and field (match or union)

### Table properties

Table properties are at table level. A combination of these define a certain
table category. By default, if absent, they are all always false

* Read-only : No Add/Del/Mod work
* Modify-only : Table entries can only be modifed
* Reset-only : Table can only be reset. Either entire table or individual entries.
* Indexed : The entries are ordered. Handles define the indexes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove Indexed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mark as provisional ?

* Keyless : Only one entry, i.e., default entry exists.
* Calculation : No defined range of key values. For example, hash calculation table
for a set of field values.
* Volatile : Data plane can Add/Del/Mod entries. Example, Add-on-miss in PNA

#### Combinations that are possible

|Table Cat name| Read-only | Modify-only | Reset-only | Indexed | Keyless | Calculation | Volatile |
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| Read-Only | True | False | False | T/F | T/F | T/F | T/F |
| Modify-Only | False | True | False | T/F | T/F | False | T/F |
| Reset-Only | False | False | True | T/F | T/F | False | T/F |
| Indexed | T/F | T/F | T/F | T/F | False | False | T/F |
| Calculation | True | False | False | False | False | True | False |


### Entry properties

* Const (read-only)
* Non-const init
* Modify-only
* Reset-only

### Field properties

* Read-only
* Modify-only
* Reset-only
* Mandatory
* Volatile : Data plane volatile. Example counter bytes.

# Known Limitations of Current P4Runtime Version

* `FieldMatch`, action `Param`, and controller packet metadata fields only
Expand Down
Loading