P4 bmv2 support new match kind ?

Hello,

Now I have a packet classification program written in python. It selects matching rules in the rule set according to the five items of source ip, destination ip, source port, destination port, and protocol in the packet header. Similar to the existing match kind in bmv2 (except that the match kind only matches one item in the packet header)

So I want to ask is it possible for me to put my algorithm into bmv2 and implement it? If so, what parts do I need to change? For a beginner, how long do you think it will take to complete the job? I thought about extern implementation, but it shouldn’t be possible.

Thanks

Hi @Versur

I am trying to understand what you already implemented in Python. Do you mind sharing the file or explaining the most important parts?

You could be a little extense and be more specific on what the program does.

Where do you store the rules? How does the program know about the rules? How does this compare to a P4 program?

There are several “match kinds” in regard to P4 tables so not sure which one you are talking about… maybe exact?. What does “one item in a packet header” mean?

I am not really sure what you want to do yet. When you clarify some of the concepts maybe others can help you with more precise information. Making a guess, if you want to implement your own type of match (like exact, lpm, ternary or range), it will involve quite some work by changing the bmv2/Simple switch code (at least C++), possibly modiying the V1Model architecture (v1model.p4) too and/or maybe core.p4 (and all the changes that need to support this on the bmv2 framework). I also guess that the control plane will have to be aware of the match kinds supported, so not sure if the P4runtime server needs changes, but seems reasonable to think so. Without any previous experience, I believe you will need a considerable amount of time. Not trivial at all I believe (but I have no experience in this type of changes myself) but possible, just depends on your availability. Once you clarify some concepts the changes might be less substantial and I can definitely be wrong in the amount of time you need. Still, it would take some time to understand how every program works before you make changes.

Cheers,

@name, Thank you very much for your reply.
I’m so sorry I didn’t reply you in time for doing other things.

Ok, let me describe in detail what I am doing now and what I want to do with bmv2.

The function I am currently implementing in python code is a packet classification algorithm.
In theory, it can be applied to any scenario that requires packet classification, such as routing table query, firewall acl query, etc.
Packet classification is a process that classifies a packet to determine which rule in the rule set matches the packet by inspecting some packet header field.
A packet classifier contains a list of rules. Each rule specifies a pattern on multiple fields in the packet header. Typically, these fields include source and destination IP addresses, source and destination port numbers, and protocol type. The rule’s pattern specifies which packets match the rule. Matching conditions include prefix based matching (e.g., for IP addresses, similar to LPM supported by bmv2), range based matching (e.g., for port numbers, similar to RANGE supported by bmv2), and exact matching (e.g., for protocol type, similar to EXACT supported by bmv2).
A packet matches a rule if each field in the packet header satisfies the matching condition of the corresponding field in the rule, e.g., the packet’s source/destination IP address matches the
prefix of the source/destination address in the rule, the packet’s source/destination port number is contained in the source/destination range specified in the rule, and the packet’s protocol type matches
the rule’s protocol type.

In practice, the input to my algorithm looks like this:

205.169.228.10, 79.60.9.165, 2000, 1708, 0x06

consist of source and destination IP addresses, source and destination port numbers, and protocol type.
The set of rules to be queried looks like this:

205.169.228.10/32       79.60.9.165/32       0 : 65535      1708 : 1708      0x06/0xFF      action1
205.171.136.164/32      79.60.10.66/32       0 : 65535      1526 : 1526      0x06/0xFF      action2	
205.191.6.238/32        79.60.2.20/32        0 : 65535      20 : 20          0x06/0xFF      action3
205.176.132.226/32      79.60.19.50/32       0 : 65535      5632 : 5632      0x06/0xFF      action4

Through my algorithm, the action1 corresponding to the first rule will eventually be output.
If implemented using p4, I think it might be something like this:

 table ipv4_classification{
         key = {
             hdr.ipv4.srcAddr: lpm;
             hdr.ipv4.dstAddr: lpm;
             hdr.ipv4.srcPort: range;
             hdr.ipv4.dstPort: range;
             hdr.ipv4.protocol: exact;
         }
         actions = {
             action1;
             action2;
             action3;
             action4;
         }

Now since my algorithm is just a simulation implementation, the rules are stored directly in a document and read directly with python. If I want to implement on bmv2, the rules should be stored in routing table entries in bmv2.
So I think I need to modify the underlying source code of bmv2 to implement a new match kind that can query the table that stores routing table rules in bmv2.

Thanks

Hi,

Thanks for being more extensive in your explanations.

I hope not to be wrong, but considering the types of the match keys you listed (lpm, range, and exact), this should already be possible to do without needing a new match kind. You can find an example here for ternary and range, which might be useful for your case. There is some information about match formats in Section 9.1.1 of the P4Runtime spec.

It is a long time I don’t try such a table with 3 different key types. Besides, consider that according to your rule example, the IP addresses can all be done with an exact type of match if you are going to use /32 address matches. Also, your source port is matching all ports, so if this kind of match is persistent, you might also remove the field at all. I also see destination port as being like an exact match. I understand you want to keep all as lpm and range matches. I am only suggesting that for the example you pointed, you do not need them.

Unless there is a limitation from bmv2, you should be able to try this. Have you tried to compile the code? I think that inserting the rules programmatically is going to take you a little long because I always have format problems :sweat_smile:. I think @andyfingerhut will be able to tell if a table like this is possible or not with the current bmv2 and if this can be achieved with P4Runtime. I beleive it should be possible cannot test it myself now, sorry.

In terms of table rules, you will have to either use the tutorial controller example to load entries from a text file, program the control plane in python for the same controller, use a different controller like ONOS or use the simple_switch_cli.

Cheers,

The existing BMv2 / simple_switch software switch, and several other P4 targets I am aware of, should be able to handle it if you use ternary instead of lpm in your table definition. It is not very well-defined what lpm means if it occurs for multiple fields in the same table, but changing them to ternary and simply using value/masks that correspond to the prefix you want should achieve the correct matching behavior:

table ipv4_classification{
         key = {
             hdr.ipv4.srcAddr: ternary;
             hdr.ipv4.dstAddr: ternary;
             hdr.ipv4.srcPort: range;
             hdr.ipv4.dstPort: range;
             hdr.ipv4.protocol: exact;
         }
         actions = {
             action1;
             action2;
             action3;
             action4;
         }
1 Like

@ederollora @andyfingerhut Thank you so much for your replies

I tried matching on multiple fields available in the same table, but although bmv2 and p4 can now support such multi-field matching, I still want to use the tool bmv2 to implement my own multi-field matching algorithm, mainly to verify the performance of my algorithm.

I’d really appreciate it if you could give me some information on how to add new match kind items, like which source code of which components I might need to modify? How difficult is it to modify? How long will it take? etc.

This may also help other researchers who study packet classification algorithms, because as far as I know, people now generally implement their own algorithms on ovs to verify performance.

Thanks very much :blush:

I have not added a new match kind to bmv2 before, myself. I do not know anyone who has done so, other than Antonin Bas who implemented the original match kinds that it now implements. I am also not aware of any written documentation that explains how to go about making such a change.