-
Notifications
You must be signed in to change notification settings - Fork 89
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
Closed
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
e553d88
Initial changes for generic tables
saynb 1d8eff5
second changes
saynb 4690968
3rd changes
saynb 55bf9be
4th changes
saynb f775ddc
5th changes
saynb 07b2da6
Adding p4types and p4info changes for GenericData (#4)
saynb e4a5309
Adding varbits and a readme writeup (#5)
saynb fd132e7
Adding proto changes
saynb 2a5eae6
Adding genericTable for direct resources. Adding P4datatypespec to ge…
saynb 35dc65a
* Adding more container types
saynb 6e7c5f1
* Add Table categories introduction
saynb d6e042b
* Adding 3-level property details (Table, Entry, field)
saynb 53b105f
* Adding Read RPC details in table categories
saynb File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
|
@@ -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 | ||
|
@@ -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 | ||
|
@@ -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 | ||
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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove Indexed There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
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 onunion
in this context.