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 	u32 tcfp_off_max_hint;
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 
is_tcf_pedit(const struct tc_action * a)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 
tcf_pedit_nkeys(const struct tc_action * a)40 static inline int tcf_pedit_nkeys(const struct tc_action *a)
41 {
42 	struct tcf_pedit_parms *parms;
43 	int nkeys;
44 
45 	rcu_read_lock();
46 	parms = to_pedit_parms(a);
47 	nkeys = parms->tcfp_nkeys;
48 	rcu_read_unlock();
49 
50 	return nkeys;
51 }
52 
tcf_pedit_htype(const struct tc_action * a,int index)53 static inline u32 tcf_pedit_htype(const struct tc_action *a, int index)
54 {
55 	u32 htype = TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK;
56 	struct tcf_pedit_parms *parms;
57 
58 	rcu_read_lock();
59 	parms = to_pedit_parms(a);
60 	if (parms->tcfp_keys_ex)
61 		htype = parms->tcfp_keys_ex[index].htype;
62 	rcu_read_unlock();
63 
64 	return htype;
65 }
66 
tcf_pedit_cmd(const struct tc_action * a,int index)67 static inline u32 tcf_pedit_cmd(const struct tc_action *a, int index)
68 {
69 	struct tcf_pedit_parms *parms;
70 	u32 cmd = __PEDIT_CMD_MAX;
71 
72 	rcu_read_lock();
73 	parms = to_pedit_parms(a);
74 	if (parms->tcfp_keys_ex)
75 		cmd = parms->tcfp_keys_ex[index].cmd;
76 	rcu_read_unlock();
77 
78 	return cmd;
79 }
80 
tcf_pedit_mask(const struct tc_action * a,int index)81 static inline u32 tcf_pedit_mask(const struct tc_action *a, int index)
82 {
83 	struct tcf_pedit_parms *parms;
84 	u32 mask;
85 
86 	rcu_read_lock();
87 	parms = to_pedit_parms(a);
88 	mask = parms->tcfp_keys[index].mask;
89 	rcu_read_unlock();
90 
91 	return mask;
92 }
93 
tcf_pedit_val(const struct tc_action * a,int index)94 static inline u32 tcf_pedit_val(const struct tc_action *a, int index)
95 {
96 	struct tcf_pedit_parms *parms;
97 	u32 val;
98 
99 	rcu_read_lock();
100 	parms = to_pedit_parms(a);
101 	val = parms->tcfp_keys[index].val;
102 	rcu_read_unlock();
103 
104 	return val;
105 }
106 
tcf_pedit_offset(const struct tc_action * a,int index)107 static inline u32 tcf_pedit_offset(const struct tc_action *a, int index)
108 {
109 	struct tcf_pedit_parms *parms;
110 	u32 off;
111 
112 	rcu_read_lock();
113 	parms = to_pedit_parms(a);
114 	off = parms->tcfp_keys[index].off;
115 	rcu_read_unlock();
116 
117 	return off;
118 }
119 #endif /* __NET_TC_PED_H */
120