On Thu, 2 Feb 2017 11:55:39 -0500, Michael Chan wrote: > +/* returns the following: > + * true - packet consumed by XDP and new buffer is allocated. > + * false - packet should be passed to the stack. > + */ > +bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons, > + struct page *page, unsigned int len, u8 *event) > +{ > + struct bpf_prog *xdp_prog = READ_ONCE(rxr->xdp_prog); > + struct bnxt_sw_rx_bd *cons_rx_buf; > + struct pci_dev *pdev = bp->pdev; > + u32 offset = bp->rx_offset; > + struct xdp_buff xdp; > + dma_addr_t mapping; > + void *orig_data; > + u32 act; > + > + if (!xdp_prog) > + return false; > + > + cons_rx_buf = &rxr->rx_buf_ring[cons]; > + > + xdp.data_hard_start = cons_rx_buf->data_ptr - bp->rx_offset; > + xdp.data = cons_rx_buf->data_ptr; > + xdp.data_end = xdp.data + len; > + orig_data = xdp.data; > + mapping = cons_rx_buf->mapping - bp->rx_dma_offset; > + > + dma_sync_single_for_cpu(&pdev->dev, mapping + offset, len, bp->rx_dir); > + > + rcu_read_lock(); > + act = bpf_prog_run_xdp(xdp_prog, &xdp); > + rcu_read_unlock(); > + > + if (orig_data != xdp.data) { > + offset = xdp.data - xdp.data_hard_start; > + len = xdp.data_end - xdp.data;
If BPF changed the start of the packet and returned XDP_PASS you should make sure stack will see the modified packet. I.e. with adjusted offset and len. (CC: Alexei, Martin in case I'm wrong) > + } > + switch (act) { > + case XDP_PASS: > + return false; > + > + default: > + bpf_warn_invalid_xdp_action(act); > + /* Fall thru */ > + case XDP_ABORTED: > + trace_xdp_exception(bp->dev, xdp_prog, act); > + /* Fall thru */ > + case XDP_DROP: > + bnxt_reuse_rx_data(rxr, cons, page); > + break; > + } > + return true; > +}