ebpf修改整包数据
Ebpf modify whole packet data
我正在使用 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 禁止指针运算”
我还将 for 循环更改为:
for (i=0; i < length && i < 1500; i++)
为了让验证者满意并确保这不是无限循环,有没有办法不这样做?
此外,我尝试将所有数据包字节设置为一个常数:
*(__u8*)temp_data = 2;
并且验证者失败:
A call to built-in function ‘memset’ is not supported.
我什么时候调用了memset?
综上所述,我想将数据包上的每个字节更改为另一个字节,这可能吗?如果是,我很乐意知道如何做。
It failed with “pointer arithmetic on pkt_end prohibited”
正如安德鲁在评论中所说,您首先必须将 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?
不,在 BPF 中,所有循环都必须在编译时知道边界。
When did I call memset?
检查编译后的字节码。您的编译器可能为您使用了 memset
,作为循环的优化。
谢谢大家的帮助!
我使用了 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。可能验证者甚至不喜欢有一个指向越界区域的变量。
我正在使用 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 禁止指针运算”
我还将 for 循环更改为:
for (i=0; i < length && i < 1500; i++)
为了让验证者满意并确保这不是无限循环,有没有办法不这样做?
此外,我尝试将所有数据包字节设置为一个常数:
*(__u8*)temp_data = 2;
并且验证者失败:
A call to built-in function ‘memset’ is not supported.
我什么时候调用了memset?
综上所述,我想将数据包上的每个字节更改为另一个字节,这可能吗?如果是,我很乐意知道如何做。
It failed with “pointer arithmetic on pkt_end prohibited”
正如安德鲁在评论中所说,您首先必须将 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?
不,在 BPF 中,所有循环都必须在编译时知道边界。
When did I call memset?
检查编译后的字节码。您的编译器可能为您使用了 memset
,作为循环的优化。
谢谢大家的帮助! 我使用了 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。可能验证者甚至不喜欢有一个指向越界区域的变量。