p4lang / pna

Portable NIC Architecture
Apache License 2.0
55 stars 21 forks source link

Add Example for add_entry/"Tables with add-on-miss capability" #54

Open apinski-cavium opened 1 year ago

apinski-cavium commented 1 year ago

It would be nice to have an example for the "Tables with add-on-miss capability" section since I am bit confused when reading the section. I am filing this issue to remind myself to submit a pull request for this which I will be doing before the next PNA meeting on Monday.

hesingh commented 1 year ago

One reason for confusion is where does one get the entry from to use in add_entry? The entry data is obtained from packet header(s). An example can be seen on slide 17 at https://opennetworking.org/wp-content/uploads/2020/04/Plenary-4-Slide-Deck.pdf

action hit(bit<8> a0, bit<16> a1) {}
action miss(bit<8> a0, bit<16> a1) {
  a0 = hdr.a0;
  a1 = hdr.a1;
  add_entry("hit", {a0, a1}, expire_time_prof_id);`
}

table foo {
    key = { hdr.ipv6.src_addr : exact;
                hdr.ipv6.dst_addr : exact;
   }
  add_on_miss = true;
  actions = { hit; miss;};
  default_action = miss;
}

In the midend.cpp file of the hardware p4c backend, add add_on_miss as a new property, e.g., https://github.com/p4lang/p4c/blob/main/backends/bmv2/simple_switch/midend.cpp#L114

hesingh commented 1 year ago

First, both v1model.p4 and psa.p4 only support void methods with extern. So the question in pna.p4 if add_entry returns a value is new territory to me.

jafingerhut commented 1 year ago

This checked-in example program uses add_entry on a table with add_on_miss = true, and is intended to be a correct example: https://github.com/p4lang/pna/blob/main/examples/pna-example-tcp-connection-tracking.p4

@hesingh - Note that the example at the link above makes it very explicit that add_entry can only be called from a default_action of the table it is in the action for. Your example in an earlier comment makes it unclear whether action permit6 can be an action of an entry added to the table, or not.

jafingerhut commented 1 year ago

@hesingh wrote in an earlier comment: "First, both v1model.p4 and psa.p4 only support void methods with extern."

That is not true.

In psa.p4, there are several extern functions that return bool.

Method get_hash of extern object Hash returns a parameterized type, which would typically be bit<W> for some value W. There are several other extern object methods that return a type other than void in PSA, besides that example: https://github.com/p4lang/p4c/blob/main/p4include/bmv2/psa.p4

hesingh commented 1 year ago

This checked-in example program uses add_entry on a table with add_on_miss = true, and is intended to be a correct example: https://github.com/p4lang/pna/blob/main/examples/pna-example-tcp-connection-tracking.p4

@hesingh - Note that the example at the link above makes it very explicit that add_entry can only be called from a default_action of the table it is in the action for. Your example in an earlier comment makes it unclear whether action permit6 can be an action of an entry added to the table, or not.

It would be good to actually set/get the data structure ct_tcp_table_hit_params_t in your P4 program.

jafingerhut commented 1 year ago

"It would be good to actually set/get the data structure ct_tcp_table_hit_params_t in your P4 program." I do not understand what you are hoping for here. Can you give an example? That type is a struct type, and it is used in the program in the call to add_entry().

jafingerhut commented 1 year ago

Note: I DO think it would be a very good idea if the text of the PNA specification had a section describing the example I mentioned in more detail, or another example that achieved similar purposes of teaching the reader how these new features work.

hesingh commented 1 year ago

See slide 17 of https://opennetworking.org/wp-content/uploads/2020/04/Plenary-4-Slide-Deck.pdf The action parameters are the entry value as in (key, value) pair. The value is being edited by new data in packet header(s). So I don't even need an add_entry extern. I think PNA seems to have decided not to have editable action parameters and use an explicit extern.

hesingh commented 1 year ago

Minor edits to PNA add-on-miss section.

https://github.com/p4lang/pna/commit/900817650a748fe6a9a372f3774fad8a0d534434

jfingerh commented 1 year ago

@hesingh wrote: "See slide 17 of https://opennetworking.org/wp-content/uploads/2020/04/Plenary-4-Slide-Deck.pdf The action parameters are the entry value as in (key, value) pair. The value is being edited by new data in packet header(s). So I don't even need an add_entry extern. I think PNA seems to have decided not to have editable action parameters and use an explicit extern."

I agree that slide deck proposes a way to edit the action parameters, but unless I am missing something (I might be), it only allows you to edit the action parameters of existing table entries.

add-on-miss is one way to write P4 source code where new table entries can be created while a packet is being processed, in the data plane. The control plane does not create the entries created by add_entry() calls -- the data plane does.

That said, it is also useful to be able to edit table entries like the slides describe. This has been discussed a couple of times in public P4.org architecture work group meetings on PNA, and it is something that several people very much want included in PNA (myself one of them). It isn't written up yet in any PNA documents, only slides presented at PNA meetings.

apinski-cavium commented 1 year ago

Just FYI. I noticed that add_entry can only be called from default_action. If I read this correctly, implicitly this mean no entry in the table can use this specific action as an action and that add_entry cannot use this action as the action for the new entry (this most likely should be rejected at compile time). I do feel like this should be very much explict just to make sure folks are not confused.

hesingh commented 1 year ago

You are correct regarding existing vs. new entries. Writing to existing entry is the mutable entries discussion. There was another reason to point to the slide - to see how data is gleaned from packet header/metadata and used as a new value for existing key.

Regarding add-on-miss, every IETF draft/RFC has a Security section. What are security risks with adding new entry? Is a scan attack possible? TCP connection tracking app adding entries is safe because state is maintained but the section doesn't say, use only for TCP connection tracking.

jafingerhut commented 1 year ago

This is not an IETF draft or an RFC. You are welcome to attempt to write a security risks section about every P4 feature you want, but in general, my view is "P4 is a programming language, like C, C++, Java, Python, etc. are programming languages". P4 is not a particular protocol. It is a programming language in which you can implement protocols, or at least parts of some of them. Its security risks are what the security risks of every programming languages are. Yes, some programming languages have subtler security issues than others, but all useful programming languages share this one biggest security risk: they let you write so many kinds of useful programs, but at the same time let you write programs with bugs, some of which can be security risks. There is no silver bullet for this, other than to think carefully about avoiding such bugs.

jafingerhut commented 1 year ago

@apinski One can easily imagine a more general add_entry mechanism that would enable you to add new table entries in a table's hit actions, and/or to add table entries to any table from any other table.

Such things are certainly possible to implement.

In networking, there is this "simple, sweet spot" where only enabling one to add entries to a table immediately after you just looked up a key, and it missed, and the key is exact match, covers so many useful use cases, and it is significantly easier to implement than the general case, that it seems worth defining this special restricted case, as PNA has done.

Examples of use case I am aware of:

jafingerhut commented 1 year ago

@apinksi And if someone wants to take my previous comment and incorporate it into a pull request, perhaps with nicer language, etc. that is very welcome. I am all for being very explicit about why a feature is very restricted, when it is very restricted.

hesingh commented 1 year ago

I agree add_entry is a language artifact. However, add-on-miss is starting to develop a protocol and this is why the text makes sense to be tighter and if folks agree, examples should be added which @jafingerhut spoke of above, e.g., Netflow.

jfingerh commented 1 year ago

As defined so far, the add_entry() extern function and the add_on_miss table property go hand-in-hand with each other. Using add_entry() for any table except one with add_on_miss=true is a compile-time error. Using add_on_miss=true for a table where none of its actions call the add_entry() extern function will never cause a table entry to be added to it in the data plane, so there was no reason to say add_on_miss=true for it.

I am sure there are ways of defining similar PNA features that are not like this, but the above is what I have in mind as part of the current definition. If the above makes it any clearer to anyone, then yes, let us add text like the above to the PNA spec, perhaps as part of a rationale appendix explaining the design of the add-on-miss feature.

hesingh commented 1 year ago

My point is, add-on-miss is a security risk except when used with state. I don't know enough about Netflow to see why it needs add-on-miss.

jafingerhut commented 1 year ago

My point is: EVERY feature of a programming language is a security risk, if used incorrectly. add-on-miss is no different there. A plain old P4 table with no add-on-miss capability can cause a person A's packet to be sent to person B if it has the wrong entries installed into it, or if the P4 program is written incorrectly.

hesingh commented 1 year ago

Many nodes such as UPF, BNG do not use add-on-miss. Packet going to a wrong layer-2 or layer-3 destination for such nodes is solved by inspecting layer-2 and layer-3 tables, clone detection, DHCP server, and provisioning systems. Service provider nodes take 4-6 months to qualify by an operator - P4 programs are expected to be correct after the qualification.

hesingh commented 1 year ago

Just FYI. I noticed that add_entry can only be called from default_action. If I read this correctly, implicitly this mean no entry in the table can use this specific action as an action and that add_entry cannot use this action as the action for the new entry (this most likely should be rejected at compile time). I do feel like this should be very much explict just to make sure folks are not confused.

See https://github.com/p4lang/p4c/pull/3614