[英]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;
並且驗證器失敗了:
不支持調用內置函數“memset”。
我什么時候打電話給memset?
總之,我想將數據包上的每個字節更改為另一個字節,這可能嗎? 如果是,我會很高興知道如何。
它因“禁止 pkt_end 上的指針運算”而失敗
正如安德魯在評論中所說,您首先必須將temp_data
聲明為__u8*
才能運行temp_data++
。
為了滿足驗證者並確保這不是無限循環,有沒有辦法不這樣做?
不,在 BPF 中,所有循環都必須在編譯時知道邊界。
我什么時候打電話給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 的變化,It 應該是 +1。也許驗證器甚至不喜歡有一個指向越界區域的變量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.