p4lang / p4runtime

Specification documents for the P4Runtime control-plane API
Apache License 2.0
142 stars 88 forks source link

Using indirect counters for Packet I/O #371

Open kishanps opened 2 years ago

kishanps commented 2 years ago

Currently the P4Runtime spec does not specify a defined API to retrieve Packet I/O counters. I wanted to run by the idea of using indexed counters to achieve the same. Essentially define one counter for each counter type (like PacketInReceive, PacketInError, PacketOutSent, PacketOutError), have its size as an array of max ports and use the port id as the index of the array.

PACKETIN_RECIEVE_COUNTER_ID 0x12000001 PACKETIN_ERROR_COUNTER_ID 0x12000002 PACKETOUT_SENT_COUNTER_ID 0x12000003 PACKETOUT_ERROR_COUNTER_ID 0x12000004

This looks inline with the spec definition and wouldn't require any API changes. Given that Packet I/O is an important part of the P4Runtime interface, does this suffice or is anyone working or feel the need for an explicit proto definition of the Packet I/O counters ?

As an additional question on using the port id as an index, if the port id's being used are not contiguous, will it be ok to have the first index for each port represent the port id followed by the actual counter value. So, essentially the size of the array will be 2x(max_ports). For example

PACKETIN_RECIEVE_COUNTER_ID 0x12000001 [1] - port id [1000] - port id '1' counter value [4] - port id [2000] - port id '4' counter value ...

jafingerhut commented 2 years ago

Suppose you have a hardware switch ASIC with a P4Runtime server running on a nearby control plane CPU.

Are the counters you are proposing maintained by the P4Runtime server software only, and count the number of packetIn/Out packets that the server software sends/receives?

Or would they be counters read from the switch ASIC and represent packet/byte counters of packetin/out packets that the switch ASIC device received/sent?

jafingerhut commented 2 years ago

Actually, one aspect of your question completely confuses me: "have its size as an array of max ports and use the port id as the index of the array."

There is nothing in the PSA or P4Runtime specification that to my knowledge implies that a PacketOut packet from controller to device will go into anything other than exactly one port on the device, called the CPU port. Are you thinking that a controller can somehow cause a PacketOut packet to go into any physical front panel port of a switch? I know there are switch ASICs that can't do that. There might be some that can, too, but I would double check if that is currently just an unconfirmed belief.

kishanps commented 2 years ago

Thanks Andy!

Are the counters you are proposing maintained by the P4Runtime server software only, and count the number of packetIn/Out packets that the server software sends/receives?

Yes, that's correct, these are software "only" counters.

Are you thinking that a controller can somehow cause a PacketOut packet to go into any physical front panel port of a switch?

The spec already provisions for this, sending PacketOut on a specific egress port is supported by many ASIC's.

jafingerhut commented 2 years ago

A few lines earlier in the spec it shows that the line you linked to is an example: https://github.com/p4lang/p4runtime/blob/45d1c7ce2aad5dae819e8bba2cd72640af189cfe/docs/v1/P4Runtime-Spec.mdk#L1750

You can write P4 code that includes that metadata field, and you can write P4 code that does not include that metadata field.

A PacketOut packet from controller to switch could easily be programmed by the P4 code to always be dropped.

Even if the PacketOut packet was processed by the P4 program loaded into the device to go to an output port, there is not necessarily any way for the hardware to know that the packet going out that switch front panel port started as a PacketOut packet, versus a packet that started as one arriving on a switch front panel port.

kishanps commented 2 years ago

there is not necessarily any way for the hardware to know that the packet going out that switch front panel port started as a PacketOut packet, versus a packet that started as one arriving on a switch front panel port.

Agree, the use-case of interest here, is to retrieve the software counters of the P4Runtime server on how many packets it sent out on a per-port basis.

jafingerhut commented 2 years ago

More generally, the P4Runtime API spec defines the interaction between controller and switch/device regardless of what P4 program is loaded into the device.

It sounds like some of the things you are asking about are things that a P4-programmable device could do, if a particular P4 program was loaded into it (i.e. remember whether a packet received by the switch was originally a PacketOut packet or not, and maintain separate per-output-port packet/byte counters for those packets, versus independent counters that were only updated if the packet did not start out as a PacketOut packet).

But, that same P4-programmable device could also be loaded with a P4 program that, shortly after the PacketOut packet arrives, completely forgets that it was originally a PacketOut packet, and/or simply counts packets sent to physical output ports regardless of that distinction.

jafingerhut commented 2 years ago

Agree, the use-case of interest here, is to retrieve the software counters of the P4Runtime server on how many packets it sent out on a per-port basis.

Understood. But what if a P4 program is loaded that does not have a controller_header field that chooses the packet's output port? What would your proposed feature do then?

kishanps commented 2 years ago

In that case, only the CPU port will have a non-zero counter value.

By "proposed feature", are you referring to the "explicit proto definition of Packet I/O counters" in my question or to the indexed counters approach ?