From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tushar Dave Subject: [PATCH net-next 3/5] ebpf: Add sg_filter_run() Date: Tue, 11 Sep 2018 21:38:02 +0200 Message-ID: <1536694684-3200-4-git-send-email-tushar.n.dave@oracle.com> References: <1536694684-3200-1-git-send-email-tushar.n.dave@oracle.com> To: ast@kernel.org, daniel@iogearbox.net, davem@davemloft.net, santosh.shilimkar@oracle.com, jakub.kicinski@netronome.com, quentin.monnet@netronome.com, jiong.wang@netronome.com, sandipan@linux.vnet.ibm.com, john.fastabend@gmail.com, kafai@fb.com, rdna@fb.com, yhs@fb.com, netdev@vger.kernel.org, rds-devel@oss.oracle.com, sowmini.varadhan@oracle.com Return-path: Received: from aserp2120.oracle.com ([141.146.126.78]:53490 "EHLO aserp2120.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726981AbeILAkO (ORCPT ); Tue, 11 Sep 2018 20:40:14 -0400 In-Reply-To: <1536694684-3200-1-git-send-email-tushar.n.dave@oracle.com> Sender: netdev-owner@vger.kernel.org List-ID: When sg_filter_run() is invoked it runs the attached eBPF prog of type BPF_PROG_TYPE_SOCKET_SG_FILTER which deals with struct scatterlist. Signed-off-by: Tushar Dave Acked-by: Sowmini Varadhan --- include/linux/filter.h | 8 ++++++++ include/uapi/linux/bpf.h | 6 ++++++ net/core/filter.c | 35 +++++++++++++++++++++++++++++++++++ tools/include/uapi/linux/bpf.h | 6 ++++++ 4 files changed, 55 insertions(+) diff --git a/include/linux/filter.h b/include/linux/filter.h index 6791a0a..ae664a9 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -1113,4 +1113,12 @@ struct bpf_sock_ops_kern { */ }; +enum __socksg_action { + __SOCKSG_PASS = 0, + __SOCKSG_DROP, + __SOCKSG_REDIRECT, +}; + +int sg_filter_run(struct sock *sk, struct scatterlist *sg); + #endif /* __LINUX_FILTER_H__ */ diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 6ec1e32..1e11789 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -2428,6 +2428,12 @@ enum sk_action { SK_PASS, }; +enum socksg_action { + SOCKSG_PASS = 0, + SOCKSG_DROP, + SOCKSG_REDIRECT, +}; + /* user accessible metadata for SK_MSG packet hook, new fields must * be added to the end of this structure */ diff --git a/net/core/filter.c b/net/core/filter.c index 469c488..a3afc61 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -121,6 +121,41 @@ int sk_filter_trim_cap(struct sock *sk, struct sk_buff *skb, unsigned int cap) } EXPORT_SYMBOL(sk_filter_trim_cap); +int sg_filter_run(struct sock *sk, struct scatterlist *sg) +{ + struct sk_filter *filter; + int result = 0; + + if (!sg) + return result; + + rcu_read_lock(); + filter = rcu_dereference(sk->sk_filter); + if (filter) { + struct sk_msg_buff mb = {0}; + + memcpy(mb.sg_data, sg, sizeof(*sg) * MAX_SKB_FRAGS); + mb.sg_start = 0; + mb.sg_end = sg_nents(sg); + mb.data = sg_virt(sg); + mb.data_end = mb.data + sg->length; + mb.sg_copy[mb.sg_end - 1] = true; + + result = BPF_PROG_RUN(filter->prog, &mb); + + /* BPF prog may have changed mb.sg_data e.g. may linearize + * multiple scatterlist entries into one. Therefore, make sure + * to update original sg and mark the sg end. + */ + memcpy(sg, mb.sg_data, sizeof(*sg) * MAX_SKB_FRAGS); + sg_mark_end(&sg[mb.sg_end - 1]); + } + rcu_read_unlock(); + + return result; +} +EXPORT_SYMBOL(sg_filter_run); + BPF_CALL_1(bpf_skb_get_pay_offset, struct sk_buff *, skb) { return skb_get_poff(skb); diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 6ec1e32..1e11789 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -2428,6 +2428,12 @@ enum sk_action { SK_PASS, }; +enum socksg_action { + SOCKSG_PASS = 0, + SOCKSG_DROP, + SOCKSG_REDIRECT, +}; + /* user accessible metadata for SK_MSG packet hook, new fields must * be added to the end of this structure */ -- 1.8.3.1