I am writing a P4 programm, and will later load it into the kernel for cilium development. For the test I have no one byte counter. P4 to count the byte that comes to the computer.
Based on this repository:
https://github.com/p4lang/p4c/blob/main/backends/ebpf/README.md
#include "ebpf_model.p4"
// Define headers
header ethernet_t {
bit<48> dstAddr;
bit<48> srcAddr;
bit<16> etherType;
}
header ipv4_t {
bit<4> version;
bit<4> ihl;
bit<8> diffserv;
bit<16> totalLen;
bit<16> identification;
bit<3> flags;
bit<13> fragOffset;
bit<8> ttl;
bit<8> protocol;
bit<16> hdrChecksum;
bit<32> srcAddr;
bit<32> dstAddr;
}
struct headers {
ethernet_t ethernet;
ipv4_t ipv4;
}
// Define the parser
parser MyParser(packet_in pkt, out headers hdr) {
state start {
pkt.extract(hdr.ethernet);
transition select(hdr.ethernet.etherType) {
0x0800: parse_ipv4;
default: accept;
}
}
state parse_ipv4 {
pkt.extract(hdr.ipv4);
transition accept;
}
}
// Define the filter control block
control MyFilter(inout headers hdr, out bool accept) {
// Define the counter array as per the model
CounterArray(32w1, false) byte_counter;
//bit<32> byteCount;
apply {
//byteCount = 0;
if (hdr.ipv4.isValid()) {
// Cast totalLen to bit<32> and add to counter
byte_counter.add(32w0, (bit<32>)hdr.ipv4.totalLen);
// Update byteCount
//byteCount = byteCount + (bit<32>)hdr.ipv4.totalLen;
}
// Set accept to true
accept = true;
}
}
// Define the package
//package ebpfFilter(MyParser(), MyFilter()) main;
// Corrected package declaration
ebpfFilter(
MyParser(),
MyFilter()
) main;
the error alwayls shows like this, I don't know how to fix the format
$ make -f ../p4c/backends/ebpf/runtime/kernel.mk BPFOBJ=out.o P4FILE=bytecounter.p4
pass verify_cmds: true
pass verify_cmds: true
pass verify_target_bpf: true
p4c-ebpf
Version 1.2.4.14 (SHA: 95e590edc BUILD: RELEASE)
p4c-ebpf -I/home/daqing/p4c/p4c/backends/ebpf/runtime/../p4include --target kernel -o out.c bytecounter.p4 --Werror ;
[--Werror=invalid] error: Invalid key type (MyFilter_byte_counter_key) for table kind BPF_MAP_TYPE_ARRAY, replacing with u32
make: *** [../p4c/backends/ebpf/runtime/kernel.mk:65: out.c] Error 1
How do I find the solution to the problem?
This error is a false error, a false positive: it doesn't mean that there is anything wrong with the P4 code.
If you look into the .c file generated from the P4 source code, you will find that MyFilter_byte_counter_key
is defined as typedef u32 MyFilter_byte_counter_key;
. The error claims that MyFilter_byte_counter_key
is invalid and the compiler will use u32
instead, while they are actually the same type! This is why I believe this error is a false positive.
You can mitigate this error by modifying the arguments you use for compiling. The backends/ebpf/runtime/kernel.mk
Makefile sets the P4ARGS
variable to --Werror
by default, which causes p4c-ebpf
to treat all warnings as errors. You can override this behavior for example by setting P4ARGS
to --Wwarn
, resulting in warnings being treated as warnings.
With the fix mentioned above, the error you are currently getting will become just a warning and your code will compile successfully. You can safely ignore this warning, your code will be fully functional despite it.