gpt4 book ai didi

c - xdp 代码计算 icmp 校验和时验证器失败?

转载 作者:行者123 更新时间:2023-11-30 16:06:07 32 4
gpt4 key购买 nike

我正在使用 xdp(使用 XDP_TX 操作)构建 icmp resv 数据包。

Linux:centos8

内核4.18.0-80.el8.x86_64

LLVM:7.0.1

clang:clang 版本 7.0.1(tags/RELEASE_701/final)

这是我的代码:

SEC("xdp_icmp")
int _xdp_icmp(struct xdp_md *xdp)
{
void *data_end = (void *)(long)xdp->data_end;
void *data = (void *)(long)xdp->data;
struct ethhdr *eth = data;
struct iphdr *iph;
struct icmphdr *icmph;
__u16 h_proto;
__be32 raddr;

....
icmph = data + sizeof(*eth) + sizeof(*iph);
if (icmph + 1 > data_end)
return XDP_DROP;

if (icmph -> type != ICMP_ECHO)
{
return XDP_PASS;
}

if (handle_ipv4(xdp) != XDP_TX)
{
return XDP_PASS;
}

raddr = iph->saddr;
swap_src_dst_mac(data);
iph->saddr = iph->daddr;
iph->daddr = raddr;
icmph->type = ICMP_ECHOREPLY;
icmph->checksum = 0;
__u32 sum = 0;
sum = bpf_csum_diff(0, 0, icmph, ICMP_ECHO_LEN, 0);
icmph->checksum = csum_fold_helper(sum);
return XDP_TX;
}

但是编译结果告诉我“验证程序失败”:

错误:

libbpf: load bpf program failed: Permission denied
libbpf: -- BEGIN DUMP LOG ---
libbpf:
...
48: (b7) r5 = 0
49: (85) call bpf_csum_diff#28
invalid access to packet, off=34 size=64, R3(id=0,off=34,r=42)
R3 offset is outside of the packet

最佳答案

我相信打电话时:

// s64 bpf_csum_diff(__be32 *from, u32 from_size, __be32 *to, u32 to_size, __wsum seed)
sum = bpf_csum_diff(0, 0, icmph, ICMP_ECHO_LEN, 0);

作为第三个参数传递的to_size 应该是字节数。假设您从内核自测试中复制了 ICMP_ECHO_LEN,我怀疑它的值是 64,从而要求内核在 64 字节长的缓冲区上计算校验和。但您从未检查过您的数据包是否有那么长(您有 if (icmph + 1 > data_end),这对我来说看起来是正确的)。

我怀疑您应该尝试将 header 的长度作为第三个参数传递,如下所示(未测试):

um = bpf_csum_diff(0, 0, icmph, sizeof(struct icmphdr), 0);

struct icmphdrinclude/uapi/linux/icmp.h 中定义,似乎有 8 个字节的长度,尽管您不需要知道这一点并且只要您传递正确的 header 长度就应该没问题。

关于c - xdp 代码计算 icmp 校验和时验证器失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60053570/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com