xref: /openbmc/linux/include/net/tc_wrapper.h (revision 265b4da8)
17f0e8102SPedro Tammela /* SPDX-License-Identifier: GPL-2.0 */
27f0e8102SPedro Tammela #ifndef __NET_TC_WRAPPER_H
37f0e8102SPedro Tammela #define __NET_TC_WRAPPER_H
47f0e8102SPedro Tammela 
57f0e8102SPedro Tammela #include <net/pkt_cls.h>
67f0e8102SPedro Tammela 
77f0e8102SPedro Tammela #if IS_ENABLED(CONFIG_RETPOLINE)
87f0e8102SPedro Tammela 
97f0e8102SPedro Tammela #include <linux/cpufeature.h>
107f0e8102SPedro Tammela #include <linux/static_key.h>
117f0e8102SPedro Tammela #include <linux/indirect_call_wrapper.h>
127f0e8102SPedro Tammela 
137f0e8102SPedro Tammela #define TC_INDIRECT_SCOPE
147f0e8102SPedro Tammela 
157f0e8102SPedro Tammela extern struct static_key_false tc_skip_wrapper;
167f0e8102SPedro Tammela 
177f0e8102SPedro Tammela /* TC Actions */
187f0e8102SPedro Tammela #ifdef CONFIG_NET_CLS_ACT
197f0e8102SPedro Tammela 
207f0e8102SPedro Tammela #define TC_INDIRECT_ACTION_DECLARE(fname)                              \
217f0e8102SPedro Tammela 	INDIRECT_CALLABLE_DECLARE(int fname(struct sk_buff *skb,       \
227f0e8102SPedro Tammela 					    const struct tc_action *a, \
237f0e8102SPedro Tammela 					    struct tcf_result *res))
247f0e8102SPedro Tammela 
257f0e8102SPedro Tammela TC_INDIRECT_ACTION_DECLARE(tcf_bpf_act);
267f0e8102SPedro Tammela TC_INDIRECT_ACTION_DECLARE(tcf_connmark_act);
277f0e8102SPedro Tammela TC_INDIRECT_ACTION_DECLARE(tcf_csum_act);
287f0e8102SPedro Tammela TC_INDIRECT_ACTION_DECLARE(tcf_ct_act);
297f0e8102SPedro Tammela TC_INDIRECT_ACTION_DECLARE(tcf_ctinfo_act);
307f0e8102SPedro Tammela TC_INDIRECT_ACTION_DECLARE(tcf_gact_act);
317f0e8102SPedro Tammela TC_INDIRECT_ACTION_DECLARE(tcf_gate_act);
327f0e8102SPedro Tammela TC_INDIRECT_ACTION_DECLARE(tcf_ife_act);
337f0e8102SPedro Tammela TC_INDIRECT_ACTION_DECLARE(tcf_ipt_act);
347f0e8102SPedro Tammela TC_INDIRECT_ACTION_DECLARE(tcf_mirred_act);
357f0e8102SPedro Tammela TC_INDIRECT_ACTION_DECLARE(tcf_mpls_act);
367f0e8102SPedro Tammela TC_INDIRECT_ACTION_DECLARE(tcf_nat_act);
377f0e8102SPedro Tammela TC_INDIRECT_ACTION_DECLARE(tcf_pedit_act);
387f0e8102SPedro Tammela TC_INDIRECT_ACTION_DECLARE(tcf_police_act);
397f0e8102SPedro Tammela TC_INDIRECT_ACTION_DECLARE(tcf_sample_act);
407f0e8102SPedro Tammela TC_INDIRECT_ACTION_DECLARE(tcf_simp_act);
417f0e8102SPedro Tammela TC_INDIRECT_ACTION_DECLARE(tcf_skbedit_act);
427f0e8102SPedro Tammela TC_INDIRECT_ACTION_DECLARE(tcf_skbmod_act);
437f0e8102SPedro Tammela TC_INDIRECT_ACTION_DECLARE(tcf_vlan_act);
447f0e8102SPedro Tammela TC_INDIRECT_ACTION_DECLARE(tunnel_key_act);
457f0e8102SPedro Tammela 
tc_act(struct sk_buff * skb,const struct tc_action * a,struct tcf_result * res)467f0e8102SPedro Tammela static inline int tc_act(struct sk_buff *skb, const struct tc_action *a,
477f0e8102SPedro Tammela 			   struct tcf_result *res)
487f0e8102SPedro Tammela {
497f0e8102SPedro Tammela 	if (static_branch_likely(&tc_skip_wrapper))
507f0e8102SPedro Tammela 		goto skip;
517f0e8102SPedro Tammela 
527f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_ACT_GACT)
537f0e8102SPedro Tammela 	if (a->ops->act == tcf_gact_act)
547f0e8102SPedro Tammela 		return tcf_gact_act(skb, a, res);
557f0e8102SPedro Tammela #endif
567f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_ACT_MIRRED)
577f0e8102SPedro Tammela 	if (a->ops->act == tcf_mirred_act)
587f0e8102SPedro Tammela 		return tcf_mirred_act(skb, a, res);
597f0e8102SPedro Tammela #endif
607f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_ACT_PEDIT)
617f0e8102SPedro Tammela 	if (a->ops->act == tcf_pedit_act)
627f0e8102SPedro Tammela 		return tcf_pedit_act(skb, a, res);
637f0e8102SPedro Tammela #endif
647f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_ACT_SKBEDIT)
657f0e8102SPedro Tammela 	if (a->ops->act == tcf_skbedit_act)
667f0e8102SPedro Tammela 		return tcf_skbedit_act(skb, a, res);
677f0e8102SPedro Tammela #endif
687f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_ACT_SKBMOD)
697f0e8102SPedro Tammela 	if (a->ops->act == tcf_skbmod_act)
707f0e8102SPedro Tammela 		return tcf_skbmod_act(skb, a, res);
717f0e8102SPedro Tammela #endif
727f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_ACT_POLICE)
737f0e8102SPedro Tammela 	if (a->ops->act == tcf_police_act)
747f0e8102SPedro Tammela 		return tcf_police_act(skb, a, res);
757f0e8102SPedro Tammela #endif
767f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_ACT_BPF)
777f0e8102SPedro Tammela 	if (a->ops->act == tcf_bpf_act)
787f0e8102SPedro Tammela 		return tcf_bpf_act(skb, a, res);
797f0e8102SPedro Tammela #endif
807f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_ACT_CONNMARK)
817f0e8102SPedro Tammela 	if (a->ops->act == tcf_connmark_act)
827f0e8102SPedro Tammela 		return tcf_connmark_act(skb, a, res);
837f0e8102SPedro Tammela #endif
847f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_ACT_CSUM)
857f0e8102SPedro Tammela 	if (a->ops->act == tcf_csum_act)
867f0e8102SPedro Tammela 		return tcf_csum_act(skb, a, res);
877f0e8102SPedro Tammela #endif
887f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_ACT_CT)
897f0e8102SPedro Tammela 	if (a->ops->act == tcf_ct_act)
907f0e8102SPedro Tammela 		return tcf_ct_act(skb, a, res);
917f0e8102SPedro Tammela #endif
927f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_ACT_CTINFO)
937f0e8102SPedro Tammela 	if (a->ops->act == tcf_ctinfo_act)
947f0e8102SPedro Tammela 		return tcf_ctinfo_act(skb, a, res);
957f0e8102SPedro Tammela #endif
967f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_ACT_GATE)
977f0e8102SPedro Tammela 	if (a->ops->act == tcf_gate_act)
987f0e8102SPedro Tammela 		return tcf_gate_act(skb, a, res);
997f0e8102SPedro Tammela #endif
1007f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_ACT_MPLS)
1017f0e8102SPedro Tammela 	if (a->ops->act == tcf_mpls_act)
1027f0e8102SPedro Tammela 		return tcf_mpls_act(skb, a, res);
1037f0e8102SPedro Tammela #endif
1047f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_ACT_NAT)
1057f0e8102SPedro Tammela 	if (a->ops->act == tcf_nat_act)
1067f0e8102SPedro Tammela 		return tcf_nat_act(skb, a, res);
1077f0e8102SPedro Tammela #endif
1087f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_ACT_TUNNEL_KEY)
1097f0e8102SPedro Tammela 	if (a->ops->act == tunnel_key_act)
1107f0e8102SPedro Tammela 		return tunnel_key_act(skb, a, res);
1117f0e8102SPedro Tammela #endif
1127f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_ACT_VLAN)
1137f0e8102SPedro Tammela 	if (a->ops->act == tcf_vlan_act)
1147f0e8102SPedro Tammela 		return tcf_vlan_act(skb, a, res);
1157f0e8102SPedro Tammela #endif
1167f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_ACT_IFE)
1177f0e8102SPedro Tammela 	if (a->ops->act == tcf_ife_act)
1187f0e8102SPedro Tammela 		return tcf_ife_act(skb, a, res);
1197f0e8102SPedro Tammela #endif
1207f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_ACT_IPT)
1217f0e8102SPedro Tammela 	if (a->ops->act == tcf_ipt_act)
1227f0e8102SPedro Tammela 		return tcf_ipt_act(skb, a, res);
1237f0e8102SPedro Tammela #endif
1247f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_ACT_SIMP)
1257f0e8102SPedro Tammela 	if (a->ops->act == tcf_simp_act)
1267f0e8102SPedro Tammela 		return tcf_simp_act(skb, a, res);
1277f0e8102SPedro Tammela #endif
1287f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_ACT_SAMPLE)
1297f0e8102SPedro Tammela 	if (a->ops->act == tcf_sample_act)
1307f0e8102SPedro Tammela 		return tcf_sample_act(skb, a, res);
1317f0e8102SPedro Tammela #endif
1327f0e8102SPedro Tammela 
1337f0e8102SPedro Tammela skip:
1347f0e8102SPedro Tammela 	return a->ops->act(skb, a, res);
1357f0e8102SPedro Tammela }
1367f0e8102SPedro Tammela 
1377f0e8102SPedro Tammela #endif /* CONFIG_NET_CLS_ACT */
1387f0e8102SPedro Tammela 
1397f0e8102SPedro Tammela /* TC Filters */
1407f0e8102SPedro Tammela #ifdef CONFIG_NET_CLS
1417f0e8102SPedro Tammela 
1427f0e8102SPedro Tammela #define TC_INDIRECT_FILTER_DECLARE(fname)                               \
1437f0e8102SPedro Tammela 	INDIRECT_CALLABLE_DECLARE(int fname(struct sk_buff *skb,        \
1447f0e8102SPedro Tammela 					    const struct tcf_proto *tp, \
1457f0e8102SPedro Tammela 					    struct tcf_result *res))
1467f0e8102SPedro Tammela 
1477f0e8102SPedro Tammela TC_INDIRECT_FILTER_DECLARE(basic_classify);
1487f0e8102SPedro Tammela TC_INDIRECT_FILTER_DECLARE(cls_bpf_classify);
1497f0e8102SPedro Tammela TC_INDIRECT_FILTER_DECLARE(cls_cgroup_classify);
1507f0e8102SPedro Tammela TC_INDIRECT_FILTER_DECLARE(fl_classify);
1517f0e8102SPedro Tammela TC_INDIRECT_FILTER_DECLARE(flow_classify);
1527f0e8102SPedro Tammela TC_INDIRECT_FILTER_DECLARE(fw_classify);
1537f0e8102SPedro Tammela TC_INDIRECT_FILTER_DECLARE(mall_classify);
1547f0e8102SPedro Tammela TC_INDIRECT_FILTER_DECLARE(route4_classify);
1557f0e8102SPedro Tammela TC_INDIRECT_FILTER_DECLARE(u32_classify);
1567f0e8102SPedro Tammela 
tc_classify(struct sk_buff * skb,const struct tcf_proto * tp,struct tcf_result * res)1577f0e8102SPedro Tammela static inline int tc_classify(struct sk_buff *skb, const struct tcf_proto *tp,
1587f0e8102SPedro Tammela 				struct tcf_result *res)
1597f0e8102SPedro Tammela {
1607f0e8102SPedro Tammela 	if (static_branch_likely(&tc_skip_wrapper))
1617f0e8102SPedro Tammela 		goto skip;
1627f0e8102SPedro Tammela 
1637f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_CLS_BPF)
1647f0e8102SPedro Tammela 	if (tp->classify == cls_bpf_classify)
1657f0e8102SPedro Tammela 		return cls_bpf_classify(skb, tp, res);
1667f0e8102SPedro Tammela #endif
1677f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_CLS_U32)
1687f0e8102SPedro Tammela 	if (tp->classify == u32_classify)
1697f0e8102SPedro Tammela 		return u32_classify(skb, tp, res);
1707f0e8102SPedro Tammela #endif
1717f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_CLS_FLOWER)
1727f0e8102SPedro Tammela 	if (tp->classify == fl_classify)
1737f0e8102SPedro Tammela 		return fl_classify(skb, tp, res);
1747f0e8102SPedro Tammela #endif
1757f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_CLS_FW)
1767f0e8102SPedro Tammela 	if (tp->classify == fw_classify)
1777f0e8102SPedro Tammela 		return fw_classify(skb, tp, res);
1787f0e8102SPedro Tammela #endif
1797f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_CLS_MATCHALL)
1807f0e8102SPedro Tammela 	if (tp->classify == mall_classify)
1817f0e8102SPedro Tammela 		return mall_classify(skb, tp, res);
1827f0e8102SPedro Tammela #endif
1837f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_CLS_BASIC)
1847f0e8102SPedro Tammela 	if (tp->classify == basic_classify)
1857f0e8102SPedro Tammela 		return basic_classify(skb, tp, res);
1867f0e8102SPedro Tammela #endif
1877f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_CLS_CGROUP)
1887f0e8102SPedro Tammela 	if (tp->classify == cls_cgroup_classify)
1897f0e8102SPedro Tammela 		return cls_cgroup_classify(skb, tp, res);
1907f0e8102SPedro Tammela #endif
1917f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_CLS_FLOW)
1927f0e8102SPedro Tammela 	if (tp->classify == flow_classify)
1937f0e8102SPedro Tammela 		return flow_classify(skb, tp, res);
1947f0e8102SPedro Tammela #endif
1957f0e8102SPedro Tammela #if IS_BUILTIN(CONFIG_NET_CLS_ROUTE4)
1967f0e8102SPedro Tammela 	if (tp->classify == route4_classify)
1977f0e8102SPedro Tammela 		return route4_classify(skb, tp, res);
1987f0e8102SPedro Tammela #endif
1997f0e8102SPedro Tammela 
2007f0e8102SPedro Tammela skip:
2017f0e8102SPedro Tammela 	return tp->classify(skb, tp, res);
2027f0e8102SPedro Tammela }
2037f0e8102SPedro Tammela 
204*40cab44bSPedro Tammela #endif /* CONFIG_NET_CLS */
205*40cab44bSPedro Tammela 
tc_wrapper_init(void)2067f0e8102SPedro Tammela static inline void tc_wrapper_init(void)
2077f0e8102SPedro Tammela {
2087f0e8102SPedro Tammela #ifdef CONFIG_X86
2097f0e8102SPedro Tammela 	if (!cpu_feature_enabled(X86_FEATURE_RETPOLINE))
2107f0e8102SPedro Tammela 		static_branch_enable(&tc_skip_wrapper);
2117f0e8102SPedro Tammela #endif
2127f0e8102SPedro Tammela }
2137f0e8102SPedro Tammela 
2147f0e8102SPedro Tammela #else
2157f0e8102SPedro Tammela 
2167f0e8102SPedro Tammela #define TC_INDIRECT_SCOPE static
2177f0e8102SPedro Tammela 
tc_act(struct sk_buff * skb,const struct tc_action * a,struct tcf_result * res)2187f0e8102SPedro Tammela static inline int tc_act(struct sk_buff *skb, const struct tc_action *a,
2197f0e8102SPedro Tammela 			   struct tcf_result *res)
2207f0e8102SPedro Tammela {
2217f0e8102SPedro Tammela 	return a->ops->act(skb, a, res);
2227f0e8102SPedro Tammela }
2237f0e8102SPedro Tammela 
tc_classify(struct sk_buff * skb,const struct tcf_proto * tp,struct tcf_result * res)2247f0e8102SPedro Tammela static inline int tc_classify(struct sk_buff *skb, const struct tcf_proto *tp,
2257f0e8102SPedro Tammela 				struct tcf_result *res)
2267f0e8102SPedro Tammela {
2277f0e8102SPedro Tammela 	return tp->classify(skb, tp, res);
2287f0e8102SPedro Tammela }
2297f0e8102SPedro Tammela 
tc_wrapper_init(void)2307f0e8102SPedro Tammela static inline void tc_wrapper_init(void)
2317f0e8102SPedro Tammela {
2327f0e8102SPedro Tammela }
2337f0e8102SPedro Tammela 
2347f0e8102SPedro Tammela #endif
2357f0e8102SPedro Tammela 
2367f0e8102SPedro Tammela #endif /* __NET_TC_WRAPPER_H */
237