xref: /linux/include/net/tc_act/tc_pedit.h (revision fafb66e5903c2bcfc7b7e259042a8282f18a6faa)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __NET_TC_PED_H
3 #define __NET_TC_PED_H
4 
5 #include <net/act_api.h>
6 #include <linux/tc_act/tc_pedit.h>
7 #include <linux/types.h>
8 
9 struct tcf_pedit_key_ex {
10 	enum pedit_header_type htype;
11 	enum pedit_cmd cmd;
12 };
13 
14 struct tcf_pedit_parms {
15 	struct tc_pedit_key	*tcfp_keys;
16 	struct tcf_pedit_key_ex	*tcfp_keys_ex;
17 	int action;
18 	unsigned char tcfp_nkeys;
19 	unsigned char tcfp_flags;
20 	struct rcu_head rcu;
21 };
22 
23 struct tcf_pedit {
24 	struct tc_action common;
25 	struct tcf_pedit_parms __rcu *parms;
26 };
27 
28 #define to_pedit(a) ((struct tcf_pedit *)a)
29 #define to_pedit_parms(a) (rcu_dereference(to_pedit(a)->parms))
30 
31 static inline bool is_tcf_pedit(const struct tc_action *a)
32 {
33 #ifdef CONFIG_NET_CLS_ACT
34 	if (a->ops && a->ops->id == TCA_ID_PEDIT)
35 		return true;
36 #endif
37 	return false;
38 }
39 
40 /* Must be called with act->tcfa_lock held to ensure consistency of parallel
41  * reads of the same action's pedit keys (e.g. flow_offload count vs fill).
42  * Note, this is only used for pedit offload.
43  */
44 static inline int tcf_pedit_nkeys_locked(const struct tc_action *a)
45 {
46 	lockdep_assert_held(&a->tcfa_lock);
47 	return rcu_dereference_protected(to_pedit(a)->parms,
48 					 lockdep_is_held(&a->tcfa_lock))->tcfp_nkeys;
49 }
50 
51 static inline u32 tcf_pedit_htype(const struct tc_action *a, int index)
52 {
53 	u32 htype = TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK;
54 	struct tcf_pedit_parms *parms;
55 
56 	rcu_read_lock();
57 	parms = to_pedit_parms(a);
58 	if (parms->tcfp_keys_ex)
59 		htype = parms->tcfp_keys_ex[index].htype;
60 	rcu_read_unlock();
61 
62 	return htype;
63 }
64 
65 static inline u32 tcf_pedit_cmd(const struct tc_action *a, int index)
66 {
67 	struct tcf_pedit_parms *parms;
68 	u32 cmd = __PEDIT_CMD_MAX;
69 
70 	rcu_read_lock();
71 	parms = to_pedit_parms(a);
72 	if (parms->tcfp_keys_ex)
73 		cmd = parms->tcfp_keys_ex[index].cmd;
74 	rcu_read_unlock();
75 
76 	return cmd;
77 }
78 
79 static inline u32 tcf_pedit_mask(const struct tc_action *a, int index)
80 {
81 	struct tcf_pedit_parms *parms;
82 	u32 mask;
83 
84 	rcu_read_lock();
85 	parms = to_pedit_parms(a);
86 	mask = parms->tcfp_keys[index].mask;
87 	rcu_read_unlock();
88 
89 	return mask;
90 }
91 
92 static inline u32 tcf_pedit_val(const struct tc_action *a, int index)
93 {
94 	struct tcf_pedit_parms *parms;
95 	u32 val;
96 
97 	rcu_read_lock();
98 	parms = to_pedit_parms(a);
99 	val = parms->tcfp_keys[index].val;
100 	rcu_read_unlock();
101 
102 	return val;
103 }
104 
105 static inline u32 tcf_pedit_offset(const struct tc_action *a, int index)
106 {
107 	struct tcf_pedit_parms *parms;
108 	u32 off;
109 
110 	rcu_read_lock();
111 	parms = to_pedit_parms(a);
112 	off = parms->tcfp_keys[index].off;
113 	rcu_read_unlock();
114 
115 	return off;
116 }
117 #endif /* __NET_TC_PED_H */
118