我从这个存储库开始我的应用程序:https ://github.com/xdp-project/xdp-tutorial/tree/master/advanced03-AF_XDP
就像“概念证明”一样,我想将提供的应用程序更改为
- 丢弃内核程序中所有其他接收到的数据包(
af_xdp_kern.c
) - 回复从用户空间收到的 ping 请求 (
af_xdp_user.c
)
我希望在执行 ping 的控制台窗口中看到的内容:
- 对每第二个 ping 请求的响应(例如,仅偶数或仅奇数序列号)
我注意到的是:
- 每个 ping 请求的响应
为了进一步调查,我用一个简单的内核程序替换了内核程序return XDP_DROP;
——据我所知,这意味着用户空间程序不应该接收任何数据包。
但不知何故,我仍然看到我发送的每个 ping 的响应。
我的内核程序:
/* 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";
用户空间程序:https ://github.com/xdp-project/xdp-tutorial/blob/master/advanced03-AF_XDP/af_xdp_user.c (删除if (false)
行287
)
有什么想法有什么问题吗?
编辑:
$ 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