net/sched: avoid indirect classify functions on retpoline kernels

Expose the necessary tc classifier functions and wire up cls_api to use
direct calls in retpoline kernels.

Signed-off-by: Pedro Tammela <pctammela@mojatatu.com>
Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
Reviewed-by: Victor Nogueira <victor@mojatatu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Pedro Tammela 2022-12-06 10:55:13 -03:00 committed by David S. Miller
parent 871cf386dd
commit 9f3101dca3
14 changed files with 49 additions and 25 deletions

View file

@ -40,6 +40,7 @@
#include <net/tc_act/tc_mpls.h> #include <net/tc_act/tc_mpls.h>
#include <net/tc_act/tc_gate.h> #include <net/tc_act/tc_gate.h>
#include <net/flow_offload.h> #include <net/flow_offload.h>
#include <net/tc_wrapper.h>
extern const struct nla_policy rtm_tca_policy[TCA_MAX + 1]; extern const struct nla_policy rtm_tca_policy[TCA_MAX + 1];
@ -1564,7 +1565,7 @@ static inline int __tcf_classify(struct sk_buff *skb,
tp->protocol != htons(ETH_P_ALL)) tp->protocol != htons(ETH_P_ALL))
continue; continue;
err = tp->classify(skb, tp, res); err = tc_classify(skb, tp, res);
#ifdef CONFIG_NET_CLS_ACT #ifdef CONFIG_NET_CLS_ACT
if (unlikely(err == TC_ACT_RECLASSIFY && !compat_mode)) { if (unlikely(err == TC_ACT_RECLASSIFY && !compat_mode)) {
first_tp = orig_tp; first_tp = orig_tp;

View file

@ -18,6 +18,7 @@
#include <net/netlink.h> #include <net/netlink.h>
#include <net/act_api.h> #include <net/act_api.h>
#include <net/pkt_cls.h> #include <net/pkt_cls.h>
#include <net/tc_wrapper.h>
struct basic_head { struct basic_head {
struct list_head flist; struct list_head flist;
@ -36,8 +37,9 @@ struct basic_filter {
struct rcu_work rwork; struct rcu_work rwork;
}; };
static int basic_classify(struct sk_buff *skb, const struct tcf_proto *tp, TC_INDIRECT_SCOPE int basic_classify(struct sk_buff *skb,
struct tcf_result *res) const struct tcf_proto *tp,
struct tcf_result *res)
{ {
int r; int r;
struct basic_head *head = rcu_dereference_bh(tp->root); struct basic_head *head = rcu_dereference_bh(tp->root);

View file

@ -19,6 +19,7 @@
#include <net/rtnetlink.h> #include <net/rtnetlink.h>
#include <net/pkt_cls.h> #include <net/pkt_cls.h>
#include <net/sock.h> #include <net/sock.h>
#include <net/tc_wrapper.h>
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Daniel Borkmann <dborkman@redhat.com>"); MODULE_AUTHOR("Daniel Borkmann <dborkman@redhat.com>");
@ -77,8 +78,9 @@ static int cls_bpf_exec_opcode(int code)
} }
} }
static int cls_bpf_classify(struct sk_buff *skb, const struct tcf_proto *tp, TC_INDIRECT_SCOPE int cls_bpf_classify(struct sk_buff *skb,
struct tcf_result *res) const struct tcf_proto *tp,
struct tcf_result *res)
{ {
struct cls_bpf_head *head = rcu_dereference_bh(tp->root); struct cls_bpf_head *head = rcu_dereference_bh(tp->root);
bool at_ingress = skb_at_tc_ingress(skb); bool at_ingress = skb_at_tc_ingress(skb);

View file

@ -13,6 +13,7 @@
#include <net/pkt_cls.h> #include <net/pkt_cls.h>
#include <net/sock.h> #include <net/sock.h>
#include <net/cls_cgroup.h> #include <net/cls_cgroup.h>
#include <net/tc_wrapper.h>
struct cls_cgroup_head { struct cls_cgroup_head {
u32 handle; u32 handle;
@ -22,8 +23,9 @@ struct cls_cgroup_head {
struct rcu_work rwork; struct rcu_work rwork;
}; };
static int cls_cgroup_classify(struct sk_buff *skb, const struct tcf_proto *tp, TC_INDIRECT_SCOPE int cls_cgroup_classify(struct sk_buff *skb,
struct tcf_result *res) const struct tcf_proto *tp,
struct tcf_result *res)
{ {
struct cls_cgroup_head *head = rcu_dereference_bh(tp->root); struct cls_cgroup_head *head = rcu_dereference_bh(tp->root);
u32 classid = task_get_classid(skb); u32 classid = task_get_classid(skb);

View file

@ -24,6 +24,7 @@
#include <net/ip.h> #include <net/ip.h>
#include <net/route.h> #include <net/route.h>
#include <net/flow_dissector.h> #include <net/flow_dissector.h>
#include <net/tc_wrapper.h>
#if IS_ENABLED(CONFIG_NF_CONNTRACK) #if IS_ENABLED(CONFIG_NF_CONNTRACK)
#include <net/netfilter/nf_conntrack.h> #include <net/netfilter/nf_conntrack.h>
@ -292,8 +293,9 @@ static u32 flow_key_get(struct sk_buff *skb, int key, struct flow_keys *flow)
(1 << FLOW_KEY_NFCT_PROTO_SRC) | \ (1 << FLOW_KEY_NFCT_PROTO_SRC) | \
(1 << FLOW_KEY_NFCT_PROTO_DST)) (1 << FLOW_KEY_NFCT_PROTO_DST))
static int flow_classify(struct sk_buff *skb, const struct tcf_proto *tp, TC_INDIRECT_SCOPE int flow_classify(struct sk_buff *skb,
struct tcf_result *res) const struct tcf_proto *tp,
struct tcf_result *res)
{ {
struct flow_head *head = rcu_dereference_bh(tp->root); struct flow_head *head = rcu_dereference_bh(tp->root);
struct flow_filter *f; struct flow_filter *f;

View file

@ -27,6 +27,7 @@
#include <net/vxlan.h> #include <net/vxlan.h>
#include <net/erspan.h> #include <net/erspan.h>
#include <net/gtp.h> #include <net/gtp.h>
#include <net/tc_wrapper.h>
#include <net/dst.h> #include <net/dst.h>
#include <net/dst_metadata.h> #include <net/dst_metadata.h>
@ -305,8 +306,9 @@ static u16 fl_ct_info_to_flower_map[] = {
TCA_FLOWER_KEY_CT_FLAGS_NEW, TCA_FLOWER_KEY_CT_FLAGS_NEW,
}; };
static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp, TC_INDIRECT_SCOPE int fl_classify(struct sk_buff *skb,
struct tcf_result *res) const struct tcf_proto *tp,
struct tcf_result *res)
{ {
struct cls_fl_head *head = rcu_dereference_bh(tp->root); struct cls_fl_head *head = rcu_dereference_bh(tp->root);
bool post_ct = tc_skb_cb(skb)->post_ct; bool post_ct = tc_skb_cb(skb)->post_ct;

View file

@ -21,6 +21,7 @@
#include <net/act_api.h> #include <net/act_api.h>
#include <net/pkt_cls.h> #include <net/pkt_cls.h>
#include <net/sch_generic.h> #include <net/sch_generic.h>
#include <net/tc_wrapper.h>
#define HTSIZE 256 #define HTSIZE 256
@ -47,8 +48,9 @@ static u32 fw_hash(u32 handle)
return handle % HTSIZE; return handle % HTSIZE;
} }
static int fw_classify(struct sk_buff *skb, const struct tcf_proto *tp, TC_INDIRECT_SCOPE int fw_classify(struct sk_buff *skb,
struct tcf_result *res) const struct tcf_proto *tp,
struct tcf_result *res)
{ {
struct fw_head *head = rcu_dereference_bh(tp->root); struct fw_head *head = rcu_dereference_bh(tp->root);
struct fw_filter *f; struct fw_filter *f;

View file

@ -12,6 +12,7 @@
#include <net/sch_generic.h> #include <net/sch_generic.h>
#include <net/pkt_cls.h> #include <net/pkt_cls.h>
#include <net/tc_wrapper.h>
struct cls_mall_head { struct cls_mall_head {
struct tcf_exts exts; struct tcf_exts exts;
@ -24,8 +25,9 @@ struct cls_mall_head {
bool deleting; bool deleting;
}; };
static int mall_classify(struct sk_buff *skb, const struct tcf_proto *tp, TC_INDIRECT_SCOPE int mall_classify(struct sk_buff *skb,
struct tcf_result *res) const struct tcf_proto *tp,
struct tcf_result *res)
{ {
struct cls_mall_head *head = rcu_dereference_bh(tp->root); struct cls_mall_head *head = rcu_dereference_bh(tp->root);

View file

@ -17,6 +17,7 @@
#include <net/netlink.h> #include <net/netlink.h>
#include <net/act_api.h> #include <net/act_api.h>
#include <net/pkt_cls.h> #include <net/pkt_cls.h>
#include <net/tc_wrapper.h>
/* /*
* 1. For now we assume that route tags < 256. * 1. For now we assume that route tags < 256.
@ -121,8 +122,9 @@ static inline int route4_hash_wild(void)
return 0; \ return 0; \
} }
static int route4_classify(struct sk_buff *skb, const struct tcf_proto *tp, TC_INDIRECT_SCOPE int route4_classify(struct sk_buff *skb,
struct tcf_result *res) const struct tcf_proto *tp,
struct tcf_result *res)
{ {
struct route4_head *head = rcu_dereference_bh(tp->root); struct route4_head *head = rcu_dereference_bh(tp->root);
struct dst_entry *dst; struct dst_entry *dst;

View file

@ -15,10 +15,12 @@
#include <net/netlink.h> #include <net/netlink.h>
#include <net/act_api.h> #include <net/act_api.h>
#include <net/pkt_cls.h> #include <net/pkt_cls.h>
#include <net/tc_wrapper.h>
#define RSVP_DST_LEN 1 #define RSVP_DST_LEN 1
#define RSVP_ID "rsvp" #define RSVP_ID "rsvp"
#define RSVP_OPS cls_rsvp_ops #define RSVP_OPS cls_rsvp_ops
#define RSVP_CLS rsvp_classify
#include "cls_rsvp.h" #include "cls_rsvp.h"
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");

View file

@ -124,8 +124,8 @@ static inline unsigned int hash_src(__be32 *src)
return r; \ return r; \
} }
static int rsvp_classify(struct sk_buff *skb, const struct tcf_proto *tp, TC_INDIRECT_SCOPE int RSVP_CLS(struct sk_buff *skb, const struct tcf_proto *tp,
struct tcf_result *res) struct tcf_result *res)
{ {
struct rsvp_head *head = rcu_dereference_bh(tp->root); struct rsvp_head *head = rcu_dereference_bh(tp->root);
struct rsvp_session *s; struct rsvp_session *s;
@ -738,7 +738,7 @@ static void rsvp_bind_class(void *fh, u32 classid, unsigned long cl, void *q,
static struct tcf_proto_ops RSVP_OPS __read_mostly = { static struct tcf_proto_ops RSVP_OPS __read_mostly = {
.kind = RSVP_ID, .kind = RSVP_ID,
.classify = rsvp_classify, .classify = RSVP_CLS,
.init = rsvp_init, .init = rsvp_init,
.destroy = rsvp_destroy, .destroy = rsvp_destroy,
.get = rsvp_get, .get = rsvp_get,

View file

@ -15,10 +15,12 @@
#include <net/act_api.h> #include <net/act_api.h>
#include <net/pkt_cls.h> #include <net/pkt_cls.h>
#include <net/netlink.h> #include <net/netlink.h>
#include <net/tc_wrapper.h>
#define RSVP_DST_LEN 4 #define RSVP_DST_LEN 4
#define RSVP_ID "rsvp6" #define RSVP_ID "rsvp6"
#define RSVP_OPS cls_rsvp6_ops #define RSVP_OPS cls_rsvp6_ops
#define RSVP_CLS rsvp6_classify
#include "cls_rsvp.h" #include "cls_rsvp.h"
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");

View file

@ -16,6 +16,7 @@
#include <net/netlink.h> #include <net/netlink.h>
#include <net/pkt_cls.h> #include <net/pkt_cls.h>
#include <net/sch_generic.h> #include <net/sch_generic.h>
#include <net/tc_wrapper.h>
/* /*
* Passing parameters to the root seems to be done more awkwardly than really * Passing parameters to the root seems to be done more awkwardly than really
@ -98,9 +99,9 @@ static struct tcindex_filter_result *tcindex_lookup(struct tcindex_data *p,
return NULL; return NULL;
} }
TC_INDIRECT_SCOPE int tcindex_classify(struct sk_buff *skb,
static int tcindex_classify(struct sk_buff *skb, const struct tcf_proto *tp, const struct tcf_proto *tp,
struct tcf_result *res) struct tcf_result *res)
{ {
struct tcindex_data *p = rcu_dereference_bh(tp->root); struct tcindex_data *p = rcu_dereference_bh(tp->root);
struct tcindex_filter_result *f; struct tcindex_filter_result *f;

View file

@ -39,6 +39,7 @@
#include <net/act_api.h> #include <net/act_api.h>
#include <net/pkt_cls.h> #include <net/pkt_cls.h>
#include <linux/idr.h> #include <linux/idr.h>
#include <net/tc_wrapper.h>
struct tc_u_knode { struct tc_u_knode {
struct tc_u_knode __rcu *next; struct tc_u_knode __rcu *next;
@ -100,8 +101,9 @@ static inline unsigned int u32_hash_fold(__be32 key,
return h; return h;
} }
static int u32_classify(struct sk_buff *skb, const struct tcf_proto *tp, TC_INDIRECT_SCOPE int u32_classify(struct sk_buff *skb,
struct tcf_result *res) const struct tcf_proto *tp,
struct tcf_result *res)
{ {
struct { struct {
struct tc_u_knode *knode; struct tc_u_knode *knode;