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

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

Open
apinski-cavium opened this issue Sep 14, 2022 · 21 comments
Open

Comments

@apinski-cavium
Copy link
Contributor

apinski-cavium commented Sep 14, 2022

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
Copy link
Contributor

hesingh commented Oct 22, 2022

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
Copy link
Contributor

hesingh commented Oct 22, 2022

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
Copy link
Collaborator

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
Copy link
Collaborator

@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
Copy link
Contributor

hesingh commented Oct 23, 2022

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
Copy link
Collaborator

"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
Copy link
Collaborator

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
Copy link
Contributor

hesingh commented Oct 23, 2022

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
Copy link
Contributor

hesingh commented Oct 23, 2022

Minor edits to PNA add-on-miss section.

9008176

@jfingerh
Copy link
Contributor

@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
Copy link
Contributor Author

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
Copy link
Contributor

hesingh commented Oct 23, 2022

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
Copy link
Collaborator

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
Copy link
Collaborator

@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:

  • Netflow/sFlow flow monitoring
  • TCP connection tracking
  • More generally, any case where you have defined some notion of a "flow" based on one or more fields from the packet, and/or metadata, and want to auto-create new entries as new such "flows" appear, and track something about them.

@jafingerhut
Copy link
Collaborator

@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
Copy link
Contributor

hesingh commented Oct 23, 2022

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
Copy link
Contributor

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
Copy link
Contributor

hesingh commented Oct 23, 2022

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
Copy link
Collaborator

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
Copy link
Contributor

hesingh commented Oct 23, 2022

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
Copy link
Contributor

hesingh commented Oct 24, 2022

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 p4lang/p4c#3614

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants