p4lang / p4c

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

eBPF-PSA: compiler assumes ingress and egress user meta share the same type #4983

Open Trigary opened 8 hours ago

Trigary commented 8 hours ago

The p4c-ebpf backend generates C code that assumes that the user_meta parameters in the ingress and the egress pipelines have the same type. Below is a small example P4 code containing a non-empty egress pipeline and different types being used for the metadatas:

struct ingress_meta_t {}
struct egress_meta_t {}

control IngressImpl(inout headers_t hdr,
                    inout ingress_meta_t user_meta,
                    in psa_ingress_input_metadata_t istd,
                    inout psa_ingress_output_metadata_t ostd) {
    apply {}
}

control EgressImpl(inout headers_t hdr,
                   inout egress_meta_t user_meta,
                   in psa_egress_input_metadata_t istd,
                   inout psa_egress_output_metadata_t ostd) {
    apply {
        // Dummy code to make the egress pipeline non-empty
        if (istd.egress_port != PSA_PORT_CPU) {
            egress_drop(ostd);
        }
    }
}

The following warning is raised when compilation is attempted:

meta_switch.c:477:15: warning: incompatible pointer types assigning to 'struct egress_meta_t *' from 'struct ingress_meta_t *' [-Wincompatible-pointer-types]
    user_meta = &(hdrMd->cpumap_usermeta);
              ^ ~~~~~~~~~~~~~~~~~~~~~~~~~

The specification explicitly states that different types are allowed to be used, and the type parameters of the programmable blocks allow different types as well:

It uses the same user-defined metadata type IM and header type IH for all ingress parsers and control blocks. The egress parser and control blocks can use the same types for those things, or different types, as the P4 program author wishes.


All tests in the backends/ebpf/tests directory use the same type for user_meta in both the ingress and the egress pipelines, that's why this issue is not caught by tests.

p4c version: p4c 1.2.4.2 (SHA: 624c6be80 BUILD: RELEASE)
The P4 source file has been attached: meta_switch.zip
The compiler was invoked using the Makefile found at backends/ebpf/runtime/kernel.mk

This issue is related to https://github.com/p4lang/p4c/issues/4958: both issues mention differences between the specification and the implementation regarding how data can be passed from the ingress to the egress pipeline.

fruffy commented 5 hours ago

Thanks for investigating these issues. Unfortunately, it looks like the eBPF-PSA back end is currently not maintained. It might take a while until this issue is fixed.