0

I started my application from this repository: https://github.com/xdp-project/xdp-tutorial/tree/master/advanced03-AF_XDP

Just as a "proof of concept" I wanted to change the supplied application to

  • drop every other received packet in the Kernel-program (af_xdp_kern.c)
  • reply to received ping requests from User-space (af_xdp_user.c)

What I expected to see in the console window performing the ping:

  • a response for every second ping request (e.g. only even or only odd sequence numbers)

What I noticed instead:

  • a response for every ping request

For further investigation, I replaced the kernel program by a simple return XDP_DROP; - according to my knowledge this would mean that the userspace-program shouldn't receive any packets.

But somehow I still see responses for every ping I send.

My Kernel program:

/* SPDX-License-Identifier: GPL-2.0 */

#include <linux/bpf.h>

#include <bpf/bpf_helpers.h>

struct bpf_map_def SEC("maps") xsks_map = {
    .type = BPF_MAP_TYPE_XSKMAP,
    .key_size = sizeof(int),
    .value_size = sizeof(int),
    .max_entries = 64,  /* Assume netdev has no more than 64 queues */
};

struct bpf_map_def SEC("maps") xdp_stats_map = {
    .type        = BPF_MAP_TYPE_PERCPU_ARRAY,
    .key_size    = sizeof(int),
    .value_size  = sizeof(__u32),
    .max_entries = 64,
};

SEC("xdp_sock")
int xdp_sock_prog(struct xdp_md *ctx) {
    int index = ctx->rx_queue_index;
    __u32 *pkt_count;

    pkt_count = bpf_map_lookup_elem(&xdp_stats_map, &index);
    if (pkt_count) {
        /* We drop every other packet */
        if ((*pkt_count)++ % 2 == 0) {
            return XDP_DROP;
        } else {
            if (bpf_map_lookup_elem(&xsks_map, &index)) {
                return bpf_redirect_map(&xsks_map, index, 0);
            }
        }
    }

    return XDP_DROP;
}

char _license[] SEC("license") = "GPL";

Userspace-Program: https://github.com/xdp-project/xdp-tutorial/blob/master/advanced03-AF_XDP/af_xdp_user.c (remove if (false) in line 287)

Any ideas what is wrong?

Edit:

$ ip link
4: veth-basic02@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 96:18:08:5f:c2:c6 brd ff:ff:ff:ff:ff:ff link-netnsid 0

$ ethtool -S veth-basic02
NIC statistics:
     peer_ifindex: 3
     rx_queue_0_xdp_packets: 717
     rx_queue_0_xdp_bytes: 74088
     rx_queue_0_xdp_drops: 0
Vipin Varghese
  • 4,540
  • 2
  • 9
  • 25
binaryBigInt
  • 1,526
  • 2
  • 18
  • 44
  • 1
    Could you check that the XDP program was indeed attached to the interface you expected? `ip link` should show a `xdp` tag for that interface. You also might have XDP statistics if you run `ethtool -S [interface]`. – pchaigno Feb 21 '20 at 15:18
  • @pchaigno I added the outputs for both commands to my original posting. I don't see a `xdp`-tag via `ip link` but I do see statistics with `ethtool` - what does this mean? – binaryBigInt Feb 21 '20 at 15:30
  • Do you really ping the machine from an external host? Or do you ping from the same host where the xdp program is installed – Ctx Feb 21 '20 at 15:53
  • @Ctx From the same host – binaryBigInt Feb 24 '20 at 07:28

1 Answers1

0

Running the AF-XDP sample works for me.

The results shared for 'ip link show ', does not show the XDP program is attached. Hence I followed the steps

  1. (For Debug only) Enhance the application to count incoming packets at index 0 and count dropped packets with index.
  2. build the xdp.o file for xd_kern.c.
  3. remove any previous instance with ip link set dev <interface> xdp off.
  4. Run ip link set dev <interface> xdp object <xdp.o file> section "xdp_sock" verbose.
  5. Run tcpdump -eni ,interface> and check for time stamps.

Note: assuming the ping rate is 1 per second. In every alternative 1 second, there are drops in any packet.

Vipin Varghese
  • 4,540
  • 2
  • 9
  • 25