簡體   English   中英

無法在 eBPF 中訪問 __skb_buff

[英]Cannot access __skb_buff in eBPF

我正在嘗試訪問在consume_skb跟蹤點中傳遞的__sk_buff結構。 然而,到目前為止,我沒有嘗試過任何工作。 我正在運行內核版本5.4.0 這是我到目前為止所嘗試的,結果是:

裝載機要點

直接訪問

SEC("tracepoint/skb/consume_skb")
int handle_skb(struct __sk_buff *skb)
{
    void *data = (void *)(long)skb->data;
    void *data_end = (void *)(long)skb->data_end;
    struct ethhdr *eth = data;
    struct iphdr *iph = data + sizeof(*eth);

    if (data + sizeof(*eth) > data_end)
        return 0;

    if (data + sizeof(*eth) + sizeof(*iph) > data_end)
        return 0;

    bpf_trace_printk("%x\n", eth->h_proto);

    return 0;
}

結果是:

libbpf: prog 'handle_skb': BPF program load failed: Permission denied
libbpf: prog 'handle_skb': -- BEGIN PROG LOAD LOG --
; void *data = (void *)(long)skb->data;
0: (61) r2 = *(u32 *)(r1 +76)
; void *data_end = (void *)(long)skb->data_end;
1: (61) r1 = *(u32 *)(r1 +80)
; struct iphdr *iph = data + sizeof(*eth);
2: (bf) r3 = r2
3: (07) r3 += 14
; if (data + sizeof(*eth) > data_end)
4: (2d) if r3 > r1 goto pc+7
 R1_w=inv(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R2_w=inv(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R3_w=inv(id=0,umin_value=14,umax_value=4294967309,var_off=(0x0; 0x1ffffffff)) R10=fp0
;
5: (bf) r3 = r2
6: (07) r3 += 34
; if (data + sizeof(*eth) > data_end)
7: (2d) if r3 > r1 goto pc+4
 R1_w=inv(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R2_w=inv(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R3_w=inv(id=0,umin_value=34,umax_value=4294967329,var_off=(0x0; 0x1ffffffff)) R10=fp0
; bpf_trace_printk("%x\n", eth->h_proto);
8: (69) r2 = *(u16 *)(r2 +12)
R2 invalid mem access 'inv'
processed 9 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
-- END PROG LOAD LOG --
libbpf: failed to load program 'handle_skb'
libbpf: failed to load object 'skb_bpf'
libbpf: failed to load BPF skeleton 'skb_bpf': -13
Failed to load and verify BPF skeleton

我理解它的方式是,在這種情況下不允許直接訪問skb (為什么?)。

bpf_skb_load_bytes

SEC("tracepoint/skb/consume_skb")
int handle_skb(struct __sk_buff *skb)
{
    struct ethhdr *eth;

    int ret;
    ret = skb_load_bytes(skb, 0, eth, sizeof(struct ethhdr));
    //Or alternatively
    //ret = bpf_skb_load_bytes(skb, 0, eth, sizeof(struct ethhdr));

    if (!ret)
    {
        return 0;
    }

    bpf_trace_printk("%x\n", eth->h_proto);

    return 0;
}

這導致:

libbpf: prog 'handle_skb': BPF program load failed: Invalid argument
libbpf: prog 'handle_skb': -- BEGIN PROG LOAD LOG --
; ret = bpf_skb_load_bytes(skb, 0, eth, sizeof(struct ethhdr));
0: (b7) r2 = 0
1: (b7) r4 = 14
2: (85) call bpf_skb_load_bytes#26
unknown func bpf_skb_load_bytes#26
processed 3 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
-- END PROG LOAD LOG --
libbpf: failed to load program 'handle_skb'
libbpf: failed to load object 'skb_bpf'
libbpf: failed to load BPF skeleton 'skb_bpf': -22
Failed to load and verify BPF skeleton

這讓我更加困惑,因為bpf_skb_load_bytes應該是一個可用的輔助函數。

現在我懷疑如何訪問和讀取(甚至不寫入) __sk_buff 難道就沒有辦法了嗎? 還是我錯過了什么?

這里發生了一些事情。 首先是跟蹤點的參數是struct sk_buff類型,而不是struct __sk_buff 我相信您必須使用bpf_probe_read助手來讀取指針指向的內存。

其次是bpf_skb_load_bytes只能與__sk_buff一起使用。 此外,並非每種程序類型都可以使用所有助手,跟蹤程序不能使用bpf_skb_load_bytes助手。 以下代碼列出了跟蹤點程序的所有可用助手:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM