Mention branches and keyring.
[releases.git] / netfilter / nft_limit.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net>
4  *
5  * Development of this code funded by Astaro AG (http://www.astaro.com/)
6  */
7
8 #include <linux/kernel.h>
9 #include <linux/init.h>
10 #include <linux/module.h>
11 #include <linux/spinlock.h>
12 #include <linux/netlink.h>
13 #include <linux/netfilter.h>
14 #include <linux/netfilter/nf_tables.h>
15 #include <net/netfilter/nf_tables.h>
16
17 struct nft_limit {
18         spinlock_t      lock;
19         u64             last;
20         u64             tokens;
21 };
22
23 struct nft_limit_priv {
24         struct nft_limit *limit;
25         u64             tokens_max;
26         u64             rate;
27         u64             nsecs;
28         u32             burst;
29         bool            invert;
30 };
31
32 static inline bool nft_limit_eval(struct nft_limit_priv *priv, u64 cost)
33 {
34         u64 now, tokens;
35         s64 delta;
36
37         spin_lock_bh(&priv->limit->lock);
38         now = ktime_get_ns();
39         tokens = priv->limit->tokens + now - priv->limit->last;
40         if (tokens > priv->tokens_max)
41                 tokens = priv->tokens_max;
42
43         priv->limit->last = now;
44         delta = tokens - cost;
45         if (delta >= 0) {
46                 priv->limit->tokens = delta;
47                 spin_unlock_bh(&priv->limit->lock);
48                 return priv->invert;
49         }
50         priv->limit->tokens = tokens;
51         spin_unlock_bh(&priv->limit->lock);
52         return !priv->invert;
53 }
54
55 /* Use same default as in iptables. */
56 #define NFT_LIMIT_PKT_BURST_DEFAULT     5
57
58 static int nft_limit_init(struct nft_limit_priv *priv,
59                           const struct nlattr * const tb[], bool pkts)
60 {
61         u64 unit, tokens, rate_with_burst;
62         bool invert = false;
63
64         if (tb[NFTA_LIMIT_RATE] == NULL ||
65             tb[NFTA_LIMIT_UNIT] == NULL)
66                 return -EINVAL;
67
68         priv->rate = be64_to_cpu(nla_get_be64(tb[NFTA_LIMIT_RATE]));
69         if (priv->rate == 0)
70                 return -EINVAL;
71
72         unit = be64_to_cpu(nla_get_be64(tb[NFTA_LIMIT_UNIT]));
73         if (check_mul_overflow(unit, NSEC_PER_SEC, &priv->nsecs))
74                 return -EOVERFLOW;
75
76         if (tb[NFTA_LIMIT_BURST])
77                 priv->burst = ntohl(nla_get_be32(tb[NFTA_LIMIT_BURST]));
78
79         if (pkts && priv->burst == 0)
80                 priv->burst = NFT_LIMIT_PKT_BURST_DEFAULT;
81
82         if (check_add_overflow(priv->rate, priv->burst, &rate_with_burst))
83                 return -EOVERFLOW;
84
85         if (pkts) {
86                 u64 tmp = div64_u64(priv->nsecs, priv->rate);
87
88                 if (check_mul_overflow(tmp, priv->burst, &tokens))
89                         return -EOVERFLOW;
90         } else {
91                 u64 tmp;
92
93                 /* The token bucket size limits the number of tokens can be
94                  * accumulated. tokens_max specifies the bucket size.
95                  * tokens_max = unit * (rate + burst) / rate.
96                  */
97                 if (check_mul_overflow(priv->nsecs, rate_with_burst, &tmp))
98                         return -EOVERFLOW;
99
100                 tokens = div64_u64(tmp, priv->rate);
101         }
102
103         if (tb[NFTA_LIMIT_FLAGS]) {
104                 u32 flags = ntohl(nla_get_be32(tb[NFTA_LIMIT_FLAGS]));
105
106                 if (flags & ~NFT_LIMIT_F_INV)
107                         return -EOPNOTSUPP;
108
109                 if (flags & NFT_LIMIT_F_INV)
110                         invert = true;
111         }
112
113         priv->limit = kmalloc(sizeof(*priv->limit), GFP_KERNEL_ACCOUNT);
114         if (!priv->limit)
115                 return -ENOMEM;
116
117         priv->limit->tokens = tokens;
118         priv->tokens_max = priv->limit->tokens;
119         priv->invert = invert;
120         priv->limit->last = ktime_get_ns();
121         spin_lock_init(&priv->limit->lock);
122
123         return 0;
124 }
125
126 static int nft_limit_dump(struct sk_buff *skb, const struct nft_limit_priv *priv,
127                           enum nft_limit_type type)
128 {
129         u32 flags = priv->invert ? NFT_LIMIT_F_INV : 0;
130         u64 secs = div_u64(priv->nsecs, NSEC_PER_SEC);
131
132         if (nla_put_be64(skb, NFTA_LIMIT_RATE, cpu_to_be64(priv->rate),
133                          NFTA_LIMIT_PAD) ||
134             nla_put_be64(skb, NFTA_LIMIT_UNIT, cpu_to_be64(secs),
135                          NFTA_LIMIT_PAD) ||
136             nla_put_be32(skb, NFTA_LIMIT_BURST, htonl(priv->burst)) ||
137             nla_put_be32(skb, NFTA_LIMIT_TYPE, htonl(type)) ||
138             nla_put_be32(skb, NFTA_LIMIT_FLAGS, htonl(flags)))
139                 goto nla_put_failure;
140         return 0;
141
142 nla_put_failure:
143         return -1;
144 }
145
146 static void nft_limit_destroy(const struct nft_ctx *ctx,
147                               const struct nft_limit_priv *priv)
148 {
149         kfree(priv->limit);
150 }
151
152 static int nft_limit_clone(struct nft_limit_priv *priv_dst,
153                            const struct nft_limit_priv *priv_src)
154 {
155         priv_dst->tokens_max = priv_src->tokens_max;
156         priv_dst->rate = priv_src->rate;
157         priv_dst->nsecs = priv_src->nsecs;
158         priv_dst->burst = priv_src->burst;
159         priv_dst->invert = priv_src->invert;
160
161         priv_dst->limit = kmalloc(sizeof(*priv_dst->limit), GFP_ATOMIC);
162         if (!priv_dst->limit)
163                 return -ENOMEM;
164
165         spin_lock_init(&priv_dst->limit->lock);
166         priv_dst->limit->tokens = priv_src->tokens_max;
167         priv_dst->limit->last = ktime_get_ns();
168
169         return 0;
170 }
171
172 struct nft_limit_priv_pkts {
173         struct nft_limit_priv   limit;
174         u64                     cost;
175 };
176
177 static void nft_limit_pkts_eval(const struct nft_expr *expr,
178                                 struct nft_regs *regs,
179                                 const struct nft_pktinfo *pkt)
180 {
181         struct nft_limit_priv_pkts *priv = nft_expr_priv(expr);
182
183         if (nft_limit_eval(&priv->limit, priv->cost))
184                 regs->verdict.code = NFT_BREAK;
185 }
186
187 static const struct nla_policy nft_limit_policy[NFTA_LIMIT_MAX + 1] = {
188         [NFTA_LIMIT_RATE]       = { .type = NLA_U64 },
189         [NFTA_LIMIT_UNIT]       = { .type = NLA_U64 },
190         [NFTA_LIMIT_BURST]      = { .type = NLA_U32 },
191         [NFTA_LIMIT_TYPE]       = { .type = NLA_U32 },
192         [NFTA_LIMIT_FLAGS]      = { .type = NLA_U32 },
193 };
194
195 static int nft_limit_pkts_init(const struct nft_ctx *ctx,
196                                const struct nft_expr *expr,
197                                const struct nlattr * const tb[])
198 {
199         struct nft_limit_priv_pkts *priv = nft_expr_priv(expr);
200         int err;
201
202         err = nft_limit_init(&priv->limit, tb, true);
203         if (err < 0)
204                 return err;
205
206         priv->cost = div64_u64(priv->limit.nsecs, priv->limit.rate);
207         return 0;
208 }
209
210 static int nft_limit_pkts_dump(struct sk_buff *skb, const struct nft_expr *expr)
211 {
212         const struct nft_limit_priv_pkts *priv = nft_expr_priv(expr);
213
214         return nft_limit_dump(skb, &priv->limit, NFT_LIMIT_PKTS);
215 }
216
217 static void nft_limit_pkts_destroy(const struct nft_ctx *ctx,
218                                    const struct nft_expr *expr)
219 {
220         const struct nft_limit_priv_pkts *priv = nft_expr_priv(expr);
221
222         nft_limit_destroy(ctx, &priv->limit);
223 }
224
225 static int nft_limit_pkts_clone(struct nft_expr *dst, const struct nft_expr *src)
226 {
227         struct nft_limit_priv_pkts *priv_dst = nft_expr_priv(dst);
228         struct nft_limit_priv_pkts *priv_src = nft_expr_priv(src);
229
230         priv_dst->cost = priv_src->cost;
231
232         return nft_limit_clone(&priv_dst->limit, &priv_src->limit);
233 }
234
235 static struct nft_expr_type nft_limit_type;
236 static const struct nft_expr_ops nft_limit_pkts_ops = {
237         .type           = &nft_limit_type,
238         .size           = NFT_EXPR_SIZE(sizeof(struct nft_limit_priv_pkts)),
239         .eval           = nft_limit_pkts_eval,
240         .init           = nft_limit_pkts_init,
241         .destroy        = nft_limit_pkts_destroy,
242         .clone          = nft_limit_pkts_clone,
243         .dump           = nft_limit_pkts_dump,
244         .reduce         = NFT_REDUCE_READONLY,
245 };
246
247 static void nft_limit_bytes_eval(const struct nft_expr *expr,
248                                  struct nft_regs *regs,
249                                  const struct nft_pktinfo *pkt)
250 {
251         struct nft_limit_priv *priv = nft_expr_priv(expr);
252         u64 cost = div64_u64(priv->nsecs * pkt->skb->len, priv->rate);
253
254         if (nft_limit_eval(priv, cost))
255                 regs->verdict.code = NFT_BREAK;
256 }
257
258 static int nft_limit_bytes_init(const struct nft_ctx *ctx,
259                                 const struct nft_expr *expr,
260                                 const struct nlattr * const tb[])
261 {
262         struct nft_limit_priv *priv = nft_expr_priv(expr);
263
264         return nft_limit_init(priv, tb, false);
265 }
266
267 static int nft_limit_bytes_dump(struct sk_buff *skb,
268                                 const struct nft_expr *expr)
269 {
270         const struct nft_limit_priv *priv = nft_expr_priv(expr);
271
272         return nft_limit_dump(skb, priv, NFT_LIMIT_PKT_BYTES);
273 }
274
275 static void nft_limit_bytes_destroy(const struct nft_ctx *ctx,
276                                     const struct nft_expr *expr)
277 {
278         const struct nft_limit_priv *priv = nft_expr_priv(expr);
279
280         nft_limit_destroy(ctx, priv);
281 }
282
283 static int nft_limit_bytes_clone(struct nft_expr *dst, const struct nft_expr *src)
284 {
285         struct nft_limit_priv *priv_dst = nft_expr_priv(dst);
286         struct nft_limit_priv *priv_src = nft_expr_priv(src);
287
288         return nft_limit_clone(priv_dst, priv_src);
289 }
290
291 static const struct nft_expr_ops nft_limit_bytes_ops = {
292         .type           = &nft_limit_type,
293         .size           = NFT_EXPR_SIZE(sizeof(struct nft_limit_priv)),
294         .eval           = nft_limit_bytes_eval,
295         .init           = nft_limit_bytes_init,
296         .dump           = nft_limit_bytes_dump,
297         .clone          = nft_limit_bytes_clone,
298         .destroy        = nft_limit_bytes_destroy,
299         .reduce         = NFT_REDUCE_READONLY,
300 };
301
302 static const struct nft_expr_ops *
303 nft_limit_select_ops(const struct nft_ctx *ctx,
304                      const struct nlattr * const tb[])
305 {
306         if (tb[NFTA_LIMIT_TYPE] == NULL)
307                 return &nft_limit_pkts_ops;
308
309         switch (ntohl(nla_get_be32(tb[NFTA_LIMIT_TYPE]))) {
310         case NFT_LIMIT_PKTS:
311                 return &nft_limit_pkts_ops;
312         case NFT_LIMIT_PKT_BYTES:
313                 return &nft_limit_bytes_ops;
314         }
315         return ERR_PTR(-EOPNOTSUPP);
316 }
317
318 static struct nft_expr_type nft_limit_type __read_mostly = {
319         .name           = "limit",
320         .select_ops     = nft_limit_select_ops,
321         .policy         = nft_limit_policy,
322         .maxattr        = NFTA_LIMIT_MAX,
323         .flags          = NFT_EXPR_STATEFUL,
324         .owner          = THIS_MODULE,
325 };
326
327 static void nft_limit_obj_pkts_eval(struct nft_object *obj,
328                                     struct nft_regs *regs,
329                                     const struct nft_pktinfo *pkt)
330 {
331         struct nft_limit_priv_pkts *priv = nft_obj_data(obj);
332
333         if (nft_limit_eval(&priv->limit, priv->cost))
334                 regs->verdict.code = NFT_BREAK;
335 }
336
337 static int nft_limit_obj_pkts_init(const struct nft_ctx *ctx,
338                                    const struct nlattr * const tb[],
339                                    struct nft_object *obj)
340 {
341         struct nft_limit_priv_pkts *priv = nft_obj_data(obj);
342         int err;
343
344         err = nft_limit_init(&priv->limit, tb, true);
345         if (err < 0)
346                 return err;
347
348         priv->cost = div64_u64(priv->limit.nsecs, priv->limit.rate);
349         return 0;
350 }
351
352 static int nft_limit_obj_pkts_dump(struct sk_buff *skb,
353                                    struct nft_object *obj,
354                                    bool reset)
355 {
356         const struct nft_limit_priv_pkts *priv = nft_obj_data(obj);
357
358         return nft_limit_dump(skb, &priv->limit, NFT_LIMIT_PKTS);
359 }
360
361 static void nft_limit_obj_pkts_destroy(const struct nft_ctx *ctx,
362                                        struct nft_object *obj)
363 {
364         struct nft_limit_priv_pkts *priv = nft_obj_data(obj);
365
366         nft_limit_destroy(ctx, &priv->limit);
367 }
368
369 static struct nft_object_type nft_limit_obj_type;
370 static const struct nft_object_ops nft_limit_obj_pkts_ops = {
371         .type           = &nft_limit_obj_type,
372         .size           = NFT_EXPR_SIZE(sizeof(struct nft_limit_priv_pkts)),
373         .init           = nft_limit_obj_pkts_init,
374         .destroy        = nft_limit_obj_pkts_destroy,
375         .eval           = nft_limit_obj_pkts_eval,
376         .dump           = nft_limit_obj_pkts_dump,
377 };
378
379 static void nft_limit_obj_bytes_eval(struct nft_object *obj,
380                                      struct nft_regs *regs,
381                                      const struct nft_pktinfo *pkt)
382 {
383         struct nft_limit_priv *priv = nft_obj_data(obj);
384         u64 cost = div64_u64(priv->nsecs * pkt->skb->len, priv->rate);
385
386         if (nft_limit_eval(priv, cost))
387                 regs->verdict.code = NFT_BREAK;
388 }
389
390 static int nft_limit_obj_bytes_init(const struct nft_ctx *ctx,
391                                     const struct nlattr * const tb[],
392                                     struct nft_object *obj)
393 {
394         struct nft_limit_priv *priv = nft_obj_data(obj);
395
396         return nft_limit_init(priv, tb, false);
397 }
398
399 static int nft_limit_obj_bytes_dump(struct sk_buff *skb,
400                                     struct nft_object *obj,
401                                     bool reset)
402 {
403         const struct nft_limit_priv *priv = nft_obj_data(obj);
404
405         return nft_limit_dump(skb, priv, NFT_LIMIT_PKT_BYTES);
406 }
407
408 static void nft_limit_obj_bytes_destroy(const struct nft_ctx *ctx,
409                                         struct nft_object *obj)
410 {
411         struct nft_limit_priv *priv = nft_obj_data(obj);
412
413         nft_limit_destroy(ctx, priv);
414 }
415
416 static struct nft_object_type nft_limit_obj_type;
417 static const struct nft_object_ops nft_limit_obj_bytes_ops = {
418         .type           = &nft_limit_obj_type,
419         .size           = sizeof(struct nft_limit_priv),
420         .init           = nft_limit_obj_bytes_init,
421         .destroy        = nft_limit_obj_bytes_destroy,
422         .eval           = nft_limit_obj_bytes_eval,
423         .dump           = nft_limit_obj_bytes_dump,
424 };
425
426 static const struct nft_object_ops *
427 nft_limit_obj_select_ops(const struct nft_ctx *ctx,
428                          const struct nlattr * const tb[])
429 {
430         if (!tb[NFTA_LIMIT_TYPE])
431                 return &nft_limit_obj_pkts_ops;
432
433         switch (ntohl(nla_get_be32(tb[NFTA_LIMIT_TYPE]))) {
434         case NFT_LIMIT_PKTS:
435                 return &nft_limit_obj_pkts_ops;
436         case NFT_LIMIT_PKT_BYTES:
437                 return &nft_limit_obj_bytes_ops;
438         }
439         return ERR_PTR(-EOPNOTSUPP);
440 }
441
442 static struct nft_object_type nft_limit_obj_type __read_mostly = {
443         .select_ops     = nft_limit_obj_select_ops,
444         .type           = NFT_OBJECT_LIMIT,
445         .maxattr        = NFTA_LIMIT_MAX,
446         .policy         = nft_limit_policy,
447         .owner          = THIS_MODULE,
448 };
449
450 static int __init nft_limit_module_init(void)
451 {
452         int err;
453
454         err = nft_register_obj(&nft_limit_obj_type);
455         if (err < 0)
456                 return err;
457
458         err = nft_register_expr(&nft_limit_type);
459         if (err < 0)
460                 goto err1;
461
462         return 0;
463 err1:
464         nft_unregister_obj(&nft_limit_obj_type);
465         return err;
466 }
467
468 static void __exit nft_limit_module_exit(void)
469 {
470         nft_unregister_expr(&nft_limit_type);
471         nft_unregister_obj(&nft_limit_obj_type);
472 }
473
474 module_init(nft_limit_module_init);
475 module_exit(nft_limit_module_exit);
476
477 MODULE_LICENSE("GPL");
478 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
479 MODULE_ALIAS_NFT_EXPR("limit");
480 MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_LIMIT);
481 MODULE_DESCRIPTION("nftables limit expression support");