act_api.c 39.3 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
	goto_chain = rcu_replace_pointer(a->goto_chain, goto_chain, 1);
92
	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

	return  nla_total_size(0) /* action number nested */
		+ nla_total_size(IFNAMSIZ) /* TCA_ACT_KIND */
		+ cookie_len /* TCA_ACT_COOKIE */
188
		+ nla_total_size(sizeof(struct nla_bitfield32)) /* TCA_ACT_HW_STATS */
189
		+ nla_total_size(0) /* TCA_ACT_STATS nested */
190
		+ nla_total_size(sizeof(struct nla_bitfield32)) /* TCA_ACT_FLAGS */
191 192
		/* TCA_STATS_BASIC */
		+ nla_total_size_64bit(sizeof(struct gnet_stats_basic))
193 194
		/* TCA_STATS_PKT64 */
		+ nla_total_size_64bit(sizeof(u64))
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
		/* 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;
}

218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
static int
tcf_action_dump_terse(struct sk_buff *skb, struct tc_action *a, bool from_act)
{
	unsigned char *b = skb_tail_pointer(skb);
	struct tc_cookie *cookie;

	if (nla_put_string(skb, TCA_KIND, a->ops->kind))
		goto nla_put_failure;
	if (tcf_action_copy_stats(skb, a, 0))
		goto nla_put_failure;
	if (from_act && nla_put_u32(skb, TCA_ACT_INDEX, a->tcfa_index))
		goto nla_put_failure;

	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();
			goto nla_put_failure;
		}
	}
	rcu_read_unlock();

	return 0;

nla_put_failure:
	nlmsg_trim(skb, b);
	return -1;
}

248
static int tcf_dump_walker(struct tcf_idrinfo *idrinfo, struct sk_buff *skb,
249
			   struct netlink_callback *cb)
250
{
251
	int err = 0, index = -1, s_i = 0, n_i = 0;
252
	u32 act_flags = cb->args[2];
253
	unsigned long jiffy_since = cb->args[3];
254
	struct nlattr *nest;
255 256 257
	struct idr *idr = &idrinfo->action_idr;
	struct tc_action *p;
	unsigned long id = 1;
258
	unsigned long tmp;
259

260
	mutex_lock(&idrinfo->lock);
261 262 263

	s_i = cb->args[0];

264
	idr_for_each_entry_ul(idr, p, tmp, id) {
265 266 267
		index++;
		if (index < s_i)
			continue;
268 269
		if (IS_ERR(p))
			continue;
270 271 272 273 274 275

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

276
		nest = nla_nest_start_noflag(skb, n_i);
277 278
		if (!nest) {
			index--;
279
			goto nla_put_failure;
280
		}
281 282 283
		err = (act_flags & TCA_FLAG_TERSE_DUMP) ?
			tcf_action_dump_terse(skb, p, true) :
			tcf_action_dump_1(skb, p, 0, 0);
284 285 286 287
		if (err < 0) {
			index--;
			nlmsg_trim(skb, nest);
			goto done;
288
		}
289 290 291 292 293
		nla_nest_end(skb, nest);
		n_i++;
		if (!(act_flags & TCA_FLAG_LARGE_DUMP_ON) &&
		    n_i >= TCA_ACT_MAX_PRIO)
			goto done;
294 295
	}
done:
296 297 298
	if (index >= 0)
		cb->args[0] = index + 1;

299
	mutex_unlock(&idrinfo->lock);
300 301 302 303
	if (n_i) {
		if (act_flags & TCA_FLAG_LARGE_DUMP_ON)
			cb->args[1] = n_i;
	}
304 305
	return n_i;

306
nla_put_failure:
307
	nla_nest_cancel(skb, nest);
308 309 310
	goto done;
}

311 312 313 314 315 316 317 318 319 320 321 322 323 324
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;
}

325
static int tcf_del_walker(struct tcf_idrinfo *idrinfo, struct sk_buff *skb,
326
			  const struct tc_action_ops *ops)
327
{
328
	struct nlattr *nest;
329
	int n_i = 0;
330
	int ret = -EINVAL;
331 332 333
	struct idr *idr = &idrinfo->action_idr;
	struct tc_action *p;
	unsigned long id = 1;
334
	unsigned long tmp;
335

336
	nest = nla_nest_start_noflag(skb, 0);
337 338
	if (nest == NULL)
		goto nla_put_failure;
339
	if (nla_put_string(skb, TCA_KIND, ops->kind))
340
		goto nla_put_failure;
341

342
	mutex_lock(&idrinfo->lock);
343
	idr_for_each_entry_ul(idr, p, tmp, id) {
344 345
		if (IS_ERR(p))
			continue;
346
		ret = tcf_idr_release_unsafe(p);
347
		if (ret == ACT_P_DELETED) {
348
			module_put(ops->owner);
349 350
			n_i++;
		} else if (ret < 0) {
351
			mutex_unlock(&idrinfo->lock);
352
			goto nla_put_failure;
353 354
		}
	}
355
	mutex_unlock(&idrinfo->lock);
356

357 358
	if (nla_put_u32(skb, TCA_FCNT, n_i))
		goto nla_put_failure;
359
	nla_nest_end(skb, nest);
360 361

	return n_i;
362
nla_put_failure:
363
	nla_nest_cancel(skb, nest);
364
	return ret;
365 366
}

367 368
int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,
		       struct netlink_callback *cb, int type,
369 370
		       const struct tc_action_ops *ops,
		       struct netlink_ext_ack *extack)
371
{
372
	struct tcf_idrinfo *idrinfo = tn->idrinfo;
373

374
	if (type == RTM_DELACTION) {
375
		return tcf_del_walker(idrinfo, skb, ops);
376
	} else if (type == RTM_GETACTION) {
377
		return tcf_dump_walker(idrinfo, skb, cb);
378
	} else {
379 380
		WARN(1, "tcf_generic_walker: unknown command %d\n", type);
		NL_SET_ERR_MSG(extack, "tcf_generic_walker: unknown command");
381 382 383
		return -EINVAL;
	}
}
384
EXPORT_SYMBOL(tcf_generic_walker);
385

386
int tcf_idr_search(struct tc_action_net *tn, struct tc_action **a, u32 index)
387
{
388 389
	struct tcf_idrinfo *idrinfo = tn->idrinfo;
	struct tc_action *p;
390

391
	mutex_lock(&idrinfo->lock);
392
	p = idr_find(&idrinfo->action_idr, index);
393
	if (IS_ERR(p))
394
		p = NULL;
395
	else if (p)
396
		refcount_inc(&p->tcfa_refcnt);
397
	mutex_unlock(&idrinfo->lock);
398

399 400 401 402 403
	if (p) {
		*a = p;
		return true;
	}
	return false;
404
}
405
EXPORT_SYMBOL(tcf_idr_search);
406

407
static int tcf_idr_delete_index(struct tcf_idrinfo *idrinfo, u32 index)
408 409 410 411
{
	struct tc_action *p;
	int ret = 0;

412
	mutex_lock(&idrinfo->lock);
413 414
	p = idr_find(&idrinfo->action_idr, index);
	if (!p) {
415
		mutex_unlock(&idrinfo->lock);
416 417 418 419 420 421 422 423 424
		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));
425
			mutex_unlock(&idrinfo->lock);
426

427
			tcf_action_cleanup(p);
428 429 430 431 432 433 434 435
			module_put(owner);
			return 0;
		}
		ret = 0;
	} else {
		ret = -EPERM;
	}

436
	mutex_unlock(&idrinfo->lock);
437 438 439
	return ret;
}

440 441
int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
		   struct tc_action **a, const struct tc_action_ops *ops,
442
		   int bind, bool cpustats, u32 flags)
443
{
444
	struct tc_action *p = kzalloc(ops->size, GFP_KERNEL);
445
	struct tcf_idrinfo *idrinfo = tn->idrinfo;
446
	int err = -ENOMEM;
447 448

	if (unlikely(!p))
449
		return -ENOMEM;
450
	refcount_set(&p->tcfa_refcnt, 1);
451
	if (bind)
452
		atomic_set(&p->tcfa_bindcnt, 1);
453

454 455
	if (cpustats) {
		p->cpu_bstats = netdev_alloc_pcpu_stats(struct gnet_stats_basic_cpu);
456
		if (!p->cpu_bstats)
457
			goto err1;
458 459 460
		p->cpu_bstats_hw = netdev_alloc_pcpu_stats(struct gnet_stats_basic_cpu);
		if (!p->cpu_bstats_hw)
			goto err2;
461 462
		p->cpu_qstats = alloc_percpu(struct gnet_stats_queue);
		if (!p->cpu_qstats)
463
			goto err3;
464
	}
465
	spin_lock_init(&p->tcfa_lock);
466
	p->tcfa_index = index;
467 468 469
	p->tcfa_tm.install = jiffies;
	p->tcfa_tm.lastuse = jiffies;
	p->tcfa_tm.firstuse = 0;
470
	p->tcfa_flags = flags;
471
	if (est) {
472 473 474
		err = gen_new_estimator(&p->tcfa_bstats, p->cpu_bstats,
					&p->tcfa_rate_est,
					&p->tcfa_lock, NULL, est);
475
		if (err)
476
			goto err4;
477 478
	}

479
	p->idrinfo = idrinfo;
480 481
	p->ops = ops;
	*a = p;
482
	return 0;
483
err4:
484
	free_percpu(p->cpu_qstats);
485 486
err3:
	free_percpu(p->cpu_bstats_hw);
487 488 489 490 491
err2:
	free_percpu(p->cpu_bstats);
err1:
	kfree(p);
	return err;
492
}
493
EXPORT_SYMBOL(tcf_idr_create);
494

495 496 497 498 499 500 501 502 503 504 505
int tcf_idr_create_from_flags(struct tc_action_net *tn, u32 index,
			      struct nlattr *est, struct tc_action **a,
			      const struct tc_action_ops *ops, int bind,
			      u32 flags)
{
	/* Set cpustats according to actions flags. */
	return tcf_idr_create(tn, index, est, a, ops, bind,
			      !(flags & TCA_ACT_FLAGS_NO_PERCPU_STATS), flags);
}
EXPORT_SYMBOL(tcf_idr_create_from_flags);

506 507 508 509 510 511
/* 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;

512
	mutex_lock(&idrinfo->lock);
513 514
	/* Remove ERR_PTR(-EBUSY) allocated by tcf_idr_check_alloc */
	WARN_ON(!IS_ERR(idr_remove(&idrinfo->action_idr, index)));
515
	mutex_unlock(&idrinfo->lock);
516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532
}
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:
533
	mutex_lock(&idrinfo->lock);
534 535 536 537 538 539
	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.
			 */
540
			mutex_unlock(&idrinfo->lock);
541 542 543 544 545 546 547 548 549 550 551 552
			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,
553
					    *index, GFP_KERNEL);
554 555 556 557 558 559 560 561
			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,
562
				    UINT_MAX, GFP_KERNEL);
563 564 565 566
		if (!ret)
			idr_replace(&idrinfo->action_idr, ERR_PTR(-EBUSY),
				    *index);
	}
567
	mutex_unlock(&idrinfo->lock);
568 569 570 571
	return ret;
}
EXPORT_SYMBOL(tcf_idr_check_alloc);

572 573
void tcf_idrinfo_destroy(const struct tc_action_ops *ops,
			 struct tcf_idrinfo *idrinfo)
574
{
575 576 577 578
	struct idr *idr = &idrinfo->action_idr;
	struct tc_action *p;
	int ret;
	unsigned long id = 1;
579
	unsigned long tmp;
580

581
	idr_for_each_entry_ul(idr, p, tmp, id) {
582 583 584 585 586
		ret = __tcf_idr_release(p, false, true);
		if (ret == ACT_P_DELETED)
			module_put(ops->owner);
		else if (ret < 0)
			return;
587
	}
588
	idr_destroy(&idrinfo->action_idr);
589
}
590
EXPORT_SYMBOL(tcf_idrinfo_destroy);
591

592
static LIST_HEAD(act_base);
L
Linus Torvalds 已提交
593 594
static DEFINE_RWLOCK(act_mod_lock);

595 596
int tcf_register_action(struct tc_action_ops *act,
			struct pernet_operations *ops)
L
Linus Torvalds 已提交
597
{
598
	struct tc_action_ops *a;
599
	int ret;
L
Linus Torvalds 已提交
600

601
	if (!act->act || !act->dump || !act->init || !act->walk || !act->lookup)
602 603
		return -EINVAL;

604 605 606 607 608 609 610 611
	/* 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 已提交
612
	write_lock(&act_mod_lock);
613
	list_for_each_entry(a, &act_base, head) {
614
		if (act->id == a->id || (strcmp(act->kind, a->kind) == 0)) {
L
Linus Torvalds 已提交
615
			write_unlock(&act_mod_lock);
616
			unregister_pernet_subsys(ops);
L
Linus Torvalds 已提交
617 618 619
			return -EEXIST;
		}
	}
620
	list_add_tail(&act->head, &act_base);
L
Linus Torvalds 已提交
621
	write_unlock(&act_mod_lock);
622

L
Linus Torvalds 已提交
623 624
	return 0;
}
625
EXPORT_SYMBOL(tcf_register_action);
L
Linus Torvalds 已提交
626

627 628
int tcf_unregister_action(struct tc_action_ops *act,
			  struct pernet_operations *ops)
L
Linus Torvalds 已提交
629
{
630
	struct tc_action_ops *a;
L
Linus Torvalds 已提交
631 632 633
	int err = -ENOENT;

	write_lock(&act_mod_lock);
634 635 636 637
	list_for_each_entry(a, &act_base, head) {
		if (a == act) {
			list_del(&act->head);
			err = 0;
L
Linus Torvalds 已提交
638
			break;
639
		}
L
Linus Torvalds 已提交
640 641
	}
	write_unlock(&act_mod_lock);
642 643
	if (!err)
		unregister_pernet_subsys(ops);
L
Linus Torvalds 已提交
644 645
	return err;
}
646
EXPORT_SYMBOL(tcf_unregister_action);
L
Linus Torvalds 已提交
647 648 649 650

/* lookup by name */
static struct tc_action_ops *tc_lookup_action_n(char *kind)
{
651
	struct tc_action_ops *a, *res = NULL;
L
Linus Torvalds 已提交
652 653 654

	if (kind) {
		read_lock(&act_mod_lock);
655
		list_for_each_entry(a, &act_base, head) {
L
Linus Torvalds 已提交
656
			if (strcmp(kind, a->kind) == 0) {
657 658
				if (try_module_get(a->owner))
					res = a;
L
Linus Torvalds 已提交
659 660 661 662 663
				break;
			}
		}
		read_unlock(&act_mod_lock);
	}
664
	return res;
L
Linus Torvalds 已提交
665 666
}

667 668
/* lookup by nlattr */
static struct tc_action_ops *tc_lookup_action(struct nlattr *kind)
L
Linus Torvalds 已提交
669
{
670
	struct tc_action_ops *a, *res = NULL;
L
Linus Torvalds 已提交
671 672 673

	if (kind) {
		read_lock(&act_mod_lock);
674
		list_for_each_entry(a, &act_base, head) {
675
			if (nla_strcmp(kind, a->kind) == 0) {
676 677
				if (try_module_get(a->owner))
					res = a;
L
Linus Torvalds 已提交
678 679 680 681 682
				break;
			}
		}
		read_unlock(&act_mod_lock);
	}
683
	return res;
L
Linus Torvalds 已提交
684 685
}

686
/*TCA_ACT_MAX_PRIO is 32, there count up to 32 */
687
#define TCA_ACT_MAX_PRIO_MASK 0x1FF
688 689
int tcf_action_exec(struct sk_buff *skb, struct tc_action **actions,
		    int nr_actions, struct tcf_result *res)
L
Linus Torvalds 已提交
690
{
691 692
	u32 jmp_prgcnt = 0;
	u32 jmp_ttl = TCA_ACT_MAX_PRIO; /*matches actions per filter */
693 694
	int i;
	int ret = TC_ACT_OK;
L
Linus Torvalds 已提交
695

696 697 698
	if (skb_skip_tc_classify(skb))
		return TC_ACT_OK;

699
restart_act_graph:
700 701 702
	for (i = 0; i < nr_actions; i++) {
		const struct tc_action *a = actions[i];

703 704 705 706
		if (jmp_prgcnt > 0) {
			jmp_prgcnt -= 1;
			continue;
		}
L
Linus Torvalds 已提交
707
repeat:
708 709 710
		ret = a->ops->act(skb, a, res);
		if (ret == TC_ACT_REPEAT)
			goto repeat;	/* we need a ttl - JHS */
711

712
		if (TC_ACT_EXT_CMP(ret, TC_ACT_JUMP)) {
713 714 715 716 717 718 719 720 721 722 723
			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;
			}
724
		} else if (TC_ACT_EXT_CMP(ret, TC_ACT_GOTO_CHAIN)) {
725 726 727 728
			if (unlikely(!rcu_access_pointer(a->goto_chain))) {
				net_warn_ratelimited("can't go to NULL chain!\n");
				return TC_ACT_SHOT;
			}
729
			tcf_action_goto_chain_exec(a, res);
730 731
		}

732
		if (ret != TC_ACT_PIPE)
733
			break;
L
Linus Torvalds 已提交
734
	}
735

L
Linus Torvalds 已提交
736 737
	return ret;
}
738
EXPORT_SYMBOL(tcf_action_exec);
L
Linus Torvalds 已提交
739

740
int tcf_action_destroy(struct tc_action *actions[], int bind)
L
Linus Torvalds 已提交
741
{
742
	const struct tc_action_ops *ops;
743 744
	struct tc_action *a;
	int ret = 0, i;
L
Linus Torvalds 已提交
745

746 747 748
	for (i = 0; i < TCA_ACT_MAX_PRIO && actions[i]; i++) {
		a = actions[i];
		actions[i] = NULL;
749
		ops = a->ops;
750
		ret = __tcf_idr_release(a, bind, true);
751
		if (ret == ACT_P_DELETED)
752
			module_put(ops->owner);
753 754
		else if (ret < 0)
			return ret;
L
Linus Torvalds 已提交
755
	}
756
	return ret;
L
Linus Torvalds 已提交
757 758
}

759 760 761 762 763
static int tcf_action_put(struct tc_action *p)
{
	return __tcf_action_put(p, false);
}

764
/* Put all actions in this array, skip those NULL's. */
765
static void tcf_action_put_many(struct tc_action *actions[])
766
{
767
	int i;
768

769
	for (i = 0; i < TCA_ACT_MAX_PRIO; i++) {
770
		struct tc_action *a = actions[i];
771
		const struct tc_action_ops *ops;
772

773 774 775
		if (!a)
			continue;
		ops = a->ops;
776 777 778 779 780
		if (tcf_action_put(a))
			module_put(ops->owner);
	}
}

L
Linus Torvalds 已提交
781 782 783 784 785 786
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);
}

787 788 789 790 791 792 793
int
tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
{
	int err = -EINVAL;
	unsigned char *b = skb_tail_pointer(skb);
	struct nlattr *nest;

794
	if (tcf_action_dump_terse(skb, a, false))
795 796
		goto nla_put_failure;

797 798 799 800
	if (a->hw_stats != TCA_ACT_HW_STATS_ANY &&
	    nla_put_bitfield32(skb, TCA_ACT_HW_STATS,
			       a->hw_stats, TCA_ACT_HW_STATS_ANY))
		goto nla_put_failure;
801

802 803 804 805 806
	if (a->used_hw_stats_valid &&
	    nla_put_bitfield32(skb, TCA_ACT_USED_HW_STATS,
			       a->used_hw_stats, TCA_ACT_HW_STATS_ANY))
		goto nla_put_failure;

807 808 809 810
	if (a->tcfa_flags &&
	    nla_put_bitfield32(skb, TCA_ACT_FLAGS,
			       a->tcfa_flags, a->tcfa_flags))
		goto nla_put_failure;
811

812
	nest = nla_nest_start_noflag(skb, TCA_OPTIONS);
813 814
	if (nest == NULL)
		goto nla_put_failure;
E
Eric Dumazet 已提交
815 816
	err = tcf_action_dump_old(skb, a, bind, ref);
	if (err > 0) {
817
		nla_nest_end(skb, nest);
L
Linus Torvalds 已提交
818 819 820
		return err;
	}

821
nla_put_failure:
822
	nlmsg_trim(skb, b);
L
Linus Torvalds 已提交
823 824
	return -1;
}
825
EXPORT_SYMBOL(tcf_action_dump_1);
L
Linus Torvalds 已提交
826

827
int tcf_action_dump(struct sk_buff *skb, struct tc_action *actions[],
828
		    int bind, int ref, bool terse)
L
Linus Torvalds 已提交
829 830
{
	struct tc_action *a;
831
	int err = -EINVAL, i;
832
	struct nlattr *nest;
L
Linus Torvalds 已提交
833

834 835
	for (i = 0; i < TCA_ACT_MAX_PRIO && actions[i]; i++) {
		a = actions[i];
836
		nest = nla_nest_start_noflag(skb, i + 1);
837 838
		if (nest == NULL)
			goto nla_put_failure;
839
		err = terse ? tcf_action_dump_terse(skb, a, false) :
840
			tcf_action_dump_1(skb, a, bind, ref);
L
Linus Torvalds 已提交
841
		if (err < 0)
842
			goto errout;
843
		nla_nest_end(skb, nest);
L
Linus Torvalds 已提交
844 845 846 847
	}

	return 0;

848
nla_put_failure:
849 850
	err = -EINVAL;
errout:
851
	nla_nest_cancel(skb, nest);
852
	return err;
L
Linus Torvalds 已提交
853 854
}

855
static struct tc_cookie *nla_memdup_cookie(struct nlattr **tb)
856
{
857 858 859 860 861 862 863 864
	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;
865
	}
866
	c->len = nla_len(tb[TCA_ACT_COOKIE]);
867

868
	return c;
869 870
}

871
static u8 tcf_action_hw_stats_get(struct nlattr *hw_stats_attr)
872
{
873
	struct nla_bitfield32 hw_stats_bf;
874 875 876 877 878

	/* If the user did not pass the attr, that means he does
	 * not care about the type. Return "any" in that case
	 * which is setting on all supported types.
	 */
879 880 881 882
	if (!hw_stats_attr)
		return TCA_ACT_HW_STATS_ANY;
	hw_stats_bf = nla_get_bitfield32(hw_stats_attr);
	return hw_stats_bf.value;
883 884
}

885
static const struct nla_policy tcf_action_policy[TCA_ACT_MAX + 1] = {
886
	[TCA_ACT_KIND]		= { .type = NLA_STRING },
887 888 889 890
	[TCA_ACT_INDEX]		= { .type = NLA_U32 },
	[TCA_ACT_COOKIE]	= { .type = NLA_BINARY,
				    .len = TC_COOKIE_MAX_SIZE },
	[TCA_ACT_OPTIONS]	= { .type = NLA_NESTED },
891 892
	[TCA_ACT_FLAGS]		= NLA_POLICY_BITFIELD32(TCA_ACT_FLAGS_NO_PERCPU_STATS),
	[TCA_ACT_HW_STATS]	= NLA_POLICY_BITFIELD32(TCA_ACT_HW_STATS_ANY),
893 894
};

895
static void tcf_idr_insert_many(struct tc_action *actions[])
896
{
897
	int i;
898

899 900 901 902 903 904 905 906 907 908 909 910 911 912
	for (i = 0; i < TCA_ACT_MAX_PRIO; i++) {
		struct tc_action *a = actions[i];
		struct tcf_idrinfo *idrinfo;

		if (!a)
			continue;
		idrinfo = a->idrinfo;
		mutex_lock(&idrinfo->lock);
		/* Replace ERR_PTR(-EBUSY) allocated by tcf_idr_check_alloc if
		 * it is just created, otherwise this is just a nop.
		 */
		idr_replace(&idrinfo->action_idr, a, a->tcfa_index);
		mutex_unlock(&idrinfo->lock);
	}
913 914
}

915 916
struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
				    struct nlattr *nla, struct nlattr *est,
917
				    char *name, int ovr, int bind,
918
				    bool rtnl_held,
919
				    struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
920
{
921
	struct nla_bitfield32 flags = { 0, 0 };
922
	u8 hw_stats = TCA_ACT_HW_STATS_ANY;
L
Linus Torvalds 已提交
923 924
	struct tc_action *a;
	struct tc_action_ops *a_o;
925
	struct tc_cookie *cookie = NULL;
L
Linus Torvalds 已提交
926
	char act_name[IFNAMSIZ];
E
Eric Dumazet 已提交
927
	struct nlattr *tb[TCA_ACT_MAX + 1];
928
	struct nlattr *kind;
929
	int err;
L
Linus Torvalds 已提交
930 931

	if (name == NULL) {
932 933
		err = nla_parse_nested_deprecated(tb, TCA_ACT_MAX, nla,
						  tcf_action_policy, extack);
934
		if (err < 0)
L
Linus Torvalds 已提交
935
			goto err_out;
936
		err = -EINVAL;
937
		kind = tb[TCA_ACT_KIND];
938 939
		if (!kind) {
			NL_SET_ERR_MSG(extack, "TC action kind must be specified");
L
Linus Torvalds 已提交
940
			goto err_out;
941
		}
942
		if (nla_strscpy(act_name, kind, IFNAMSIZ) < 0) {
943 944 945
			NL_SET_ERR_MSG(extack, "TC action name too long");
			goto err_out;
		}
946
		if (tb[TCA_ACT_COOKIE]) {
947 948
			cookie = nla_memdup_cookie(tb);
			if (!cookie) {
949
				NL_SET_ERR_MSG(extack, "No memory to generate TC cookie");
950 951 952 953
				err = -ENOMEM;
				goto err_out;
			}
		}
954
		hw_stats = tcf_action_hw_stats_get(tb[TCA_ACT_HW_STATS]);
955 956
		if (tb[TCA_ACT_FLAGS])
			flags = nla_get_bitfield32(tb[TCA_ACT_FLAGS]);
L
Linus Torvalds 已提交
957
	} else {
958 959 960
		if (strlcpy(act_name, name, IFNAMSIZ) >= IFNAMSIZ) {
			NL_SET_ERR_MSG(extack, "TC action name too long");
			err = -EINVAL;
L
Linus Torvalds 已提交
961
			goto err_out;
962
		}
L
Linus Torvalds 已提交
963 964 965 966
	}

	a_o = tc_lookup_action_n(act_name);
	if (a_o == NULL) {
967
#ifdef CONFIG_MODULES
968 969
		if (rtnl_held)
			rtnl_unlock();
970
		request_module("act_%s", act_name);
971 972
		if (rtnl_held)
			rtnl_lock();
L
Linus Torvalds 已提交
973 974 975 976 977 978 979 980 981 982

		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) {
983
			err = -EAGAIN;
L
Linus Torvalds 已提交
984 985 986
			goto err_mod;
		}
#endif
987
		NL_SET_ERR_MSG(extack, "Failed to load TC action module");
988
		err = -ENOENT;
T
Tom Rix 已提交
989
		goto err_free;
L
Linus Torvalds 已提交
990 991 992 993
	}

	/* backward compatibility for policer */
	if (name == NULL)
994
		err = a_o->init(net, tb[TCA_ACT_OPTIONS], est, &a, ovr, bind,
995
				rtnl_held, tp, flags.value, extack);
L
Linus Torvalds 已提交
996
	else
997
		err = a_o->init(net, nla, est, &a, ovr, bind, rtnl_held,
998
				tp, flags.value, extack);
999
	if (err < 0)
1000
		goto err_mod;
L
Linus Torvalds 已提交
1001

1002 1003
	if (!name && tb[TCA_ACT_COOKIE])
		tcf_set_action_cookie(&a->act_cookie, cookie);
1004

1005
	if (!name)
1006
		a->hw_stats = hw_stats;
1007

L
Linus Torvalds 已提交
1008
	/* module count goes up only when brand new policy is created
E
Eric Dumazet 已提交
1009 1010 1011
	 * if it exists and is only bound to in a_o->init() then
	 * ACT_P_CREATED is not returned (a zero is).
	 */
1012
	if (err != ACT_P_CREATED)
L
Linus Torvalds 已提交
1013 1014 1015 1016 1017 1018
		module_put(a_o->owner);

	return a;

err_mod:
	module_put(a_o->owner);
T
Tom Rix 已提交
1019
err_free:
1020 1021 1022 1023
	if (cookie) {
		kfree(cookie->data);
		kfree(cookie);
	}
T
Tom Rix 已提交
1024
err_out:
1025
	return ERR_PTR(err);
L
Linus Torvalds 已提交
1026 1027
}

1028 1029
/* Returns numbers of initialized actions or negative error. */

1030 1031
int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
		    struct nlattr *est, char *name, int ovr, int bind,
1032
		    struct tc_action *actions[], size_t *attr_size,
1033
		    bool rtnl_held, struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
1034
{
E
Eric Dumazet 已提交
1035
	struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
1036
	struct tc_action *act;
1037
	size_t sz = 0;
1038
	int err;
L
Linus Torvalds 已提交
1039 1040
	int i;

1041 1042
	err = nla_parse_nested_deprecated(tb, TCA_ACT_MAX_PRIO, nla, NULL,
					  extack);
1043
	if (err < 0)
1044
		return err;
L
Linus Torvalds 已提交
1045

1046
	for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
1047
		act = tcf_action_init_1(net, tp, tb[i], est, name, ovr, bind,
1048
					rtnl_held, extack);
1049 1050
		if (IS_ERR(act)) {
			err = PTR_ERR(act);
L
Linus Torvalds 已提交
1051
			goto err;
1052
		}
1053
		sz += tcf_action_fill_size(act);
1054 1055
		/* Start from index 0 */
		actions[i - 1] = act;
L
Linus Torvalds 已提交
1056
	}
1057

1058 1059 1060 1061 1062
	/* We have to commit them all together, because if any error happened in
	 * between, we could not handle the failure gracefully.
	 */
	tcf_idr_insert_many(actions);

1063
	*attr_size = tcf_action_full_attrs_size(sz);
1064
	return i - 1;
L
Linus Torvalds 已提交
1065 1066

err:
1067 1068
	tcf_action_destroy(actions, bind);
	return err;
L
Linus Torvalds 已提交
1069 1070
}

1071 1072
void tcf_action_update_stats(struct tc_action *a, u64 bytes, u64 packets,
			     u64 drops, bool hw)
1073
{
1074 1075
	if (a->cpu_bstats) {
		_bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), bytes, packets);
1076

1077
		this_cpu_ptr(a->cpu_qstats)->drops += drops;
1078 1079 1080 1081 1082 1083

		if (hw)
			_bstats_cpu_update(this_cpu_ptr(a->cpu_bstats_hw),
					   bytes, packets);
		return;
	}
1084

1085
	_bstats_update(&a->tcfa_bstats, bytes, packets);
1086
	a->tcfa_qstats.drops += drops;
1087
	if (hw)
1088
		_bstats_update(&a->tcfa_bstats_hw, bytes, packets);
1089 1090 1091
}
EXPORT_SYMBOL(tcf_action_update_stats);

1092
int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *p,
L
Linus Torvalds 已提交
1093 1094 1095 1096
			  int compat_mode)
{
	int err = 0;
	struct gnet_dump d;
1097

1098
	if (p == NULL)
L
Linus Torvalds 已提交
1099 1100 1101
		goto errout;

	/* compat_mode being true specifies a call that is supposed
1102
	 * to add additional backward compatibility statistic TLVs.
L
Linus Torvalds 已提交
1103 1104
	 */
	if (compat_mode) {
1105
		if (p->type == TCA_OLD_COMPAT)
L
Linus Torvalds 已提交
1106
			err = gnet_stats_start_copy_compat(skb, 0,
1107 1108
							   TCA_STATS,
							   TCA_XSTATS,
1109
							   &p->tcfa_lock, &d,
1110
							   TCA_PAD);
L
Linus Torvalds 已提交
1111 1112 1113 1114
		else
			return 0;
	} else
		err = gnet_stats_start_copy(skb, TCA_ACT_STATS,
1115
					    &p->tcfa_lock, &d, TCA_ACT_PAD);
L
Linus Torvalds 已提交
1116 1117 1118 1119

	if (err < 0)
		goto errout;

1120
	if (gnet_stats_copy_basic(NULL, &d, p->cpu_bstats, &p->tcfa_bstats) < 0 ||
1121 1122
	    gnet_stats_copy_basic_hw(NULL, &d, p->cpu_bstats_hw,
				     &p->tcfa_bstats_hw) < 0 ||
1123
	    gnet_stats_copy_rate_est(&d, &p->tcfa_rate_est) < 0 ||
1124
	    gnet_stats_copy_queue(&d, p->cpu_qstats,
1125 1126
				  &p->tcfa_qstats,
				  p->tcfa_qstats.qlen) < 0)
L
Linus Torvalds 已提交
1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137
		goto errout;

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

	return 0;

errout:
	return -1;
}

1138
static int tca_get_fill(struct sk_buff *skb, struct tc_action *actions[],
1139 1140
			u32 portid, u32 seq, u16 flags, int event, int bind,
			int ref)
L
Linus Torvalds 已提交
1141 1142 1143
{
	struct tcamsg *t;
	struct nlmsghdr *nlh;
1144
	unsigned char *b = skb_tail_pointer(skb);
1145
	struct nlattr *nest;
L
Linus Torvalds 已提交
1146

1147
	nlh = nlmsg_put(skb, portid, seq, event, sizeof(*t), flags);
1148 1149 1150
	if (!nlh)
		goto out_nlmsg_trim;
	t = nlmsg_data(nlh);
L
Linus Torvalds 已提交
1151
	t->tca_family = AF_UNSPEC;
1152 1153
	t->tca__pad1 = 0;
	t->tca__pad2 = 0;
1154

1155
	nest = nla_nest_start_noflag(skb, TCA_ACT_TAB);
1156
	if (!nest)
1157
		goto out_nlmsg_trim;
L
Linus Torvalds 已提交
1158

1159
	if (tcf_action_dump(skb, actions, bind, ref, false) < 0)
1160
		goto out_nlmsg_trim;
L
Linus Torvalds 已提交
1161

1162
	nla_nest_end(skb, nest);
1163

1164
	nlh->nlmsg_len = skb_tail_pointer(skb) - b;
L
Linus Torvalds 已提交
1165 1166
	return skb->len;

1167
out_nlmsg_trim:
1168
	nlmsg_trim(skb, b);
L
Linus Torvalds 已提交
1169 1170 1171 1172
	return -1;
}

static int
1173
tcf_get_notify(struct net *net, u32 portid, struct nlmsghdr *n,
1174
	       struct tc_action *actions[], int event,
1175
	       struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
1176 1177 1178 1179 1180 1181
{
	struct sk_buff *skb;

	skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!skb)
		return -ENOBUFS;
1182
	if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, event,
1183
			 0, 1) <= 0) {
1184
		NL_SET_ERR_MSG(extack, "Failed to fill netlink attributes while adding TC action");
L
Linus Torvalds 已提交
1185 1186 1187
		kfree_skb(skb);
		return -EINVAL;
	}
1188

1189
	return rtnl_unicast(skb, net, portid);
L
Linus Torvalds 已提交
1190 1191
}

1192
static struct tc_action *tcf_action_get_1(struct net *net, struct nlattr *nla,
1193 1194
					  struct nlmsghdr *n, u32 portid,
					  struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
1195
{
E
Eric Dumazet 已提交
1196
	struct nlattr *tb[TCA_ACT_MAX + 1];
1197
	const struct tc_action_ops *ops;
L
Linus Torvalds 已提交
1198 1199
	struct tc_action *a;
	int index;
1200
	int err;
L
Linus Torvalds 已提交
1201

1202 1203
	err = nla_parse_nested_deprecated(tb, TCA_ACT_MAX, nla,
					  tcf_action_policy, extack);
1204
	if (err < 0)
1205
		goto err_out;
L
Linus Torvalds 已提交
1206

1207
	err = -EINVAL;
1208
	if (tb[TCA_ACT_INDEX] == NULL ||
1209 1210
	    nla_len(tb[TCA_ACT_INDEX]) < sizeof(index)) {
		NL_SET_ERR_MSG(extack, "Invalid TC action index value");
1211
		goto err_out;
1212
	}
1213
	index = nla_get_u32(tb[TCA_ACT_INDEX]);
L
Linus Torvalds 已提交
1214

1215
	err = -EINVAL;
1216
	ops = tc_lookup_action(tb[TCA_ACT_KIND]);
1217
	if (!ops) { /* could happen in batch of actions */
1218
		NL_SET_ERR_MSG(extack, "Specified TC action kind not found");
1219
		goto err_out;
1220
	}
1221
	err = -ENOENT;
1222 1223
	if (ops->lookup(net, &a, index) == 0) {
		NL_SET_ERR_MSG(extack, "TC action with specified index not found");
L
Linus Torvalds 已提交
1224
		goto err_mod;
1225
	}
L
Linus Torvalds 已提交
1226

1227
	module_put(ops->owner);
L
Linus Torvalds 已提交
1228
	return a;
1229

L
Linus Torvalds 已提交
1230
err_mod:
1231
	module_put(ops->owner);
1232 1233
err_out:
	return ERR_PTR(err);
L
Linus Torvalds 已提交
1234 1235
}

1236
static int tca_action_flush(struct net *net, struct nlattr *nla,
1237 1238
			    struct nlmsghdr *n, u32 portid,
			    struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
1239 1240 1241 1242 1243 1244
{
	struct sk_buff *skb;
	unsigned char *b;
	struct nlmsghdr *nlh;
	struct tcamsg *t;
	struct netlink_callback dcb;
1245
	struct nlattr *nest;
E
Eric Dumazet 已提交
1246
	struct nlattr *tb[TCA_ACT_MAX + 1];
1247
	const struct tc_action_ops *ops;
1248
	struct nlattr *kind;
1249
	int err = -ENOMEM;
L
Linus Torvalds 已提交
1250 1251

	skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
1252
	if (!skb)
1253
		return err;
L
Linus Torvalds 已提交
1254

1255
	b = skb_tail_pointer(skb);
L
Linus Torvalds 已提交
1256

1257 1258
	err = nla_parse_nested_deprecated(tb, TCA_ACT_MAX, nla,
					  tcf_action_policy, extack);
1259
	if (err < 0)
L
Linus Torvalds 已提交
1260 1261
		goto err_out;

1262
	err = -EINVAL;
1263
	kind = tb[TCA_ACT_KIND];
1264
	ops = tc_lookup_action(kind);
1265 1266
	if (!ops) { /*some idjot trying to flush unknown action */
		NL_SET_ERR_MSG(extack, "Cannot flush unknown TC action");
L
Linus Torvalds 已提交
1267
		goto err_out;
1268
	}
L
Linus Torvalds 已提交
1269

1270 1271
	nlh = nlmsg_put(skb, portid, n->nlmsg_seq, RTM_DELACTION,
			sizeof(*t), 0);
1272 1273
	if (!nlh) {
		NL_SET_ERR_MSG(extack, "Failed to create TC action flush notification");
1274
		goto out_module_put;
1275
	}
1276
	t = nlmsg_data(nlh);
L
Linus Torvalds 已提交
1277
	t->tca_family = AF_UNSPEC;
1278 1279
	t->tca__pad1 = 0;
	t->tca__pad2 = 0;
L
Linus Torvalds 已提交
1280

1281
	nest = nla_nest_start_noflag(skb, TCA_ACT_TAB);
1282 1283
	if (!nest) {
		NL_SET_ERR_MSG(extack, "Failed to add new netlink message");
1284
		goto out_module_put;
1285
	}
L
Linus Torvalds 已提交
1286

1287
	err = ops->walk(net, skb, &dcb, RTM_DELACTION, ops, extack);
1288 1289
	if (err <= 0) {
		nla_nest_cancel(skb, nest);
1290
		goto out_module_put;
1291
	}
L
Linus Torvalds 已提交
1292

1293
	nla_nest_end(skb, nest);
L
Linus Torvalds 已提交
1294

1295
	nlh->nlmsg_len = skb_tail_pointer(skb) - b;
L
Linus Torvalds 已提交
1296
	nlh->nlmsg_flags |= NLM_F_ROOT;
1297
	module_put(ops->owner);
1298
	err = rtnetlink_send(skb, net, portid, RTNLGRP_TC,
E
Eric Dumazet 已提交
1299
			     n->nlmsg_flags & NLM_F_ECHO);
L
Linus Torvalds 已提交
1300 1301
	if (err > 0)
		return 0;
1302 1303
	if (err < 0)
		NL_SET_ERR_MSG(extack, "Failed to send TC action flush notification");
L
Linus Torvalds 已提交
1304 1305 1306

	return err;

1307
out_module_put:
1308
	module_put(ops->owner);
L
Linus Torvalds 已提交
1309 1310 1311 1312 1313
err_out:
	kfree_skb(skb);
	return err;
}

1314
static int tcf_action_delete(struct net *net, struct tc_action *actions[])
1315
{
1316
	int i;
1317

1318 1319
	for (i = 0; i < TCA_ACT_MAX_PRIO && actions[i]; i++) {
		struct tc_action *a = actions[i];
1320 1321 1322 1323
		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.
		 */
1324 1325
		struct tcf_idrinfo *idrinfo = a->idrinfo;
		u32 act_index = a->tcfa_index;
1326

1327
		actions[i] = NULL;
1328 1329 1330 1331
		if (tcf_action_put(a)) {
			/* last reference, action was deleted concurrently */
			module_put(ops->owner);
		} else  {
1332 1333
			int ret;

1334
			/* now do the delete */
1335
			ret = tcf_idr_delete_index(idrinfo, act_index);
1336
			if (ret < 0)
1337 1338 1339 1340 1341 1342
				return ret;
		}
	}
	return 0;
}

1343
static int
1344
tcf_del_notify(struct net *net, struct nlmsghdr *n, struct tc_action *actions[],
1345
	       u32 portid, size_t attr_size, struct netlink_ext_ack *extack)
1346 1347 1348 1349
{
	int ret;
	struct sk_buff *skb;

1350 1351
	skb = alloc_skb(attr_size <= NLMSG_GOODSIZE ? NLMSG_GOODSIZE : attr_size,
			GFP_KERNEL);
1352 1353 1354 1355
	if (!skb)
		return -ENOBUFS;

	if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, RTM_DELACTION,
1356
			 0, 2) <= 0) {
1357
		NL_SET_ERR_MSG(extack, "Failed to fill netlink TC action attributes");
1358 1359 1360 1361 1362
		kfree_skb(skb);
		return -EINVAL;
	}

	/* now do the delete */
1363
	ret = tcf_action_delete(net, actions);
1364
	if (ret < 0) {
1365
		NL_SET_ERR_MSG(extack, "Failed to delete TC action");
1366 1367 1368
		kfree_skb(skb);
		return ret;
	}
1369 1370 1371 1372 1373 1374 1375 1376

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

L
Linus Torvalds 已提交
1377
static int
1378
tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
1379
	      u32 portid, int event, struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
1380
{
1381
	int i, ret;
E
Eric Dumazet 已提交
1382
	struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
1383
	struct tc_action *act;
1384
	size_t attr_size = 0;
1385
	struct tc_action *actions[TCA_ACT_MAX_PRIO] = {};
L
Linus Torvalds 已提交
1386

1387 1388
	ret = nla_parse_nested_deprecated(tb, TCA_ACT_MAX_PRIO, nla, NULL,
					  extack);
1389 1390
	if (ret < 0)
		return ret;
L
Linus Torvalds 已提交
1391

E
Eric Dumazet 已提交
1392
	if (event == RTM_DELACTION && n->nlmsg_flags & NLM_F_ROOT) {
1393
		if (tb[1])
1394
			return tca_action_flush(net, tb[1], n, portid, extack);
1395

1396
		NL_SET_ERR_MSG(extack, "Invalid netlink attributes while flushing TC action");
1397
		return -EINVAL;
L
Linus Torvalds 已提交
1398 1399
	}

1400
	for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
1401
		act = tcf_action_get_1(net, tb[i], n, portid, extack);
1402 1403
		if (IS_ERR(act)) {
			ret = PTR_ERR(act);
L
Linus Torvalds 已提交
1404
			goto err;
1405
		}
1406
		attr_size += tcf_action_fill_size(act);
1407
		actions[i - 1] = act;
L
Linus Torvalds 已提交
1408
	}
1409 1410

	attr_size = tcf_action_full_attrs_size(attr_size);
L
Linus Torvalds 已提交
1411 1412

	if (event == RTM_GETACTION)
1413
		ret = tcf_get_notify(net, portid, n, actions, event, extack);
L
Linus Torvalds 已提交
1414
	else { /* delete */
1415
		ret = tcf_del_notify(net, n, actions, portid, attr_size, extack);
1416
		if (ret)
L
Linus Torvalds 已提交
1417
			goto err;
1418
		return 0;
L
Linus Torvalds 已提交
1419 1420
	}
err:
1421
	tcf_action_put_many(actions);
L
Linus Torvalds 已提交
1422 1423 1424
	return ret;
}

1425
static int
1426
tcf_add_notify(struct net *net, struct nlmsghdr *n, struct tc_action *actions[],
1427
	       u32 portid, size_t attr_size, struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
1428 1429 1430 1431
{
	struct sk_buff *skb;
	int err = 0;

1432 1433
	skb = alloc_skb(attr_size <= NLMSG_GOODSIZE ? NLMSG_GOODSIZE : attr_size,
			GFP_KERNEL);
L
Linus Torvalds 已提交
1434 1435 1436
	if (!skb)
		return -ENOBUFS;

1437 1438
	if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, n->nlmsg_flags,
			 RTM_NEWACTION, 0, 0) <= 0) {
1439
		NL_SET_ERR_MSG(extack, "Failed to fill netlink attributes while adding TC action");
1440 1441 1442
		kfree_skb(skb);
		return -EINVAL;
	}
1443

1444 1445
	err = rtnetlink_send(skb, net, portid, RTNLGRP_TC,
			     n->nlmsg_flags & NLM_F_ECHO);
L
Linus Torvalds 已提交
1446 1447 1448 1449 1450
	if (err > 0)
		err = 0;
	return err;
}

J
Jamal Hadi Salim 已提交
1451
static int tcf_action_add(struct net *net, struct nlattr *nla,
1452 1453
			  struct nlmsghdr *n, u32 portid, int ovr,
			  struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
1454
{
1455
	size_t attr_size = 0;
1456
	int loop, ret;
1457
	struct tc_action *actions[TCA_ACT_MAX_PRIO] = {};
L
Linus Torvalds 已提交
1458

1459 1460 1461 1462 1463 1464 1465
	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;
	}

1466
	if (ret < 0)
1467
		return ret;
1468
	ret = tcf_add_notify(net, n, actions, portid, attr_size, extack);
1469
	if (ovr)
1470
		tcf_action_put_many(actions);
L
Linus Torvalds 已提交
1471

1472
	return ret;
L
Linus Torvalds 已提交
1473 1474
}

1475
static const struct nla_policy tcaa_policy[TCA_ROOT_MAX + 1] = {
1476 1477
	[TCA_ROOT_FLAGS] = NLA_POLICY_BITFIELD32(TCA_FLAG_LARGE_DUMP_ON |
						 TCA_FLAG_TERSE_DUMP),
1478
	[TCA_ROOT_TIME_DELTA]      = { .type = NLA_U32 },
1479 1480
};

1481 1482
static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
			 struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
1483
{
1484
	struct net *net = sock_net(skb->sk);
1485
	struct nlattr *tca[TCA_ROOT_MAX + 1];
G
Gaurav Singh 已提交
1486
	u32 portid = NETLINK_CB(skb).portid;
L
Linus Torvalds 已提交
1487 1488
	int ret = 0, ovr = 0;

1489 1490
	if ((n->nlmsg_type != RTM_GETACTION) &&
	    !netlink_capable(skb, CAP_NET_ADMIN))
1491 1492
		return -EPERM;

1493 1494
	ret = nlmsg_parse_deprecated(n, sizeof(struct tcamsg), tca,
				     TCA_ROOT_MAX, NULL, extack);
1495 1496 1497 1498
	if (ret < 0)
		return ret;

	if (tca[TCA_ACT_TAB] == NULL) {
1499
		NL_SET_ERR_MSG(extack, "Netlink action attributes missing");
L
Linus Torvalds 已提交
1500 1501 1502
		return -EINVAL;
	}

E
Eric Dumazet 已提交
1503
	/* n->nlmsg_flags & NLM_F_CREATE */
L
Linus Torvalds 已提交
1504 1505 1506
	switch (n->nlmsg_type) {
	case RTM_NEWACTION:
		/* we are going to assume all other flags
L
Lucas De Marchi 已提交
1507
		 * imply create only if it doesn't exist
L
Linus Torvalds 已提交
1508 1509 1510 1511
		 * Note that CREATE | EXCL implies that
		 * but since we want avoid ambiguity (eg when flags
		 * is zero) then just set this
		 */
E
Eric Dumazet 已提交
1512
		if (n->nlmsg_flags & NLM_F_REPLACE)
L
Linus Torvalds 已提交
1513
			ovr = 1;
1514 1515
		ret = tcf_action_add(net, tca[TCA_ACT_TAB], n, portid, ovr,
				     extack);
L
Linus Torvalds 已提交
1516 1517
		break;
	case RTM_DELACTION:
1518
		ret = tca_action_gd(net, tca[TCA_ACT_TAB], n,
1519
				    portid, RTM_DELACTION, extack);
L
Linus Torvalds 已提交
1520 1521
		break;
	case RTM_GETACTION:
1522
		ret = tca_action_gd(net, tca[TCA_ACT_TAB], n,
1523
				    portid, RTM_GETACTION, extack);
L
Linus Torvalds 已提交
1524 1525 1526 1527 1528 1529 1530 1531
		break;
	default:
		BUG();
	}

	return ret;
}

1532
static struct nlattr *find_dump_kind(struct nlattr **nla)
L
Linus Torvalds 已提交
1533
{
E
Eric Dumazet 已提交
1534
	struct nlattr *tb1, *tb2[TCA_ACT_MAX + 1];
1535 1536
	struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
	struct nlattr *kind;
L
Linus Torvalds 已提交
1537

1538
	tb1 = nla[TCA_ACT_TAB];
L
Linus Torvalds 已提交
1539 1540 1541
	if (tb1 == NULL)
		return NULL;

1542
	if (nla_parse_deprecated(tb, TCA_ACT_MAX_PRIO, nla_data(tb1), NLMSG_ALIGN(nla_len(tb1)), NULL, NULL) < 0)
L
Linus Torvalds 已提交
1543 1544
		return NULL;

1545 1546
	if (tb[1] == NULL)
		return NULL;
1547
	if (nla_parse_nested_deprecated(tb2, TCA_ACT_MAX, tb[1], tcf_action_policy, NULL) < 0)
L
Linus Torvalds 已提交
1548
		return NULL;
1549
	kind = tb2[TCA_ACT_KIND];
L
Linus Torvalds 已提交
1550

1551
	return kind;
L
Linus Torvalds 已提交
1552 1553
}

J
Jamal Hadi Salim 已提交
1554
static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
L
Linus Torvalds 已提交
1555
{
1556
	struct net *net = sock_net(skb->sk);
L
Linus Torvalds 已提交
1557
	struct nlmsghdr *nlh;
1558
	unsigned char *b = skb_tail_pointer(skb);
1559
	struct nlattr *nest;
L
Linus Torvalds 已提交
1560 1561
	struct tc_action_ops *a_o;
	int ret = 0;
1562
	struct tcamsg *t = (struct tcamsg *) nlmsg_data(cb->nlh);
1563 1564
	struct nlattr *tb[TCA_ROOT_MAX + 1];
	struct nlattr *count_attr = NULL;
1565
	unsigned long jiffy_since = 0;
1566 1567
	struct nlattr *kind = NULL;
	struct nla_bitfield32 bf;
1568
	u32 msecs_since = 0;
1569 1570
	u32 act_count = 0;

1571 1572
	ret = nlmsg_parse_deprecated(cb->nlh, sizeof(struct tcamsg), tb,
				     TCA_ROOT_MAX, tcaa_policy, cb->extack);
1573 1574
	if (ret < 0)
		return ret;
L
Linus Torvalds 已提交
1575

1576
	kind = find_dump_kind(tb);
L
Linus Torvalds 已提交
1577
	if (kind == NULL) {
1578
		pr_info("tc_dump_action: action bad kind\n");
L
Linus Torvalds 已提交
1579 1580 1581
		return 0;
	}

1582
	a_o = tc_lookup_action(kind);
E
Eric Dumazet 已提交
1583
	if (a_o == NULL)
L
Linus Torvalds 已提交
1584 1585
		return 0;

1586 1587 1588 1589 1590 1591
	cb->args[2] = 0;
	if (tb[TCA_ROOT_FLAGS]) {
		bf = nla_get_bitfield32(tb[TCA_ROOT_FLAGS]);
		cb->args[2] = bf.value;
	}

1592 1593 1594 1595
	if (tb[TCA_ROOT_TIME_DELTA]) {
		msecs_since = nla_get_u32(tb[TCA_ROOT_TIME_DELTA]);
	}

1596
	nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
1597 1598 1599
			cb->nlh->nlmsg_type, sizeof(*t), 0);
	if (!nlh)
		goto out_module_put;
1600

1601 1602 1603
	if (msecs_since)
		jiffy_since = jiffies - msecs_to_jiffies(msecs_since);

1604
	t = nlmsg_data(nlh);
L
Linus Torvalds 已提交
1605
	t->tca_family = AF_UNSPEC;
1606 1607
	t->tca__pad1 = 0;
	t->tca__pad2 = 0;
1608
	cb->args[3] = jiffy_since;
1609 1610 1611
	count_attr = nla_reserve(skb, TCA_ROOT_COUNT, sizeof(u32));
	if (!count_attr)
		goto out_module_put;
L
Linus Torvalds 已提交
1612

1613
	nest = nla_nest_start_noflag(skb, TCA_ACT_TAB);
1614
	if (nest == NULL)
1615
		goto out_module_put;
L
Linus Torvalds 已提交
1616

1617
	ret = a_o->walk(net, skb, cb, RTM_GETACTION, a_o, NULL);
L
Linus Torvalds 已提交
1618
	if (ret < 0)
1619
		goto out_module_put;
L
Linus Torvalds 已提交
1620 1621

	if (ret > 0) {
1622
		nla_nest_end(skb, nest);
L
Linus Torvalds 已提交
1623
		ret = skb->len;
1624 1625 1626
		act_count = cb->args[1];
		memcpy(nla_data(count_attr), &act_count, sizeof(u32));
		cb->args[1] = 0;
L
Linus Torvalds 已提交
1627
	} else
1628
		nlmsg_trim(skb, b);
L
Linus Torvalds 已提交
1629

1630
	nlh->nlmsg_len = skb_tail_pointer(skb) - b;
1631
	if (NETLINK_CB(cb->skb).portid && ret)
L
Linus Torvalds 已提交
1632 1633 1634 1635
		nlh->nlmsg_flags |= NLM_F_MULTI;
	module_put(a_o->owner);
	return skb->len;

1636
out_module_put:
L
Linus Torvalds 已提交
1637
	module_put(a_o->owner);
1638
	nlmsg_trim(skb, b);
L
Linus Torvalds 已提交
1639 1640 1641 1642 1643
	return skb->len;
}

static int __init tc_action_init(void)
{
1644 1645
	rtnl_register(PF_UNSPEC, RTM_NEWACTION, tc_ctl_action, NULL, 0);
	rtnl_register(PF_UNSPEC, RTM_DELACTION, tc_ctl_action, NULL, 0);
1646
	rtnl_register(PF_UNSPEC, RTM_GETACTION, tc_ctl_action, tc_dump_action,
1647
		      0);
L
Linus Torvalds 已提交
1648 1649 1650 1651 1652

	return 0;
}

subsys_initcall(tc_action_init);