简体   繁体   English

Ebpf 修改整包数据

[英]Ebpf modify whole packet data

I am using XDP and trying to modify ctx->data .我正在使用 XDP 并尝试修改ctx->data Let's say for this example, I want to set all the packet bytes to x+3 (x is a byte from the packet).假设对于此示例,我想将所有数据包字节设置为 x+3(x 是数据包中的一个字节)。 Is that possible?那可能吗? I tried the following code and got errors from the verifier:我尝试了以下代码并从验证器中得到错误:

int xdp_start(struct xdp_md* ctx)
{
    void* data = (void*)(long)ctx->data;
    void* data_end = (void*)(long)ctx->data_end;
    uint32_t length = data_end - data;
    void* temp_data = data;
    size_t i = 0;
    #pragma unroll
    for(i=0; i < length; i++)
    {
        if ((__u8*)temp_data > (__u8*)data_end)
            break;
        *(__u8*)temp_data += (__u8)2;
        temp_data++;
     }
     return XDP_PASS;
}

It failed with “pointer arithmetic on pkt_end prohibited”它因“禁止 pkt_end 上的指针运算”而失败

I also changed the for loop to:我还将 for 循环更改为:

for (i=0; i < length && i < 1500; i++)

To satisfy the verifier and make sure that this is not an infinite loop there is a way to not do that?为了满足验证者并确保这不是无限循环,有没有办法不这样做?

Also, I tried to set all packet bytes to a constant number:此外,我尝试将所有数据包字节设置为常量:

*(__u8*)temp_data = 2;

And the verifier failed with:并且验证器失败了:

A call to built-in function 'memset' is not supported.不支持调用内置函数“memset”。

When did I call memset?我什么时候打电话给memset?

In summary, I want to change each byte on the packet into another byte, is that possible?总之,我想将数据包上的每个字节更改为另一个字节,这可能吗? If yes I will be happy to know how.如果是,我会很高兴知道如何。

It failed with “pointer arithmetic on pkt_end prohibited”它因“禁止 pkt_end 上的指针运算”而失败

As Andrew said in comments, you'll first have to declare temp_data as a __u8* to be able to run temp_data++ .正如安德鲁在评论中所说,您首先必须将temp_data声明为__u8*才能运行temp_data++

To satisfy the verifier and make sure that this is not an infinite loop there is a way to not do that?为了满足验证者并确保这不是无限循环,有没有办法不这样做?

No, all loops have to have bounds known at compile time in BPF.不,在 BPF 中,所有循环都必须在编译时知道边界。

When did I call memset?我什么时候打电话给memset?

Check the compiled bytecode.检查编译的字节码。 Your compiler likely used memset for you, as an optimization for the loop.您的编译器可能为您使用了memset ,作为循环的优化。

Thank you all for your help!感谢大家的帮助! I used Andrew and pchaigno advice and the verifier still reject my program.我使用了 Andrew 和 pchaigno 的建议,但验证器仍然拒绝我的程序。 Then I understood that my problem also was that I was incremented the pointer without checking it.然后我明白我的问题也是我在没有检查的情况下增加了指针。

int xdp_start(struct xdp_md* ctx)
{
    void* data = (void*)(long)ctx->data;
    void* data_end = (void*)(long)ctx->data_end;
    uint32_t length = data_end - data;
    void* temp_data = data;
    size_t i = 0;
    #pragma unroll
    for(i=0; i < length; i++)
    {
        if ((__u8*)temp_data + 1 > (__u8*)data_end)
            break;
        *(__u8*)temp_data += (__u8)2;
        (__u8*)temp_data++;
     }
     return XDP_PASS;
}

Notice the change in the if, It should be + 1. Maybe the verifier does not even like that there is a variable that points to an out of bounds area.注意 if 的变化,It 应该是 +1。也许验证器甚至不喜欢有一个指向越界区域的变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM