这是我所有的 XDP / BPF 内核代码:
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") rx_queue_pckt_counter_map = {
.type = BPF_MAP_TYPE_ARRAY,
.key_size = sizeof(int),
.value_size = sizeof(unsigned long),
.max_entries = 48,
};
SEC("xdp_sock")
int xdp_sock_prog(struct xdp_md *ctx) {
int index = ctx->rx_queue_index;
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
void *pos = data;
struct ethhdr *eth = (struct ethhdr*)(pos);
if(eth + sizeof(struct ethhdr) <= data_end) {
if(bpf_ntohs(eth->h_proto) == ETH_P_IP) {
struct iphdr *iph = (struct iphdr*)(pos + sizeof(struct ethhdr));
if(iph + sizeof(struct iphdr) <= data_end) {
if(iph->protocol == IPPROTO_UDP) {
const __u16 iph_sz_in_bytes = iph->ihl * 4;
if(iph + iph_sz_in_bytes <= data_end) {
struct udphdr *udh = (struct udphdr*)(pos + sizeof(struct ethhdr) + iph_sz_in_bytes);
if(udh + sizeof(struct udphdr) <= data_end) {
void *rec = bpf_map_lookup_elem(&rx_queue_pckt_counter_map, &index);
if(rec) {
long *pckt_counter_val = (long*)(rec);
*pckt_counter_val += 1;
} else {
return XDP_PASS;
}
if (bpf_map_lookup_elem(&xsks_map, &index)) {
const int ret_val = bpf_redirect_map(&xsks_map, index, 0);
bpf_printk("RET-VAL: %d\n", ret_val);
return ret_val;
}
}
}
}
}
}
}
return XDP_PASS;
}
char _license[] SEC("license") = "GPL";
我正在尝试过滤所有 IP-UDP 数据包并将它们发送到用户空间。我还计算了到达每个 RX-Queue 的数据包数量(用 表示ctx->rx_queue_index
)。
我的程序编译得很好,但无论出于何种原因,我的用户空间程序中都没有收到任何数据包。我已经在我的另一篇文章中讨论过这个问题:AF_XDP:尽管在 RX-Queue 0 上引导,但没有来自多播的数据包
我sudo ethtool -N eth20 flow-type udp4 action 0
事先执行了将所有数据包引导到 RX-Queue 0
。
我可以通过以下方式查看当前活动的所有 bpf 地图
$ sudo bpftool map list
32: lpm_trie flags 0x1
key 8B value 8B max_entries 1 memlock 4096B
33: lpm_trie flags 0x1
key 20B value 8B max_entries 1 memlock 4096B
34: lpm_trie flags 0x1
key 8B value 8B max_entries 1 memlock 4096B
35: lpm_trie flags 0x1
key 20B value 8B max_entries 1 memlock 4096B
36: lpm_trie flags 0x1
key 8B value 8B max_entries 1 memlock 4096B
37: lpm_trie flags 0x1
key 20B value 8B max_entries 1 memlock 4096B
125: array name rx_queue_pckt_c flags 0x0
key 4B value 8B max_entries 48 memlock 4096B
126: xskmap name xsks_map flags 0x0
key 4B value 4B max_entries 64 memlock 4096B
但我认为只有125
和126
我的程序有关。
队列引导有效,因为sudo bpftool map dump id 125
我得到:
key: 00 00 00 00 value: 99 1a cc 04 00 00 00 00
key: 01 00 00 00 value: 00 00 00 00 00 00 00 00
key: 02 00 00 00 value: 00 00 00 00 00 00 00 00
key: 03 00 00 00 value: 00 00 00 00 00 00 00 00
key: 04 00 00 00 value: 00 00 00 00 00 00 00 00
key: 05 00 00 00 value: 00 00 00 00 00 00 00 00
key: 06 00 00 00 value: 00 00 00 00 00 00 00 00
key: 07 00 00 00 value: 00 00 00 00 00 00 00 00
key: 08 00 00 00 value: 00 00 00 00 00 00 00 00
key: 09 00 00 00 value: 00 00 00 00 00 00 00 00
key: 0a 00 00 00 value: 00 00 00 00 00 00 00 00
key: 0b 00 00 00 value: 00 00 00 00 00 00 00 00
key: 0c 00 00 00 value: 00 00 00 00 00 00 00 00
key: 0d 00 00 00 value: 00 00 00 00 00 00 00 00
key: 0e 00 00 00 value: 00 00 00 00 00 00 00 00
key: 0f 00 00 00 value: 00 00 00 00 00 00 00 00
key: 10 00 00 00 value: 00 00 00 00 00 00 00 00
key: 11 00 00 00 value: 00 00 00 00 00 00 00 00
key: 12 00 00 00 value: 00 00 00 00 00 00 00 00
key: 13 00 00 00 value: 00 00 00 00 00 00 00 00
key: 14 00 00 00 value: 00 00 00 00 00 00 00 00
key: 15 00 00 00 value: 00 00 00 00 00 00 00 00
key: 16 00 00 00 value: 00 00 00 00 00 00 00 00
key: 17 00 00 00 value: 00 00 00 00 00 00 00 00
key: 18 00 00 00 value: 00 00 00 00 00 00 00 00
key: 19 00 00 00 value: 00 00 00 00 00 00 00 00
key: 1a 00 00 00 value: 00 00 00 00 00 00 00 00
key: 1b 00 00 00 value: 00 00 00 00 00 00 00 00
key: 1c 00 00 00 value: 00 00 00 00 00 00 00 00
key: 1d 00 00 00 value: 00 00 00 00 00 00 00 00
key: 1e 00 00 00 value: 00 00 00 00 00 00 00 00
key: 1f 00 00 00 value: 00 00 00 00 00 00 00 00
key: 20 00 00 00 value: 00 00 00 00 00 00 00 00
key: 21 00 00 00 value: 00 00 00 00 00 00 00 00
key: 22 00 00 00 value: 00 00 00 00 00 00 00 00
key: 23 00 00 00 value: 00 00 00 00 00 00 00 00
key: 24 00 00 00 value: 00 00 00 00 00 00 00 00
key: 25 00 00 00 value: 00 00 00 00 00 00 00 00
key: 26 00 00 00 value: 00 00 00 00 00 00 00 00
key: 27 00 00 00 value: 00 00 00 00 00 00 00 00
key: 28 00 00 00 value: 00 00 00 00 00 00 00 00
key: 29 00 00 00 value: 00 00 00 00 00 00 00 00
key: 2a 00 00 00 value: 00 00 00 00 00 00 00 00
key: 2b 00 00 00 value: 00 00 00 00 00 00 00 00
key: 2c 00 00 00 value: 00 00 00 00 00 00 00 00
key: 2d 00 00 00 value: 00 00 00 00 00 00 00 00
key: 2e 00 00 00 value: 00 00 00 00 00 00 00 00
key: 2f 00 00 00 value: 00 00 00 00 00 00 00 00
Found 48 elements
如您所见,只有 RX-Queue 0 的计数器大于 0。
但是,如果我看一下BPF_MAP_TYPE_XSKMAP
(用于将数据包传输到用户空间),我会得到:
$ sudo bpftool map dump id 126
key:
00 00 00 00
value:
Operation not supported
key:
01 00 00 00
value:
Operation not supported
key:
02 00 00 00
value:
Operation not supported
key:
03 00 00 00
value:
Operation not supported
key:
04 00 00 00
value:
Operation not supported
...
key:
3e 00 00 00
value:
Operation not supported
key:
3f 00 00 00
value:
Operation not supported
Found 0 elements
该消息是否表明Operation not supported
我在用户空间程序中没有收到任何数据包?还是在运行时无法接收到值?我也觉得奇怪Found 0 elements
。
任何想法这里有什么问题?