xdp-project / xdp-tutorial

XDP tutorial
2.33k stars 562 forks source link

Not receiving TCP packets in xdp program. #346

Closed H0mTanks closed 1 year ago

H0mTanks commented 1 year ago

Hello, I'm trying to write a packet parser, however it seems like I'm not receiving any TCP Packets. I've boiled down what I'm doing to the following example program:

//myxdp.c

SEC("xdp")
int xdp_prog(struct xdp_md* ctx)
{
    //Parse ethernet header
    struct ethhdr* ethernet_hdr = (struct ethhdr*)(long)ctx->data;
    if ((u8*)(ethernet_hdr + 1) > (u8*)(long)ctx->data_end) goto done;

    if (ethernet_hdr->h_proto == bpf_ntohs(ETH_P_IP)) {

        //IPV4 Packet
        struct iphdr* ip_hdr = (struct iphdr*)(ethernet_hdr + 1);
        if ((u8*)(ip_hdr + 1) > (u8*)(long)ctx->data_end) goto done;

        //Print the protocol
        bpf_printk("ipv4 protocol %u", ip_hdr->protocol);
    }
    else if (ethernet_hdr->h_proto == bpf_ntohs(ETH_P_IPV6)) {

        //IPV6 Packet
        struct ipv6hdr* ip_hdr = (struct ipv6hdr*)(ethernet_hdr + 1);
        if ((u8*)(ip_hdr + 1) > (u8*)(long)ctx->data_end) goto done;

        //Print the protocol
        bpf_printk("ipv6 protocol %u", ip_hdr->nexthdr);
    }

done:
    return XDP_PASS;
}

Compiling the program with: clang -O2 -g -Wall -target bpf -c myxdp.c -o myxdp.o Loading the program with: sudo ip link set dev lo xdpgeneric obj myxdp.o sec xdp

While looking at the trace in /sys/kernel/debug/tracing/trace_pipe, the only thing that's printed is ipv4 protocol 17, which is the UDP Protocol. I've monitored my system with WireShark and I seem to be getting TCP Packets there.

Appreciate any help, thank you.

tohojo commented 1 year ago

Gurnoor Singh Virdi @.***> writes:

Hello, I'm trying to write a packet parser, however it seems like I'm not receiving any TCP Packets. I've boiled down what I'm doing to the following example program:

//myxdp.c

SEC("xdp")
int xdp_prog(struct xdp_md* ctx)
{
    //Parse ethernet header
    struct ethhdr* ethernet_hdr = (struct ethhdr*)(long)ctx->data;
    if ((u8*)(ethernet_hdr + 1) > (u8*)(long)ctx->data_end) goto done;

    if (ethernet_hdr->h_proto == bpf_ntohs(ETH_P_IP)) {

        //IPV4 Packet
        struct iphdr* ip_hdr = (struct iphdr*)(ethernet_hdr + 1);
        if ((u8*)(ip_hdr + 1) > (u8*)(long)ctx->data_end) goto done;

        //Print the protocol
        bpf_printk("ipv4 protocol %u", ip_hdr->protocol);
    }
    else if (ethernet_hdr->h_proto == bpf_ntohs(ETH_P_IPV6)) {

        //IPV6 Packet
        struct ipv6hdr* ip_hdr = (struct ipv6hdr*)(ethernet_hdr + 1);
        if ((u8*)(ip_hdr + 1) > (u8*)(long)ctx->data_end) goto done;

        //Print the protocol
        bpf_printk("ipv6 protocol %u", ip_hdr->nexthdr);
    }

done:
    return XDP_PASS;
}

Compiling the program with: clang -O2 -g -Wall -target bpf -c myxdp.c -o myxdp.o Loading the program with: sudo ip link set dev lo xdpgeneric obj myxdp.o sec xdp

How would you expect to receive TCP packets on the lo interface? Try running it on a veth device instead (and I wouldn't recommend using xdpgeneric in general; if you can't use native XDP you may as well use a TC program).

H0mTanks commented 1 year ago

Ah silly oversight, easy fix. My main use-case is xdp using windows-ebpf, the TC hooks aren't available on that yet. Started learning with xdp on linux since there's a lot more documentation. Thank you for your help, closing the issue.