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

Extending the spec with one shot action selector programming #42

Merged
5 commits merged into from
Aug 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 132 additions & 5 deletions docs/v1/P4Runtime-Spec.mdk
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,7 @@ described as follows:

* The streaming channel between the controller and the server defines the
liveness of the controller session. The controller is considered "offline" or
"dead" as soon as its corresponding stream channel to the the switch is
"dead" as soon as its corresponding stream channel to the switch is
broken, in which case the P4Runtime server quickly sets one of the slave
controllers with the highest `election_id` as master.

Expand Down Expand Up @@ -1934,6 +1934,11 @@ in the `TableAction` message will either be:
* an action profile member id or group id for indirect tables for which the
`implementation` property is an action profile with selector.

* an `ActionProfileActionSet` specification for indirect tables for
which the `implementation` property is an action profile with
selector. This usage is described in [One Shot Action Selector
Programming](#sec-oneshot)

The `Action` Protobuf message, which is used for direct tables only, has the
following fields:

Expand Down Expand Up @@ -2173,8 +2178,7 @@ For more information about idle timeout, in particular regarding
`IdleTimeoutNotification`, please refer to the [Table idle timeout
notifications](#sec-table-idle-timeout-notification) section.

## `ActionProfileMember` & `ActionProfileGroup`

## `ActionProfileMember` & `ActionProfileGroup` { #sec-action-profile-member-and-group }
P4Runtime defines an API for programming a PSA ActionProfile extern using
`ActionProfileMember` messages. PSA ActionSelector extern can be programmed
using both `ActionProfileMember` and `ActionProfileGroup` messages. PSA supports
Expand Down Expand Up @@ -2291,7 +2295,7 @@ An `ActionProfileGroup` entity update message has the following fields:
* `weight` specifying the probability of the member's selection at runtime.
* `watch` is the controller defined 32-bit port number that the member's
liveness depends on. At runtime, the member must be excluded from
selection if the this watch port is down.
selection if the watch port is down.

* `max_size` is the maximum sum of all member weights for the group. This field
is defined when the group is inserted, but it must not be changed in a
Expand Down Expand Up @@ -2320,6 +2324,129 @@ following semantics.
- `DELETE`: Delete the group entry and deallocate the `group_id`. The group
should not be referenced in the table action of any table entry.

### One Shot Action Selector Programming { #sec-oneshot }

P4Runtime supports syntactic sugar to program a table, which is
implemented with an action selector, in one shot. One shot means that a
table entry, an action profile group, and a set of action profile
members can be programmed with a single update message. Using one shots
has the advantage that the controller does not need to keep track of
group ids and member ids.

One shots are programmed by choosing the `ActionProfileActionSet`
message as the `TableAction`. The `ActionProfileActionSet` message
consists of a set of `ActionProfileAction` messages, which in turn
have the following fields:

* `action` is one of the actions specified by the table that is being
programmed.

* `weight` specifying the probability of the action's selection at
runtime.

* `watch` is the controller defined 32-bit port number that the
action's liveness depends on. At runtime, the action must be
excluded from selection if the watch port is down.

Semantically, one shots are equivalent to programming the table entry,
group, and members individually; with the necessary group id and member ids
bound to unused ids. An implementation is free to implement one shots in
other ways, as long as the implementation matches the above semantics.

To preserve read-write symmetry, an implementation must answer
`ReadRequest`s with the original one shot messages. It may not return
a desugared version of the one shot message.

For example, consider the action selector table defined
[here](#sec-action-profile-member-and-group). This table could be programmed
with the following one shot update:

~ Begin Prototext
table_entry {
table_id: 1
match { /* lpm match */ }
action {
action_profile_action_set {
action_profile_actions {
action { /* set nexthop 1 */ }
weight: 1
watch: 1
}
action_profile_actions {
action { /* set nexthop 2 */ }
weight: 2
watch: 2
}
action_profile_actions {
action { /* set nexthop 3 */ }
weight: 3
watch: 3
}
}
}
}
~ End Prototext

Which would be equivalent to the following updates, where `GROUP_ID`,
`MEMBER_ID_1`, `MEMBER_ID_2`, and `MEMBER_ID_3` are unused ids:

~ Begin Prototext
table_entry {
table_id: 1
match { /* lpm match */ }
action { action_profile_group_id: GROUP_ID }
}
action_profile_group {
action_profile_id: 1
group_id: GROUP_ID
members {
member_id: MEMBER_ID_1
weight: 1
watch: 1
}
members {
member_id: MEMBER_ID_2
weight: 2
watch: 2
}
members {
member_id: MEMBER_ID_3
weight: 3
watch: 3
}
}
action_profile_member {
action_profile_id: 1
member_id: MEMBER_ID_1
action { /* set nexthop 1 */ }
}
action_profile_member {
action_profile_id: 1
member_id: MEMBER_ID_2
action { /* set nexthop 2 */ }
}
action_profile_member {
action_profile_id: 1
member_id: MEMBER_ID_3
action { /* set nexthop 3 */ }
}
~ End Prototext

All the tables associated with an action selector may either be
programmed exclusively with one shots, or exclusively with
`ActionProfileMember` and `ActionProfileGroup` messages. Programming
some entries with one shots, and other entries with
`ActionProfileMember` and `ActionProfileGroup` messages is not
allowed, and the server must return the error code
`INVALID_ARGUMENT` in that case.

A P4Runtime server *must* support the one shot style of programming
tables with an action selector implementation. Support for the
`ActionProfileMember` and `ActionProfileGroup` style is *optional*.
Copy link
Member

Choose a reason for hiding this comment

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

I think "optional" is too weak, I would prefer "recommended"

If `ActionProfileMember` and `ActionProfileGroup` are not supported
by a server, it must return an `UNIMPLEMENTED` error for every
`ActionProfileMember` or `ActionProfileGroup` message that it receives.

## `CounterEntry` & `DirectCounterEntry`

PSA defines Counters as a mechanism for keeping statistics of bytes and packets.
Expand Down Expand Up @@ -3502,7 +3629,7 @@ message PacketMetadata {

* `metadata` is a repeated field of `PacketMetadata` messages used to carry the
arbitrary controller metadata. The size and value of such metadata field needs
to consistent with what specified in the the corresponding P4Info
to consistent with what specified in the corresponding P4Info
`ControllerPacketMetadata`. Indeed, when a P4Runtime client (or server)
generates a `PacketOut` (or `PacketIn`) message, it needs to populate the
metadata field with as many values as in `ControllerPacketMetadata.metadata`
Expand Down
11 changes: 11 additions & 0 deletions proto/p4/v1/p4runtime.proto
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ message TableAction {
Action action = 1;
uint32 action_profile_member_id = 2;
uint32 action_profile_group_id = 3;
ActionProfileActionSet action_profile_action_set = 4;
}
}

Expand All @@ -264,6 +265,16 @@ message Action {
repeated Param params = 4;
}

message ActionProfileActionSet {
repeated ActionProfileAction action_profile_actions = 1;
}

message ActionProfileAction {
Action action = 1;
int32 weight = 2;
int32 watch = 3;
}

//------------------------------------------------------------------------------
message ActionProfileMember {
uint32 action_profile_id = 1;
Expand Down