bpf: finally expose xdp_rxq_info to XDP bpf-programs
authorJesper Dangaard Brouer <brouer@redhat.com>
Wed, 3 Jan 2018 10:26:14 +0000 (11:26 +0100)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 5 Jan 2018 23:21:22 +0000 (15:21 -0800)
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 <brouer@redhat.com>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
include/uapi/linux/bpf.h
net/core/filter.c

index f2f8b36e2ad49f18187bdd4e7334b66922ba78b1..405317f9c0643d88f1175832188bd1a00074bc8e 100644 (file)
@@ -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 {
index 130b842c3a15a63369ac4ccef904484975f355b9..acdb94c0e97f74c7ee9eff9a34fee092f8284ad7 100644 (file)
@@ -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));
+               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));
+               break;
        }
 
        return insn - insn_buf;