Giter Club home page Giter Club logo

Comments (11)

antoninbas avatar antoninbas commented on July 1, 2024

You can replicate packets in the dataplane using the packet replication engine. This is out of the scope of P4, but bmv2 comes with an implementation. I realized that there is no up-to-date example, so I'll give some details here.

First, you need to define the necessary metadata fields. bmv2 requires these fields to be defined in the P4 program, or multicast won't be enabled:

header_type intrinsic_metadata_t {
    fields {
        mcast_grp : 4;
        egress_rid : 4;
        mcast_hash : 16;
    }
}
metadata intrinsic_metadata_t intrinsic_metadata;

You can ignore the last field for now. When you want a packet to be replicated, you need to set intrinsic_metadata.mcast_grp to a non-zero value in the ingress pipeline. However, this cannot be just any non-zero value, it has to be a valid multicast group id, i.e. a group id that you have configured using the runtime APIs / the CLI.
So now I need to describe the CLI commands. A classic PRE configuration could look like this:

mc_mgrp_create 1
mc_node_create 0 1
mc_node_create 1 2
mc_node_associate 1 0
mc_node_associate 1 1

The first command creates a multicast group with id 1. You can now write that value to intrinsic_metadata.mcast_grp in your P4 program.
The second command creates a multicast node with rid value 0, and adds port 1 to the node (you can have a list of ports here, not just one).
The third commands creates a multicast node with rid value 1, and adds port 2 to the node.
The 4th and 5th commands associates both nodes to the multicast group.

You can now use multicast group 1 to replicate a packet on ports 1 and 2. These packets will be injected in the egress pipeline, where you can write to the packet headers based on the egress port or intrinsic_metadata.egress_rid.

Let me know if you need more help with this.

from p4factory.

holidayfun avatar holidayfun commented on July 1, 2024

Thanks for this easy to understand example!

Adding the Metadata and a Match+Action table for mapping an ip to a multicast group id worked fine, but when i try to create a mc group or a mc node in the CLI, i get the following exception

RuntimeCmd: mc_mgrp_create 1
Creating multicast group 1
Traceback (most recent call last):
File "/home/hartmann/behavioral-model/tools/runtime_CLI.py", line 1974, in
main()
File "/home/hartmann/behavioral-model/tools/runtime_CLI.py", line 1971, in main
RuntimeAPI(args.pre, standard_client, mc_client).cmdloop()
File "/usr/lib/python2.7/cmd.py", line 142, in cmdloop
stop = self.onecmd(line)
File "/usr/lib/python2.7/cmd.py", line 221, in onecmd
return func(arg)
File "/home/hartmann/behavioral-model/tools/runtime_CLI.py", line 546, in handle
return f(_args, *_kwargs)
File "/home/hartmann/behavioral-model/tools/runtime_CLI.py", line 1271, in do_mc_mgrp_create
mgrp_hdl = self.mc_client.bm_mc_mgrp_create(0, mgrp)
File "/home/hartmann/behavioral-model/tools/bm_runtime/simple_pre/SimplePre.py", line 103, in bm_mc_mgrp_create
return self.recv_bm_mc_mgrp_create()
File "/home/hartmann/behavioral-model/tools/bm_runtime/simple_pre/SimplePre.py", line 121, in recv_bm_mc_mgrp_create
raise x
thrift.Thrift.TApplicationException: TMultiplexedProcessor: Unknown service: simple_pre
1

from p4factory.

antoninbas avatar antoninbas commented on July 1, 2024

These PRE commands are specific to simple_switch. While it is possible to use the generic runtime_CLI.py for this, I recommend using the simple_switch CLI, which is a superset of runtime_CLI.py.
You can start the simple_switch CLI with ./targets/simple_switch/sswitch_CLI
If you have installed the behavioral-model code, then you can start it with simple_switch_CLI
If you prefer to use runtime_CLI.py, you have to use command line option --pre SimplePreLAG.

from p4factory.

holidayfun avatar holidayfun commented on July 1, 2024

If i try to start the simple_switch_CLI, i get an ImportError: No module named runtime_CLI.
The sswitch_CLI doesn't take the --thrift-ip argument, so i can't use it.

If i start the runtime_CLI with --pre SimplePreLAG, the utility starts, but if i try to use mc_mgrp_create 1 the CLI throws the same error as seen above.
Do i also have to start the switch with some kind of --pre option?
Looking at bm -h it seems that there is no such option availiable?

from p4factory.

antoninbas avatar antoninbas commented on July 1, 2024

You cannot run a non-installed version of simple_switch_CLI. If you try to run the one in the build directory, you would get that import error (except if you set the PYTHONPATH properly).

You will notice that they are 3 sub-directories under targets in this repository: simple_router, simple_switch and l2_switch. All 3 are P4-programmable software switches, relying heavily on the bmv2 forwarding library. However, they have some small differences in their architecture. Please do not confuse a bmv2 target with a P4 program. Each target can run an almost unlimited number of P4 programs, but each target impose some restrictions on the program or how it can be written. simple_switch is the default target, the standard target. This is pretty much the one everyone should be using.

When you look at the help message for runtime_CLI, you will see that they are three possible values for --pre: None, SimplePre and SimplePreLAG. The right value has to be used for each target (if you want to use mc_* commands). The simple_router target does not have a PRE, so no matter which value you provide, you cannot execute a mc_* command. l2_switch requires SimplePre, and simple_switch requires SimplePreLAG.

Here is what I observe on my machine. First I start simple_switch with simple_switch --log-console <path to a JSON file>. Then:

antonin@antonin-torpille:~/Documents/Barefoot/p4lang/bmv2_dbg$ ./tools/runtime_CLI.py --pre None
Obtaining JSON from switch...
Done
Control utility for runtime P4 table manipulation
RuntimeCmd: mc_mgrp_create 1
Error: Cannot execute this command without packet replication engine
antonin@antonin-torpille:~/Documents/Barefoot/p4lang/bmv2_dbg$ ./tools/runtime_CLI.py --pre SimplePre
Obtaining JSON from switch...
Done
Control utility for runtime P4 table manipulation
RuntimeCmd: mc_mgrp_create 1
Creating multicast group 1
Traceback (most recent call last):
...
thrift.Thrift.TApplicationException: TMultiplexedProcessor: Unknown service: simple_pre
antonin@antonin-torpille:~/Documents/Barefoot/p4lang/bmv2_dbg$ ./tools/runtime_CLI.py --pre SimplePreLAG
Obtaining JSON from switch...
Done
Control utility for runtime P4 table manipulation
RuntimeCmd: mc_mgrp_create 1
Creating multicast group 1

Last one is the right one!

from p4factory.

holidayfun avatar holidayfun commented on July 1, 2024

Thanks for clarifying the difference target vs p4 program, wasn't that clear before!
Got the multicast running with our help.

Now i need to use the recirculation and cloning feature, do you know any example for that?
Is it possible to modify fields of the clone before it is send to ingress or is it necessary to set some metadata and modify the fields when the packet gets reinserted to ingress?

from p4factory.

antoninbas avatar antoninbas commented on July 1, 2024

We support 2 cloning primitives (clone_ingress_pkt_to_egress, clone_egress_pkt_to_egress) and 2 "redirection" primitives (recirculate and resubmit).
Usually I advise people to look at the simple_switch implementation (https://github.com/p4lang/behavioral-model/blob/master/targets/simple_switch/simple_switch.cpp) to figure out the exact behavior. It is not a lot of code (500 lines).
I actually have an example for resubmit here: https://github.com/p4lang/tutorials/tree/master/examples/resubmit
I can give a quick summary for each one. The common point is that they all take a field_list as a parameter, which is the list of metadata fields / headers that you want to copy along with the clone / redirected packet.

  • clone_ingress_pkt_to_egress: clones the original packet (before ingress parser) and injects it in the egress pipeline. Packet being cloned carries on as usual.
  • clone_egress_pkt_to_egress: clones the outgoing packet (the one about to leave the switch, i.e. at the end of the egress pipeline) and injects it at the beginning of the egress pipeline. Packet being cloned carries on as usual.
  • resubmit: at the end of the ingress pipeline, reinjects the packet at the beginning of the packet processing
  • recirculate: at the end of the egress pipeline, reinjects the packet at the beginning of the packet processing

As you can say, except for clone_ingress_pkt_to_egress, the modifications you do on the packet fields will be preserved.

from p4factory.

holidayfun avatar holidayfun commented on July 1, 2024

Is there a way to get the functionallity of clone_egress_pkt_to_ingress like in the p4 spec?
As far as i can see in the simple_switch implementation, recirculate pushes the packet back into the ingress pipeline, but there is no way to push a copy of the packet back into the ingress pipeline and let the original packet be sent out?
Maybe there is some kind of workaround for this?

from p4factory.

antoninbas avatar antoninbas commented on July 1, 2024

You could always call clone_egress_pkt_to_egress and then call recirculate the copy. You can use standard_metadata.instance_type to identify the packet (values are given by this enum: https://github.com/p4lang/behavioral-model/blob/master/targets/simple_switch/simple_switch.h#L106).
Alternatively you can create your own version of the simple_switch target, one which implements clone_egress_pkt_to_ingress.

from p4factory.

holidayfun avatar holidayfun commented on July 1, 2024

Then i need to check in the egress for the instance_type and if it's EGRESS_CLONE i call recirculate.
But i can't call any action in the control egress {} block or am i wrong?
I could do this by creating a table without reads {} block so that the default action gets called on apply(table) and in this default action do the recirculation, but that seems kind of strange, so is there another way to call a action without the need to apply a table beforehand?

from p4factory.

antoninbas avatar antoninbas commented on July 1, 2024

This is correct, actions cannot be called directly from the control flow and you need to define a table without a reads attribute.

from p4factory.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.