Re: [iovisor-dev] modifying packets in XDP

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

 



On Thu, Aug 24, 2017 at 12:17 PM, Ilya Baldin <ibaldin@xxxxxxxxx> wrote:
> Thank you, everyone for the replies. This explains about bpf_probe_read.
>
> I tried the approach below (changed the check to offset +1) however that
> didn’t help, I still get the same error and BCC refuses to load the program
>
>  R0=inv,min_value=2,max_value=65537,min_align=1,aux_off_align=2
> R1=inv,min_value=6,max_value=65541,min_align=1,aux_off_align=2 R2=pkt_end
> R3=pkt(id=1,off=0,r=20),aux_off_align=2
> R4=imm0,min_value=0,max_value=0,min_align=2147483648,aux_off_align=2
> R5=imm0,min_value=0,max_value=0,min_align=2147483648,aux_off_align=2
> R6=inv,min_value=4,max_value=65539,min_align=1,aux_off_align=2 R10=fp
> 65: (69) r1 = *(u16 *)(r6 +0)
> R6 invalid mem access 'inv'

Note that:
R6=inv,min_value=4,max_value=65539,min_align=1,aux_off_align=2
"inv" means unknown value.

Could you double check your program?

>
> HINT: The invalid mem access 'inv' error can happen if you try to
> dereference memory without first using bpf_probe_read() to copy it to the
> BPF stack. Sometimes the bpf_probe_read is automatic by the bcc rewriter,
> other times you'll need to be explicit.
>
> and it is the ‘write’ statements that are causing it as in when I try to
> write into the packet
>
> start[off1] = val;
>
> is when I get the error.
>
> Is the solution to use the tc loader instead of bcc? Less convenient, but
> doable, I suppose.
>
> -ilya
>
> Ilya Baldin
>
>
> On Aug 24, 2017, at 12:43 PM, Brenden Blanco <bblanco@xxxxxxxxx> wrote:
>
> On Thu, Aug 24, 2017 at 9:26 AM, Daniel Borkmann via iovisor-dev
> <iovisor-dev@xxxxxxxxxxxxxxxxx> wrote:
>
> On 08/24/2017 06:17 PM, Y Song wrote:
>
>
> CC to bcc mailing list as well.
>
> bpf_probe_read is not allowed in XDP programs.
>
> Your comparison may need to comparison not just starting offset, but
> also including the memory size so the
> whole write won't fall beyond the "data_end".
>
> Regarding to bcc translates "start[off2]" to bpf_probe_read, it is
> possible that bcc rewriter tries to infer bpf_probe candidate and
> finds this one ...
>
>
>
> I was wondering about this last one, and where this suggestion
> comes from exactly (bcc for sure?). How does the error message
> look like?
>
>
> The error comes from here:
> https://github.com/iovisor/bcc/blob/master/src/cc/libbpf.c#L210
>
> But as Yonghong said, you cannot use bpf_probe_read from XDP and hence
> should ignore the warning.
>
> I would suggest rewriting your check to be something like:
>
>  if (((void*)&start[off1 + 1] > data_end) || ((void*)&start[off2 + 1]
>
> data_end))
>
>    return 0;
>
>
>
> On Thu, Aug 24, 2017 at 8:22 AM, Ilya Baldin <ibaldin@xxxxxxxxx> wrote:
>
>
> Hello everyone,
>
> A couple of questions. I’m using XDP with BCC on a Fedora 25 with kernel
> 4.13.0-0.rc5.git0.2.fc27.x86_64 with e1000 driver. Basic XDP examples appear
> to work, I was able to create my own simple example counting TCP SYN
> packets, so the setup is at least partially correct.
>
> I’m playing around now with modifying TCP payload on the fly and failing
> miserably. The function that is supposed to swap two u16s in TCP payload is
> below
>
> static inline int swapu16(uint16_t *start, void *data_end, int off1, int
> off2) {
>   int len = (uint16_t*)data_end - start;
>   uint16_t poff1, poff2;
>
>   if (((void*)&start[off1] > data_end) || ((void*)&start[off2] >
> data_end))
>     return 0;
>
>   poff1 = start[off1];
>   poff2 = start[off2];
>
>   //start[off2] = poff1;
>   //start[off1] = poff2;
>
>   return 1;
> }
>
> and it gets called with start pointing to the beginning of the payload
> (I’m reasonably sure that is correct).
>
> If I *uncomment* either of the two lines in the function I get verifier
> errors suggesting I use bpf_probe_read. First question
>
> 1. Is what I’m attempting even possible - am I allowed to modify the
> packet in XDP hook? If no this may be a short conversation.
>
> 2. If it is possible, is there a canonical way of doing it compared to
> what I’m trying to do?
>
> 3. I actually attempted to use bpf_probe_read() (even though with the
> code structured as above, it appears they are inserted automatically,
> because the BPF program is installed properly with those two lines commented
> out), like in the code shown below:
>
> static inline int swapu16(uint16_t *start, void *data_end, int off1, int
> off2) {
>   int len = (uint16_t*)data_end - start;
>   uint16_t poff1, poff2;
>
>   if (((void*)&start[off1] > data_end) || ((void*)&start[off2] >
> data_end))
>     return 0;
>
>   bpf_probe_read(&poff1, sizeof(uint16_t), (void*)&start[off1]);
>   //poff1 = start[off1];
>   //poff2 = start[off2];
>
>   //start[off2] = poff1;
>   //start[off1] = poff2;
>
>   return 1;
> }
>
> I get a verifier error
> ….
> 60: (2d) if r1 > r2 goto pc+5
>  R1=inv,min_value=4,max_value=65539,min_align=1,aux_off_align=2
> R2=pkt_end R3=inv,min_value=2,max_value=65537,min_align=1,aux_off_align=2
> R4=imm0,min_value=0,max_value=0,min_align=2147483648
> R5=pkt(id=0,off=42,r=42) R6=pkt(id=1,off=0,r=20),aux_off_align=2
> R7=imm0,min_value=0,max_value=0,min_align=2147483648 R10=fp
> 61: (bf) r1 = r10
> 62: (07) r1 += -32
> 63: (b7) r2 = 2
> 64: (85) call bpf_probe_read#4
> unknown func bpf_probe_read#4
>
> which is really strange. In fact it appears I’m unable to invoke any of
> the helper bpf functions explicitly.
>
> Many thanks for your suggestions.
>
> -ilya
>
> Ilya Baldin
>
>
>
> _______________________________________________
> iovisor-dev mailing list
> iovisor-dev@xxxxxxxxxxxxxxxxx
> https://lists.iovisor.org/mailman/listinfo/iovisor-dev
>
>




[Index of Archives]     [Linux Networking Development]     [Fedora Linux Users]     [Linux SCTP]     [DCCP]     [Gimp]     [Yosemite Campsites]

  Powered by Linux