标签: xdp-bpf

测试 XDP 与 DPDK

我确实有一些 DPDK 经验,但目前我正在阅读许多有关 XDP 的博客。我正在尝试比较这两种技术并了解 DPDK 和 XDP 之间的差异。这引发了一些问题。我希望有人能帮助我解决以下问题:

  1. 通过 DPDK,我可以将工作线程映射到 CPU 内核,并隔离 DPDK 将使用的 CPU 内核。如果是 eBPF / XDP,则使用哪些 CPU 内核?是否使用了所有可用的 CPU 内核?是否可以隔离用于 eBPF / XDP 程序的 CPU 内核?
  2. 当我测试 DPDK 应用程序的吞吐量时,我可以检查环形缓冲区(内存池)是否已满,从而导致数据包丢失。但如何检查 eBPF/XDP 程序是否因吞吐量过高而导致丢包?我假设当 eBPF / XDP 程序花费太多时间来处理数据包时,最终您会看到数据包丢失?(特别是在高速率发送64B数据包时查找可以发送的最大数据包数量)

预先感谢您的帮助!

cpu dpdk ebpf xdp-bpf

10
推荐指数
1
解决办法
7043
查看次数

在 BPF_PROG_TYPE_SK_LOOKUP 中获取连接所有者的 PID

我找到了一个 eBPF 示例,它代理请求,根据目标端口过滤哪些请求。

我试图按客户端的 process_id 而不是目标端口进行过滤,并尝试添加bpf_get_current_pid_tgid() here。然而,该方法似乎在该上下文中未找到/可用。

在这种情况下,如何找到正确的方法来获取连接所有者 process_id ?

ebpf xdp-bpf

6
推荐指数
1
解决办法
356
查看次数

XDP 程序 ip 链接错误:Prog 部分被拒绝:不允许操作

我尝试进入XDP,为此我有一个非常小的程序:

// SPDX-License-Identifier: GPL-2.0
#include <linux/bpf.h>
#include "bpf/bpf_helpers.h"
#include "xdpsock.h"

struct {
    __uint(type, BPF_MAP_TYPE_ARRAY);
    __uint(max_entries, MAX_SOCKS);
    __uint(key_size, sizeof(int));
    __uint(value_size, sizeof(int));
} xsks_map SEC(".maps");

SEC("xdp_sock") int xdp_sock_prog(struct xdp_md *ctx) {

    return XDP_DROP;
}
Run Code Online (Sandbox Code Playgroud)

但如果我尝试将其加载到虚拟接口中veth-basic02,则会收到此错误:

$ sudo ip -force link set dev veth-basic02 xdp 对象 xdpsock_kern.o 部分 xdp_sock

Prog 部分“xdp_sock”被拒绝:不允许操作 (1)!- 类型:6 - 指令:2(0 超出限制) - 许可证:

验证者分析:

获取节目/地图时出错!

内核版本:5.3.0-28-generic

这是我正在使用的 Makefile:

OBJS = xdpsock_kern.o

LLC ?= llc
CLANG ?= clang
INC_FLAGS = -nostdinc -isystem `$(CLANG) -print-file-name=include` …
Run Code Online (Sandbox Code Playgroud)

linux networking bpf xdp-bpf

3
推荐指数
1
解决办法
2998
查看次数

BPF验证器称程序超过1M指令

对于以下程序,我从验证器处收到一条错误,指出它超过了 1M 指令,即使它不应该。该程序查找 HTTP 数据包的主机名。

#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>

struct server_name {
    char server_name[256];
    __u16 length;
};

#define MAX_SERVER_NAME_LENGTH 253
#define HEADER_LEN 6

SEC("xdp")
int collect_ips_prog(struct xdp_md *ctx) {
    char *data_end = (char *)(long)ctx->data_end;
    char *data = (char *)(long)ctx->data;
    int host_header_found = 0;

    for (__u16 i = 0; i <= 512 - HEADER_LEN; i++) {
        host_header_found = 0;

        if (data_end < data + HEADER_LEN) {
            goto end;
        }

        // Elf loader does not allow NULL terminated strings, so have to …
Run Code Online (Sandbox Code Playgroud)

c linux-kernel ebpf xdp-bpf

3
推荐指数
1
解决办法
1204
查看次数

eBPF:“bpf_map_update()”返回“从堆栈中间接读取无效”错误

我有一个带有以下映射定义的 eBPF 程序:

struct bpf_map_def SEC("maps") servers = {
    .type = BPF_MAP_TYPE_HASH,
    .key_size = sizeof(struct ip_key),
    .value_size = sizeof(struct dest_info),
    .max_entries = MAX_SERVERS,
};

struct bpf_map_def SEC("maps") client_addrs = {
    .type = BPF_MAP_TYPE_HASH,
    .key_size = sizeof(struct port_key),
    .value_size = sizeof(struct client_port_addr),
    .max_entries = MAX_CLIENTS,
};
Run Code Online (Sandbox Code Playgroud)

其中结构体定义如下:

struct port_key {
    __u16 port;
    __u16 pad[3];
};

struct ip_key {
    __u32 key;
    __u32 pad;
};

struct dest_info {
    __u32 saddr;
    __u32 daddr;
    __u64 bytes;
    __u64 pkts;
    __u8 dmac[6];
    __u16 pad;
};

struct client_port_addr …
Run Code Online (Sandbox Code Playgroud)

bpf ebpf xdp-bpf

3
推荐指数
1
解决办法
1496
查看次数

XDP 上的线程安全操作

我可以从文档中确认,如果在 HASH_MAP 上完成,bpf_map_update_elem 是一个原子操作。来源(https://man7.org/linux/man-pages/man2/bpf.2.html)。[引用:map_update_elem() 以原子方式替换现有元素]

我的问题是2倍。

  1. 如果元素不存在怎么办,map_update_elem 仍然是原子的吗?

  2. XDP 操作 bpf_map_delete_elem 线程在用户空间程序中安全吗?

该映射是 HASH_MAP。

bpf ebpf xdp-bpf xdp-ebpf libbpf

3
推荐指数
1
解决办法
915
查看次数

无法使用 XDP 丢弃传出流量

我刚刚学习XDP。在旅途中,我遇到了一个我无法理解的案例。当我注意到没有任何变化时,我在某些 UDP 数据包上尝试了一些奇特的东西。所以我尝试用一​​个最小的例子来重现这个问题。这是最小的例子:

#include <linux/bpf.h>
#include <linux/in.h>                             
#include <linux/if_ether.h>                       
#include <linux/ip.h>
#include <linux/udp.h>
                                                         
#define SEC(NAME) __attribute__((section(NAME), used))
                                                                                                                      
SEC("obfuscator_main")
int dropper(struct xdp_md *ctx) {
    return XDP_DROP;        
}
char _license[] SEC("license") = "GPL";
Run Code Online (Sandbox Code Playgroud)

(不要介意“混淆器”名称,它是其余代码的剩余部分)。

我编译并加载这个:

clang -Wall -O2 -target bpf -c obfuscate.c -o obfuscate.o
sudo ip link set dev enp3s0 xdp obj obfuscate.o sec obfuscator_main
Run Code Online (Sandbox Code Playgroud)

我确认到我的计算机的传入流量已完全丢失。但是,数据包仍然可以出去。我 ping 运行 tcpdump 的远程服务器,它看到了 ICMP 请求。但我在本地计算机上没有得到任何响应。

为什么它不能对传出的数据包执行任何操作?

xdp-bpf

2
推荐指数
1
解决办法
981
查看次数

eBPF:如何使用“bpf_map_update_elem”从内核空间发送数据?

我试图通过运行以下 BPF 程序将数据(IP 地址)从内核空间发送到用户空间:

struct bpf_map_def EVENTS = {
    .type        = BPF_MAP_TYPE_HASH,
    .key_size    = sizeof(__u32),
    .value_size  = sizeof(__u32),
    .max_entries = 1,
};


SEC("xdp")
int _xdp_ip_filter(struct xdp_md *ctx) {
    bpf_printk("got a packet\n");     
    void *data_end = (void *)(long)ctx->data_end;
    void *data     = (void *)(long)ctx->data;
    struct ethhdr *eth = data;

    // check packet size
    if (eth + 1 > data_end) {
        return XDP_PASS;
    }

    // get the source address of the packet
    struct iphdr *iph = data + sizeof(struct ethhdr);
    if (iph + 1 …
Run Code Online (Sandbox Code Playgroud)

c bpf ebpf xdp-bpf

2
推荐指数
1
解决办法
2365
查看次数

标签 统计

xdp-bpf ×8

ebpf ×6

bpf ×4

c ×2

cpu ×1

dpdk ×1

libbpf ×1

linux ×1

linux-kernel ×1

networking ×1

xdp-ebpf ×1