linuxlinux-kernelperfebpf

eBPF trace at net:net_dev_queue not providing correct IP address



I wrote a eBPF code to calculate the time difference between a packet at two tracepoints, net_dev_queue and net_dev_xmit. To generate a key, I need to extract the IP address from the data with struct trace_event_raw_net_dev_template. When extract the IP address, it is always 0.0.0.0. Following the code I am using. May I know what am I missing? Thanks

struct flow_key
{
    __be32 src_ip;
    __be32 dst_ip;
    __u16 src_port;
    __u16 dst_port;
    __u8 protocol;
};

static __always_inline int parse_flow_key(struct sk_buff *skb, struct flow_key *key)
{
    struct iphdr iph;
    bpf_core_read(&iph, sizeof(iph), skb->head + skb->network_header);



    if (skb->protocol != bpf_htons(ETH_P_IP)) {
        // This is not an IP packet
        bpf_printk("Not an IP packet 0x%xn", skb->protocol);
        return -1;
    }

    key->src_ip = iph.saddr;
    key->dst_ip = iph.daddr;
    key->protocol = iph.protocol;
    bpf_printk(" %pI4 -> %pI4 ", iph.saddr, iph.daddr);
 

// More code 
}

SEC("tracepoint/net/net_dev_queue")
int tp_ingress_kernel(struct trace_event_raw_net_dev_template *ctx)
{
    struct sk_buff skb;
    bpf_probe_read(&skb, sizeof(skb), ctx->skbaddr);
    struct flow_key key = {};

    if (parse_flow_key(&skb, &key) < 0)
        return 0;
    bpf_printk("Packet received in kernel\n");

    return 0;
}

Solution

  • add & to your iph

    bpf_printk(" %pI4 -> %pI4 ", &iph.saddr, &iph.daddr);