Jamal Hadi Salim wrote: > This commit allows users to create, update, delete, get, flush and dump > dynamic action kinds based on P4 action definition. > > At the moment dynamic actions are tied to P4 programs only and cannot be > used outside of a P4 program definition. > > Visualize the following action in a P4 program: > > action ipv4_forward(@tc_type("macaddr) bit<48> dstAddr, @tc_type("dev") bit<8> port) > { > // Action code (generated by the compiler) So this is BPF or what? > } > > The above is an action called ipv4_forward which receives as parameters > a bit<48> dstAddr (a mac address) and a bit<8> port (something close to > ifindex). > > which is invoked on a P4 table match as such: > > table mytable { > key = { > hdr.ipv4.dstAddr @tc_type("ipv4"): lpm; > } > > actions = { > ipv4_forward; > drop; > NoAction; > } > > size = 1024; > } > > We don't have an equivalent built in "ipv4_forward" action in TC. So we > create this action dynamically. > > The mechanics of dynamic actions follow the CRUD semantics. > > ___DYNAMIC ACTION KIND CREATION___ > > In this stage we issue the creation command for the dynamic action which > specifies the action name, its ID, parameters and the parameter types. > So for the ipv4_forward action, the creation would look something like > this: > > tc p4template create action/aP4proggie/ipv4_forward \ > param dstAddr type macaddr id 1 param port type dev id 2 > > Note1: Although the P4 program defined dstAddr as type bit48 we use our > type called macaddr (likewise for port) - see commit on p4 types for > details. > > Note2: All the template commands (tc p4template) are generated by the > p4c compiler. > > Note that in the template creation op we usually just specify the action > name, the parameters and their respective types. Also see that we specify > a pipeline name during the template creation command. As an example, the > above command creates an action template that is bounded to > pipeline or program named aP4proggie. > > Note, In P4, actions are assumed to pre-exist and have an upper bound > number of instances. Typically if you have 1M table entries you want to allocate > enough action instances to cover the 1M entries. However, this is a big waste > waste of memory if the action instances are not in use. So for our case, we allow > the user to specify a minimal amount of actions instances in the template and then > if more dynamic action instances are needed then they will be added on > demand as in the current approach with tc filter-action relationship. > For example, if one were to create the action ipv4_forward preallocating > 128 instances, one would issue the following command: > > tc p4template create action/aP4proggie/ipv4_forward num_prealloc 128 \ > param dstAddr type macaddr id 1 param port type dev id 2 > > By default, 16 action instances will be preallocated. > If the user wishes to have more actions instances, they will have to be > created individually by the control plane using the tc actions command. > For example: > > tc actions add action aP4proggie/ipv4_forward \ > param dstAddr AA:BB:CC:DD:EE:DD param port eth1 > > Only then they can issue a table entry creation command using this newly > created action instance. > > Note, this does not disqualify a user from binding to an existing action > instances. For example: > > tc p4ctrl create aP4proggie/table/mycontrol/mytable \ > srcAddr 10.10.10.0/24 action ipv4_forward index 1 > > ___ACTION KIND ACTIVATION___ > > Once we provided all the necessary information for the new dynamic action, > we can go to the final stage, which is action activation. In this stage, > we activate the dynamic action and make it available for instantiation. > To activate the action template, we issue the following command: > > tc p4template update action aP4proggie/ipv4_forward state active > > After the above the command, the action is ready to be instantiated. > > ___RUNTIME___ > > This next section deals with the runtime part of action templates, which > handle action template instantiation and binding. > > To instantiate a new action that was created from a template, we use the > following command: > > tc actions add action aP4proggie/ipv4_forward \ > param dstAddr AA:BB:CC:DD:EE:FF param port eth0 index 1 > > Observe these are the same semantics as what tc today already provides > with a caveat that we have a keyword "param" to precede the appropriate > parameters - as such specifying the index is optional (kernel provides > one when unspecified). > > As previously stated, we refer to the action by it's "full name" > (pipeline_name/action_name). Here we are creating an instance of the > ipv4_forward action specifying as parameter values AA:BB:CC:DD:EE:FF for > dstAddr and eth0 for port. We can create as many instances for action > templates as we wish. > > To bind the above instantiated action to a table entry, you can do use the > same classical approach used to bind ordinary actions to filters, for > example: > > tc p4ctrl create aP4proggie/table/mycontrol/mytable \ > srcAddr 10.10.10.0/24 action ipv4_forward index 1 > > The above command will bind our newly instantiated action to a table > entry which is executed if there's a match. > > Of course one could have created the table entry as: > > tc p4ctrl create aP4proggie/table/mycontrol/mytable \ > srcAddr 10.10.10.0/24 \ > action ipv4_forward param dstAddr AA:BB:CC:DD:EE:FF param port eth0 > > Actions from other P4 control blocks (in the same pipeline) might be > referenced as the action index is global within a pipeline. > Where did what the action actually does get defined? It looks like a label at this point, but without code?