act_api.c 36.8 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0-or-later
L
Linus Torvalds 已提交
2 3 4 5 6 7 8 9 10 11
/*
 * net/sched/act_api.c	Packet action API.
 *
 * Author:	Jamal Hadi Salim
 */

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/errno.h>
12
#include <linux/slab.h>
L
Linus Torvalds 已提交
13 14 15
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/kmod.h>
16
#include <linux/err.h>
17
#include <linux/module.h>
18 19
#include <net/net_namespace.h>
#include <net/sock.h>
L
Linus Torvalds 已提交
20
#include <net/sch_generic.h>
21
#include <net/pkt_cls.h>
L
Linus Torvalds 已提交
22
#include <net/act_api.h>
23
#include <net/netlink.h>
L
Linus Torvalds 已提交
24

25 26 27
static void tcf_action_goto_chain_exec(const struct tc_action *a,
				       struct tcf_result *res)
{
28
	const struct tcf_chain *chain = rcu_dereference_bh(a->goto_chain);
29 30 31 32

	res->goto_tp = rcu_dereference_bh(chain->filter_chain);
}

33 34 35 36 37 38 39 40 41 42 43 44 45
static void tcf_free_cookie_rcu(struct rcu_head *p)
{
	struct tc_cookie *cookie = container_of(p, struct tc_cookie, rcu);

	kfree(cookie->data);
	kfree(cookie);
}

static void tcf_set_action_cookie(struct tc_cookie __rcu **old_cookie,
				  struct tc_cookie *new_cookie)
{
	struct tc_cookie *old;

46
	old = xchg((__force struct tc_cookie **)old_cookie, new_cookie);
47 48 49 50
	if (old)
		call_rcu(&old->rcu, tcf_free_cookie_rcu);
}

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
int tcf_action_check_ctrlact(int action, struct tcf_proto *tp,
			     struct tcf_chain **newchain,
			     struct netlink_ext_ack *extack)
{
	int opcode = TC_ACT_EXT_OPCODE(action), ret = -EINVAL;
	u32 chain_index;

	if (!opcode)
		ret = action > TC_ACT_VALUE_MAX ? -EINVAL : 0;
	else if (opcode <= TC_ACT_EXT_OPCODE_MAX || action == TC_ACT_UNSPEC)
		ret = 0;
	if (ret) {
		NL_SET_ERR_MSG(extack, "invalid control action");
		goto end;
	}

	if (TC_ACT_EXT_CMP(action, TC_ACT_GOTO_CHAIN)) {
		chain_index = action & TC_ACT_EXT_VAL_MASK;
		if (!tp || !newchain) {
			ret = -EINVAL;
			NL_SET_ERR_MSG(extack,
				       "can't goto NULL proto/chain");
			goto end;
		}
		*newchain = tcf_chain_get_by_act(tp->chain->block, chain_index);
		if (!*newchain) {
			ret = -ENOMEM;
			NL_SET_ERR_MSG(extack,
				       "can't allocate goto_chain");
		}
	}
end:
	return ret;
}
EXPORT_SYMBOL(tcf_action_check_ctrlact);

struct tcf_chain *tcf_action_set_ctrlact(struct tc_action *a, int action,
88
					 struct tcf_chain *goto_chain)
89 90
{
	a->tcfa_action = action;
91 92
	rcu_swap_protected(a->goto_chain, goto_chain, 1);
	return goto_chain;
93 94 95
}
EXPORT_SYMBOL(tcf_action_set_ctrlact);

C
Cong Wang 已提交
96 97 98 99 100 101
/* XXX: For standalone actions, we don't need a RCU grace period either, because
 * actions are always connected to filters and filters are already destroyed in
 * RCU callbacks, so after a RCU grace period actions are already disconnected
 * from filters. Readers later can not find us.
 */
static void free_tcf(struct tc_action *p)
102
{
103
	struct tcf_chain *chain = rcu_dereference_protected(p->goto_chain, 1);
104

105
	free_percpu(p->cpu_bstats);
106
	free_percpu(p->cpu_bstats_hw);
107
	free_percpu(p->cpu_qstats);
108

109
	tcf_set_action_cookie(&p->act_cookie, NULL);
110 111
	if (chain)
		tcf_chain_put_by_act(chain);
112

113 114 115
	kfree(p);
}

116
static void tcf_action_cleanup(struct tc_action *p)
117
{
118 119 120
	if (p->ops->cleanup)
		p->ops->cleanup(p);

121
	gen_kill_estimator(&p->tcfa_rate_est);
C
Cong Wang 已提交
122
	free_tcf(p);
123 124
}

125 126 127 128
static int __tcf_action_put(struct tc_action *p, bool bind)
{
	struct tcf_idrinfo *idrinfo = p->idrinfo;

129
	if (refcount_dec_and_mutex_lock(&p->tcfa_refcnt, &idrinfo->lock)) {
130 131 132
		if (bind)
			atomic_dec(&p->tcfa_bindcnt);
		idr_remove(&idrinfo->action_idr, p->tcfa_index);
133
		mutex_unlock(&idrinfo->lock);
134 135 136 137 138 139 140 141 142 143 144

		tcf_action_cleanup(p);
		return 1;
	}

	if (bind)
		atomic_dec(&p->tcfa_bindcnt);

	return 0;
}

145
int __tcf_idr_release(struct tc_action *p, bool bind, bool strict)
146 147 148
{
	int ret = 0;

149 150 151 152 153 154 155 156 157 158 159 160
	/* Release with strict==1 and bind==0 is only called through act API
	 * interface (classifiers always bind). Only case when action with
	 * positive reference count and zero bind count can exist is when it was
	 * also created with act API (unbinding last classifier will destroy the
	 * action if it was created by classifier). So only case when bind count
	 * can be changed after initial check is when unbound action is
	 * destroyed by act API while classifier binds to action with same id
	 * concurrently. This result either creation of new action(same behavior
	 * as before), or reusing existing action if concurrent process
	 * increments reference count before action is deleted. Both scenarios
	 * are acceptable.
	 */
161
	if (p) {
162
		if (!bind && strict && atomic_read(&p->tcfa_bindcnt) > 0)
163
			return -EPERM;
164

165
		if (__tcf_action_put(p, bind))
166
			ret = ACT_P_DELETED;
167
	}
168

169 170
	return ret;
}
171
EXPORT_SYMBOL(__tcf_idr_release);
172

173 174
static size_t tcf_action_shared_attrs_size(const struct tc_action *act)
{
175
	struct tc_cookie *act_cookie;
176 177
	u32 cookie_len = 0;

178 179 180 181 182 183
	rcu_read_lock();
	act_cookie = rcu_dereference(act->act_cookie);

	if (act_cookie)
		cookie_len = nla_total_size(act_cookie->len);
	rcu_read_unlock();
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213

	return  nla_total_size(0) /* action number nested */
		+ nla_total_size(IFNAMSIZ) /* TCA_ACT_KIND */
		+ cookie_len /* TCA_ACT_COOKIE */
		+ nla_total_size(0) /* TCA_ACT_STATS nested */
		/* TCA_STATS_BASIC */
		+ nla_total_size_64bit(sizeof(struct gnet_stats_basic))
		/* TCA_STATS_QUEUE */
		+ nla_total_size_64bit(sizeof(struct gnet_stats_queue))
		+ nla_total_size(0) /* TCA_OPTIONS nested */
		+ nla_total_size(sizeof(struct tcf_t)); /* TCA_GACT_TM */
}

static size_t tcf_action_full_attrs_size(size_t sz)
{
	return NLMSG_HDRLEN                     /* struct nlmsghdr */
		+ sizeof(struct tcamsg)
		+ nla_total_size(0)             /* TCA_ACT_TAB nested */
		+ sz;
}

static size_t tcf_action_fill_size(const struct tc_action *act)
{
	size_t sz = tcf_action_shared_attrs_size(act);

	if (act->ops->get_fill_size)
		return act->ops->get_fill_size(act) + sz;
	return sz;
}

214
static int tcf_dump_walker(struct tcf_idrinfo *idrinfo, struct sk_buff *skb,
215
			   struct netlink_callback *cb)
216
{
217
	int err = 0, index = -1, s_i = 0, n_i = 0;
218
	u32 act_flags = cb->args[2];
219
	unsigned long jiffy_since = cb->args[3];
220
	struct nlattr *nest;
221 222 223
	struct idr *idr = &idrinfo->action_idr;
	struct tc_action *p;
	unsigned long id = 1;
224
	unsigned long tmp;
225

226
	mutex_lock(&idrinfo->lock);
227 228 229

	s_i = cb->args[0];

230
	idr_for_each_entry_ul(idr, p, tmp, id) {
231 232 233 234 235 236 237 238 239
		index++;
		if (index < s_i)
			continue;

		if (jiffy_since &&
		    time_after(jiffy_since,
			       (unsigned long)p->tcfa_tm.lastuse))
			continue;

240
		nest = nla_nest_start_noflag(skb, n_i);
241 242
		if (!nest) {
			index--;
243
			goto nla_put_failure;
244
		}
245 246 247 248 249
		err = tcf_action_dump_1(skb, p, 0, 0);
		if (err < 0) {
			index--;
			nlmsg_trim(skb, nest);
			goto done;
250
		}
251 252 253 254 255
		nla_nest_end(skb, nest);
		n_i++;
		if (!(act_flags & TCA_FLAG_LARGE_DUMP_ON) &&
		    n_i >= TCA_ACT_MAX_PRIO)
			goto done;
256 257
	}
done:
258 259 260
	if (index >= 0)
		cb->args[0] = index + 1;

261
	mutex_unlock(&idrinfo->lock);
262 263 264 265
	if (n_i) {
		if (act_flags & TCA_FLAG_LARGE_DUMP_ON)
			cb->args[1] = n_i;
	}
266 267
	return n_i;

268
nla_put_failure:
269
	nla_nest_cancel(skb, nest);
270 271 272
	goto done;
}

273 274 275 276 277 278 279 280 281 282 283 284 285 286
static int tcf_idr_release_unsafe(struct tc_action *p)
{
	if (atomic_read(&p->tcfa_bindcnt) > 0)
		return -EPERM;

	if (refcount_dec_and_test(&p->tcfa_refcnt)) {
		idr_remove(&p->idrinfo->action_idr, p->tcfa_index);
		tcf_action_cleanup(p);
		return ACT_P_DELETED;
	}

	return 0;
}

287
static int tcf_del_walker(struct tcf_idrinfo *idrinfo, struct sk_buff *skb,
288
			  const struct tc_action_ops *ops)
289
{
290
	struct nlattr *nest;
291
	int n_i = 0;
292
	int ret = -EINVAL;
293 294 295
	struct idr *idr = &idrinfo->action_idr;
	struct tc_action *p;
	unsigned long id = 1;
296
	unsigned long tmp;
297

298
	nest = nla_nest_start_noflag(skb, 0);
299 300
	if (nest == NULL)
		goto nla_put_failure;
301
	if (nla_put_string(skb, TCA_KIND, ops->kind))
302
		goto nla_put_failure;
303

304
	mutex_lock(&idrinfo->lock);
305
	idr_for_each_entry_ul(idr, p, tmp, id) {
306
		ret = tcf_idr_release_unsafe(p);
307
		if (ret == ACT_P_DELETED) {
308
			module_put(ops->owner);
309 310
			n_i++;
		} else if (ret < 0) {
311
			mutex_unlock(&idrinfo->lock);
312
			goto nla_put_failure;
313 314
		}
	}
315
	mutex_unlock(&idrinfo->lock);
316

317 318
	if (nla_put_u32(skb, TCA_FCNT, n_i))
		goto nla_put_failure;
319
	nla_nest_end(skb, nest);
320 321

	return n_i;
322
nla_put_failure:
323
	nla_nest_cancel(skb, nest);
324
	return ret;
325 326
}

327 328
int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,
		       struct netlink_callback *cb, int type,
329 330
		       const struct tc_action_ops *ops,
		       struct netlink_ext_ack *extack)
331
{
332
	struct tcf_idrinfo *idrinfo = tn->idrinfo;
333

334
	if (type == RTM_DELACTION) {
335
		return tcf_del_walker(idrinfo, skb, ops);
336
	} else if (type == RTM_GETACTION) {
337
		return tcf_dump_walker(idrinfo, skb, cb);
338
	} else {
339 340
		WARN(1, "tcf_generic_walker: unknown command %d\n", type);
		NL_SET_ERR_MSG(extack, "tcf_generic_walker: unknown command");
341 342 343
		return -EINVAL;
	}
}
344
EXPORT_SYMBOL(tcf_generic_walker);
345

346
int tcf_idr_search(struct tc_action_net *tn, struct tc_action **a, u32 index)
347
{
348 349
	struct tcf_idrinfo *idrinfo = tn->idrinfo;
	struct tc_action *p;
350

351
	mutex_lock(&idrinfo->lock);
352
	p = idr_find(&idrinfo->action_idr, index);
353
	if (IS_ERR(p))
354
		p = NULL;
355
	else if (p)
356
		refcount_inc(&p->tcfa_refcnt);
357
	mutex_unlock(&idrinfo->lock);
358

359 360 361 362 363
	if (p) {
		*a = p;
		return true;
	}
	return false;
364
}
365
EXPORT_SYMBOL(tcf_idr_search);
366

367
static int tcf_idr_delete_index(struct tcf_idrinfo *idrinfo, u32 index)
368 369 370 371
{
	struct tc_action *p;
	int ret = 0;

372
	mutex_lock(&idrinfo->lock);
373 374
	p = idr_find(&idrinfo->action_idr, index);
	if (!p) {
375
		mutex_unlock(&idrinfo->lock);
376 377 378 379 380 381 382 383 384
		return -ENOENT;
	}

	if (!atomic_read(&p->tcfa_bindcnt)) {
		if (refcount_dec_and_test(&p->tcfa_refcnt)) {
			struct module *owner = p->ops->owner;

			WARN_ON(p != idr_remove(&idrinfo->action_idr,
						p->tcfa_index));
385
			mutex_unlock(&idrinfo->lock);
386

387
			tcf_action_cleanup(p);
388 389 390 391 392 393 394 395
			module_put(owner);
			return 0;
		}
		ret = 0;
	} else {
		ret = -EPERM;
	}

396
	mutex_unlock(&idrinfo->lock);
397 398 399
	return ret;
}

400 401 402
int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
		   struct tc_action **a, const struct tc_action_ops *ops,
		   int bind, bool cpustats)
403
{
404
	struct tc_action *p = kzalloc(ops->size, GFP_KERNEL);
405
	struct tcf_idrinfo *idrinfo = tn->idrinfo;
406
	int err = -ENOMEM;
407 408

	if (unlikely(!p))
409
		return -ENOMEM;
410
	refcount_set(&p->tcfa_refcnt, 1);
411
	if (bind)
412
		atomic_set(&p->tcfa_bindcnt, 1);
413

414 415
	if (cpustats) {
		p->cpu_bstats = netdev_alloc_pcpu_stats(struct gnet_stats_basic_cpu);
416
		if (!p->cpu_bstats)
417
			goto err1;
418 419 420
		p->cpu_bstats_hw = netdev_alloc_pcpu_stats(struct gnet_stats_basic_cpu);
		if (!p->cpu_bstats_hw)
			goto err2;
421 422
		p->cpu_qstats = alloc_percpu(struct gnet_stats_queue);
		if (!p->cpu_qstats)
423
			goto err3;
424
	}
425
	spin_lock_init(&p->tcfa_lock);
426
	p->tcfa_index = index;
427 428 429
	p->tcfa_tm.install = jiffies;
	p->tcfa_tm.lastuse = jiffies;
	p->tcfa_tm.firstuse = 0;
430
	if (est) {
431 432 433
		err = gen_new_estimator(&p->tcfa_bstats, p->cpu_bstats,
					&p->tcfa_rate_est,
					&p->tcfa_lock, NULL, est);
434
		if (err)
435
			goto err4;
436 437
	}

438
	p->idrinfo = idrinfo;
439 440
	p->ops = ops;
	*a = p;
441
	return 0;
442
err4:
443
	free_percpu(p->cpu_qstats);
444 445
err3:
	free_percpu(p->cpu_bstats_hw);
446 447 448 449 450
err2:
	free_percpu(p->cpu_bstats);
err1:
	kfree(p);
	return err;
451
}
452
EXPORT_SYMBOL(tcf_idr_create);
453

454
void tcf_idr_insert(struct tc_action_net *tn, struct tc_action *a)
455
{
456
	struct tcf_idrinfo *idrinfo = tn->idrinfo;
457

458
	mutex_lock(&idrinfo->lock);
459 460
	/* Replace ERR_PTR(-EBUSY) allocated by tcf_idr_check_alloc */
	WARN_ON(!IS_ERR(idr_replace(&idrinfo->action_idr, a, a->tcfa_index)));
461
	mutex_unlock(&idrinfo->lock);
462
}
463
EXPORT_SYMBOL(tcf_idr_insert);
L
Linus Torvalds 已提交
464

465 466 467 468 469 470
/* Cleanup idr index that was allocated but not initialized. */

void tcf_idr_cleanup(struct tc_action_net *tn, u32 index)
{
	struct tcf_idrinfo *idrinfo = tn->idrinfo;

471
	mutex_lock(&idrinfo->lock);
472 473
	/* Remove ERR_PTR(-EBUSY) allocated by tcf_idr_check_alloc */
	WARN_ON(!IS_ERR(idr_remove(&idrinfo->action_idr, index)));
474
	mutex_unlock(&idrinfo->lock);
475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491
}
EXPORT_SYMBOL(tcf_idr_cleanup);

/* Check if action with specified index exists. If actions is found, increments
 * its reference and bind counters, and return 1. Otherwise insert temporary
 * error pointer (to prevent concurrent users from inserting actions with same
 * index) and return 0.
 */

int tcf_idr_check_alloc(struct tc_action_net *tn, u32 *index,
			struct tc_action **a, int bind)
{
	struct tcf_idrinfo *idrinfo = tn->idrinfo;
	struct tc_action *p;
	int ret;

again:
492
	mutex_lock(&idrinfo->lock);
493 494 495 496 497 498
	if (*index) {
		p = idr_find(&idrinfo->action_idr, *index);
		if (IS_ERR(p)) {
			/* This means that another process allocated
			 * index but did not assign the pointer yet.
			 */
499
			mutex_unlock(&idrinfo->lock);
500 501 502 503 504 505 506 507 508 509 510 511
			goto again;
		}

		if (p) {
			refcount_inc(&p->tcfa_refcnt);
			if (bind)
				atomic_inc(&p->tcfa_bindcnt);
			*a = p;
			ret = 1;
		} else {
			*a = NULL;
			ret = idr_alloc_u32(&idrinfo->action_idr, NULL, index,
512
					    *index, GFP_KERNEL);
513 514 515 516 517 518 519 520
			if (!ret)
				idr_replace(&idrinfo->action_idr,
					    ERR_PTR(-EBUSY), *index);
		}
	} else {
		*index = 1;
		*a = NULL;
		ret = idr_alloc_u32(&idrinfo->action_idr, NULL, index,
521
				    UINT_MAX, GFP_KERNEL);
522 523 524 525
		if (!ret)
			idr_replace(&idrinfo->action_idr, ERR_PTR(-EBUSY),
				    *index);
	}
526
	mutex_unlock(&idrinfo->lock);
527 528 529 530
	return ret;
}
EXPORT_SYMBOL(tcf_idr_check_alloc);

531 532
void tcf_idrinfo_destroy(const struct tc_action_ops *ops,
			 struct tcf_idrinfo *idrinfo)
533
{
534 535 536 537
	struct idr *idr = &idrinfo->action_idr;
	struct tc_action *p;
	int ret;
	unsigned long id = 1;
538
	unsigned long tmp;
539

540
	idr_for_each_entry_ul(idr, p, tmp, id) {
541 542 543 544 545
		ret = __tcf_idr_release(p, false, true);
		if (ret == ACT_P_DELETED)
			module_put(ops->owner);
		else if (ret < 0)
			return;
546
	}
547
	idr_destroy(&idrinfo->action_idr);
548
}
549
EXPORT_SYMBOL(tcf_idrinfo_destroy);
550

551
static LIST_HEAD(act_base);
L
Linus Torvalds 已提交
552 553
static DEFINE_RWLOCK(act_mod_lock);

554 555
int tcf_register_action(struct tc_action_ops *act,
			struct pernet_operations *ops)
L
Linus Torvalds 已提交
556
{
557
	struct tc_action_ops *a;
558
	int ret;
L
Linus Torvalds 已提交
559

560
	if (!act->act || !act->dump || !act->init || !act->walk || !act->lookup)
561 562
		return -EINVAL;

563 564 565 566 567 568 569 570
	/* We have to register pernet ops before making the action ops visible,
	 * otherwise tcf_action_init_1() could get a partially initialized
	 * netns.
	 */
	ret = register_pernet_subsys(ops);
	if (ret)
		return ret;

L
Linus Torvalds 已提交
571
	write_lock(&act_mod_lock);
572
	list_for_each_entry(a, &act_base, head) {
573
		if (act->id == a->id || (strcmp(act->kind, a->kind) == 0)) {
L
Linus Torvalds 已提交
574
			write_unlock(&act_mod_lock);
575
			unregister_pernet_subsys(ops);
L
Linus Torvalds 已提交
576 577 578
			return -EEXIST;
		}
	}
579
	list_add_tail(&act->head, &act_base);
L
Linus Torvalds 已提交
580
	write_unlock(&act_mod_lock);
581

L
Linus Torvalds 已提交
582 583
	return 0;
}
584
EXPORT_SYMBOL(tcf_register_action);
L
Linus Torvalds 已提交
585

586 587
int tcf_unregister_action(struct tc_action_ops *act,
			  struct pernet_operations *ops)
L
Linus Torvalds 已提交
588
{
589
	struct tc_action_ops *a;
L
Linus Torvalds 已提交
590 591 592
	int err = -ENOENT;

	write_lock(&act_mod_lock);
593 594 595 596
	list_for_each_entry(a, &act_base, head) {
		if (a == act) {
			list_del(&act->head);
			err = 0;
L
Linus Torvalds 已提交
597
			break;
598
		}
L
Linus Torvalds 已提交
599 600
	}
	write_unlock(&act_mod_lock);
601 602
	if (!err)
		unregister_pernet_subsys(ops);
L
Linus Torvalds 已提交
603 604
	return err;
}
605
EXPORT_SYMBOL(tcf_unregister_action);
L
Linus Torvalds 已提交
606 607 608 609

/* lookup by name */
static struct tc_action_ops *tc_lookup_action_n(char *kind)
{
610
	struct tc_action_ops *a, *res = NULL;
L
Linus Torvalds 已提交
611 612 613

	if (kind) {
		read_lock(&act_mod_lock);
614
		list_for_each_entry(a, &act_base, head) {
L
Linus Torvalds 已提交
615
			if (strcmp(kind, a->kind) == 0) {
616 617
				if (try_module_get(a->owner))
					res = a;
L
Linus Torvalds 已提交
618 619 620 621 622
				break;
			}
		}
		read_unlock(&act_mod_lock);
	}
623
	return res;
L
Linus Torvalds 已提交
624 625
}

626 627
/* lookup by nlattr */
static struct tc_action_ops *tc_lookup_action(struct nlattr *kind)
L
Linus Torvalds 已提交
628
{
629
	struct tc_action_ops *a, *res = NULL;
L
Linus Torvalds 已提交
630 631 632

	if (kind) {
		read_lock(&act_mod_lock);
633
		list_for_each_entry(a, &act_base, head) {
634
			if (nla_strcmp(kind, a->kind) == 0) {
635 636
				if (try_module_get(a->owner))
					res = a;
L
Linus Torvalds 已提交
637 638 639 640 641
				break;
			}
		}
		read_unlock(&act_mod_lock);
	}
642
	return res;
L
Linus Torvalds 已提交
643 644
}

645 646
/*TCA_ACT_MAX_PRIO is 32, there count upto 32 */
#define TCA_ACT_MAX_PRIO_MASK 0x1FF
647 648
int tcf_action_exec(struct sk_buff *skb, struct tc_action **actions,
		    int nr_actions, struct tcf_result *res)
L
Linus Torvalds 已提交
649
{
650 651
	u32 jmp_prgcnt = 0;
	u32 jmp_ttl = TCA_ACT_MAX_PRIO; /*matches actions per filter */
652 653
	int i;
	int ret = TC_ACT_OK;
L
Linus Torvalds 已提交
654

655 656 657
	if (skb_skip_tc_classify(skb))
		return TC_ACT_OK;

658
restart_act_graph:
659 660 661
	for (i = 0; i < nr_actions; i++) {
		const struct tc_action *a = actions[i];

662 663 664 665
		if (jmp_prgcnt > 0) {
			jmp_prgcnt -= 1;
			continue;
		}
L
Linus Torvalds 已提交
666
repeat:
667 668 669
		ret = a->ops->act(skb, a, res);
		if (ret == TC_ACT_REPEAT)
			goto repeat;	/* we need a ttl - JHS */
670

671
		if (TC_ACT_EXT_CMP(ret, TC_ACT_JUMP)) {
672 673 674 675 676 677 678 679 680 681 682
			jmp_prgcnt = ret & TCA_ACT_MAX_PRIO_MASK;
			if (!jmp_prgcnt || (jmp_prgcnt > nr_actions)) {
				/* faulty opcode, stop pipeline */
				return TC_ACT_OK;
			} else {
				jmp_ttl -= 1;
				if (jmp_ttl > 0)
					goto restart_act_graph;
				else /* faulty graph, stop pipeline */
					return TC_ACT_OK;
			}
683
		} else if (TC_ACT_EXT_CMP(ret, TC_ACT_GOTO_CHAIN)) {
684 685 686 687
			if (unlikely(!rcu_access_pointer(a->goto_chain))) {
				net_warn_ratelimited("can't go to NULL chain!\n");
				return TC_ACT_SHOT;
			}
688
			tcf_action_goto_chain_exec(a, res);
689 690
		}

691
		if (ret != TC_ACT_PIPE)
692
			break;
L
Linus Torvalds 已提交
693
	}
694

L
Linus Torvalds 已提交
695 696
	return ret;
}
697
EXPORT_SYMBOL(tcf_action_exec);
L
Linus Torvalds 已提交
698

699
int tcf_action_destroy(struct tc_action *actions[], int bind)
L
Linus Torvalds 已提交
700
{
701
	const struct tc_action_ops *ops;
702 703
	struct tc_action *a;
	int ret = 0, i;
L
Linus Torvalds 已提交
704

705 706 707
	for (i = 0; i < TCA_ACT_MAX_PRIO && actions[i]; i++) {
		a = actions[i];
		actions[i] = NULL;
708
		ops = a->ops;
709
		ret = __tcf_idr_release(a, bind, true);
710
		if (ret == ACT_P_DELETED)
711
			module_put(ops->owner);
712 713
		else if (ret < 0)
			return ret;
L
Linus Torvalds 已提交
714
	}
715
	return ret;
L
Linus Torvalds 已提交
716 717
}

718 719 720 721 722 723 724
static int tcf_action_destroy_1(struct tc_action *a, int bind)
{
	struct tc_action *actions[] = { a, NULL };

	return tcf_action_destroy(actions, bind);
}

725 726 727 728 729
static int tcf_action_put(struct tc_action *p)
{
	return __tcf_action_put(p, false);
}

730
/* Put all actions in this array, skip those NULL's. */
731
static void tcf_action_put_many(struct tc_action *actions[])
732
{
733
	int i;
734

735
	for (i = 0; i < TCA_ACT_MAX_PRIO; i++) {
736
		struct tc_action *a = actions[i];
737
		const struct tc_action_ops *ops;
738

739 740 741
		if (!a)
			continue;
		ops = a->ops;
742 743 744 745 746
		if (tcf_action_put(a))
			module_put(ops->owner);
	}
}

L
Linus Torvalds 已提交
747 748 749 750 751 752 753 754 755 756
int
tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
{
	return a->ops->dump(skb, a, bind, ref);
}

int
tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
{
	int err = -EINVAL;
757
	unsigned char *b = skb_tail_pointer(skb);
758
	struct nlattr *nest;
759
	struct tc_cookie *cookie;
L
Linus Torvalds 已提交
760

761 762
	if (nla_put_string(skb, TCA_KIND, a->ops->kind))
		goto nla_put_failure;
L
Linus Torvalds 已提交
763
	if (tcf_action_copy_stats(skb, a, 0))
764
		goto nla_put_failure;
765 766 767 768 769 770

	rcu_read_lock();
	cookie = rcu_dereference(a->act_cookie);
	if (cookie) {
		if (nla_put(skb, TCA_ACT_COOKIE, cookie->len, cookie->data)) {
			rcu_read_unlock();
771
			goto nla_put_failure;
772
		}
773
	}
774
	rcu_read_unlock();
775

776
	nest = nla_nest_start_noflag(skb, TCA_OPTIONS);
777 778
	if (nest == NULL)
		goto nla_put_failure;
E
Eric Dumazet 已提交
779 780
	err = tcf_action_dump_old(skb, a, bind, ref);
	if (err > 0) {
781
		nla_nest_end(skb, nest);
L
Linus Torvalds 已提交
782 783 784
		return err;
	}

785
nla_put_failure:
786
	nlmsg_trim(skb, b);
L
Linus Torvalds 已提交
787 788
	return -1;
}
789
EXPORT_SYMBOL(tcf_action_dump_1);
L
Linus Torvalds 已提交
790

791
int tcf_action_dump(struct sk_buff *skb, struct tc_action *actions[],
792
		    int bind, int ref)
L
Linus Torvalds 已提交
793 794
{
	struct tc_action *a;
795
	int err = -EINVAL, i;
796
	struct nlattr *nest;
L
Linus Torvalds 已提交
797

798 799
	for (i = 0; i < TCA_ACT_MAX_PRIO && actions[i]; i++) {
		a = actions[i];
800
		nest = nla_nest_start_noflag(skb, i + 1);
801 802
		if (nest == NULL)
			goto nla_put_failure;
L
Linus Torvalds 已提交
803 804
		err = tcf_action_dump_1(skb, a, bind, ref);
		if (err < 0)
805
			goto errout;
806
		nla_nest_end(skb, nest);
L
Linus Torvalds 已提交
807 808 809 810
	}

	return 0;

811
nla_put_failure:
812 813
	err = -EINVAL;
errout:
814
	nla_nest_cancel(skb, nest);
815
	return err;
L
Linus Torvalds 已提交
816 817
}

818
static struct tc_cookie *nla_memdup_cookie(struct nlattr **tb)
819
{
820 821 822 823 824 825 826 827
	struct tc_cookie *c = kzalloc(sizeof(*c), GFP_KERNEL);
	if (!c)
		return NULL;

	c->data = nla_memdup(tb[TCA_ACT_COOKIE], GFP_KERNEL);
	if (!c->data) {
		kfree(c);
		return NULL;
828
	}
829
	c->len = nla_len(tb[TCA_ACT_COOKIE]);
830

831
	return c;
832 833
}

834
static const struct nla_policy tcf_action_policy[TCA_ACT_MAX + 1] = {
835
	[TCA_ACT_KIND]		= { .type = NLA_STRING },
836 837 838 839 840 841
	[TCA_ACT_INDEX]		= { .type = NLA_U32 },
	[TCA_ACT_COOKIE]	= { .type = NLA_BINARY,
				    .len = TC_COOKIE_MAX_SIZE },
	[TCA_ACT_OPTIONS]	= { .type = NLA_NESTED },
};

842 843
struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
				    struct nlattr *nla, struct nlattr *est,
844
				    char *name, int ovr, int bind,
845
				    bool rtnl_held,
846
				    struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
847 848 849
{
	struct tc_action *a;
	struct tc_action_ops *a_o;
850
	struct tc_cookie *cookie = NULL;
L
Linus Torvalds 已提交
851
	char act_name[IFNAMSIZ];
E
Eric Dumazet 已提交
852
	struct nlattr *tb[TCA_ACT_MAX + 1];
853
	struct nlattr *kind;
854
	int err;
L
Linus Torvalds 已提交
855 856

	if (name == NULL) {
857 858
		err = nla_parse_nested_deprecated(tb, TCA_ACT_MAX, nla,
						  tcf_action_policy, extack);
859
		if (err < 0)
L
Linus Torvalds 已提交
860
			goto err_out;
861
		err = -EINVAL;
862
		kind = tb[TCA_ACT_KIND];
863 864
		if (!kind) {
			NL_SET_ERR_MSG(extack, "TC action kind must be specified");
L
Linus Torvalds 已提交
865
			goto err_out;
866
		}
867 868 869 870
		if (nla_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ) {
			NL_SET_ERR_MSG(extack, "TC action name too long");
			goto err_out;
		}
871
		if (tb[TCA_ACT_COOKIE]) {
872 873
			cookie = nla_memdup_cookie(tb);
			if (!cookie) {
874
				NL_SET_ERR_MSG(extack, "No memory to generate TC cookie");
875 876 877 878
				err = -ENOMEM;
				goto err_out;
			}
		}
L
Linus Torvalds 已提交
879
	} else {
880 881 882
		if (strlcpy(act_name, name, IFNAMSIZ) >= IFNAMSIZ) {
			NL_SET_ERR_MSG(extack, "TC action name too long");
			err = -EINVAL;
L
Linus Torvalds 已提交
883
			goto err_out;
884
		}
L
Linus Torvalds 已提交
885 886 887 888
	}

	a_o = tc_lookup_action_n(act_name);
	if (a_o == NULL) {
889
#ifdef CONFIG_MODULES
890 891
		if (rtnl_held)
			rtnl_unlock();
892
		request_module("act_%s", act_name);
893 894
		if (rtnl_held)
			rtnl_lock();
L
Linus Torvalds 已提交
895 896 897 898 899 900 901 902 903 904

		a_o = tc_lookup_action_n(act_name);

		/* We dropped the RTNL semaphore in order to
		 * perform the module load.  So, even if we
		 * succeeded in loading the module we have to
		 * tell the caller to replay the request.  We
		 * indicate this using -EAGAIN.
		 */
		if (a_o != NULL) {
905
			err = -EAGAIN;
L
Linus Torvalds 已提交
906 907 908
			goto err_mod;
		}
#endif
909
		NL_SET_ERR_MSG(extack, "Failed to load TC action module");
910
		err = -ENOENT;
L
Linus Torvalds 已提交
911 912 913 914 915
		goto err_out;
	}

	/* backward compatibility for policer */
	if (name == NULL)
916
		err = a_o->init(net, tb[TCA_ACT_OPTIONS], est, &a, ovr, bind,
917
				rtnl_held, tp, extack);
L
Linus Torvalds 已提交
918
	else
919
		err = a_o->init(net, nla, est, &a, ovr, bind, rtnl_held,
920
				tp, extack);
921
	if (err < 0)
922
		goto err_mod;
L
Linus Torvalds 已提交
923

924 925
	if (!name && tb[TCA_ACT_COOKIE])
		tcf_set_action_cookie(&a->act_cookie, cookie);
926

L
Linus Torvalds 已提交
927
	/* module count goes up only when brand new policy is created
E
Eric Dumazet 已提交
928 929 930
	 * if it exists and is only bound to in a_o->init() then
	 * ACT_P_CREATED is not returned (a zero is).
	 */
931
	if (err != ACT_P_CREATED)
L
Linus Torvalds 已提交
932 933
		module_put(a_o->owner);

934
	if (TC_ACT_EXT_CMP(a->tcfa_action, TC_ACT_GOTO_CHAIN) &&
935
	    !rcu_access_pointer(a->goto_chain)) {
936
		tcf_action_destroy_1(a, bind);
937
		NL_SET_ERR_MSG(extack, "can't use goto chain with NULL chain");
938
		return ERR_PTR(-EINVAL);
939 940
	}

L
Linus Torvalds 已提交
941 942 943 944 945
	return a;

err_mod:
	module_put(a_o->owner);
err_out:
946 947 948 949
	if (cookie) {
		kfree(cookie->data);
		kfree(cookie);
	}
950
	return ERR_PTR(err);
L
Linus Torvalds 已提交
951 952
}

953 954
/* Returns numbers of initialized actions or negative error. */

955 956
int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
		    struct nlattr *est, char *name, int ovr, int bind,
957
		    struct tc_action *actions[], size_t *attr_size,
958
		    bool rtnl_held, struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
959
{
E
Eric Dumazet 已提交
960
	struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
961
	struct tc_action *act;
962
	size_t sz = 0;
963
	int err;
L
Linus Torvalds 已提交
964 965
	int i;

966 967
	err = nla_parse_nested_deprecated(tb, TCA_ACT_MAX_PRIO, nla, NULL,
					  extack);
968
	if (err < 0)
969
		return err;
L
Linus Torvalds 已提交
970

971
	for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
972
		act = tcf_action_init_1(net, tp, tb[i], est, name, ovr, bind,
973
					rtnl_held, extack);
974 975
		if (IS_ERR(act)) {
			err = PTR_ERR(act);
L
Linus Torvalds 已提交
976
			goto err;
977
		}
978
		act->order = i;
979
		sz += tcf_action_fill_size(act);
980 981
		/* Start from index 0 */
		actions[i - 1] = act;
L
Linus Torvalds 已提交
982
	}
983

984
	*attr_size = tcf_action_full_attrs_size(sz);
985
	return i - 1;
L
Linus Torvalds 已提交
986 987

err:
988 989
	tcf_action_destroy(actions, bind);
	return err;
L
Linus Torvalds 已提交
990 991
}

992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005
void tcf_action_update_stats(struct tc_action *a, u64 bytes, u32 packets,
			     bool drop, bool hw)
{
	_bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), bytes, packets);

	if (drop)
		this_cpu_ptr(a->cpu_qstats)->drops += packets;

	if (hw)
		_bstats_cpu_update(this_cpu_ptr(a->cpu_bstats_hw),
				   bytes, packets);
}
EXPORT_SYMBOL(tcf_action_update_stats);

1006
int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *p,
L
Linus Torvalds 已提交
1007 1008 1009 1010
			  int compat_mode)
{
	int err = 0;
	struct gnet_dump d;
1011

1012
	if (p == NULL)
L
Linus Torvalds 已提交
1013 1014 1015
		goto errout;

	/* compat_mode being true specifies a call that is supposed
1016
	 * to add additional backward compatibility statistic TLVs.
L
Linus Torvalds 已提交
1017 1018
	 */
	if (compat_mode) {
1019
		if (p->type == TCA_OLD_COMPAT)
L
Linus Torvalds 已提交
1020
			err = gnet_stats_start_copy_compat(skb, 0,
1021 1022
							   TCA_STATS,
							   TCA_XSTATS,
1023
							   &p->tcfa_lock, &d,
1024
							   TCA_PAD);
L
Linus Torvalds 已提交
1025 1026 1027 1028
		else
			return 0;
	} else
		err = gnet_stats_start_copy(skb, TCA_ACT_STATS,
1029
					    &p->tcfa_lock, &d, TCA_ACT_PAD);
L
Linus Torvalds 已提交
1030 1031 1032 1033

	if (err < 0)
		goto errout;

1034
	if (gnet_stats_copy_basic(NULL, &d, p->cpu_bstats, &p->tcfa_bstats) < 0 ||
1035 1036
	    gnet_stats_copy_basic_hw(NULL, &d, p->cpu_bstats_hw,
				     &p->tcfa_bstats_hw) < 0 ||
1037
	    gnet_stats_copy_rate_est(&d, &p->tcfa_rate_est) < 0 ||
1038
	    gnet_stats_copy_queue(&d, p->cpu_qstats,
1039 1040
				  &p->tcfa_qstats,
				  p->tcfa_qstats.qlen) < 0)
L
Linus Torvalds 已提交
1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051
		goto errout;

	if (gnet_stats_finish_copy(&d) < 0)
		goto errout;

	return 0;

errout:
	return -1;
}

1052
static int tca_get_fill(struct sk_buff *skb, struct tc_action *actions[],
1053 1054
			u32 portid, u32 seq, u16 flags, int event, int bind,
			int ref)
L
Linus Torvalds 已提交
1055 1056 1057
{
	struct tcamsg *t;
	struct nlmsghdr *nlh;
1058
	unsigned char *b = skb_tail_pointer(skb);
1059
	struct nlattr *nest;
L
Linus Torvalds 已提交
1060

1061
	nlh = nlmsg_put(skb, portid, seq, event, sizeof(*t), flags);
1062 1063 1064
	if (!nlh)
		goto out_nlmsg_trim;
	t = nlmsg_data(nlh);
L
Linus Torvalds 已提交
1065
	t->tca_family = AF_UNSPEC;
1066 1067
	t->tca__pad1 = 0;
	t->tca__pad2 = 0;
1068

1069
	nest = nla_nest_start_noflag(skb, TCA_ACT_TAB);
1070
	if (!nest)
1071
		goto out_nlmsg_trim;
L
Linus Torvalds 已提交
1072

1073
	if (tcf_action_dump(skb, actions, bind, ref) < 0)
1074
		goto out_nlmsg_trim;
L
Linus Torvalds 已提交
1075

1076
	nla_nest_end(skb, nest);
1077

1078
	nlh->nlmsg_len = skb_tail_pointer(skb) - b;
L
Linus Torvalds 已提交
1079 1080
	return skb->len;

1081
out_nlmsg_trim:
1082
	nlmsg_trim(skb, b);
L
Linus Torvalds 已提交
1083 1084 1085 1086
	return -1;
}

static int
1087
tcf_get_notify(struct net *net, u32 portid, struct nlmsghdr *n,
1088
	       struct tc_action *actions[], int event,
1089
	       struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
1090 1091 1092 1093 1094 1095
{
	struct sk_buff *skb;

	skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!skb)
		return -ENOBUFS;
1096
	if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, event,
1097
			 0, 1) <= 0) {
1098
		NL_SET_ERR_MSG(extack, "Failed to fill netlink attributes while adding TC action");
L
Linus Torvalds 已提交
1099 1100 1101
		kfree_skb(skb);
		return -EINVAL;
	}
1102

1103
	return rtnl_unicast(skb, net, portid);
L
Linus Torvalds 已提交
1104 1105
}

1106
static struct tc_action *tcf_action_get_1(struct net *net, struct nlattr *nla,
1107 1108
					  struct nlmsghdr *n, u32 portid,
					  struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
1109
{
E
Eric Dumazet 已提交
1110
	struct nlattr *tb[TCA_ACT_MAX + 1];
1111
	const struct tc_action_ops *ops;
L
Linus Torvalds 已提交
1112 1113
	struct tc_action *a;
	int index;
1114
	int err;
L
Linus Torvalds 已提交
1115

1116 1117
	err = nla_parse_nested_deprecated(tb, TCA_ACT_MAX, nla,
					  tcf_action_policy, extack);
1118
	if (err < 0)
1119
		goto err_out;
L
Linus Torvalds 已提交
1120

1121
	err = -EINVAL;
1122
	if (tb[TCA_ACT_INDEX] == NULL ||
1123 1124
	    nla_len(tb[TCA_ACT_INDEX]) < sizeof(index)) {
		NL_SET_ERR_MSG(extack, "Invalid TC action index value");
1125
		goto err_out;
1126
	}
1127
	index = nla_get_u32(tb[TCA_ACT_INDEX]);
L
Linus Torvalds 已提交
1128

1129
	err = -EINVAL;
1130
	ops = tc_lookup_action(tb[TCA_ACT_KIND]);
1131
	if (!ops) { /* could happen in batch of actions */
1132
		NL_SET_ERR_MSG(extack, "Specified TC action kind not found");
1133
		goto err_out;
1134
	}
1135
	err = -ENOENT;
1136 1137
	if (ops->lookup(net, &a, index) == 0) {
		NL_SET_ERR_MSG(extack, "TC action with specified index not found");
L
Linus Torvalds 已提交
1138
		goto err_mod;
1139
	}
L
Linus Torvalds 已提交
1140

1141
	module_put(ops->owner);
L
Linus Torvalds 已提交
1142
	return a;
1143

L
Linus Torvalds 已提交
1144
err_mod:
1145
	module_put(ops->owner);
1146 1147
err_out:
	return ERR_PTR(err);
L
Linus Torvalds 已提交
1148 1149
}

1150
static int tca_action_flush(struct net *net, struct nlattr *nla,
1151 1152
			    struct nlmsghdr *n, u32 portid,
			    struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
1153 1154 1155 1156 1157 1158
{
	struct sk_buff *skb;
	unsigned char *b;
	struct nlmsghdr *nlh;
	struct tcamsg *t;
	struct netlink_callback dcb;
1159
	struct nlattr *nest;
E
Eric Dumazet 已提交
1160
	struct nlattr *tb[TCA_ACT_MAX + 1];
1161
	const struct tc_action_ops *ops;
1162
	struct nlattr *kind;
1163
	int err = -ENOMEM;
L
Linus Torvalds 已提交
1164 1165

	skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
1166
	if (!skb)
1167
		return err;
L
Linus Torvalds 已提交
1168

1169
	b = skb_tail_pointer(skb);
L
Linus Torvalds 已提交
1170

1171 1172
	err = nla_parse_nested_deprecated(tb, TCA_ACT_MAX, nla,
					  tcf_action_policy, extack);
1173
	if (err < 0)
L
Linus Torvalds 已提交
1174 1175
		goto err_out;

1176
	err = -EINVAL;
1177
	kind = tb[TCA_ACT_KIND];
1178
	ops = tc_lookup_action(kind);
1179 1180
	if (!ops) { /*some idjot trying to flush unknown action */
		NL_SET_ERR_MSG(extack, "Cannot flush unknown TC action");
L
Linus Torvalds 已提交
1181
		goto err_out;
1182
	}
L
Linus Torvalds 已提交
1183

1184 1185
	nlh = nlmsg_put(skb, portid, n->nlmsg_seq, RTM_DELACTION,
			sizeof(*t), 0);
1186 1187
	if (!nlh) {
		NL_SET_ERR_MSG(extack, "Failed to create TC action flush notification");
1188
		goto out_module_put;
1189
	}
1190
	t = nlmsg_data(nlh);
L
Linus Torvalds 已提交
1191
	t->tca_family = AF_UNSPEC;
1192 1193
	t->tca__pad1 = 0;
	t->tca__pad2 = 0;
L
Linus Torvalds 已提交
1194

1195
	nest = nla_nest_start_noflag(skb, TCA_ACT_TAB);
1196 1197
	if (!nest) {
		NL_SET_ERR_MSG(extack, "Failed to add new netlink message");
1198
		goto out_module_put;
1199
	}
L
Linus Torvalds 已提交
1200

1201
	err = ops->walk(net, skb, &dcb, RTM_DELACTION, ops, extack);
1202 1203
	if (err <= 0) {
		nla_nest_cancel(skb, nest);
1204
		goto out_module_put;
1205
	}
L
Linus Torvalds 已提交
1206

1207
	nla_nest_end(skb, nest);
L
Linus Torvalds 已提交
1208

1209
	nlh->nlmsg_len = skb_tail_pointer(skb) - b;
L
Linus Torvalds 已提交
1210
	nlh->nlmsg_flags |= NLM_F_ROOT;
1211
	module_put(ops->owner);
1212
	err = rtnetlink_send(skb, net, portid, RTNLGRP_TC,
E
Eric Dumazet 已提交
1213
			     n->nlmsg_flags & NLM_F_ECHO);
L
Linus Torvalds 已提交
1214 1215
	if (err > 0)
		return 0;
1216 1217
	if (err < 0)
		NL_SET_ERR_MSG(extack, "Failed to send TC action flush notification");
L
Linus Torvalds 已提交
1218 1219 1220

	return err;

1221
out_module_put:
1222
	module_put(ops->owner);
L
Linus Torvalds 已提交
1223 1224 1225 1226 1227
err_out:
	kfree_skb(skb);
	return err;
}

1228
static int tcf_action_delete(struct net *net, struct tc_action *actions[])
1229
{
1230
	int i;
1231

1232 1233
	for (i = 0; i < TCA_ACT_MAX_PRIO && actions[i]; i++) {
		struct tc_action *a = actions[i];
1234 1235 1236 1237
		const struct tc_action_ops *ops = a->ops;
		/* Actions can be deleted concurrently so we must save their
		 * type and id to search again after reference is released.
		 */
1238 1239
		struct tcf_idrinfo *idrinfo = a->idrinfo;
		u32 act_index = a->tcfa_index;
1240

1241
		actions[i] = NULL;
1242 1243 1244 1245
		if (tcf_action_put(a)) {
			/* last reference, action was deleted concurrently */
			module_put(ops->owner);
		} else  {
1246 1247
			int ret;

1248
			/* now do the delete */
1249
			ret = tcf_idr_delete_index(idrinfo, act_index);
1250
			if (ret < 0)
1251 1252 1253 1254 1255 1256
				return ret;
		}
	}
	return 0;
}

1257
static int
1258
tcf_del_notify(struct net *net, struct nlmsghdr *n, struct tc_action *actions[],
1259
	       u32 portid, size_t attr_size, struct netlink_ext_ack *extack)
1260 1261 1262 1263
{
	int ret;
	struct sk_buff *skb;

1264 1265
	skb = alloc_skb(attr_size <= NLMSG_GOODSIZE ? NLMSG_GOODSIZE : attr_size,
			GFP_KERNEL);
1266 1267 1268 1269
	if (!skb)
		return -ENOBUFS;

	if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, RTM_DELACTION,
1270
			 0, 2) <= 0) {
1271
		NL_SET_ERR_MSG(extack, "Failed to fill netlink TC action attributes");
1272 1273 1274 1275 1276
		kfree_skb(skb);
		return -EINVAL;
	}

	/* now do the delete */
1277
	ret = tcf_action_delete(net, actions);
1278
	if (ret < 0) {
1279
		NL_SET_ERR_MSG(extack, "Failed to delete TC action");
1280 1281 1282
		kfree_skb(skb);
		return ret;
	}
1283 1284 1285 1286 1287 1288 1289 1290

	ret = rtnetlink_send(skb, net, portid, RTNLGRP_TC,
			     n->nlmsg_flags & NLM_F_ECHO);
	if (ret > 0)
		return 0;
	return ret;
}

L
Linus Torvalds 已提交
1291
static int
1292
tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
1293
	      u32 portid, int event, struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
1294
{
1295
	int i, ret;
E
Eric Dumazet 已提交
1296
	struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
1297
	struct tc_action *act;
1298
	size_t attr_size = 0;
1299
	struct tc_action *actions[TCA_ACT_MAX_PRIO] = {};
L
Linus Torvalds 已提交
1300

1301 1302
	ret = nla_parse_nested_deprecated(tb, TCA_ACT_MAX_PRIO, nla, NULL,
					  extack);
1303 1304
	if (ret < 0)
		return ret;
L
Linus Torvalds 已提交
1305

E
Eric Dumazet 已提交
1306
	if (event == RTM_DELACTION && n->nlmsg_flags & NLM_F_ROOT) {
1307
		if (tb[1])
1308
			return tca_action_flush(net, tb[1], n, portid, extack);
1309

1310
		NL_SET_ERR_MSG(extack, "Invalid netlink attributes while flushing TC action");
1311
		return -EINVAL;
L
Linus Torvalds 已提交
1312 1313
	}

1314
	for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
1315
		act = tcf_action_get_1(net, tb[i], n, portid, extack);
1316 1317
		if (IS_ERR(act)) {
			ret = PTR_ERR(act);
L
Linus Torvalds 已提交
1318
			goto err;
1319
		}
1320
		attr_size += tcf_action_fill_size(act);
1321
		actions[i - 1] = act;
L
Linus Torvalds 已提交
1322
	}
1323 1324

	attr_size = tcf_action_full_attrs_size(attr_size);
L
Linus Torvalds 已提交
1325 1326

	if (event == RTM_GETACTION)
1327
		ret = tcf_get_notify(net, portid, n, actions, event, extack);
L
Linus Torvalds 已提交
1328
	else { /* delete */
1329
		ret = tcf_del_notify(net, n, actions, portid, attr_size, extack);
1330
		if (ret)
L
Linus Torvalds 已提交
1331
			goto err;
1332
		return 0;
L
Linus Torvalds 已提交
1333 1334
	}
err:
1335
	tcf_action_put_many(actions);
L
Linus Torvalds 已提交
1336 1337 1338
	return ret;
}

1339
static int
1340
tcf_add_notify(struct net *net, struct nlmsghdr *n, struct tc_action *actions[],
1341
	       u32 portid, size_t attr_size, struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
1342 1343 1344 1345
{
	struct sk_buff *skb;
	int err = 0;

1346 1347
	skb = alloc_skb(attr_size <= NLMSG_GOODSIZE ? NLMSG_GOODSIZE : attr_size,
			GFP_KERNEL);
L
Linus Torvalds 已提交
1348 1349 1350
	if (!skb)
		return -ENOBUFS;

1351 1352
	if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, n->nlmsg_flags,
			 RTM_NEWACTION, 0, 0) <= 0) {
1353
		NL_SET_ERR_MSG(extack, "Failed to fill netlink attributes while adding TC action");
1354 1355 1356
		kfree_skb(skb);
		return -EINVAL;
	}
1357

1358 1359
	err = rtnetlink_send(skb, net, portid, RTNLGRP_TC,
			     n->nlmsg_flags & NLM_F_ECHO);
L
Linus Torvalds 已提交
1360 1361 1362 1363 1364
	if (err > 0)
		err = 0;
	return err;
}

J
Jamal Hadi Salim 已提交
1365
static int tcf_action_add(struct net *net, struct nlattr *nla,
1366 1367
			  struct nlmsghdr *n, u32 portid, int ovr,
			  struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
1368
{
1369
	size_t attr_size = 0;
1370
	int loop, ret;
1371
	struct tc_action *actions[TCA_ACT_MAX_PRIO] = {};
L
Linus Torvalds 已提交
1372

1373 1374 1375 1376 1377 1378 1379
	for (loop = 0; loop < 10; loop++) {
		ret = tcf_action_init(net, NULL, nla, NULL, NULL, ovr, 0,
				      actions, &attr_size, true, extack);
		if (ret != -EAGAIN)
			break;
	}

1380
	if (ret < 0)
1381
		return ret;
1382
	ret = tcf_add_notify(net, n, actions, portid, attr_size, extack);
1383
	if (ovr)
1384
		tcf_action_put_many(actions);
L
Linus Torvalds 已提交
1385

1386
	return ret;
L
Linus Torvalds 已提交
1387 1388
}

1389 1390 1391 1392
static u32 tcaa_root_flags_allowed = TCA_FLAG_LARGE_DUMP_ON;
static const struct nla_policy tcaa_policy[TCA_ROOT_MAX + 1] = {
	[TCA_ROOT_FLAGS] = { .type = NLA_BITFIELD32,
			     .validation_data = &tcaa_root_flags_allowed },
1393
	[TCA_ROOT_TIME_DELTA]      = { .type = NLA_U32 },
1394 1395
};

1396 1397
static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
			 struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
1398
{
1399
	struct net *net = sock_net(skb->sk);
1400
	struct nlattr *tca[TCA_ROOT_MAX + 1];
1401
	u32 portid = skb ? NETLINK_CB(skb).portid : 0;
L
Linus Torvalds 已提交
1402 1403
	int ret = 0, ovr = 0;

1404 1405
	if ((n->nlmsg_type != RTM_GETACTION) &&
	    !netlink_capable(skb, CAP_NET_ADMIN))
1406 1407
		return -EPERM;

1408 1409
	ret = nlmsg_parse_deprecated(n, sizeof(struct tcamsg), tca,
				     TCA_ROOT_MAX, NULL, extack);
1410 1411 1412 1413
	if (ret < 0)
		return ret;

	if (tca[TCA_ACT_TAB] == NULL) {
1414
		NL_SET_ERR_MSG(extack, "Netlink action attributes missing");
L
Linus Torvalds 已提交
1415 1416 1417
		return -EINVAL;
	}

E
Eric Dumazet 已提交
1418
	/* n->nlmsg_flags & NLM_F_CREATE */
L
Linus Torvalds 已提交
1419 1420 1421
	switch (n->nlmsg_type) {
	case RTM_NEWACTION:
		/* we are going to assume all other flags
L
Lucas De Marchi 已提交
1422
		 * imply create only if it doesn't exist
L
Linus Torvalds 已提交
1423 1424 1425 1426
		 * Note that CREATE | EXCL implies that
		 * but since we want avoid ambiguity (eg when flags
		 * is zero) then just set this
		 */
E
Eric Dumazet 已提交
1427
		if (n->nlmsg_flags & NLM_F_REPLACE)
L
Linus Torvalds 已提交
1428
			ovr = 1;
1429 1430
		ret = tcf_action_add(net, tca[TCA_ACT_TAB], n, portid, ovr,
				     extack);
L
Linus Torvalds 已提交
1431 1432
		break;
	case RTM_DELACTION:
1433
		ret = tca_action_gd(net, tca[TCA_ACT_TAB], n,
1434
				    portid, RTM_DELACTION, extack);
L
Linus Torvalds 已提交
1435 1436
		break;
	case RTM_GETACTION:
1437
		ret = tca_action_gd(net, tca[TCA_ACT_TAB], n,
1438
				    portid, RTM_GETACTION, extack);
L
Linus Torvalds 已提交
1439 1440 1441 1442 1443 1444 1445 1446
		break;
	default:
		BUG();
	}

	return ret;
}

1447
static struct nlattr *find_dump_kind(struct nlattr **nla)
L
Linus Torvalds 已提交
1448
{
E
Eric Dumazet 已提交
1449
	struct nlattr *tb1, *tb2[TCA_ACT_MAX + 1];
1450 1451
	struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
	struct nlattr *kind;
L
Linus Torvalds 已提交
1452

1453
	tb1 = nla[TCA_ACT_TAB];
L
Linus Torvalds 已提交
1454 1455 1456
	if (tb1 == NULL)
		return NULL;

1457
	if (nla_parse_deprecated(tb, TCA_ACT_MAX_PRIO, nla_data(tb1), NLMSG_ALIGN(nla_len(tb1)), NULL, NULL) < 0)
L
Linus Torvalds 已提交
1458 1459
		return NULL;

1460 1461
	if (tb[1] == NULL)
		return NULL;
1462
	if (nla_parse_nested_deprecated(tb2, TCA_ACT_MAX, tb[1], tcf_action_policy, NULL) < 0)
L
Linus Torvalds 已提交
1463
		return NULL;
1464
	kind = tb2[TCA_ACT_KIND];
L
Linus Torvalds 已提交
1465

1466
	return kind;
L
Linus Torvalds 已提交
1467 1468
}

J
Jamal Hadi Salim 已提交
1469
static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
L
Linus Torvalds 已提交
1470
{
1471
	struct net *net = sock_net(skb->sk);
L
Linus Torvalds 已提交
1472
	struct nlmsghdr *nlh;
1473
	unsigned char *b = skb_tail_pointer(skb);
1474
	struct nlattr *nest;
L
Linus Torvalds 已提交
1475 1476
	struct tc_action_ops *a_o;
	int ret = 0;
1477
	struct tcamsg *t = (struct tcamsg *) nlmsg_data(cb->nlh);
1478 1479
	struct nlattr *tb[TCA_ROOT_MAX + 1];
	struct nlattr *count_attr = NULL;
1480
	unsigned long jiffy_since = 0;
1481 1482
	struct nlattr *kind = NULL;
	struct nla_bitfield32 bf;
1483
	u32 msecs_since = 0;
1484 1485
	u32 act_count = 0;

1486 1487
	ret = nlmsg_parse_deprecated(cb->nlh, sizeof(struct tcamsg), tb,
				     TCA_ROOT_MAX, tcaa_policy, cb->extack);
1488 1489
	if (ret < 0)
		return ret;
L
Linus Torvalds 已提交
1490

1491
	kind = find_dump_kind(tb);
L
Linus Torvalds 已提交
1492
	if (kind == NULL) {
1493
		pr_info("tc_dump_action: action bad kind\n");
L
Linus Torvalds 已提交
1494 1495 1496
		return 0;
	}

1497
	a_o = tc_lookup_action(kind);
E
Eric Dumazet 已提交
1498
	if (a_o == NULL)
L
Linus Torvalds 已提交
1499 1500
		return 0;

1501 1502 1503 1504 1505 1506
	cb->args[2] = 0;
	if (tb[TCA_ROOT_FLAGS]) {
		bf = nla_get_bitfield32(tb[TCA_ROOT_FLAGS]);
		cb->args[2] = bf.value;
	}

1507 1508 1509 1510
	if (tb[TCA_ROOT_TIME_DELTA]) {
		msecs_since = nla_get_u32(tb[TCA_ROOT_TIME_DELTA]);
	}

1511
	nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
1512 1513 1514
			cb->nlh->nlmsg_type, sizeof(*t), 0);
	if (!nlh)
		goto out_module_put;
1515

1516 1517 1518
	if (msecs_since)
		jiffy_since = jiffies - msecs_to_jiffies(msecs_since);

1519
	t = nlmsg_data(nlh);
L
Linus Torvalds 已提交
1520
	t->tca_family = AF_UNSPEC;
1521 1522
	t->tca__pad1 = 0;
	t->tca__pad2 = 0;
1523
	cb->args[3] = jiffy_since;
1524 1525 1526
	count_attr = nla_reserve(skb, TCA_ROOT_COUNT, sizeof(u32));
	if (!count_attr)
		goto out_module_put;
L
Linus Torvalds 已提交
1527

1528
	nest = nla_nest_start_noflag(skb, TCA_ACT_TAB);
1529
	if (nest == NULL)
1530
		goto out_module_put;
L
Linus Torvalds 已提交
1531

1532
	ret = a_o->walk(net, skb, cb, RTM_GETACTION, a_o, NULL);
L
Linus Torvalds 已提交
1533
	if (ret < 0)
1534
		goto out_module_put;
L
Linus Torvalds 已提交
1535 1536

	if (ret > 0) {
1537
		nla_nest_end(skb, nest);
L
Linus Torvalds 已提交
1538
		ret = skb->len;
1539 1540 1541
		act_count = cb->args[1];
		memcpy(nla_data(count_attr), &act_count, sizeof(u32));
		cb->args[1] = 0;
L
Linus Torvalds 已提交
1542
	} else
1543
		nlmsg_trim(skb, b);
L
Linus Torvalds 已提交
1544

1545
	nlh->nlmsg_len = skb_tail_pointer(skb) - b;
1546
	if (NETLINK_CB(cb->skb).portid && ret)
L
Linus Torvalds 已提交
1547 1548 1549 1550
		nlh->nlmsg_flags |= NLM_F_MULTI;
	module_put(a_o->owner);
	return skb->len;

1551
out_module_put:
L
Linus Torvalds 已提交
1552
	module_put(a_o->owner);
1553
	nlmsg_trim(skb, b);
L
Linus Torvalds 已提交
1554 1555 1556 1557 1558
	return skb->len;
}

static int __init tc_action_init(void)
{
1559 1560
	rtnl_register(PF_UNSPEC, RTM_NEWACTION, tc_ctl_action, NULL, 0);
	rtnl_register(PF_UNSPEC, RTM_DELACTION, tc_ctl_action, NULL, 0);
1561
	rtnl_register(PF_UNSPEC, RTM_GETACTION, tc_ctl_action, tc_dump_action,
1562
		      0);
L
Linus Torvalds 已提交
1563 1564 1565 1566 1567

	return 0;
}

subsys_initcall(tc_action_init);