On 01/03/2018 11:26 AM, Jesper Dangaard Brouer wrote:
> Now all XDP driver have been updated to setup xdp_rxq_info and assign
> this to xdp_buff->rxq.  Thus, it is now safe to enable access to some
> of the xdp_rxq_info struct members.
> 
> This patch extend xdp_md and expose UAPI to userspace for
> ingress_ifindex and rx_queue_index.  Access happens via bpf
> instruction rewrite, that load data directly from struct xdp_rxq_info.
> 
> * ingress_ifindex map to xdp_rxq_info->dev->ifindex
> * rx_queue_index  map to xdp_rxq_info->queue_index
> 
> Signed-off-by: Jesper Dangaard Brouer <bro...@redhat.com>
> Acked-by: Alexei Starovoitov <a...@kernel.org>
> ---
>  include/uapi/linux/bpf.h |    3 +++
>  net/core/filter.c        |   19 +++++++++++++++++++
>  2 files changed, 22 insertions(+)
> 
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index 69eabfcb9bdb..a6000a95d40e 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -899,6 +899,9 @@ struct xdp_md {
>       __u32 data;
>       __u32 data_end;
>       __u32 data_meta;
> +     /* Below access go though struct xdp_rxq_info */
> +     __u32 ingress_ifindex; /* rxq->dev->ifindex */
> +     __u32 rx_queue_index;  /* rxq->queue_index  */
>  };
>  
>  enum sk_action {
> diff --git a/net/core/filter.c b/net/core/filter.c
> index 130b842c3a15..acdb94c0e97f 100644
> --- a/net/core/filter.c
> +++ b/net/core/filter.c
> @@ -4304,6 +4304,25 @@ static u32 xdp_convert_ctx_access(enum bpf_access_type 
> type,
>                                     si->dst_reg, si->src_reg,
>                                     offsetof(struct xdp_buff, data_end));
>               break;
> +     case offsetof(struct xdp_md, ingress_ifindex):
> +             *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct xdp_buff, rxq),
> +                                   si->dst_reg, si->src_reg,
> +                                   offsetof(struct xdp_buff, rxq));
> +             *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct xdp_rxq_info, 
> dev),
> +                                   si->dst_reg, si->dst_reg,
> +                                   offsetof(struct xdp_rxq_info, dev));
> +             *insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->dst_reg,
> +                                   bpf_target_off(struct net_device,
> +                                                  ifindex, 4, target_size));

The bpf_target_off() is actually only used in the context of narrow ctx access.

This should just be:

*insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->dst_reg,
                      offsetof(struct net_device, ifindex));

> +             break;
> +     case offsetof(struct xdp_md, rx_queue_index):
> +             *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct xdp_buff, rxq),
> +                                   si->dst_reg, si->src_reg,
> +                                   offsetof(struct xdp_buff, rxq));
> +             *insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->dst_reg,
> +                                   bpf_target_off(struct xdp_rxq_info,
> +                                             queue_index, 4, target_size));

And here:

*insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->dst_reg,
                      offsetof(struct xdp_rxq_info, queue_index));

> +             break;
>       }
>  
>       return insn - insn_buf;
> 

Reply via email to