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