P4 16 Language design - why tables are not allowed to be updated from Data plane


I was reading through P416 and P4Runtime specifications and was trying to understand the modification of tables - the look-up tables and not the table objects defined in the p4 program - and wanted to know/understand the design logic behind the following specifications: -

  1. In the sections 6.4.1 of P4Runtime API (P4~16~ Language Specification) and of P416 specs (P4~16~ Language Specification), it simply mentions that table modifications can be done by Control Plane. It does not explicitly state anywhere that table updates are not possible by P4 prrograms installed on the target or via Dataplane. Is it true that table updates are only allowed via Control plane? If yes then please consider the following question as well: -
  2. Why are table modifications - add, delete, modification of table entries - only allowed through Control Plane? Why aren’t table updates possible via code logic in p4 programs via the Data plane? (For example, if packet processing metadata indicates increase or decrease in traffic on some link, then updating packet forwarding rules directly by calling necessary APIs from the packet processing pipeline.)
1 Like

Read somewhere that updating table will cost time and the switch needs to be fast.

1 Like

Thanks for the prompt response! I agree that might be a supporting reason for the design choice. Also, looking for reasons if any from an implementation constraints or security concerns PoV. Any other reasons would help as well.
But still is it so that updates are only possible from CP and not p4 programs in DP?

Yeah It is not possible from data plane. You should make a controller and send the packets to controller and make the controller update the table.

The basic answer to why P4 does not stress the ability to modify tables in the data plane is that doing this in general is an expensive complex feature to implement in the packet processing devices with the best price/performance/power ratios, like switch ASICs and NICs.

Yes, it can be implemented in general purpose CPU cores, but such packet processing devices do not ahve the best price/performance/power ratios, but are orders of magnitude worse in those ratios, typically.

The Portable NIC Architecture has in the last couple of years introduced a couple of ways that the data plane can modify tables without the control plane having to do so, that did not exist in previous architectures:

(1) The add_on_miss feature, where if you do an apply() operation on a table and it gets a miss, the default_action (the action that is executed when the table gets a miss) can call a new extern function called add_entry that can add a new entry. It is proposed to be limited to only adding exact match keys, and only the key fields values that were just looked up and missed, but the action and action parameters for this data-plane-added entry can be any of the possible hit actions of the table from the P4 source code.

Admittedly, this is not a fully general mechanism to add new entries, because it does not let the P4 program add any other key other than the one just looked up and missed, nor does it enable adding entries to other tables, only the one that experienced a miss, and it does not support anything except exact match key fields.

However, this does cover a large number of use cases, particularly flow tables where you want to add a new entry if you get a miss, and in particular a new entry that will match future packets with exactly the same key.

This is implemented in many switch ASICs and NICs.

(2) The ability to delete old entries in the data plane that have not been matched in a configurable time interval. See the documentation for pna_idle_timeout = PSA_IdleTimeout_t.AUTO_DELETE in the PNA specification: P4 Portable NIC Architecture (PNA)

This ability is also not a fully general capability to delete arbitrary table entries without control plane help. Again, it is a feature supported by multiple switch ASICs and NICs in the industry, and it goes hand-in-hand with feature (1), usually on the same tables. If you want to add entries at high rate without control plane help, you often also wish to delete entries at high rate without control plane help.


Another possible use-case: stateful dataplane processing. For example, you want the dataplane to implement a certainly policy for the first 5 packets of a new flow (eg create mirror copies and forward), thereafter implement another policy (eg just forward, no mirroring). This requires the dataplane to have a feedback loop to take real-time dataplane info and feed it back into the dataplane. I think the original poster’s question hinted at this, but I am not sure if it was the primary use-case.

@rgrindley I will link to another reply to @Svenzer’s same question in another forum, the p4-discuss email list: https://groups.google.com/a/lists.p4.org/g/p4-discuss/c/r6i33CjTsys/m/XesIgni8CAAJ

That reply links to this pull request to the language spec: Data plane writable per table entry state v1 by jafingerhut · Pull Request #1239 · p4lang/p4-spec · GitHub

That PR proposes a (for now) experimental enhancement to the language that lets you concisely write P4 actions where some of the action parameters can be modified in the data plane while processing a packet, and the results of those changes will be visible to the next packet matching that table entry.

Note: You can do these kinds of things already today, without this change to the language spec, by instead using P4 register arrays that exist in many P4 implementations. P4 register arrays can be read, and new values written back, while processing data packets, and enable pretty much the same features as the language spec extension above does, but with a different syntax. So in some ways, that language spec extension does not actually provide new functionality to P4 – just a more concise syntax to do things that could already be done before.

There are many, many interesting features implemented on Tofino using P4 register arrays in ways that I would not have even imagined before I saw the research papers describing them. For example, implementing “the fast path” of Paxos message processing in a switch ASIC, while handling the relatively rare occurrences of link and/or switch failures in control plane software to get a full Paxos implementation:

The example of “handle the first 5 packets of a flow differently than the 6th or later packets of the same flow” is a much simpler thing to do, it has been done use P4 register arrays for years now, and the above proposal would make the syntax a bit nicer.