xdp-tutorial icon indicating copy to clipboard operation
xdp-tutorial copied to clipboard

advanced03-AF_XDP - still receiving packets in user-space although returning `XDP_DROP` in kernel

Open Bresenham opened this issue 6 years ago • 2 comments

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.c to:
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?

Bresenham avatar Feb 21 '20 13:02 Bresenham

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.

Bresenham avatar Feb 24 '20 08:02 Bresenham

It looks like, xsk.c doesn't like it if no map is loaded/used by the kernel program.

Bresenham avatar Feb 24 '20 13:02 Bresenham