0

我正在使用 XDP 并尝试修改ctx->data. 假设对于这个例子,我想将所有数据包字节设置为 x+3(x 是数据包中的一个字节)。那可能吗?我尝试了以下代码并从验证者那里得到错误:

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;
}

它因“禁止 pkt_end 上的指针运算”而失败</p>

我还将 for 循环更改为:

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

为了满足验证者并确保这不是无限循环,有办法不这样做吗?

另外,我尝试将所有数据包字节设置为一个常数:

*(__u8*)temp_data = 2;

验证器失败了:

不支持调用内置函数“memset”。

我什么时候打电话给 memset?

综上所述,我想将数据包上的每个字节更改为另一个字节,这可能吗?如果是的话,我会很高兴知道如何。

4

2 回答 2

2

它因“禁止 pkt_end 上的指针运算”而失败</p>

正如 Andrew 在评论中所说,您首先必须声明temp_data为 a__u8*才能运行temp_data++

为了满足验证者并确保这不是无限循环,有办法不这样做吗?

不,所有循环都必须在 BPF 中的编译时知道边界。

我什么时候打电话给 memset?

检查编译的字节码。您的编译器可能会memset为您使用,作为循环的优化。

于 2021-07-07T20:59:06.307 回答
0

谢谢大家的帮助!我使用了 Andrew 和 pchaigno 的建议,验证者仍然拒绝我的程序。然后我明白我的问题也是我在没有检查的情况下增加了指针。

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;
}

注意 if 的变化,它应该是 + 1。也许验证者甚至不喜欢有一个变量指向一个越界区域。

于 2021-07-10T10:56:06.147 回答