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:25 PM, Y Song <ys114321@xxxxxxxxx> wrote:
> 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'

Here is a full BCC version that worked for me:

#!/usr/bin/env python
import bcc
text = """
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 + 1] > data_end) || ((void*)&start[off2 + 1]
> data_end))
    return 0;

  poff1 = start[off1];
  poff2 = start[off2];

  start[off2] = poff1;
  start[off1] = poff2;

  return 1;
}
int on_xdp_rx(struct xdp_md *xdp) {
  void *data_end = (void *)(long)xdp->data_end;
  void *data = (void *)(long)xdp->data;

  if (!swapu16(data, data_end, 4, 6))
    return XDP_DROP;
  return XDP_PASS;
}
"""
b = bcc.BPF(text=text)
b.attach_xdp("eno1", b.load_func("on_xdp_rx", b.XDP), 0)

>
> 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