Re: How to read from pkt_end?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

> How do I read from the end of the packet in a XDP program? I tried the
> below ebpf program to read the last 4 bytes of the packet, but the
> verifier rejects it.

Got it working with some trial and error - the trick was to AND the
calculated offset with 0x3fff - largest value for a packet size that
allows 9K jumbo.

Here's the working code -

__section("prog")
int xdp_prog(struct xdp_md *ctx)
{
    void *data = (void *)(long)ctx->data;
    void *data_end = (void *)(long)ctx->data_end;

    __u16 len = data_end - data;
    if ((data + len) > data_end)
        return XDP_ABORTED;

    __u16 ofs = (len - 4) & 0x3fff;
    __u32 *mgc = (__u32*)(data+ofs);
    if ((mgc + 1) > (__u32*)data_end)
        return XDP_ABORTED;

    if (*mgc == 0x1d10c0da)
        return XDP_DROP;

    return XDP_PASS;
}

What clued me onto the AND thing was the following lines in
Documentation/networking/filter.txt about overflow -

    Operation 'r3 += rX' may overflow and become less than original skb->data,
    therefore the verifier has to prevent that.  So when it sees 'r3 += rX'
    instruction and rX is more than 16-bit value, any subsequent
bounds-check of r3
    against skb->data_end will not give us 'range' information, so
attempts to read
    through the pointer will give "invalid access to packet" error.

Without the (superfluous) data + len > data_end check, LLVM was
optimizing the code in a way that led to scalar arithmetic which the
verifier wouldn't allow.

Of course, the ideal way to work backwards from the end of  the packet
is to allow arithmetic on pkt_end (so you could do `ofs = data_end -
4`), but there may be valid reasons not to allow that, that I'm not
aware of.

Srivats



[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux