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