]> git.ipfire.org Git - thirdparty/kernel/linux.git/blame - net/sched/act_api.c
tipc: purge deferredq list for each grp member in tipc_group_delete
[thirdparty/kernel/linux.git] / net / sched / act_api.c
CommitLineData
2874c5fd 1// SPDX-License-Identifier: GPL-2.0-or-later
1da177e4
LT
2/*
3 * net/sched/act_api.c Packet action API.
4 *
1da177e4 5 * Author: Jamal Hadi Salim
1da177e4
LT
6 */
7
1da177e4
LT
8#include <linux/types.h>
9#include <linux/kernel.h>
1da177e4 10#include <linux/string.h>
1da177e4 11#include <linux/errno.h>
5a0e3ad6 12#include <linux/slab.h>
1da177e4 13#include <linux/skbuff.h>
1da177e4
LT
14#include <linux/init.h>
15#include <linux/kmod.h>
ab27cfb8 16#include <linux/err.h>
3a9a231d 17#include <linux/module.h>
b854272b
DL
18#include <net/net_namespace.h>
19#include <net/sock.h>
1da177e4 20#include <net/sch_generic.h>
1045ba77 21#include <net/pkt_cls.h>
1da177e4 22#include <net/act_api.h>
dc5fc579 23#include <net/netlink.h>
1da177e4 24
db50514f
JP
25static void tcf_action_goto_chain_exec(const struct tc_action *a,
26 struct tcf_result *res)
27{
ee3bbfe8 28 const struct tcf_chain *chain = rcu_dereference_bh(a->goto_chain);
db50514f
JP
29
30 res->goto_tp = rcu_dereference_bh(chain->filter_chain);
31}
32
eec94fdb
VB
33static void tcf_free_cookie_rcu(struct rcu_head *p)
34{
35 struct tc_cookie *cookie = container_of(p, struct tc_cookie, rcu);
36
37 kfree(cookie->data);
38 kfree(cookie);
39}
40
41static void tcf_set_action_cookie(struct tc_cookie __rcu **old_cookie,
42 struct tc_cookie *new_cookie)
43{
44 struct tc_cookie *old;
45
0dbc81ea 46 old = xchg((__force struct tc_cookie **)old_cookie, new_cookie);
eec94fdb
VB
47 if (old)
48 call_rcu(&old->rcu, tcf_free_cookie_rcu);
49}
50
85d0966f
DC
51int tcf_action_check_ctrlact(int action, struct tcf_proto *tp,
52 struct tcf_chain **newchain,
53 struct netlink_ext_ack *extack)
54{
55 int opcode = TC_ACT_EXT_OPCODE(action), ret = -EINVAL;
56 u32 chain_index;
57
58 if (!opcode)
59 ret = action > TC_ACT_VALUE_MAX ? -EINVAL : 0;
60 else if (opcode <= TC_ACT_EXT_OPCODE_MAX || action == TC_ACT_UNSPEC)
61 ret = 0;
62 if (ret) {
63 NL_SET_ERR_MSG(extack, "invalid control action");
64 goto end;
65 }
66
67 if (TC_ACT_EXT_CMP(action, TC_ACT_GOTO_CHAIN)) {
68 chain_index = action & TC_ACT_EXT_VAL_MASK;
69 if (!tp || !newchain) {
70 ret = -EINVAL;
71 NL_SET_ERR_MSG(extack,
72 "can't goto NULL proto/chain");
73 goto end;
74 }
75 *newchain = tcf_chain_get_by_act(tp->chain->block, chain_index);
76 if (!*newchain) {
77 ret = -ENOMEM;
78 NL_SET_ERR_MSG(extack,
79 "can't allocate goto_chain");
80 }
81 }
82end:
83 return ret;
84}
85EXPORT_SYMBOL(tcf_action_check_ctrlact);
86
87struct tcf_chain *tcf_action_set_ctrlact(struct tc_action *a, int action,
ee3bbfe8 88 struct tcf_chain *goto_chain)
85d0966f 89{
85d0966f 90 a->tcfa_action = action;
ee3bbfe8
DC
91 rcu_swap_protected(a->goto_chain, goto_chain, 1);
92 return goto_chain;
85d0966f
DC
93}
94EXPORT_SYMBOL(tcf_action_set_ctrlact);
95
d7fb60b9
CW
96/* XXX: For standalone actions, we don't need a RCU grace period either, because
97 * actions are always connected to filters and filters are already destroyed in
98 * RCU callbacks, so after a RCU grace period actions are already disconnected
99 * from filters. Readers later can not find us.
100 */
101static void free_tcf(struct tc_action *p)
519c818e 102{
ee3bbfe8 103 struct tcf_chain *chain = rcu_dereference_protected(p->goto_chain, 1);
85d0966f 104
519c818e 105 free_percpu(p->cpu_bstats);
28169aba 106 free_percpu(p->cpu_bstats_hw);
519c818e 107 free_percpu(p->cpu_qstats);
1045ba77 108
eec94fdb 109 tcf_set_action_cookie(&p->act_cookie, NULL);
85d0966f
DC
110 if (chain)
111 tcf_chain_put_by_act(chain);
1045ba77 112
519c818e
ED
113 kfree(p);
114}
115
16af6067 116static void tcf_action_cleanup(struct tc_action *p)
e9ce1cd3 117{
16af6067
VB
118 if (p->ops->cleanup)
119 p->ops->cleanup(p);
120
1c0d32fd 121 gen_kill_estimator(&p->tcfa_rate_est);
d7fb60b9 122 free_tcf(p);
e9ce1cd3 123}
e9ce1cd3 124
16af6067
VB
125static int __tcf_action_put(struct tc_action *p, bool bind)
126{
127 struct tcf_idrinfo *idrinfo = p->idrinfo;
128
95278dda 129 if (refcount_dec_and_mutex_lock(&p->tcfa_refcnt, &idrinfo->lock)) {
16af6067
VB
130 if (bind)
131 atomic_dec(&p->tcfa_bindcnt);
132 idr_remove(&idrinfo->action_idr, p->tcfa_index);
95278dda 133 mutex_unlock(&idrinfo->lock);
16af6067
VB
134
135 tcf_action_cleanup(p);
136 return 1;
137 }
138
139 if (bind)
140 atomic_dec(&p->tcfa_bindcnt);
141
142 return 0;
143}
144
65a206c0 145int __tcf_idr_release(struct tc_action *p, bool bind, bool strict)
e9ce1cd3
DM
146{
147 int ret = 0;
148
036bb443
VB
149 /* Release with strict==1 and bind==0 is only called through act API
150 * interface (classifiers always bind). Only case when action with
151 * positive reference count and zero bind count can exist is when it was
152 * also created with act API (unbinding last classifier will destroy the
153 * action if it was created by classifier). So only case when bind count
154 * can be changed after initial check is when unbound action is
155 * destroyed by act API while classifier binds to action with same id
156 * concurrently. This result either creation of new action(same behavior
157 * as before), or reusing existing action if concurrent process
158 * increments reference count before action is deleted. Both scenarios
159 * are acceptable.
160 */
e9ce1cd3 161 if (p) {
16af6067 162 if (!bind && strict && atomic_read(&p->tcfa_bindcnt) > 0)
55334a5d 163 return -EPERM;
e9ce1cd3 164
16af6067 165 if (__tcf_action_put(p, bind))
1d4150c0 166 ret = ACT_P_DELETED;
e9ce1cd3 167 }
28e6b67f 168
e9ce1cd3
DM
169 return ret;
170}
65a206c0 171EXPORT_SYMBOL(__tcf_idr_release);
e9ce1cd3 172
4e76e75d
RM
173static size_t tcf_action_shared_attrs_size(const struct tc_action *act)
174{
e0479b67 175 struct tc_cookie *act_cookie;
4e76e75d
RM
176 u32 cookie_len = 0;
177
e0479b67
VB
178 rcu_read_lock();
179 act_cookie = rcu_dereference(act->act_cookie);
180
181 if (act_cookie)
182 cookie_len = nla_total_size(act_cookie->len);
183 rcu_read_unlock();
4e76e75d
RM
184
185 return nla_total_size(0) /* action number nested */
186 + nla_total_size(IFNAMSIZ) /* TCA_ACT_KIND */
187 + cookie_len /* TCA_ACT_COOKIE */
188 + nla_total_size(0) /* TCA_ACT_STATS nested */
189 /* TCA_STATS_BASIC */
190 + nla_total_size_64bit(sizeof(struct gnet_stats_basic))
191 /* TCA_STATS_QUEUE */
192 + nla_total_size_64bit(sizeof(struct gnet_stats_queue))
193 + nla_total_size(0) /* TCA_OPTIONS nested */
194 + nla_total_size(sizeof(struct tcf_t)); /* TCA_GACT_TM */
195}
196
197static size_t tcf_action_full_attrs_size(size_t sz)
198{
199 return NLMSG_HDRLEN /* struct nlmsghdr */
200 + sizeof(struct tcamsg)
201 + nla_total_size(0) /* TCA_ACT_TAB nested */
202 + sz;
203}
204
205static size_t tcf_action_fill_size(const struct tc_action *act)
206{
207 size_t sz = tcf_action_shared_attrs_size(act);
208
209 if (act->ops->get_fill_size)
210 return act->ops->get_fill_size(act) + sz;
211 return sz;
212}
213
65a206c0 214static int tcf_dump_walker(struct tcf_idrinfo *idrinfo, struct sk_buff *skb,
a85a970a 215 struct netlink_callback *cb)
e9ce1cd3 216{
65a206c0 217 int err = 0, index = -1, s_i = 0, n_i = 0;
90825b23 218 u32 act_flags = cb->args[2];
e62e484d 219 unsigned long jiffy_since = cb->args[3];
4b3550ef 220 struct nlattr *nest;
65a206c0
CM
221 struct idr *idr = &idrinfo->action_idr;
222 struct tc_action *p;
223 unsigned long id = 1;
e9ce1cd3 224
95278dda 225 mutex_lock(&idrinfo->lock);
e9ce1cd3
DM
226
227 s_i = cb->args[0];
228
7a457577 229 idr_for_each_entry_ul(idr, p, id) {
65a206c0
CM
230 index++;
231 if (index < s_i)
232 continue;
233
234 if (jiffy_since &&
235 time_after(jiffy_since,
236 (unsigned long)p->tcfa_tm.lastuse))
237 continue;
238
ae0be8de 239 nest = nla_nest_start_noflag(skb, n_i);
734549eb
CD
240 if (!nest) {
241 index--;
65a206c0 242 goto nla_put_failure;
734549eb 243 }
65a206c0
CM
244 err = tcf_action_dump_1(skb, p, 0, 0);
245 if (err < 0) {
246 index--;
247 nlmsg_trim(skb, nest);
248 goto done;
e9ce1cd3 249 }
65a206c0
CM
250 nla_nest_end(skb, nest);
251 n_i++;
252 if (!(act_flags & TCA_FLAG_LARGE_DUMP_ON) &&
253 n_i >= TCA_ACT_MAX_PRIO)
254 goto done;
e9ce1cd3
DM
255 }
256done:
e62e484d
JHS
257 if (index >= 0)
258 cb->args[0] = index + 1;
259
95278dda 260 mutex_unlock(&idrinfo->lock);
90825b23 261 if (n_i) {
90825b23
JHS
262 if (act_flags & TCA_FLAG_LARGE_DUMP_ON)
263 cb->args[1] = n_i;
264 }
e9ce1cd3
DM
265 return n_i;
266
7ba699c6 267nla_put_failure:
4b3550ef 268 nla_nest_cancel(skb, nest);
e9ce1cd3
DM
269 goto done;
270}
271
ec3ed293
VB
272static int tcf_idr_release_unsafe(struct tc_action *p)
273{
274 if (atomic_read(&p->tcfa_bindcnt) > 0)
275 return -EPERM;
276
277 if (refcount_dec_and_test(&p->tcfa_refcnt)) {
278 idr_remove(&p->idrinfo->action_idr, p->tcfa_index);
279 tcf_action_cleanup(p);
280 return ACT_P_DELETED;
281 }
282
283 return 0;
284}
285
65a206c0 286static int tcf_del_walker(struct tcf_idrinfo *idrinfo, struct sk_buff *skb,
a85a970a 287 const struct tc_action_ops *ops)
e9ce1cd3 288{
4b3550ef 289 struct nlattr *nest;
65a206c0 290 int n_i = 0;
55334a5d 291 int ret = -EINVAL;
65a206c0
CM
292 struct idr *idr = &idrinfo->action_idr;
293 struct tc_action *p;
294 unsigned long id = 1;
e9ce1cd3 295
ae0be8de 296 nest = nla_nest_start_noflag(skb, 0);
4b3550ef
PM
297 if (nest == NULL)
298 goto nla_put_failure;
a85a970a 299 if (nla_put_string(skb, TCA_KIND, ops->kind))
1b34ec43 300 goto nla_put_failure;
65a206c0 301
95278dda 302 mutex_lock(&idrinfo->lock);
7a457577 303 idr_for_each_entry_ul(idr, p, id) {
ec3ed293 304 ret = tcf_idr_release_unsafe(p);
65a206c0 305 if (ret == ACT_P_DELETED) {
255cd50f 306 module_put(ops->owner);
65a206c0
CM
307 n_i++;
308 } else if (ret < 0) {
95278dda 309 mutex_unlock(&idrinfo->lock);
65a206c0 310 goto nla_put_failure;
e9ce1cd3
DM
311 }
312 }
95278dda 313 mutex_unlock(&idrinfo->lock);
ec3ed293 314
1b34ec43
DM
315 if (nla_put_u32(skb, TCA_FCNT, n_i))
316 goto nla_put_failure;
4b3550ef 317 nla_nest_end(skb, nest);
e9ce1cd3
DM
318
319 return n_i;
7ba699c6 320nla_put_failure:
4b3550ef 321 nla_nest_cancel(skb, nest);
55334a5d 322 return ret;
e9ce1cd3
DM
323}
324
ddf97ccd
WC
325int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,
326 struct netlink_callback *cb, int type,
b3620145
AA
327 const struct tc_action_ops *ops,
328 struct netlink_ext_ack *extack)
e9ce1cd3 329{
65a206c0 330 struct tcf_idrinfo *idrinfo = tn->idrinfo;
ddf97ccd 331
e9ce1cd3 332 if (type == RTM_DELACTION) {
65a206c0 333 return tcf_del_walker(idrinfo, skb, ops);
e9ce1cd3 334 } else if (type == RTM_GETACTION) {
65a206c0 335 return tcf_dump_walker(idrinfo, skb, cb);
e9ce1cd3 336 } else {
b3620145
AA
337 WARN(1, "tcf_generic_walker: unknown command %d\n", type);
338 NL_SET_ERR_MSG(extack, "tcf_generic_walker: unknown command");
e9ce1cd3
DM
339 return -EINVAL;
340 }
341}
ddf97ccd 342EXPORT_SYMBOL(tcf_generic_walker);
e9ce1cd3 343
7d485c45 344int tcf_idr_search(struct tc_action_net *tn, struct tc_action **a, u32 index)
e9ce1cd3 345{
3f7c72bc
VB
346 struct tcf_idrinfo *idrinfo = tn->idrinfo;
347 struct tc_action *p;
e9ce1cd3 348
95278dda 349 mutex_lock(&idrinfo->lock);
322d884b 350 p = idr_find(&idrinfo->action_idr, index);
7d485c45 351 if (IS_ERR(p))
0190c1d4 352 p = NULL;
7d485c45 353 else if (p)
3f7c72bc 354 refcount_inc(&p->tcfa_refcnt);
95278dda 355 mutex_unlock(&idrinfo->lock);
e9ce1cd3 356
3f7c72bc
VB
357 if (p) {
358 *a = p;
359 return true;
360 }
361 return false;
e9ce1cd3 362}
65a206c0 363EXPORT_SYMBOL(tcf_idr_search);
e9ce1cd3 364
97a3f84f 365static int tcf_idr_delete_index(struct tcf_idrinfo *idrinfo, u32 index)
2a2ea349 366{
2a2ea349
VB
367 struct tc_action *p;
368 int ret = 0;
369
95278dda 370 mutex_lock(&idrinfo->lock);
2a2ea349
VB
371 p = idr_find(&idrinfo->action_idr, index);
372 if (!p) {
95278dda 373 mutex_unlock(&idrinfo->lock);
2a2ea349
VB
374 return -ENOENT;
375 }
376
377 if (!atomic_read(&p->tcfa_bindcnt)) {
378 if (refcount_dec_and_test(&p->tcfa_refcnt)) {
379 struct module *owner = p->ops->owner;
380
381 WARN_ON(p != idr_remove(&idrinfo->action_idr,
382 p->tcfa_index));
95278dda 383 mutex_unlock(&idrinfo->lock);
2a2ea349 384
16af6067 385 tcf_action_cleanup(p);
2a2ea349
VB
386 module_put(owner);
387 return 0;
388 }
389 ret = 0;
390 } else {
391 ret = -EPERM;
392 }
393
95278dda 394 mutex_unlock(&idrinfo->lock);
2a2ea349
VB
395 return ret;
396}
2a2ea349 397
65a206c0
CM
398int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
399 struct tc_action **a, const struct tc_action_ops *ops,
400 int bind, bool cpustats)
e9ce1cd3 401{
ec0595cc 402 struct tc_action *p = kzalloc(ops->size, GFP_KERNEL);
65a206c0 403 struct tcf_idrinfo *idrinfo = tn->idrinfo;
519c818e 404 int err = -ENOMEM;
e9ce1cd3
DM
405
406 if (unlikely(!p))
86062033 407 return -ENOMEM;
036bb443 408 refcount_set(&p->tcfa_refcnt, 1);
e9ce1cd3 409 if (bind)
036bb443 410 atomic_set(&p->tcfa_bindcnt, 1);
e9ce1cd3 411
519c818e
ED
412 if (cpustats) {
413 p->cpu_bstats = netdev_alloc_pcpu_stats(struct gnet_stats_basic_cpu);
339913a8 414 if (!p->cpu_bstats)
519c818e 415 goto err1;
28169aba
EC
416 p->cpu_bstats_hw = netdev_alloc_pcpu_stats(struct gnet_stats_basic_cpu);
417 if (!p->cpu_bstats_hw)
418 goto err2;
339913a8
MW
419 p->cpu_qstats = alloc_percpu(struct gnet_stats_queue);
420 if (!p->cpu_qstats)
28169aba 421 goto err3;
519c818e 422 }
ec0595cc 423 spin_lock_init(&p->tcfa_lock);
339913a8 424 p->tcfa_index = index;
ec0595cc
WC
425 p->tcfa_tm.install = jiffies;
426 p->tcfa_tm.lastuse = jiffies;
427 p->tcfa_tm.firstuse = 0;
0e991ec6 428 if (est) {
ec0595cc
WC
429 err = gen_new_estimator(&p->tcfa_bstats, p->cpu_bstats,
430 &p->tcfa_rate_est,
431 &p->tcfa_lock, NULL, est);
339913a8 432 if (err)
28169aba 433 goto err4;
0e991ec6
SH
434 }
435
65a206c0 436 p->idrinfo = idrinfo;
ec0595cc 437 p->ops = ops;
ec0595cc 438 *a = p;
86062033 439 return 0;
28169aba 440err4:
339913a8 441 free_percpu(p->cpu_qstats);
28169aba
EC
442err3:
443 free_percpu(p->cpu_bstats_hw);
339913a8
MW
444err2:
445 free_percpu(p->cpu_bstats);
446err1:
447 kfree(p);
448 return err;
e9ce1cd3 449}
65a206c0 450EXPORT_SYMBOL(tcf_idr_create);
e9ce1cd3 451
65a206c0 452void tcf_idr_insert(struct tc_action_net *tn, struct tc_action *a)
e9ce1cd3 453{
65a206c0 454 struct tcf_idrinfo *idrinfo = tn->idrinfo;
e9ce1cd3 455
95278dda 456 mutex_lock(&idrinfo->lock);
0190c1d4
VB
457 /* Replace ERR_PTR(-EBUSY) allocated by tcf_idr_check_alloc */
458 WARN_ON(!IS_ERR(idr_replace(&idrinfo->action_idr, a, a->tcfa_index)));
95278dda 459 mutex_unlock(&idrinfo->lock);
e9ce1cd3 460}
65a206c0 461EXPORT_SYMBOL(tcf_idr_insert);
1da177e4 462
0190c1d4
VB
463/* Cleanup idr index that was allocated but not initialized. */
464
465void tcf_idr_cleanup(struct tc_action_net *tn, u32 index)
466{
467 struct tcf_idrinfo *idrinfo = tn->idrinfo;
468
95278dda 469 mutex_lock(&idrinfo->lock);
0190c1d4
VB
470 /* Remove ERR_PTR(-EBUSY) allocated by tcf_idr_check_alloc */
471 WARN_ON(!IS_ERR(idr_remove(&idrinfo->action_idr, index)));
95278dda 472 mutex_unlock(&idrinfo->lock);
0190c1d4
VB
473}
474EXPORT_SYMBOL(tcf_idr_cleanup);
475
476/* Check if action with specified index exists. If actions is found, increments
477 * its reference and bind counters, and return 1. Otherwise insert temporary
478 * error pointer (to prevent concurrent users from inserting actions with same
479 * index) and return 0.
480 */
481
482int tcf_idr_check_alloc(struct tc_action_net *tn, u32 *index,
483 struct tc_action **a, int bind)
484{
485 struct tcf_idrinfo *idrinfo = tn->idrinfo;
486 struct tc_action *p;
487 int ret;
488
489again:
95278dda 490 mutex_lock(&idrinfo->lock);
0190c1d4
VB
491 if (*index) {
492 p = idr_find(&idrinfo->action_idr, *index);
493 if (IS_ERR(p)) {
494 /* This means that another process allocated
495 * index but did not assign the pointer yet.
496 */
95278dda 497 mutex_unlock(&idrinfo->lock);
0190c1d4
VB
498 goto again;
499 }
500
501 if (p) {
502 refcount_inc(&p->tcfa_refcnt);
503 if (bind)
504 atomic_inc(&p->tcfa_bindcnt);
505 *a = p;
506 ret = 1;
507 } else {
508 *a = NULL;
509 ret = idr_alloc_u32(&idrinfo->action_idr, NULL, index,
95278dda 510 *index, GFP_KERNEL);
0190c1d4
VB
511 if (!ret)
512 idr_replace(&idrinfo->action_idr,
513 ERR_PTR(-EBUSY), *index);
514 }
515 } else {
516 *index = 1;
517 *a = NULL;
518 ret = idr_alloc_u32(&idrinfo->action_idr, NULL, index,
95278dda 519 UINT_MAX, GFP_KERNEL);
0190c1d4
VB
520 if (!ret)
521 idr_replace(&idrinfo->action_idr, ERR_PTR(-EBUSY),
522 *index);
523 }
95278dda 524 mutex_unlock(&idrinfo->lock);
0190c1d4
VB
525 return ret;
526}
527EXPORT_SYMBOL(tcf_idr_check_alloc);
528
65a206c0
CM
529void tcf_idrinfo_destroy(const struct tc_action_ops *ops,
530 struct tcf_idrinfo *idrinfo)
1d4150c0 531{
65a206c0
CM
532 struct idr *idr = &idrinfo->action_idr;
533 struct tc_action *p;
534 int ret;
535 unsigned long id = 1;
1d4150c0 536
7a457577 537 idr_for_each_entry_ul(idr, p, id) {
65a206c0
CM
538 ret = __tcf_idr_release(p, false, true);
539 if (ret == ACT_P_DELETED)
540 module_put(ops->owner);
541 else if (ret < 0)
542 return;
1d4150c0 543 }
65a206c0 544 idr_destroy(&idrinfo->action_idr);
1d4150c0 545}
65a206c0 546EXPORT_SYMBOL(tcf_idrinfo_destroy);
1d4150c0 547
1f747c26 548static LIST_HEAD(act_base);
1da177e4
LT
549static DEFINE_RWLOCK(act_mod_lock);
550
ddf97ccd
WC
551int tcf_register_action(struct tc_action_ops *act,
552 struct pernet_operations *ops)
1da177e4 553{
1f747c26 554 struct tc_action_ops *a;
ddf97ccd 555 int ret;
1da177e4 556
ddf97ccd 557 if (!act->act || !act->dump || !act->init || !act->walk || !act->lookup)
76c82d7a
JHS
558 return -EINVAL;
559
ab102b80
WC
560 /* We have to register pernet ops before making the action ops visible,
561 * otherwise tcf_action_init_1() could get a partially initialized
562 * netns.
563 */
564 ret = register_pernet_subsys(ops);
565 if (ret)
566 return ret;
567
1da177e4 568 write_lock(&act_mod_lock);
1f747c26 569 list_for_each_entry(a, &act_base, head) {
eddd2cf1 570 if (act->id == a->id || (strcmp(act->kind, a->kind) == 0)) {
1da177e4 571 write_unlock(&act_mod_lock);
ab102b80 572 unregister_pernet_subsys(ops);
1da177e4
LT
573 return -EEXIST;
574 }
575 }
1f747c26 576 list_add_tail(&act->head, &act_base);
1da177e4 577 write_unlock(&act_mod_lock);
ddf97ccd 578
1da177e4
LT
579 return 0;
580}
62e3ba1b 581EXPORT_SYMBOL(tcf_register_action);
1da177e4 582
ddf97ccd
WC
583int tcf_unregister_action(struct tc_action_ops *act,
584 struct pernet_operations *ops)
1da177e4 585{
1f747c26 586 struct tc_action_ops *a;
1da177e4
LT
587 int err = -ENOENT;
588
589 write_lock(&act_mod_lock);
a792866a
ED
590 list_for_each_entry(a, &act_base, head) {
591 if (a == act) {
592 list_del(&act->head);
593 err = 0;
1da177e4 594 break;
a792866a 595 }
1da177e4
LT
596 }
597 write_unlock(&act_mod_lock);
ab102b80
WC
598 if (!err)
599 unregister_pernet_subsys(ops);
1da177e4
LT
600 return err;
601}
62e3ba1b 602EXPORT_SYMBOL(tcf_unregister_action);
1da177e4
LT
603
604/* lookup by name */
605static struct tc_action_ops *tc_lookup_action_n(char *kind)
606{
a792866a 607 struct tc_action_ops *a, *res = NULL;
1da177e4
LT
608
609 if (kind) {
610 read_lock(&act_mod_lock);
1f747c26 611 list_for_each_entry(a, &act_base, head) {
1da177e4 612 if (strcmp(kind, a->kind) == 0) {
a792866a
ED
613 if (try_module_get(a->owner))
614 res = a;
1da177e4
LT
615 break;
616 }
617 }
618 read_unlock(&act_mod_lock);
619 }
a792866a 620 return res;
1da177e4
LT
621}
622
7ba699c6
PM
623/* lookup by nlattr */
624static struct tc_action_ops *tc_lookup_action(struct nlattr *kind)
1da177e4 625{
a792866a 626 struct tc_action_ops *a, *res = NULL;
1da177e4
LT
627
628 if (kind) {
629 read_lock(&act_mod_lock);
1f747c26 630 list_for_each_entry(a, &act_base, head) {
7ba699c6 631 if (nla_strcmp(kind, a->kind) == 0) {
a792866a
ED
632 if (try_module_get(a->owner))
633 res = a;
1da177e4
LT
634 break;
635 }
636 }
637 read_unlock(&act_mod_lock);
638 }
a792866a 639 return res;
1da177e4 640}
1da177e4 641
e0ee84de
JHS
642/*TCA_ACT_MAX_PRIO is 32, there count upto 32 */
643#define TCA_ACT_MAX_PRIO_MASK 0x1FF
22dc13c8
WC
644int tcf_action_exec(struct sk_buff *skb, struct tc_action **actions,
645 int nr_actions, struct tcf_result *res)
1da177e4 646{
e0ee84de
JHS
647 u32 jmp_prgcnt = 0;
648 u32 jmp_ttl = TCA_ACT_MAX_PRIO; /*matches actions per filter */
ec1a9cca
JP
649 int i;
650 int ret = TC_ACT_OK;
1da177e4 651
e7246e12
WB
652 if (skb_skip_tc_classify(skb))
653 return TC_ACT_OK;
654
e0ee84de 655restart_act_graph:
22dc13c8
WC
656 for (i = 0; i < nr_actions; i++) {
657 const struct tc_action *a = actions[i];
658
e0ee84de
JHS
659 if (jmp_prgcnt > 0) {
660 jmp_prgcnt -= 1;
661 continue;
662 }
1da177e4 663repeat:
63acd680 664 ret = a->ops->act(skb, a, res);
63acd680
JHS
665 if (ret == TC_ACT_REPEAT)
666 goto repeat; /* we need a ttl - JHS */
e0ee84de 667
9da3242e 668 if (TC_ACT_EXT_CMP(ret, TC_ACT_JUMP)) {
e0ee84de
JHS
669 jmp_prgcnt = ret & TCA_ACT_MAX_PRIO_MASK;
670 if (!jmp_prgcnt || (jmp_prgcnt > nr_actions)) {
671 /* faulty opcode, stop pipeline */
672 return TC_ACT_OK;
673 } else {
674 jmp_ttl -= 1;
675 if (jmp_ttl > 0)
676 goto restart_act_graph;
677 else /* faulty graph, stop pipeline */
678 return TC_ACT_OK;
679 }
db50514f 680 } else if (TC_ACT_EXT_CMP(ret, TC_ACT_GOTO_CHAIN)) {
ee3bbfe8
DC
681 if (unlikely(!rcu_access_pointer(a->goto_chain))) {
682 net_warn_ratelimited("can't go to NULL chain!\n");
683 return TC_ACT_SHOT;
684 }
db50514f 685 tcf_action_goto_chain_exec(a, res);
e0ee84de
JHS
686 }
687
63acd680 688 if (ret != TC_ACT_PIPE)
e7246e12 689 break;
1da177e4 690 }
e0ee84de 691
1da177e4
LT
692 return ret;
693}
62e3ba1b 694EXPORT_SYMBOL(tcf_action_exec);
1da177e4 695
90b73b77 696int tcf_action_destroy(struct tc_action *actions[], int bind)
1da177e4 697{
255cd50f 698 const struct tc_action_ops *ops;
90b73b77
VB
699 struct tc_action *a;
700 int ret = 0, i;
1da177e4 701
90b73b77
VB
702 for (i = 0; i < TCA_ACT_MAX_PRIO && actions[i]; i++) {
703 a = actions[i];
704 actions[i] = NULL;
255cd50f 705 ops = a->ops;
65a206c0 706 ret = __tcf_idr_release(a, bind, true);
55334a5d 707 if (ret == ACT_P_DELETED)
255cd50f 708 module_put(ops->owner);
55334a5d
WC
709 else if (ret < 0)
710 return ret;
1da177e4 711 }
55334a5d 712 return ret;
1da177e4
LT
713}
714
97763dc0
PA
715static int tcf_action_destroy_1(struct tc_action *a, int bind)
716{
717 struct tc_action *actions[] = { a, NULL };
718
719 return tcf_action_destroy(actions, bind);
720}
721
16af6067
VB
722static int tcf_action_put(struct tc_action *p)
723{
724 return __tcf_action_put(p, false);
725}
726
edfaf94f 727/* Put all actions in this array, skip those NULL's. */
90b73b77 728static void tcf_action_put_many(struct tc_action *actions[])
cae422f3 729{
90b73b77 730 int i;
cae422f3 731
edfaf94f 732 for (i = 0; i < TCA_ACT_MAX_PRIO; i++) {
90b73b77 733 struct tc_action *a = actions[i];
edfaf94f 734 const struct tc_action_ops *ops;
cae422f3 735
edfaf94f
CW
736 if (!a)
737 continue;
738 ops = a->ops;
cae422f3
VB
739 if (tcf_action_put(a))
740 module_put(ops->owner);
741 }
742}
743
1da177e4
LT
744int
745tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
746{
1da177e4
LT
747 return a->ops->dump(skb, a, bind, ref);
748}
749
750int
751tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
752{
753 int err = -EINVAL;
27a884dc 754 unsigned char *b = skb_tail_pointer(skb);
4b3550ef 755 struct nlattr *nest;
eec94fdb 756 struct tc_cookie *cookie;
1da177e4 757
1b34ec43
DM
758 if (nla_put_string(skb, TCA_KIND, a->ops->kind))
759 goto nla_put_failure;
1da177e4 760 if (tcf_action_copy_stats(skb, a, 0))
7ba699c6 761 goto nla_put_failure;
eec94fdb
VB
762
763 rcu_read_lock();
764 cookie = rcu_dereference(a->act_cookie);
765 if (cookie) {
766 if (nla_put(skb, TCA_ACT_COOKIE, cookie->len, cookie->data)) {
767 rcu_read_unlock();
1045ba77 768 goto nla_put_failure;
eec94fdb 769 }
1045ba77 770 }
eec94fdb 771 rcu_read_unlock();
1045ba77 772
ae0be8de 773 nest = nla_nest_start_noflag(skb, TCA_OPTIONS);
4b3550ef
PM
774 if (nest == NULL)
775 goto nla_put_failure;
cc7ec456
ED
776 err = tcf_action_dump_old(skb, a, bind, ref);
777 if (err > 0) {
4b3550ef 778 nla_nest_end(skb, nest);
1da177e4
LT
779 return err;
780 }
781
7ba699c6 782nla_put_failure:
dc5fc579 783 nlmsg_trim(skb, b);
1da177e4
LT
784 return -1;
785}
62e3ba1b 786EXPORT_SYMBOL(tcf_action_dump_1);
1da177e4 787
90b73b77 788int tcf_action_dump(struct sk_buff *skb, struct tc_action *actions[],
0b0f43fe 789 int bind, int ref)
1da177e4
LT
790{
791 struct tc_action *a;
90b73b77 792 int err = -EINVAL, i;
4b3550ef 793 struct nlattr *nest;
1da177e4 794
90b73b77
VB
795 for (i = 0; i < TCA_ACT_MAX_PRIO && actions[i]; i++) {
796 a = actions[i];
4097e9d2 797 nest = nla_nest_start_noflag(skb, i + 1);
4b3550ef
PM
798 if (nest == NULL)
799 goto nla_put_failure;
1da177e4
LT
800 err = tcf_action_dump_1(skb, a, bind, ref);
801 if (err < 0)
4fe683f5 802 goto errout;
4b3550ef 803 nla_nest_end(skb, nest);
1da177e4
LT
804 }
805
806 return 0;
807
7ba699c6 808nla_put_failure:
4fe683f5
TG
809 err = -EINVAL;
810errout:
4b3550ef 811 nla_nest_cancel(skb, nest);
4fe683f5 812 return err;
1da177e4
LT
813}
814
e0535ce5 815static struct tc_cookie *nla_memdup_cookie(struct nlattr **tb)
1045ba77 816{
e0535ce5
WB
817 struct tc_cookie *c = kzalloc(sizeof(*c), GFP_KERNEL);
818 if (!c)
819 return NULL;
820
821 c->data = nla_memdup(tb[TCA_ACT_COOKIE], GFP_KERNEL);
822 if (!c->data) {
823 kfree(c);
824 return NULL;
1045ba77 825 }
e0535ce5 826 c->len = nla_len(tb[TCA_ACT_COOKIE]);
1045ba77 827
e0535ce5 828 return c;
1045ba77
JHS
829}
830
9fb9f251
JP
831struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
832 struct nlattr *nla, struct nlattr *est,
aea0d727 833 char *name, int ovr, int bind,
789871bb 834 bool rtnl_held,
aea0d727 835 struct netlink_ext_ack *extack)
1da177e4
LT
836{
837 struct tc_action *a;
838 struct tc_action_ops *a_o;
e0535ce5 839 struct tc_cookie *cookie = NULL;
1da177e4 840 char act_name[IFNAMSIZ];
cc7ec456 841 struct nlattr *tb[TCA_ACT_MAX + 1];
7ba699c6 842 struct nlattr *kind;
ab27cfb8 843 int err;
1da177e4 844
1da177e4 845 if (name == NULL) {
8cb08174
JB
846 err = nla_parse_nested_deprecated(tb, TCA_ACT_MAX, nla, NULL,
847 extack);
cee63723 848 if (err < 0)
1da177e4 849 goto err_out;
cee63723 850 err = -EINVAL;
7ba699c6 851 kind = tb[TCA_ACT_KIND];
84ae017a
AA
852 if (!kind) {
853 NL_SET_ERR_MSG(extack, "TC action kind must be specified");
1da177e4 854 goto err_out;
84ae017a
AA
855 }
856 if (nla_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ) {
857 NL_SET_ERR_MSG(extack, "TC action name too long");
1da177e4 858 goto err_out;
84ae017a 859 }
e0535ce5
WB
860 if (tb[TCA_ACT_COOKIE]) {
861 int cklen = nla_len(tb[TCA_ACT_COOKIE]);
862
84ae017a
AA
863 if (cklen > TC_COOKIE_MAX_SIZE) {
864 NL_SET_ERR_MSG(extack, "TC cookie size above the maximum");
e0535ce5 865 goto err_out;
84ae017a 866 }
e0535ce5
WB
867
868 cookie = nla_memdup_cookie(tb);
869 if (!cookie) {
84ae017a 870 NL_SET_ERR_MSG(extack, "No memory to generate TC cookie");
e0535ce5
WB
871 err = -ENOMEM;
872 goto err_out;
873 }
874 }
1da177e4 875 } else {
84ae017a
AA
876 if (strlcpy(act_name, name, IFNAMSIZ) >= IFNAMSIZ) {
877 NL_SET_ERR_MSG(extack, "TC action name too long");
878 err = -EINVAL;
1da177e4 879 goto err_out;
84ae017a 880 }
1da177e4
LT
881 }
882
883 a_o = tc_lookup_action_n(act_name);
884 if (a_o == NULL) {
95a5afca 885#ifdef CONFIG_MODULES
789871bb
VB
886 if (rtnl_held)
887 rtnl_unlock();
4bba3925 888 request_module("act_%s", act_name);
789871bb
VB
889 if (rtnl_held)
890 rtnl_lock();
1da177e4
LT
891
892 a_o = tc_lookup_action_n(act_name);
893
894 /* We dropped the RTNL semaphore in order to
895 * perform the module load. So, even if we
896 * succeeded in loading the module we have to
897 * tell the caller to replay the request. We
898 * indicate this using -EAGAIN.
899 */
900 if (a_o != NULL) {
ab27cfb8 901 err = -EAGAIN;
1da177e4
LT
902 goto err_mod;
903 }
904#endif
84ae017a 905 NL_SET_ERR_MSG(extack, "Failed to load TC action module");
ab27cfb8 906 err = -ENOENT;
1da177e4
LT
907 goto err_out;
908 }
909
1da177e4
LT
910 /* backward compatibility for policer */
911 if (name == NULL)
589dad6d 912 err = a_o->init(net, tb[TCA_ACT_OPTIONS], est, &a, ovr, bind,
85d0966f 913 rtnl_held, tp, extack);
1da177e4 914 else
789871bb 915 err = a_o->init(net, nla, est, &a, ovr, bind, rtnl_held,
85d0966f 916 tp, extack);
ab27cfb8 917 if (err < 0)
a85a970a 918 goto err_mod;
1da177e4 919
eec94fdb
VB
920 if (!name && tb[TCA_ACT_COOKIE])
921 tcf_set_action_cookie(&a->act_cookie, cookie);
1045ba77 922
1da177e4 923 /* module count goes up only when brand new policy is created
cc7ec456
ED
924 * if it exists and is only bound to in a_o->init() then
925 * ACT_P_CREATED is not returned (a zero is).
926 */
ab27cfb8 927 if (err != ACT_P_CREATED)
1da177e4 928 module_put(a_o->owner);
1da177e4 929
85d0966f 930 if (TC_ACT_EXT_CMP(a->tcfa_action, TC_ACT_GOTO_CHAIN) &&
ee3bbfe8 931 !rcu_access_pointer(a->goto_chain)) {
97763dc0 932 tcf_action_destroy_1(a, bind);
85d0966f 933 NL_SET_ERR_MSG(extack, "can't use goto chain with NULL chain");
97763dc0 934 return ERR_PTR(-EINVAL);
802bfb19
PA
935 }
936
1da177e4
LT
937 return a;
938
1da177e4
LT
939err_mod:
940 module_put(a_o->owner);
941err_out:
e0535ce5
WB
942 if (cookie) {
943 kfree(cookie->data);
944 kfree(cookie);
945 }
ab27cfb8 946 return ERR_PTR(err);
1da177e4
LT
947}
948
90b73b77
VB
949/* Returns numbers of initialized actions or negative error. */
950
9fb9f251
JP
951int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
952 struct nlattr *est, char *name, int ovr, int bind,
90b73b77 953 struct tc_action *actions[], size_t *attr_size,
789871bb 954 bool rtnl_held, struct netlink_ext_ack *extack)
1da177e4 955{
cc7ec456 956 struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
33be6271 957 struct tc_action *act;
4e76e75d 958 size_t sz = 0;
cee63723 959 int err;
1da177e4
LT
960 int i;
961
8cb08174
JB
962 err = nla_parse_nested_deprecated(tb, TCA_ACT_MAX_PRIO, nla, NULL,
963 extack);
cee63723 964 if (err < 0)
33be6271 965 return err;
1da177e4 966
7ba699c6 967 for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
aea0d727 968 act = tcf_action_init_1(net, tp, tb[i], est, name, ovr, bind,
789871bb 969 rtnl_held, extack);
33be6271
WC
970 if (IS_ERR(act)) {
971 err = PTR_ERR(act);
1da177e4 972 goto err;
33be6271 973 }
7ba699c6 974 act->order = i;
4e76e75d 975 sz += tcf_action_fill_size(act);
90b73b77
VB
976 /* Start from index 0 */
977 actions[i - 1] = act;
1da177e4 978 }
aecc5cef 979
4e76e75d 980 *attr_size = tcf_action_full_attrs_size(sz);
90b73b77 981 return i - 1;
1da177e4
LT
982
983err:
33be6271
WC
984 tcf_action_destroy(actions, bind);
985 return err;
1da177e4
LT
986}
987
ec0595cc 988int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *p,
1da177e4
LT
989 int compat_mode)
990{
991 int err = 0;
992 struct gnet_dump d;
10297b99 993
7eb8896d 994 if (p == NULL)
1da177e4
LT
995 goto errout;
996
997 /* compat_mode being true specifies a call that is supposed
06fe9fb4 998 * to add additional backward compatibility statistic TLVs.
1da177e4
LT
999 */
1000 if (compat_mode) {
ec0595cc 1001 if (p->type == TCA_OLD_COMPAT)
1da177e4 1002 err = gnet_stats_start_copy_compat(skb, 0,
9854518e
ND
1003 TCA_STATS,
1004 TCA_XSTATS,
ec0595cc 1005 &p->tcfa_lock, &d,
9854518e 1006 TCA_PAD);
1da177e4
LT
1007 else
1008 return 0;
1009 } else
1010 err = gnet_stats_start_copy(skb, TCA_ACT_STATS,
ec0595cc 1011 &p->tcfa_lock, &d, TCA_ACT_PAD);
1da177e4
LT
1012
1013 if (err < 0)
1014 goto errout;
1015
ec0595cc 1016 if (gnet_stats_copy_basic(NULL, &d, p->cpu_bstats, &p->tcfa_bstats) < 0 ||
28169aba
EC
1017 gnet_stats_copy_basic_hw(NULL, &d, p->cpu_bstats_hw,
1018 &p->tcfa_bstats_hw) < 0 ||
1c0d32fd 1019 gnet_stats_copy_rate_est(&d, &p->tcfa_rate_est) < 0 ||
519c818e 1020 gnet_stats_copy_queue(&d, p->cpu_qstats,
ec0595cc
WC
1021 &p->tcfa_qstats,
1022 p->tcfa_qstats.qlen) < 0)
1da177e4
LT
1023 goto errout;
1024
1025 if (gnet_stats_finish_copy(&d) < 0)
1026 goto errout;
1027
1028 return 0;
1029
1030errout:
1031 return -1;
1032}
1033
90b73b77 1034static int tca_get_fill(struct sk_buff *skb, struct tc_action *actions[],
0b0f43fe
JHS
1035 u32 portid, u32 seq, u16 flags, int event, int bind,
1036 int ref)
1da177e4
LT
1037{
1038 struct tcamsg *t;
1039 struct nlmsghdr *nlh;
27a884dc 1040 unsigned char *b = skb_tail_pointer(skb);
4b3550ef 1041 struct nlattr *nest;
1da177e4 1042
15e47304 1043 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*t), flags);
8b00a53c
DM
1044 if (!nlh)
1045 goto out_nlmsg_trim;
1046 t = nlmsg_data(nlh);
1da177e4 1047 t->tca_family = AF_UNSPEC;
9ef1d4c7
PM
1048 t->tca__pad1 = 0;
1049 t->tca__pad2 = 0;
10297b99 1050
ae0be8de 1051 nest = nla_nest_start_noflag(skb, TCA_ACT_TAB);
1af85155 1052 if (!nest)
8b00a53c 1053 goto out_nlmsg_trim;
1da177e4 1054
33be6271 1055 if (tcf_action_dump(skb, actions, bind, ref) < 0)
8b00a53c 1056 goto out_nlmsg_trim;
1da177e4 1057
4b3550ef 1058 nla_nest_end(skb, nest);
10297b99 1059
27a884dc 1060 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
1da177e4
LT
1061 return skb->len;
1062
8b00a53c 1063out_nlmsg_trim:
dc5fc579 1064 nlmsg_trim(skb, b);
1da177e4
LT
1065 return -1;
1066}
1067
1068static int
c4c4290c 1069tcf_get_notify(struct net *net, u32 portid, struct nlmsghdr *n,
90b73b77 1070 struct tc_action *actions[], int event,
84ae017a 1071 struct netlink_ext_ack *extack)
1da177e4
LT
1072{
1073 struct sk_buff *skb;
1da177e4
LT
1074
1075 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
1076 if (!skb)
1077 return -ENOBUFS;
0b0f43fe 1078 if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, event,
3f7c72bc 1079 0, 1) <= 0) {
84ae017a 1080 NL_SET_ERR_MSG(extack, "Failed to fill netlink attributes while adding TC action");
1da177e4
LT
1081 kfree_skb(skb);
1082 return -EINVAL;
1083 }
2942e900 1084
15e47304 1085 return rtnl_unicast(skb, net, portid);
1da177e4
LT
1086}
1087
ddf97ccd 1088static struct tc_action *tcf_action_get_1(struct net *net, struct nlattr *nla,
84ae017a
AA
1089 struct nlmsghdr *n, u32 portid,
1090 struct netlink_ext_ack *extack)
1da177e4 1091{
cc7ec456 1092 struct nlattr *tb[TCA_ACT_MAX + 1];
a85a970a 1093 const struct tc_action_ops *ops;
1da177e4
LT
1094 struct tc_action *a;
1095 int index;
ab27cfb8 1096 int err;
1da177e4 1097
8cb08174 1098 err = nla_parse_nested_deprecated(tb, TCA_ACT_MAX, nla, NULL, extack);
cee63723 1099 if (err < 0)
ab27cfb8 1100 goto err_out;
1da177e4 1101
cee63723 1102 err = -EINVAL;
7ba699c6 1103 if (tb[TCA_ACT_INDEX] == NULL ||
84ae017a
AA
1104 nla_len(tb[TCA_ACT_INDEX]) < sizeof(index)) {
1105 NL_SET_ERR_MSG(extack, "Invalid TC action index value");
ab27cfb8 1106 goto err_out;
84ae017a 1107 }
1587bac4 1108 index = nla_get_u32(tb[TCA_ACT_INDEX]);
1da177e4 1109
ab27cfb8 1110 err = -EINVAL;
a85a970a 1111 ops = tc_lookup_action(tb[TCA_ACT_KIND]);
84ae017a 1112 if (!ops) { /* could happen in batch of actions */
f061b48c 1113 NL_SET_ERR_MSG(extack, "Specified TC action kind not found");
a85a970a 1114 goto err_out;
84ae017a 1115 }
ab27cfb8 1116 err = -ENOENT;
f061b48c
CW
1117 if (ops->lookup(net, &a, index) == 0) {
1118 NL_SET_ERR_MSG(extack, "TC action with specified index not found");
1da177e4 1119 goto err_mod;
f061b48c 1120 }
1da177e4 1121
a85a970a 1122 module_put(ops->owner);
1da177e4 1123 return a;
ab27cfb8 1124
1da177e4 1125err_mod:
a85a970a 1126 module_put(ops->owner);
ab27cfb8
PM
1127err_out:
1128 return ERR_PTR(err);
1da177e4
LT
1129}
1130
7316ae88 1131static int tca_action_flush(struct net *net, struct nlattr *nla,
84ae017a
AA
1132 struct nlmsghdr *n, u32 portid,
1133 struct netlink_ext_ack *extack)
1da177e4
LT
1134{
1135 struct sk_buff *skb;
1136 unsigned char *b;
1137 struct nlmsghdr *nlh;
1138 struct tcamsg *t;
1139 struct netlink_callback dcb;
4b3550ef 1140 struct nlattr *nest;
cc7ec456 1141 struct nlattr *tb[TCA_ACT_MAX + 1];
a85a970a 1142 const struct tc_action_ops *ops;
7ba699c6 1143 struct nlattr *kind;
36723873 1144 int err = -ENOMEM;
1da177e4 1145
1da177e4 1146 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
84ae017a 1147 if (!skb)
36723873 1148 return err;
1da177e4 1149
27a884dc 1150 b = skb_tail_pointer(skb);
1da177e4 1151
8cb08174 1152 err = nla_parse_nested_deprecated(tb, TCA_ACT_MAX, nla, NULL, extack);
cee63723 1153 if (err < 0)
1da177e4
LT
1154 goto err_out;
1155
cee63723 1156 err = -EINVAL;
7ba699c6 1157 kind = tb[TCA_ACT_KIND];
a85a970a 1158 ops = tc_lookup_action(kind);
84ae017a
AA
1159 if (!ops) { /*some idjot trying to flush unknown action */
1160 NL_SET_ERR_MSG(extack, "Cannot flush unknown TC action");
1da177e4 1161 goto err_out;
84ae017a 1162 }
1da177e4 1163
0b0f43fe
JHS
1164 nlh = nlmsg_put(skb, portid, n->nlmsg_seq, RTM_DELACTION,
1165 sizeof(*t), 0);
84ae017a
AA
1166 if (!nlh) {
1167 NL_SET_ERR_MSG(extack, "Failed to create TC action flush notification");
8b00a53c 1168 goto out_module_put;
84ae017a 1169 }
8b00a53c 1170 t = nlmsg_data(nlh);
1da177e4 1171 t->tca_family = AF_UNSPEC;
9ef1d4c7
PM
1172 t->tca__pad1 = 0;
1173 t->tca__pad2 = 0;
1da177e4 1174
ae0be8de 1175 nest = nla_nest_start_noflag(skb, TCA_ACT_TAB);
84ae017a
AA
1176 if (!nest) {
1177 NL_SET_ERR_MSG(extack, "Failed to add new netlink message");
8b00a53c 1178 goto out_module_put;
84ae017a 1179 }
1da177e4 1180
41780105 1181 err = ops->walk(net, skb, &dcb, RTM_DELACTION, ops, extack);
66dede2d
DC
1182 if (err <= 0) {
1183 nla_nest_cancel(skb, nest);
8b00a53c 1184 goto out_module_put;
66dede2d 1185 }
1da177e4 1186
4b3550ef 1187 nla_nest_end(skb, nest);
1da177e4 1188
27a884dc 1189 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
1da177e4 1190 nlh->nlmsg_flags |= NLM_F_ROOT;
a85a970a 1191 module_put(ops->owner);
15e47304 1192 err = rtnetlink_send(skb, net, portid, RTNLGRP_TC,
cc7ec456 1193 n->nlmsg_flags & NLM_F_ECHO);
1da177e4
LT
1194 if (err > 0)
1195 return 0;
84ae017a
AA
1196 if (err < 0)
1197 NL_SET_ERR_MSG(extack, "Failed to send TC action flush notification");
1da177e4
LT
1198
1199 return err;
1200
8b00a53c 1201out_module_put:
a85a970a 1202 module_put(ops->owner);
1da177e4
LT
1203err_out:
1204 kfree_skb(skb);
1da177e4
LT
1205 return err;
1206}
1207
b144e7ec 1208static int tcf_action_delete(struct net *net, struct tc_action *actions[])
16af6067 1209{
97a3f84f 1210 int i;
16af6067 1211
90b73b77
VB
1212 for (i = 0; i < TCA_ACT_MAX_PRIO && actions[i]; i++) {
1213 struct tc_action *a = actions[i];
16af6067 1214 const struct tc_action_ops *ops = a->ops;
16af6067
VB
1215 /* Actions can be deleted concurrently so we must save their
1216 * type and id to search again after reference is released.
1217 */
97a3f84f
CW
1218 struct tcf_idrinfo *idrinfo = a->idrinfo;
1219 u32 act_index = a->tcfa_index;
16af6067 1220
c10bbfae 1221 actions[i] = NULL;
16af6067
VB
1222 if (tcf_action_put(a)) {
1223 /* last reference, action was deleted concurrently */
1224 module_put(ops->owner);
1225 } else {
97a3f84f
CW
1226 int ret;
1227
16af6067 1228 /* now do the delete */
97a3f84f 1229 ret = tcf_idr_delete_index(idrinfo, act_index);
edfaf94f 1230 if (ret < 0)
16af6067
VB
1231 return ret;
1232 }
1233 }
1234 return 0;
1235}
1236
a56e1953 1237static int
90b73b77 1238tcf_del_notify(struct net *net, struct nlmsghdr *n, struct tc_action *actions[],
edfaf94f 1239 u32 portid, size_t attr_size, struct netlink_ext_ack *extack)
a56e1953
WC
1240{
1241 int ret;
1242 struct sk_buff *skb;
1243
d04e6990
RM
1244 skb = alloc_skb(attr_size <= NLMSG_GOODSIZE ? NLMSG_GOODSIZE : attr_size,
1245 GFP_KERNEL);
a56e1953
WC
1246 if (!skb)
1247 return -ENOBUFS;
1248
1249 if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, RTM_DELACTION,
3f7c72bc 1250 0, 2) <= 0) {
84ae017a 1251 NL_SET_ERR_MSG(extack, "Failed to fill netlink TC action attributes");
a56e1953
WC
1252 kfree_skb(skb);
1253 return -EINVAL;
1254 }
1255
1256 /* now do the delete */
b144e7ec 1257 ret = tcf_action_delete(net, actions);
55334a5d 1258 if (ret < 0) {
84ae017a 1259 NL_SET_ERR_MSG(extack, "Failed to delete TC action");
55334a5d
WC
1260 kfree_skb(skb);
1261 return ret;
1262 }
a56e1953
WC
1263
1264 ret = rtnetlink_send(skb, net, portid, RTNLGRP_TC,
1265 n->nlmsg_flags & NLM_F_ECHO);
1266 if (ret > 0)
1267 return 0;
1268 return ret;
1269}
1270
1da177e4 1271static int
7316ae88 1272tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
84ae017a 1273 u32 portid, int event, struct netlink_ext_ack *extack)
1da177e4 1274{
cee63723 1275 int i, ret;
cc7ec456 1276 struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
33be6271 1277 struct tc_action *act;
d04e6990 1278 size_t attr_size = 0;
edfaf94f 1279 struct tc_action *actions[TCA_ACT_MAX_PRIO] = {};
1da177e4 1280
8cb08174
JB
1281 ret = nla_parse_nested_deprecated(tb, TCA_ACT_MAX_PRIO, nla, NULL,
1282 extack);
cee63723
PM
1283 if (ret < 0)
1284 return ret;
1da177e4 1285
cc7ec456 1286 if (event == RTM_DELACTION && n->nlmsg_flags & NLM_F_ROOT) {
1af85155 1287 if (tb[1])
84ae017a 1288 return tca_action_flush(net, tb[1], n, portid, extack);
1af85155 1289
84ae017a 1290 NL_SET_ERR_MSG(extack, "Invalid netlink attributes while flushing TC action");
1af85155 1291 return -EINVAL;
1da177e4
LT
1292 }
1293
7ba699c6 1294 for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
84ae017a 1295 act = tcf_action_get_1(net, tb[i], n, portid, extack);
ab27cfb8
PM
1296 if (IS_ERR(act)) {
1297 ret = PTR_ERR(act);
1da177e4 1298 goto err;
ab27cfb8 1299 }
4e76e75d 1300 attr_size += tcf_action_fill_size(act);
90b73b77 1301 actions[i - 1] = act;
1da177e4 1302 }
4e76e75d
RM
1303
1304 attr_size = tcf_action_full_attrs_size(attr_size);
1da177e4
LT
1305
1306 if (event == RTM_GETACTION)
90b73b77 1307 ret = tcf_get_notify(net, portid, n, actions, event, extack);
1da177e4 1308 else { /* delete */
edfaf94f 1309 ret = tcf_del_notify(net, n, actions, portid, attr_size, extack);
a56e1953 1310 if (ret)
1da177e4 1311 goto err;
edfaf94f 1312 return 0;
1da177e4
LT
1313 }
1314err:
edfaf94f 1315 tcf_action_put_many(actions);
1da177e4
LT
1316 return ret;
1317}
1318
a56e1953 1319static int
90b73b77 1320tcf_add_notify(struct net *net, struct nlmsghdr *n, struct tc_action *actions[],
d04e6990 1321 u32 portid, size_t attr_size, struct netlink_ext_ack *extack)
1da177e4 1322{
1da177e4 1323 struct sk_buff *skb;
1da177e4
LT
1324 int err = 0;
1325
d04e6990
RM
1326 skb = alloc_skb(attr_size <= NLMSG_GOODSIZE ? NLMSG_GOODSIZE : attr_size,
1327 GFP_KERNEL);
1da177e4
LT
1328 if (!skb)
1329 return -ENOBUFS;
1330
a56e1953
WC
1331 if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, n->nlmsg_flags,
1332 RTM_NEWACTION, 0, 0) <= 0) {
d143b9e3 1333 NL_SET_ERR_MSG(extack, "Failed to fill netlink attributes while adding TC action");
a56e1953
WC
1334 kfree_skb(skb);
1335 return -EINVAL;
1336 }
10297b99 1337
a56e1953
WC
1338 err = rtnetlink_send(skb, net, portid, RTNLGRP_TC,
1339 n->nlmsg_flags & NLM_F_ECHO);
1da177e4
LT
1340 if (err > 0)
1341 err = 0;
1342 return err;
1da177e4
LT
1343}
1344
5a7a5555 1345static int tcf_action_add(struct net *net, struct nlattr *nla,
aea0d727
AA
1346 struct nlmsghdr *n, u32 portid, int ovr,
1347 struct netlink_ext_ack *extack)
1da177e4 1348{
d04e6990 1349 size_t attr_size = 0;
1da177e4 1350 int ret = 0;
90b73b77 1351 struct tc_action *actions[TCA_ACT_MAX_PRIO] = {};
1da177e4 1352
90b73b77 1353 ret = tcf_action_init(net, NULL, nla, NULL, NULL, ovr, 0, actions,
789871bb 1354 &attr_size, true, extack);
90b73b77 1355 if (ret < 0)
f07fed82 1356 return ret;
90b73b77 1357 ret = tcf_add_notify(net, n, actions, portid, attr_size, extack);
cae422f3 1358 if (ovr)
90b73b77 1359 tcf_action_put_many(actions);
1da177e4 1360
cae422f3 1361 return ret;
1da177e4
LT
1362}
1363
90825b23
JHS
1364static u32 tcaa_root_flags_allowed = TCA_FLAG_LARGE_DUMP_ON;
1365static const struct nla_policy tcaa_policy[TCA_ROOT_MAX + 1] = {
1366 [TCA_ROOT_FLAGS] = { .type = NLA_BITFIELD32,
1367 .validation_data = &tcaa_root_flags_allowed },
e62e484d 1368 [TCA_ROOT_TIME_DELTA] = { .type = NLA_U32 },
90825b23
JHS
1369};
1370
c21ef3e3
DA
1371static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
1372 struct netlink_ext_ack *extack)
1da177e4 1373{
3b1e0a65 1374 struct net *net = sock_net(skb->sk);
90825b23 1375 struct nlattr *tca[TCA_ROOT_MAX + 1];
15e47304 1376 u32 portid = skb ? NETLINK_CB(skb).portid : 0;
1da177e4
LT
1377 int ret = 0, ovr = 0;
1378
0b0f43fe
JHS
1379 if ((n->nlmsg_type != RTM_GETACTION) &&
1380 !netlink_capable(skb, CAP_NET_ADMIN))
dfc47ef8
EB
1381 return -EPERM;
1382
8cb08174
JB
1383 ret = nlmsg_parse_deprecated(n, sizeof(struct tcamsg), tca,
1384 TCA_ROOT_MAX, NULL, extack);
7ba699c6
PM
1385 if (ret < 0)
1386 return ret;
1387
1388 if (tca[TCA_ACT_TAB] == NULL) {
84ae017a 1389 NL_SET_ERR_MSG(extack, "Netlink action attributes missing");
1da177e4
LT
1390 return -EINVAL;
1391 }
1392
cc7ec456 1393 /* n->nlmsg_flags & NLM_F_CREATE */
1da177e4
LT
1394 switch (n->nlmsg_type) {
1395 case RTM_NEWACTION:
1396 /* we are going to assume all other flags
25985edc 1397 * imply create only if it doesn't exist
1da177e4
LT
1398 * Note that CREATE | EXCL implies that
1399 * but since we want avoid ambiguity (eg when flags
1400 * is zero) then just set this
1401 */
cc7ec456 1402 if (n->nlmsg_flags & NLM_F_REPLACE)
1da177e4
LT
1403 ovr = 1;
1404replay:
aea0d727
AA
1405 ret = tcf_action_add(net, tca[TCA_ACT_TAB], n, portid, ovr,
1406 extack);
1da177e4
LT
1407 if (ret == -EAGAIN)
1408 goto replay;
1409 break;
1410 case RTM_DELACTION:
7316ae88 1411 ret = tca_action_gd(net, tca[TCA_ACT_TAB], n,
84ae017a 1412 portid, RTM_DELACTION, extack);
1da177e4
LT
1413 break;
1414 case RTM_GETACTION:
7316ae88 1415 ret = tca_action_gd(net, tca[TCA_ACT_TAB], n,
84ae017a 1416 portid, RTM_GETACTION, extack);
1da177e4
LT
1417 break;
1418 default:
1419 BUG();
1420 }
1421
1422 return ret;
1423}
1424
90825b23 1425static struct nlattr *find_dump_kind(struct nlattr **nla)
1da177e4 1426{
cc7ec456 1427 struct nlattr *tb1, *tb2[TCA_ACT_MAX + 1];
7ba699c6 1428 struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
7ba699c6 1429 struct nlattr *kind;
1da177e4 1430
7ba699c6 1431 tb1 = nla[TCA_ACT_TAB];
1da177e4
LT
1432 if (tb1 == NULL)
1433 return NULL;
1434
8cb08174 1435 if (nla_parse_deprecated(tb, TCA_ACT_MAX_PRIO, nla_data(tb1), NLMSG_ALIGN(nla_len(tb1)), NULL, NULL) < 0)
1da177e4 1436 return NULL;
1da177e4 1437
6d834e04
PM
1438 if (tb[1] == NULL)
1439 return NULL;
8cb08174 1440 if (nla_parse_nested_deprecated(tb2, TCA_ACT_MAX, tb[1], NULL, NULL) < 0)
1da177e4 1441 return NULL;
7ba699c6 1442 kind = tb2[TCA_ACT_KIND];
1da177e4 1443
26dab893 1444 return kind;
1da177e4
LT
1445}
1446
5a7a5555 1447static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
1da177e4 1448{
ddf97ccd 1449 struct net *net = sock_net(skb->sk);
1da177e4 1450 struct nlmsghdr *nlh;
27a884dc 1451 unsigned char *b = skb_tail_pointer(skb);
4b3550ef 1452 struct nlattr *nest;
1da177e4 1453 struct tc_action_ops *a_o;
1da177e4 1454 int ret = 0;
8b00a53c 1455 struct tcamsg *t = (struct tcamsg *) nlmsg_data(cb->nlh);
90825b23
JHS
1456 struct nlattr *tb[TCA_ROOT_MAX + 1];
1457 struct nlattr *count_attr = NULL;
e62e484d 1458 unsigned long jiffy_since = 0;
90825b23
JHS
1459 struct nlattr *kind = NULL;
1460 struct nla_bitfield32 bf;
e62e484d 1461 u32 msecs_since = 0;
90825b23
JHS
1462 u32 act_count = 0;
1463
8cb08174
JB
1464 ret = nlmsg_parse_deprecated(cb->nlh, sizeof(struct tcamsg), tb,
1465 TCA_ROOT_MAX, tcaa_policy, cb->extack);
90825b23
JHS
1466 if (ret < 0)
1467 return ret;
1da177e4 1468
90825b23 1469 kind = find_dump_kind(tb);
1da177e4 1470 if (kind == NULL) {
6ff9c364 1471 pr_info("tc_dump_action: action bad kind\n");
1da177e4
LT
1472 return 0;
1473 }
1474
26dab893 1475 a_o = tc_lookup_action(kind);
cc7ec456 1476 if (a_o == NULL)
1da177e4 1477 return 0;
1da177e4 1478
90825b23
JHS
1479 cb->args[2] = 0;
1480 if (tb[TCA_ROOT_FLAGS]) {
1481 bf = nla_get_bitfield32(tb[TCA_ROOT_FLAGS]);
1482 cb->args[2] = bf.value;
1483 }
1484
e62e484d
JHS
1485 if (tb[TCA_ROOT_TIME_DELTA]) {
1486 msecs_since = nla_get_u32(tb[TCA_ROOT_TIME_DELTA]);
1487 }
1488
15e47304 1489 nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
8b00a53c
DM
1490 cb->nlh->nlmsg_type, sizeof(*t), 0);
1491 if (!nlh)
1492 goto out_module_put;
90825b23 1493
e62e484d
JHS
1494 if (msecs_since)
1495 jiffy_since = jiffies - msecs_to_jiffies(msecs_since);
1496
8b00a53c 1497 t = nlmsg_data(nlh);
1da177e4 1498 t->tca_family = AF_UNSPEC;
9ef1d4c7
PM
1499 t->tca__pad1 = 0;
1500 t->tca__pad2 = 0;
e62e484d 1501 cb->args[3] = jiffy_since;
90825b23
JHS
1502 count_attr = nla_reserve(skb, TCA_ROOT_COUNT, sizeof(u32));
1503 if (!count_attr)
1504 goto out_module_put;
1da177e4 1505
ae0be8de 1506 nest = nla_nest_start_noflag(skb, TCA_ACT_TAB);
4b3550ef 1507 if (nest == NULL)
8b00a53c 1508 goto out_module_put;
1da177e4 1509
41780105 1510 ret = a_o->walk(net, skb, cb, RTM_GETACTION, a_o, NULL);
1da177e4 1511 if (ret < 0)
8b00a53c 1512 goto out_module_put;
1da177e4
LT
1513
1514 if (ret > 0) {
4b3550ef 1515 nla_nest_end(skb, nest);
1da177e4 1516 ret = skb->len;
90825b23
JHS
1517 act_count = cb->args[1];
1518 memcpy(nla_data(count_attr), &act_count, sizeof(u32));
1519 cb->args[1] = 0;
1da177e4 1520 } else
ebecaa66 1521 nlmsg_trim(skb, b);
1da177e4 1522
27a884dc 1523 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
15e47304 1524 if (NETLINK_CB(cb->skb).portid && ret)
1da177e4
LT
1525 nlh->nlmsg_flags |= NLM_F_MULTI;
1526 module_put(a_o->owner);
1527 return skb->len;
1528
8b00a53c 1529out_module_put:
1da177e4 1530 module_put(a_o->owner);
dc5fc579 1531 nlmsg_trim(skb, b);
1da177e4
LT
1532 return skb->len;
1533}
1534
1535static int __init tc_action_init(void)
1536{
b97bac64
FW
1537 rtnl_register(PF_UNSPEC, RTM_NEWACTION, tc_ctl_action, NULL, 0);
1538 rtnl_register(PF_UNSPEC, RTM_DELACTION, tc_ctl_action, NULL, 0);
c7ac8679 1539 rtnl_register(PF_UNSPEC, RTM_GETACTION, tc_ctl_action, tc_dump_action,
b97bac64 1540 0);
1da177e4 1541
1da177e4
LT
1542 return 0;
1543}
1544
1545subsys_initcall(tc_action_init);