Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
P4 externs are an abstraction in the language to call for extending language functionality. For example, the function that sends a packet to a specific port (send_to_port) in P4 PNA is an extern. Externs can be seen as classes, which have constructors and methods. Take, for example, the Register extern definition: extern Register<T> { Register(@tc_numel bit<32> size); @tc_md_read T read(@tc_key bit<32> index); @tc_md_write void write(@tc_key bit<32> index, @tc_data T value); } struct tc_ControlPath_Register<T> { @tc_key bit<32> index; @tc_data T value; } Which can then be instantiated within a P4 program as: Register<bit<32>>(128) reg1; Register<bit<16>>(1024) reg2; Will be abstracted into the template by the P4C compiler for "reg1" as follows: tc p4template create extern/root/register extid 10 numinstances 2 tc p4template create extern_inst/aP4Proggie/register/reg1 instid 1 \ control_path tc_key index type bit32 tc_data value type bit32 \ numelemens 128 default_value 22 =========================EXTERN RUNTIME COMMANDS========================= Once we seal the pipeline, the register values will be assigned to the default value specified on the template as "default_value". After sealing, we can update the runtime instance element. For example to update reg1[2] with the value 33, we will do the following: tc p4ctrl update aP4proggie/extern/register/reg1 tc_key index 2 \ tc_data value 33 We can also get its value: tc p4ctrl get aP4proggie/extern/register/reg1 tc_key index 2 Which will yield the following output: total exts 0 extern order 1: tc_key index id 1 type bit32 value: 1 tc_data value id 2 type bit32 value: 33 We can also dump all of the elements in this register: tc p4ctrl get aP4proggie/extern/register/reg1 Note that the only valid runtime operations are get and update. =========================EXTERN P4 Runtime ========================= The generated ebpf code invokes the externs in the P4TC domain using the md_read or md_write kfuncs, for example: if the P4 program had this invocation: tmp1 = reg1.read(index1); Then equivalent generated ebpf code is as follows: param.pipe_id = aP4Proggie_ID; param.ext_id = EXTERN_REGISTER; param.inst_id = EXTERN_REGISTER_INSTANCE_ID1; param.index = index1; param.param_id = EXTERN_REGISTER_PARAM_ID; bpf_p4tc_extern_md_read(skb, &res, ¶m); tmp1 = (u32 *)res.params; Co-developed-by: Victor Nogueira <[email protected]> Signed-off-by: Victor Nogueira <[email protected]> Co-developed-by: Pedro Tammela <[email protected]> Signed-off-by: Pedro Tammela <[email protected]> Signed-off-by: Jamal Hadi Salim <[email protected]>
- Loading branch information