On 2018/09/10 17:24, Ilias Apalodimas wrote:
> Add basic AF_XDP support without zero-copy
> 
> Signed-off-by: Ilias Apalodimas <ilias.apalodi...@linaro.org>
> ---
...
> @@ -707,6 +731,26 @@ static int netsec_process_rx(struct netsec_priv *priv, 
> int budget)
>               if (unlikely(!buf_addr))
>                       break;
>  
> +             if (xdp_prog) {
> +                     xdp_result = netsec_run_xdp(desc, priv, xdp_prog,
> +                                                 pkt_len);
> +                     if (xdp_result != NETSEC_XDP_PASS) {
> +                             xdp_flush |= xdp_result & NETSEC_XDP_REDIR;
> +
> +                             dma_unmap_single_attrs(priv->dev,
> +                                                    desc->dma_addr,
> +                                                    desc->len, DMA_TO_DEVICE,
> +                                                    DMA_ATTR_SKIP_CPU_SYNC);
> +
> +                             desc->len = desc_len;
> +                             desc->dma_addr = dma_handle;
> +                             desc->addr = buf_addr;
> +                             netsec_rx_fill(priv, idx, 1);
> +                             nsetsec_adv_desc(&dring->tail);
> +                     }
> +                     continue;

Continue even on XDP_PASS? Is this really correct?

Also seems there is no handling of adjust_head/tail for XDP_PASS case.

> +             }
> +
>               skb = build_skb(desc->addr, desc->len);
>               if (unlikely(!skb)) {
>                       dma_unmap_single(priv->dev, dma_handle, desc_len,
> @@ -740,6 +784,9 @@ static int netsec_process_rx(struct netsec_priv *priv, 
> int budget)
>               nsetsec_adv_desc(&dring->tail);
>       }
>  
> +     if (xdp_flush & NETSEC_XDP_REDIR)
> +             xdp_do_flush_map();
> +
>       return done;
>  }
...
> +static u32 netsec_run_xdp(struct netsec_desc *desc, struct netsec_priv *priv,
> +                       struct bpf_prog *prog, u16 len)
> +
> +{
> +     struct netsec_desc_ring *dring = &priv->desc_ring[NETSEC_RING_RX];
> +     struct xdp_buff xdp;
> +     u32 ret = NETSEC_XDP_PASS;
> +     int err;
> +     u32 act;
> +
> +     xdp.data_hard_start = desc->addr;
> +     xdp.data = desc->addr;

There is no headroom. REDIRECT using devmap/cpumap will fail due to
this. Generally we need XDP_PACKET_HEADROOM.

> +     xdp_set_data_meta_invalid(&xdp);
> +     xdp.data_end = xdp.data + len;
> +     xdp.rxq = &dring->xdp_rxq;
> +
> +     rcu_read_lock();
> +     act = bpf_prog_run_xdp(prog, &xdp);
> +
> +     switch (act) {
> +     case XDP_PASS:
> +             ret = NETSEC_XDP_PASS;
> +             break;
> +     case XDP_TX:
> +             ret = netsec_xmit_xdp(priv, &xdp, desc);
> +             break;
> +     case XDP_REDIRECT:
> +             err = xdp_do_redirect(priv->ndev, &xdp, prog);
> +             if (!err) {
> +                     ret = NETSEC_XDP_REDIR;
> +             } else {
> +                     ret = NETSEC_XDP_CONSUMED;
> +                     xdp_return_buff(&xdp);
> +             }
> +             break;
> +     default:
> +             bpf_warn_invalid_xdp_action(act);
> +             /* fall through */
> +     case XDP_ABORTED:
> +             trace_xdp_exception(priv->ndev, prog, act);
> +             /* fall through -- handle aborts by dropping packet */
> +     case XDP_DROP:
> +             ret = NETSEC_XDP_CONSUMED;
> +             break;
> +     }
> +
> +     rcu_read_unlock();
> +
> +     return ret;
> +}
> +
> +static int netsec_xdp_setup(struct netsec_priv *priv, struct bpf_prog *prog)
> +{
> +     struct net_device *dev = priv->ndev;
> +     struct bpf_prog *old_prog;
> +
> +     /* For now just support only the usual MTU sized frames */
> +     if (prog && dev->mtu > 1500) {
> +             netdev_warn(dev, "Jumbo frames not yet supported with XDP\n");

Why not using extack?

> +             return -EOPNOTSUPP;
> +     }
> +

-- 
Toshiaki Makita

Reply via email to