Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C AF_XDP:从堆栈间接读取无效_C_Linux_Networking_Xdp Bpf - Fatal编程技术网

C AF_XDP:从堆栈间接读取无效

C AF_XDP:从堆栈间接读取无效,c,linux,networking,xdp-bpf,C,Linux,Networking,Xdp Bpf,我试图实现我在本文中提到的映射: 我的内核程序有以下映射: struct bpf_map_def SEC("maps") xdp_packet_mapping = { .type = BPF_MAP_TYPE_HASH, .key_size = sizeof(struct pckt_raw_idntfy), .value_size = sizeof(int), .max_entries = sizeof(int) }; 与 在AF-XDP程序中,我使用当前作为密

我试图实现我在本文中提到的映射:

我的内核程序有以下映射:

struct bpf_map_def SEC("maps") xdp_packet_mapping = {
    .type = BPF_MAP_TYPE_HASH,
    .key_size = sizeof(struct pckt_raw_idntfy),
    .value_size = sizeof(int),
    .max_entries = sizeof(int)
};

在AF-XDP程序中,我使用当前作为密钥处理的数据包的相应值创建了一个
pckt_raw_idntfy
-struct:

const struct pckt_raw_idntfy raw = {
    .src_ip = iph->saddr,
    .dst_ip = iph->daddr,
    .dst_port = udh->dest
};
然后,我在
xdp_packet_mapping
中查找该值,并在该值存在时将该数据包重定向到用户空间:

void *ret = bpf_map_lookup_elem(&xdp_packet_mapping, &raw);
if(ret) {
    const int *idx = (int*)(ret);
    if (bpf_map_lookup_elem(&xsks_map, idx)) {
        return bpf_redirect_map(&xsks_map, *idx, 0);
    }
}
在用户空间中,我按如下方式填充地图:

int find_map_fd(struct bpf_object *bpf_obj, const char *mapname) {
    struct bpf_map *map;
    int map_fd = -1;

    map = bpf_object__find_map_by_name(bpf_obj, mapname);
    if (!map) {
        fprintf(stderr, "ERR: cannot find map by name: %s\n", mapname);
        exit(1);
    } else {
        map_fd = bpf_map__fd(map);
    }
    return map_fd;
}

void populate_packet_mapping(struct bpf_object *bpf_obj) {
    const int xdp_packet_map_fd = find_map_fd(bpf_obj, "xdp_packet_mapping");

    for(uint16_t i = 0; i < ip_addrs_size; i++) {
        const struct pckt_idntfy *pck_triple = ip_addrs[i];
        struct pckt_raw_idntfy *raw;
        pckt_idntfy_to_raw(pck_triple, raw);

        int ret = bpf_map_update_elem(xdp_packet_map_fd, raw, &i, 0);
        if(ret == 0) {
            ;
        } else {
            fprintf(stderr, "Lookup elem for key %u failed!\n", i);
        }
    }
}
来自纤毛的基因对这个问题有很好的解释

简而言之,这是因为编译器在调用map update helper之前会自动向键添加一些填充,并将其移动到堆栈中。但是当这个程序被检查时,验证器意识到有一些它不知道的未初始化字节,并拒绝了这个程序

您可以通过打包结构来修复它,尽管这也有一些缺点建议的解决方案是手动填充您的按键,使其适合四个字节的倍数。从OP的编辑:

struct pckt\u raw\u idntfy{
int src_ip;/*4字节*/
int dst_ip;/*4字节*/
uint16_t dst_端口;/*2字节*/
uint16\u t pad;/*在此处添加2个字节的填充*/
};

有关更多详细信息,请参阅指南(grep表示
间接
)。

尝试填充或打包钥匙。请参阅来自纤毛(grep表示
间接
)。
int find_map_fd(struct bpf_object *bpf_obj, const char *mapname) {
    struct bpf_map *map;
    int map_fd = -1;

    map = bpf_object__find_map_by_name(bpf_obj, mapname);
    if (!map) {
        fprintf(stderr, "ERR: cannot find map by name: %s\n", mapname);
        exit(1);
    } else {
        map_fd = bpf_map__fd(map);
    }
    return map_fd;
}

void populate_packet_mapping(struct bpf_object *bpf_obj) {
    const int xdp_packet_map_fd = find_map_fd(bpf_obj, "xdp_packet_mapping");

    for(uint16_t i = 0; i < ip_addrs_size; i++) {
        const struct pckt_idntfy *pck_triple = ip_addrs[i];
        struct pckt_raw_idntfy *raw;
        pckt_idntfy_to_raw(pck_triple, raw);

        int ret = bpf_map_update_elem(xdp_packet_map_fd, raw, &i, 0);
        if(ret == 0) {
            ;
        } else {
            fprintf(stderr, "Lookup elem for key %u failed!\n", i);
        }
    }
}
libbpf: load bpf program failed: Permission denied
libbpf: -- BEGIN DUMP LOG ---
libbpf: 
0: (b7) r6 = 2
1: (61) r2 = *(u32 *)(r1 +4)
2: (61) r1 = *(u32 *)(r1 +0)
3: (bf) r3 = r1
4: (07) r3 += 196
5: (2d) if r3 > r2 goto pc+49
 R1_w=pkt(id=0,off=0,r=196,imm=0) R2_w=pkt_end(id=0,off=0,imm=0) R3_w=pkt(id=0,off=196,r=196,imm=0) R6_w=inv2 R10=fp0
6: (71) r3 = *(u8 *)(r1 +12)
7: (71) r4 = *(u8 *)(r1 +13)
8: (67) r4 <<= 8
9: (4f) r4 |= r3
10: (55) if r4 != 0x8 goto pc+44
 R1_w=pkt(id=0,off=0,r=196,imm=0) R2_w=pkt_end(id=0,off=0,imm=0) R3_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff)) R4_w=inv8 R6_w=inv2 R10=fp0
11: (bf) r3 = r1
12: (07) r3 += 414
13: (2d) if r3 > r2 goto pc+41
 R1=pkt(id=0,off=0,r=414,imm=0) R2=pkt_end(id=0,off=0,imm=0) R3=pkt(id=0,off=414,r=414,imm=0) R4=inv8 R6=inv2 R10=fp0
14: (71) r3 = *(u8 *)(r1 +23)
15: (55) if r3 != 0x11 goto pc+39
 R1=pkt(id=0,off=0,r=414,imm=0) R2=pkt_end(id=0,off=0,imm=0) R3_w=inv17 R4=inv8 R6=inv2 R10=fp0
16: (bf) r3 = r1
17: (07) r3 += 14
18: (71) r4 = *(u8 *)(r3 +0)
19: (67) r4 <<= 2
20: (57) r4 &= 60
21: (bf) r5 = r4
22: (27) r5 *= 20
23: (bf) r0 = r3
24: (0f) r0 += r5
last_idx 24 first_idx 13
regs=20 stack=0 before 23: (bf) r0 = r3
regs=20 stack=0 before 22: (27) r5 *= 20
regs=20 stack=0 before 21: (bf) r5 = r4
regs=10 stack=0 before 20: (57) r4 &= 60
regs=10 stack=0 before 19: (67) r4 <<= 2
regs=10 stack=0 before 18: (71) r4 = *(u8 *)(r3 +0)
25: (2d) if r0 > r2 goto pc+29
 R0=pkt(id=1,off=14,r=14,umax_value=1200,var_off=(0x0; 0x7f0)) R1=pkt(id=0,off=0,r=414,imm=0) R2=pkt_end(id=0,off=0,imm=0) R3=pkt(id=0,off=14,r=414,imm=0) R4=inv(id=0,umax_value=60,var_off=(0x0; 0x3c)) R5=invP(id=0,umax_value=1200,var_off=(0x0; 0x7f0)) R6=inv2 R10=fp0
26: (0f) r3 += r4
last_idx 26 first_idx 25
regs=10 stack=0 before 25: (2d) if r0 > r2 goto pc+29
 R0_rw=pkt(id=1,off=14,r=0,umax_value=1200,var_off=(0x0; 0x7f0)) R1=pkt(id=0,off=0,r=414,imm=0) R2_r=pkt_end(id=0,off=0,imm=0) R3_rw=pkt(id=0,off=14,r=414,imm=0) R4_rw=invP(id=0,umax_value=60,var_off=(0x0; 0x3c)) R5_w=invP(id=0,umax_value=1200,var_off=(0x0; 0x7f0)) R6=inv2 R10=fp0
parent didn't have regs=10 stack=0 marks
last_idx 24 first_idx 13
regs=10 stack=0 before 24: (0f) r0 += r5
regs=10 stack=0 before 23: (bf) r0 = r3
regs=10 stack=0 before 22: (27) r5 *= 20
regs=10 stack=0 before 21: (bf) r5 = r4
regs=10 stack=0 before 20: (57) r4 &= 60
regs=10 stack=0 before 19: (67) r4 <<= 2
regs=10 stack=0 before 18: (71) r4 = *(u8 *)(r3 +0)
27: (bf) r4 = r3
28: (07) r4 += 64
29: (2d) if r4 > r2 goto pc+25
 R0=pkt(id=1,off=14,r=14,umax_value=1200,var_off=(0x0; 0x7f0)) R1=pkt(id=0,off=0,r=414,imm=0) R2=pkt_end(id=0,off=0,imm=0) R3_w=pkt(id=2,off=14,r=78,umax_value=60,var_off=(0x0; 0x3c)) R4_w=pkt(id=2,off=78,r=78,umax_value=60,var_off=(0x0; 0x3c)) R5=invP(id=0,umax_value=1200,var_off=(0x0; 0x7f0)) R6=inv2 R10=fp0
30: (61) r2 = *(u32 *)(r1 +26)
31: (63) *(u32 *)(r10 -16) = r2
32: (61) r1 = *(u32 *)(r1 +30)
33: (63) *(u32 *)(r10 -12) = r1
34: (69) r1 = *(u16 *)(r3 +2)
35: (6b) *(u16 *)(r10 -8) = r1
36: (bf) r2 = r10
37: (07) r2 += -16
38: (18) r1 = 0xffff915728bba000
40: (85) call bpf_map_lookup_elem#1
invalid indirect read from stack off -16+10 size 12
processed 40 insns (limit 1000000) max_states_per_insn 0 total_states 2 peak_states 2 mark_read 1

libbpf: -- END LOG --
struct pckt_raw_idntfy {
    int src_ip;
    int dst_ip;
    uint16_t dst_port;
    uint16_t pad;
};