1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright (c) 2008, Intel Corporation.
4 *
5 * Author: Alexander Duyck <alexander.h.duyck@intel.com>
6 */
7
8#ifndef __NET_TC_SKBEDIT_H
9#define __NET_TC_SKBEDIT_H
10
11#include <net/act_api.h>
12#include <linux/tc_act/tc_skbedit.h>
13
14struct tcf_skbedit_params {
15 int action;
16 u32 flags;
17 u32 priority;
18 u32 mark;
19 u32 mask;
20 u16 queue_mapping;
21 u16 mapping_mod;
22 u16 ptype;
23 struct rcu_head rcu;
24};
25
26struct tcf_skbedit {
27 struct tc_action common;
28 struct tcf_skbedit_params __rcu *params;
29};
30#define to_skbedit(a) ((struct tcf_skbedit *)a)
31
32/* Return true iff action is the one identified by FLAG. */
33static inline bool is_tcf_skbedit_with_flag(const struct tc_action *a, u32 flag)
34{
35#ifdef CONFIG_NET_CLS_ACT
36 u32 flags;
37
38 if (a->ops && a->ops->id == TCA_ID_SKBEDIT) {
39 rcu_read_lock();
40 flags = rcu_dereference(to_skbedit(a)->params)->flags;
41 rcu_read_unlock();
42 return flags == flag;
43 }
44#endif
45 return false;
46}
47
48/* Return true iff action is mark */
49static inline bool is_tcf_skbedit_mark(const struct tc_action *a)
50{
51 return is_tcf_skbedit_with_flag(a, SKBEDIT_F_MARK);
52}
53
54static inline u32 tcf_skbedit_mark(const struct tc_action *a)
55{
56 u32 mark;
57
58 rcu_read_lock();
59 mark = rcu_dereference(to_skbedit(a)->params)->mark;
60 rcu_read_unlock();
61
62 return mark;
63}
64
65/* Return true iff action is ptype */
66static inline bool is_tcf_skbedit_ptype(const struct tc_action *a)
67{
68 return is_tcf_skbedit_with_flag(a, SKBEDIT_F_PTYPE);
69}
70
71static inline u32 tcf_skbedit_ptype(const struct tc_action *a)
72{
73 u16 ptype;
74
75 rcu_read_lock();
76 ptype = rcu_dereference(to_skbedit(a)->params)->ptype;
77 rcu_read_unlock();
78
79 return ptype;
80}
81
82/* Return true iff action is priority */
83static inline bool is_tcf_skbedit_priority(const struct tc_action *a)
84{
85 return is_tcf_skbedit_with_flag(a, SKBEDIT_F_PRIORITY);
86}
87
88static inline u32 tcf_skbedit_priority(const struct tc_action *a)
89{
90 u32 priority;
91
92 rcu_read_lock();
93 priority = rcu_dereference(to_skbedit(a)->params)->priority;
94 rcu_read_unlock();
95
96 return priority;
97}
98
99static inline u16 tcf_skbedit_rx_queue_mapping(const struct tc_action *a)
100{
101 u16 rx_queue;
102
103 rcu_read_lock();
104 rx_queue = rcu_dereference(to_skbedit(a)->params)->queue_mapping;
105 rcu_read_unlock();
106
107 return rx_queue;
108}
109
110/* Return true iff action is queue_mapping */
111static inline bool is_tcf_skbedit_queue_mapping(const struct tc_action *a)
112{
113 return is_tcf_skbedit_with_flag(a, SKBEDIT_F_QUEUE_MAPPING);
114}
115
116/* Return true if action is on ingress traffic */
117static inline bool is_tcf_skbedit_ingress(u32 flags)
118{
119 return flags & TCA_ACT_FLAGS_AT_INGRESS;
120}
121
122static inline bool is_tcf_skbedit_tx_queue_mapping(const struct tc_action *a)
123{
124 return is_tcf_skbedit_queue_mapping(a) &&
125 !is_tcf_skbedit_ingress(flags: a->tcfa_flags);
126}
127
128static inline bool is_tcf_skbedit_rx_queue_mapping(const struct tc_action *a)
129{
130 return is_tcf_skbedit_queue_mapping(a) &&
131 is_tcf_skbedit_ingress(flags: a->tcfa_flags);
132}
133
134/* Return true iff action is inheritdsfield */
135static inline bool is_tcf_skbedit_inheritdsfield(const struct tc_action *a)
136{
137 return is_tcf_skbedit_with_flag(a, SKBEDIT_F_INHERITDSFIELD);
138}
139
140#endif /* __NET_TC_SKBEDIT_H */
141