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