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 <tushar.n.d...@oracle.com> Acked-by: Sowmini Varadhan <sowmini.varad...@oracle.com> --- include/linux/filter.h | 8 ++++++++ include/uapi/linux/bpf.h | 6 ++++++ net/core/filter.c | 24 ++++++++++++++++++++++++ tools/include/uapi/linux/bpf.h | 6 ++++++ 4 files changed, 44 insertions(+) diff --git a/include/linux/filter.h b/include/linux/filter.h index 5d565c5..9f1f7c1 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -1112,4 +1112,12 @@ struct bpf_sock_ops_kern { */ }; +enum __socksg_action { + __SOCKSG_DROP = 0, + __SOCKSG_PASS, + __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..d1d0ceb 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_DROP = 0, + SOCKSG_PASS, + 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 cec3807..e427c8e 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -121,6 +121,30 @@ 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; + + 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) - 1; + mb.data = sg_virt(sg); + mb.data_end = mb.data + sg->length; + mb.sg_copy[mb.sg_end] = true; + result = BPF_PROG_RUN(filter->prog, &mb); + } + 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..d1d0ceb 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_DROP = 0, + SOCKSG_PASS, + 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