首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >未创建eBPF / XDP映射

未创建eBPF / XDP映射
EN

Stack Overflow用户
提问于 2022-03-17 10:14:58
回答 1查看 171关注 0票数 0

我在BPF中为XDP提供了一个实现,其中我指定要创建的五个映射如下:

代码语言:javascript
复制
    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") server_ips = {
        .type = BPF_MAP_TYPE_HASH,
        .key_size = sizeof(struct ip_key),
        .value_size = sizeof(struct server_ip_key),
        .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,
    };
    
    struct bpf_map_def SEC("maps") stoc_port_maps = {
        .type = BPF_MAP_TYPE_HASH,
        .key_size = sizeof(struct port_key),
        .value_size = sizeof(struct port_map),
        .max_entries = MAX_FLOWS,
    };
    
    struct bpf_map_def SEC("maps") ctos_port_maps = {
        .type = BPF_MAP_TYPE_HASH,
        .key_size = sizeof(struct port_key),
        .value_size = sizeof(struct port_map),
        .max_entries = MAX_FLOWS,
    };

但是,无论我做什么,servers映射都不会被创建。当我运行bpftool map show时,我只得到如下输出:

代码语言:javascript
复制
root@balancer:/xdp# bpftool map list  
68: hash  name client_addrs  flags 0x0
        key 8B  value 16B  max_entries 4096  memlock 98304B
69: hash  name ctos_port_maps  flags 0x0
        key 8B  value 20B  max_entries 4096  memlock 131072B
70: hash  name server_ips  flags 0x0
        key 8B  value 8B  max_entries 512  memlock 8192B
73: hash  name stoc_port_maps  flags 0x0
        key 8B  value 20B  max_entries 4096  memlock 131072B
74: array  name xdp_lb_k.rodata  flags 0x480
        key 4B  value 50B  max_entries 1  memlock 4096B
        frozen
root@balancer:/xdp#

值得注意的是,每个键或值结构都已被填充到最接近的8个字节的倍数中,并且没有编译或验证器错误。我也在码头集装箱上运行这个程序。到目前为止,我已经尝试在代码中移动servers映射定义,注释掉仅保留servers定义为活动的其他映射定义,将名称更改为其他组合,以及其他一些微小的更改,但到目前为止还没有起作用。

如果您需要我的代码或信息的任何其他部分来更好地分析情况,请告诉我。

附录1: --我正在使用这个Makefile规则编译对象文件:

代码语言:javascript
复制
xdp_lb_kern.o: xdp_lb_kern.c 
    clang -S \
        -target bpf \
        -D __BPF_TRACING__ \
        -I../../libbpf/src \
        -I../../custom-headers \
        -Wall \
        -Wno-unused-value \
        -Wno-pointer-sign \
        -Wno-compare-distinct-pointer-types \
        -O2 -emit-llvm -c -o ${@:.o=.ll} $<
    llc -march=bpf -filetype=obj -o $@ ${@:.o=.ll}

然后,在容器的环境中,我使用以下规则加载程序:

代码语言:javascript
复制
load_balancer:
    bpftool net detach xdpgeneric dev eth0
    rm -f /sys/fs/bpf/xdp_lb
    bpftool prog load xdp_lb_kern.o /sys/fs/bpf/xdp_lb
    bpftool net attach xdpgeneric pinned /sys/fs/bpf/xdp_lb dev eth0

编译过程生成一个.o和一个.ll输出文件。映射定义可见的.ll输出文件的起始行如下所示:

代码语言:javascript
复制
; ModuleID = 'xdp_lb_kern.c'
source_filename = "xdp_lb_kern.c"
target datalayout = "e-m:e-p:64:64-i64:64-n32:64-S128"
target triple = "bpf"

%struct.bpf_map_def = type { i32, i32, i32, i32, i32 }
%struct.xdp_md = type { i32, i32, i32, i32, i32 }
%struct.ip_key = type { i32, i32 }
%struct.port_key = type { i16, [3 x i16] }
%struct.ethhdr = type { [6 x i8], [6 x i8], i16 }
%struct.iphdr = type { i8, i8, i16, i16, i16, i8, i8, i16, i32, i32 }

@servers = dso_local global %struct.bpf_map_def { i32 1, i32 8, i32 32, i32 512, i32 0 }, section "maps", align 4
@server_ips = dso_local global %struct.bpf_map_def { i32 1, i32 8, i32 8, i32 512, i32 0 }, section "maps", align 4
@client_addrs = dso_local global %struct.bpf_map_def { i32 1, i32 8, i32 16, i32 4096, i32 0 }, section "maps", align 4
@stoc_port_maps = dso_local global %struct.bpf_map_def { i32 1, i32 8, i32 20, i32 4096, i32 0 }, section "maps", align 4
@ctos_port_maps = dso_local global %struct.bpf_map_def { i32 1, i32 8, i32 20, i32 4096, i32 0 }, section "maps", align 4
@loadbal.____fmt = internal constant [24 x i8] c"balancer got something!\00", align 1
@_license = dso_local global [4 x i8] c"GPL\00", section "license", align 1
@process_packet.____fmt = internal constant [26 x i8] c"it's an ip packet from %x\00", align 1
@llvm.used = appending global [7 x i8*] [i8* getelementptr inbounds ([4 x i8], [4 x i8]* @_license, i32 0, i32 0), i8* bitcast (%struct.bpf_map_def* @client_addrs to i8*), i8* bitcast (%struct.bpf_map_def* @ctos_port_maps to i8*), i8* bitcast (i32 (%struct.xdp_md*)* @loadbal to i8*), i8* bitcast (%struct.bpf_map_def* @server_ips to i8*), i8* bitcast (%struct.bpf_map_def* @servers to i8*), i8* bitcast (%struct.bpf_map_def* @stoc_port_maps to i8*)], section "llvm.metadata"

; Function Attrs: nounwind
define dso_local i32 @loadbal(%struct.xdp_md* nocapture readonly %0) #0 section "xdp" {
  %2 = alloca %struct.ip_key, align 4
  %3 = alloca %struct.port_key, align 2
  %4 = alloca %struct.port_key, align 2
  %5 = getelementptr inbounds %struct.xdp_md, %struct.xdp_md* %0, i64 0, i32 1
  %6 = load i32, i32* %5, align 4, !tbaa !2
  %7 = zext i32 %6 to i64
  %8 = inttoptr i64 %7 to i8*
  %9 = getelementptr inbounds %struct.xdp_md, %struct.xdp_md* %0, i64 0, i32 0
  %10 = load i32, i32* %9, align 4, !tbaa !7
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-19 23:24:49

根据注释中的讨论,没有创建映射,因为它实际上没有在eBPF代码中使用(问题中没有提供)。

当您意识到自己时,代码中调用映射的分支实际上是无法到达的。基于此,clang很可能编译出这部分代码,并且映射没有在生成的eBPF字节码中使用。在准备加载程序时,bpftool (libbpf)查看所需的映射,只创建程序所需的映射。如果没有程序使用,它可以跳过ELF文件中定义的映射。

这里的一个提示是,如果程序有效地使用了映射,那么它就是如果地图丢失,则无法成功加载:如果您的程序加载,那么如果需要的话,映射必然会出现。请注意,bpftool prog show将显示程序使用的映射的ids。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71510575

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档