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;
> +}

Reply via email to