advanced03-AF_XDP - still receiving packets in user-space although returning `XDP_DROP` in kernel
What I did:
- Setup virtual interface via
$ sudo ./testenv.sh setup --name="veth-basic02" - Constantly pinging the interface via
$ sudo ./testenv ping - Changing
af_xdp_kern.cto:
SEC("xdp_sock")
int xdp_sock_prog(struct xdp_md *ctx) {
return XDP_DROP;
}
- Compiling everything and then
$ sudo ./af_xdp_user --dev veth-basic02 --force
As you can see, I drop every packet in the kernel, but for whatever reason, the user-space application is still receiving packets:
AF_XDP RX: 2 pkts ( 1 pps) 0 Kbytes ( 0 Mbits/s) period:2.000218
TX: 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000218
AF_XDP RX: 4 pkts ( 1 pps) 0 Kbytes ( 0 Mbits/s) period:2.000136
TX: 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000136
AF_XDP RX: 6 pkts ( 1 pps) 0 Kbytes ( 0 Mbits/s) period:2.000119
TX: 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000119
AF_XDP RX: 8 pkts ( 1 pps) 0 Kbytes ( 0 Mbits/s) period:2.000114
TX: 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000114
AF_XDP RX: 10 pkts ( 1 pps) 1 Kbytes ( 0 Mbits/s) period:2.000111
TX: 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000111
If I get the sequence number of the pings via printf("RECEIEVD ICMP6 PACKET WITH SEQUENCE: %d\n", ntohs(icmp->icmp6_sequence)); inside the process_packet-function, I further noticed that they are valid ping requests:
RECEIEVD ICMP6 PACKET WITH SEQUENCE: 2144
RECEIEVD ICMP6 PACKET WITH SEQUENCE: 2145
AF_XDP RX: 2 pkts ( 1 pps) 0 Kbytes ( 0 Mbits/s) period:2.000160
TX: 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000160
RECEIEVD ICMP6 PACKET WITH SEQUENCE: 2146
RECEIEVD ICMP6 PACKET WITH SEQUENCE: 2147
AF_XDP RX: 4 pkts ( 1 pps) 0 Kbytes ( 0 Mbits/s) period:2.000129
TX: 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000129
RECEIEVD ICMP6 PACKET WITH SEQUENCE: 2148
RECEIEVD ICMP6 PACKET WITH SEQUENCE: 2149
AF_XDP RX: 6 pkts ( 1 pps) 0 Kbytes ( 0 Mbits/s) period:2.000114
TX: 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000114
In my opinion, the user space application should not receive anything if the kernel BPF-program decides to drop everything.
What did I do incorrectly? Did I understand something wrong?
After further investigation: The XDP-program is not loaded into the kernel because cfg.filename[0] == 0.
Edit: If I enter af_xdp_kern.o manually to struct config cfg I get: ERROR: Can't setup AF_XDP socket "No such file or directory". If I then revert these changes and set cfg.filename back to "", I still get ERROR: Can't setup AF_XDP socket "No such file or directory".
To get rid of this error, I have to set cfg.do_unload=true and execute the program one more time.
So even though the program tells me that the file was not found, it loaded something into the kernel!
Edit_2: If I change cfg.progsec to something meaningless like blablabla, the program still compiles and works the same as if I would have entered a correct progsec like xdp_sock (a progsec which actually exists in af_xdp_kern.c).
In my opinion this clearly shows that no XDP-Program is loaded. At least the way I do it. But I don't know how to fix this at the moment.
To further prove this I changed cfg to:
struct config cfg = {
.ifindex = -1,
.do_unload = false,
.filename = "af_xdp_kern.o",
.progsec = "blabla"
};
so that during runtime I get the error ERR: couldn't find a program in ELF section 'blabla'.
Don't know why it would show me ERROR: Can't setup AF_XDP socket "No such file or directory" in case I enter both, a correct filename and correct progsec.
$ sudo ./af_xdp_user --filename af_xdp_kern.o --progsec xdp_sock -d veth-basic0 also leads to ERROR: Can't setup AF_XDP socket "No such file or directory"
Edit_3: I tracked the error into xsk.c function named xsk_lookup_bpf_maps. The argument xsk->xsks_map_fd == -1 holds true. Because of this, the call to that function in xsk_setup_xdp_prog fails.
This is because prog_info.nr_map_ids == 0 in xsk_lookup_bpf_maps.
It looks like, xsk.c doesn't like it if no map is loaded/used by the kernel program.