summaryrefslogtreecommitdiffstats
path: root/include/net/tc_act/tc_police.h
blob: 283bde711a425ff35000a71f0837aab477f0b1a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __NET_TC_POLICE_H
#define __NET_TC_POLICE_H

#include <net/act_api.h>

struct tcf_police_params {
	int			tcfp_result;
	u32			tcfp_ewma_rate;
	s64			tcfp_burst;
	u32			tcfp_mtu;
	s64			tcfp_mtu_ptoks;
	s64			tcfp_pkt_burst;
	struct psched_ratecfg	rate;
	bool			rate_present;
	struct psched_ratecfg	peak;
	bool			peak_present;
	struct psched_pktrate	ppsrate;
	bool			pps_present;
	struct rcu_head rcu;
};

struct tcf_police {
	struct tc_action	common;
	struct tcf_police_params __rcu *params;

	spinlock_t		tcfp_lock ____cacheline_aligned_in_smp;
	s64			tcfp_toks;
	s64			tcfp_ptoks;
	s64			tcfp_pkttoks;
	s64			tcfp_t_c;
};

#define to_police(pc) ((struct tcf_police *)pc)

/* old policer structure from before tc actions */
struct tc_police_compat {
	u32			index;
	int			action;
	u32			limit;
	u32			burst;
	u32			mtu;
	struct tc_ratespec	rate;
	struct tc_ratespec	peakrate;
};

static inline bool is_tcf_police(const struct tc_action *act)
{
#ifdef CONFIG_NET_CLS_ACT
	if (act->ops && act->ops->id == TCA_ID_POLICE)
		return true;
#endif
	return false;
}

static inline u64 tcf_police_rate_bytes_ps(const struct tc_action *act)
{
	struct tcf_police *police = to_police(act);
	struct tcf_police_params *params;

	params = rcu_dereference_protected(police->params,
					   lockdep_is_held(&police->tcf_lock));
	return params->rate.rate_bytes_ps;
}

static inline u32 tcf_police_burst(const struct tc_action *act)
{
	struct tcf_police *police = to_police(act);
	struct tcf_police_params *params;
	u32 burst;

	params = rcu_dereference_protected(police->params,
					   lockdep_is_held(&police->tcf_lock));

	/*
	 *  "rate" bytes   "burst" nanoseconds
	 *  ------------ * -------------------
	 *    1 second          2^6 ticks
	 *
	 * ------------------------------------
	 *        NSEC_PER_SEC nanoseconds
	 *        ------------------------
	 *              2^6 ticks
	 *
	 *    "rate" bytes   "burst" nanoseconds            2^6 ticks
	 *  = ------------ * ------------------- * ------------------------
	 *      1 second          2^6 ticks        NSEC_PER_SEC nanoseconds
	 *
	 *   "rate" * "burst"
	 * = ---------------- bytes/nanosecond
	 *    NSEC_PER_SEC^2
	 *
	 *
	 *   "rate" * "burst"
	 * = ---------------- bytes/second
	 *     NSEC_PER_SEC
	 */
	burst = div_u64(params->tcfp_burst * params->rate.rate_bytes_ps,
			NSEC_PER_SEC);

	return burst;
}

static inline u64 tcf_police_rate_pkt_ps(const struct tc_action *act)
{
	struct tcf_police *police = to_police(act);
	struct tcf_police_params *params;

	params = rcu_dereference_protected(police->params,
					   lockdep_is_held(&police->tcf_lock));
	return params->ppsrate.rate_pkts_ps;
}

static inline u32 tcf_police_burst_pkt(const struct tc_action *act)
{
	struct tcf_police *police = to_police(act);
	struct tcf_police_params *params;
	u32 burst;

	params = rcu_dereference_protected(police->params,
					   lockdep_is_held(&police->tcf_lock));

	/*
	 *  "rate" pkts     "burst" nanoseconds
	 *  ------------ *  -------------------
	 *    1 second          2^6 ticks
	 *
	 * ------------------------------------
	 *        NSEC_PER_SEC nanoseconds
	 *        ------------------------
	 *              2^6 ticks
	 *
	 *    "rate" pkts    "burst" nanoseconds            2^6 ticks
	 *  = ------------ * ------------------- * ------------------------
	 *      1 second          2^6 ticks        NSEC_PER_SEC nanoseconds
	 *
	 *   "rate" * "burst"
	 * = ---------------- pkts/nanosecond
	 *    NSEC_PER_SEC^2
	 *
	 *
	 *   "rate" * "burst"
	 * = ---------------- pkts/second
	 *     NSEC_PER_SEC
	 */
	burst = div_u64(params->tcfp_pkt_burst * params->ppsrate.rate_pkts_ps,
			NSEC_PER_SEC);

	return burst;
}

static inline u32 tcf_police_tcfp_mtu(const struct tc_action *act)
{
	struct tcf_police *police = to_police(act);
	struct tcf_police_params *params;

	params = rcu_dereference_protected(police->params,
					   lockdep_is_held(&police->tcf_lock));
	return params->tcfp_mtu;
}

static inline u64 tcf_police_peakrate_bytes_ps(const struct tc_action *act)
{
	struct tcf_police *police = to_police(act);
	struct tcf_police_params *params;

	params = rcu_dereference_protected(police->params,
					   lockdep_is_held(&police->tcf_lock));
	return params->peak.rate_bytes_ps;
}

static inline u32 tcf_police_tcfp_ewma_rate(const struct tc_action *act)
{
	struct tcf_police *police = to_police(act);
	struct tcf_police_params *params;

	params = rcu_dereference_protected(police->params,
					   lockdep_is_held(&police->tcf_lock));
	return params->tcfp_ewma_rate;
}

static inline u16 tcf_police_rate_overhead(const struct tc_action *act)
{
	struct tcf_police *police = to_police(act);
	struct tcf_police_params *params;

	params = rcu_dereference_protected(police->params,
					   lockdep_is_held(&police->tcf_lock));
	return params->rate.overhead;
}

#endif /* __NET_TC_POLICE_H */