p4lang / p4c

P4_16 reference compiler
https://p4.org/
Apache License 2.0
667 stars 441 forks source link

Testing hash tuple data with ebpf psa #3507

Open hesingh opened 2 years ago

hesingh commented 2 years ago

This is the P4 program used to test ebpf psa. I am chasing testing of StructExpression by using a hash in P4 code.


./p4c-ebpf --arch psa --target kernel -o out.c ../backends/ebpf/psa/examples/upf.p4

$ git diff examples/upf.p4
diff --git a/backends/ebpf/psa/examples/upf.p4 b/backends/ebpf/psa/examples/upf.p4
index 806831476..814eceea0 100644
--- a/backends/ebpf/psa/examples/upf.p4
+++ b/backends/ebpf/psa/examples/upf.p4
@@ -146,6 +146,7 @@ struct upf_meta_t {

 struct metadata {
     upf_meta_t upf;
+    bit<16>    hash;
 }

 struct headers {
@@ -338,6 +339,7 @@ control upf_ingress(
         in    psa_ingress_input_metadata_t  istd,
         inout psa_ingress_output_metadata_t ostd) {

+        Hash<bit<16>>(PSA_HashAlgorithm_t.CRC16) h;

     action drop() {
         ingress_drop(ostd);
@@ -481,6 +483,8 @@ control upf_ingress(

     apply {
+        bit<16> hash_value = h.get_hash({meta.upf.gtpu_local_ip});
+
         source_interface_lookup_by_port.apply();
         if (gtpu.isValid()) {
             if (session_lookup_by_teid.apply().hit) {

The out.c file has this code which I don't understand - why is there no struct for hash data in generated code?

/* upf_ingress_h.get_hash({meta->upf.gtpu_local_ip}) */
crc16_finalize(ingress_upf_ingress_h_reg);

I see this commit added code to process StructExpression by a backend but no P4 program exists in the commit to test this new processing.

https://github.com/p4lang/p4c/commit/c794fb4aa8968f976bb0842b45543fdc5fe9fab1

tatry commented 2 years ago

The out.c file has this code which I don't understand - why is there no struct for hash data in generated code?

/* upf_ingress_h.get_hash({meta->upf.gtpu_local_ip}) */
crc16_finalize(ingress_upf_ingress_h_reg);

Implemented algorithm calculate hash based on definition, so it require register variable and input data. Struct for hash data should be generated (as far I remember), but it is not used at all. Each field of data is passed to the crc16_update function (it can be called multiple times) to update the register value based on input data. Some CRC algorithms after data process transform register value (e.g. by xor with some value), that's why crc16_finalize function exists, because implementation for CRC16 and CRC32 is the same. See https://github.com/p4lang/p4c/commit/77ddb3e82d6bd4f0e9f9206c7c2b7e9a456eccdc

There are at least two reasons why there is no struct used for hash data in generated code:

I see this commit added code to process StructExpression by a backend but no P4 program exists in the commit to test this new processing.

c794fb4

For example see hash-crc16.p4 test P4 program, added by later commit.