This is sort of a follow up to a (deleted) previous question. I have discovered that the sk_buff
I am trying to read is filled with 0
s. Note that the following code prints 0
twice, once for the successful read, and another time for the supposed value of data_len
. Am I going wrong about reading the struct, or is it just not filled on entry to the tracepoint?
SEC("tracepoint/skb/consume_skb")
int handle_skb(struct sk_buff *skb)
{
unsigned int data_len = 1;
long ret;
ret = bpf_probe_read_kernel(&data_len, sizeof(data_len), &(skb->data_len));
if (ret < 0) {
bpf_printk("Error on probe read.n \n");
}
bpf_printk("ret: %d \n", ret);
bpf_printk("len: %u \n", data_len);
return 0;
}
(Although this code perfectly shows my problem, I have tried many different configurations without any change to the result)
The loader I am using: gist
Any help would be appreciated, thanks!
EDIT
I have tested something similar with kfree_skb
, here the same problem persists. However when printing protocol
available in the tracepoint I get 1
which also cannot be right.
I am now thinking this has to do with something in the setup instead of the code.
I think, you are using the wrong argument format for the consume_skb
tracepoint. Instead of using a single sk_buff
argument, try the format as reported here:
$ cat /sys/kernel/debug/tracing/events/skb/consume_skb/format
name: consume_skb
ID: 1425
format:
field:unsigned short common_type; offset:0; size:2; signed:0;
field:unsigned char common_flags; offset:2; size:1; signed:0;
field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
field:int common_pid; offset:4; size:4; signed:1;
field:void * skbaddr; offset:8; size:8; signed:0;
print fmt: "skbaddr=%p", REC->skbaddr
The following code shows reasonable, non-zero output for me:
struct __attribute__((__packed__)) consume_skb_args {
unsigned short common_type;
unsigned char common_flags;
unsigned char common_preempt_count;
int common_pid;
void *skbaddr;
};
SEC("tracepoint/skb/consume_skb")
int tp_consume_skb(struct consume_skb_args *ctx)
{
char devname[IFNAMSIZ];
struct sk_buff *skb = (struct sk_buff *) ctx->skbaddr;
struct net_device *dev;
unsigned int data_len;
bpf_probe_read(&dev, sizeof(dev), &(skb->dev));
bpf_probe_read(devname, IFNAMSIZ, &(dev->name));
bpf_probe_read(&data_len, sizeof(data_len), &(skb->data_len));
bpf_printk("skbaddr=%p dev=%s datalen=%d\n", skb, devname, data_len);
return 0;
}
Ouput:
<idle>-0 [004] ..s. 20482442.519133: 0: skbaddr=00000000d60bcc39 dev=enp2s0 datalen=1232
<idle>-0 [004] ..s. 20482442.519183: 0: skbaddr=000000004be4ad2d dev=enp2s0 datalen=64
<idle>-0 [004] ..s. 20482442.534944: 0: skbaddr=000000005dbe2a3e dev=enp2s0 datalen=64
<idle>-0 [004] .Ns. 20482442.535075: 0: skbaddr=0000000068722cfa dev=enp2s0 datalen=496