I am using XDP and trying to modify 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).
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”
I also changed the for loop to:
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.
When did I call 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.
Thank you all for your help! I used Andrew and pchaigno advice and the verifier still reject my program. 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.