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
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
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 */
tcf_pedit_nkeys_locked(const struct tc_action * a)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
tcf_pedit_htype(const struct tc_action * a,int index)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
tcf_pedit_cmd(const struct tc_action * a,int index)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
tcf_pedit_mask(const struct tc_action * a,int index)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
tcf_pedit_val(const struct tc_action * a,int index)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
tcf_pedit_offset(const struct tc_action * a,int index)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