act_api.c 40.7 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 28 29 30 31 32 33 34 35 36 37 38 39 40
#ifdef CONFIG_INET
DEFINE_STATIC_KEY_FALSE(tcf_frag_xmit_count);
EXPORT_SYMBOL_GPL(tcf_frag_xmit_count);
#endif

int tcf_dev_queue_xmit(struct sk_buff *skb, int (*xmit)(struct sk_buff *skb))
{
#ifdef CONFIG_INET
	if (static_branch_unlikely(&tcf_frag_xmit_count))
		return sch_frag_xmit_hook(skb, xmit);
#endif

	return xmit(skb);
}
EXPORT_SYMBOL_GPL(tcf_dev_queue_xmit);

41 42 43
static void tcf_action_goto_chain_exec(const struct tc_action *a,
				       struct tcf_result *res)
{
44
	const struct tcf_chain *chain = rcu_dereference_bh(a->goto_chain);
45 46 47 48

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

49 50 51 52 53 54 55 56 57 58 59 60 61
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;

62
	old = xchg((__force struct tc_cookie **)old_cookie, new_cookie);
63 64 65 66
	if (old)
		call_rcu(&old->rcu, tcf_free_cookie_rcu);
}

67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
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,
104
					 struct tcf_chain *goto_chain)
105 106
{
	a->tcfa_action = action;
107
	goto_chain = rcu_replace_pointer(a->goto_chain, goto_chain, 1);
108
	return goto_chain;
109 110 111
}
EXPORT_SYMBOL(tcf_action_set_ctrlact);

C
Cong Wang 已提交
112 113 114 115 116 117
/* 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)
118
{
119
	struct tcf_chain *chain = rcu_dereference_protected(p->goto_chain, 1);
120

121
	free_percpu(p->cpu_bstats);
122
	free_percpu(p->cpu_bstats_hw);
123
	free_percpu(p->cpu_qstats);
124

125
	tcf_set_action_cookie(&p->act_cookie, NULL);
126 127
	if (chain)
		tcf_chain_put_by_act(chain);
128

129 130 131
	kfree(p);
}

132
static void tcf_action_cleanup(struct tc_action *p)
133
{
134 135 136
	if (p->ops->cleanup)
		p->ops->cleanup(p);

137
	gen_kill_estimator(&p->tcfa_rate_est);
C
Cong Wang 已提交
138
	free_tcf(p);
139 140
}

141 142 143 144
static int __tcf_action_put(struct tc_action *p, bool bind)
{
	struct tcf_idrinfo *idrinfo = p->idrinfo;

145
	if (refcount_dec_and_mutex_lock(&p->tcfa_refcnt, &idrinfo->lock)) {
146 147 148
		if (bind)
			atomic_dec(&p->tcfa_bindcnt);
		idr_remove(&idrinfo->action_idr, p->tcfa_index);
149
		mutex_unlock(&idrinfo->lock);
150 151 152 153 154 155 156 157 158 159 160

		tcf_action_cleanup(p);
		return 1;
	}

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

	return 0;
}

161
static int __tcf_idr_release(struct tc_action *p, bool bind, bool strict)
162 163 164
{
	int ret = 0;

165 166 167 168 169 170 171 172 173 174 175 176
	/* 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.
	 */
177
	if (p) {
178
		if (!bind && strict && atomic_read(&p->tcfa_bindcnt) > 0)
179
			return -EPERM;
180

181
		if (__tcf_action_put(p, bind))
182
			ret = ACT_P_DELETED;
183
	}
184

185 186
	return ret;
}
187 188 189 190 191 192 193 194 195 196 197 198

int tcf_idr_release(struct tc_action *a, bool bind)
{
	const struct tc_action_ops *ops = a->ops;
	int ret;

	ret = __tcf_idr_release(a, bind, false);
	if (ret == ACT_P_DELETED)
		module_put(ops->owner);
	return ret;
}
EXPORT_SYMBOL(tcf_idr_release);
199

200 201
static size_t tcf_action_shared_attrs_size(const struct tc_action *act)
{
202
	struct tc_cookie *act_cookie;
203 204
	u32 cookie_len = 0;

205 206 207 208 209 210
	rcu_read_lock();
	act_cookie = rcu_dereference(act->act_cookie);

	if (act_cookie)
		cookie_len = nla_total_size(act_cookie->len);
	rcu_read_unlock();
211 212 213 214

	return  nla_total_size(0) /* action number nested */
		+ nla_total_size(IFNAMSIZ) /* TCA_ACT_KIND */
		+ cookie_len /* TCA_ACT_COOKIE */
215
		+ nla_total_size(sizeof(struct nla_bitfield32)) /* TCA_ACT_HW_STATS */
216
		+ nla_total_size(0) /* TCA_ACT_STATS nested */
217
		+ nla_total_size(sizeof(struct nla_bitfield32)) /* TCA_ACT_FLAGS */
218 219
		/* TCA_STATS_BASIC */
		+ nla_total_size_64bit(sizeof(struct gnet_stats_basic))
220 221
		/* TCA_STATS_PKT64 */
		+ nla_total_size_64bit(sizeof(u64))
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
		/* 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;
}

245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
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;
}

275
static int tcf_dump_walker(struct tcf_idrinfo *idrinfo, struct sk_buff *skb,
276
			   struct netlink_callback *cb)
277
{
278
	int err = 0, index = -1, s_i = 0, n_i = 0;
279
	u32 act_flags = cb->args[2];
280
	unsigned long jiffy_since = cb->args[3];
281
	struct nlattr *nest;
282 283 284
	struct idr *idr = &idrinfo->action_idr;
	struct tc_action *p;
	unsigned long id = 1;
285
	unsigned long tmp;
286

287
	mutex_lock(&idrinfo->lock);
288 289 290

	s_i = cb->args[0];

291
	idr_for_each_entry_ul(idr, p, tmp, id) {
292 293 294
		index++;
		if (index < s_i)
			continue;
295 296
		if (IS_ERR(p))
			continue;
297 298 299 300 301 302

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

303
		nest = nla_nest_start_noflag(skb, n_i);
304 305
		if (!nest) {
			index--;
306
			goto nla_put_failure;
307
		}
308
		err = (act_flags & TCA_ACT_FLAG_TERSE_DUMP) ?
309 310
			tcf_action_dump_terse(skb, p, true) :
			tcf_action_dump_1(skb, p, 0, 0);
311 312 313 314
		if (err < 0) {
			index--;
			nlmsg_trim(skb, nest);
			goto done;
315
		}
316 317
		nla_nest_end(skb, nest);
		n_i++;
318
		if (!(act_flags & TCA_ACT_FLAG_LARGE_DUMP_ON) &&
319 320
		    n_i >= TCA_ACT_MAX_PRIO)
			goto done;
321 322
	}
done:
323 324 325
	if (index >= 0)
		cb->args[0] = index + 1;

326
	mutex_unlock(&idrinfo->lock);
327
	if (n_i) {
328
		if (act_flags & TCA_ACT_FLAG_LARGE_DUMP_ON)
329 330
			cb->args[1] = n_i;
	}
331 332
	return n_i;

333
nla_put_failure:
334
	nla_nest_cancel(skb, nest);
335 336 337
	goto done;
}

338 339 340 341 342 343 344 345 346 347 348 349 350 351
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;
}

352
static int tcf_del_walker(struct tcf_idrinfo *idrinfo, struct sk_buff *skb,
353
			  const struct tc_action_ops *ops)
354
{
355
	struct nlattr *nest;
356
	int n_i = 0;
357
	int ret = -EINVAL;
358 359 360
	struct idr *idr = &idrinfo->action_idr;
	struct tc_action *p;
	unsigned long id = 1;
361
	unsigned long tmp;
362

363
	nest = nla_nest_start_noflag(skb, 0);
364 365
	if (nest == NULL)
		goto nla_put_failure;
366
	if (nla_put_string(skb, TCA_KIND, ops->kind))
367
		goto nla_put_failure;
368

369
	mutex_lock(&idrinfo->lock);
370
	idr_for_each_entry_ul(idr, p, tmp, id) {
371 372
		if (IS_ERR(p))
			continue;
373
		ret = tcf_idr_release_unsafe(p);
374
		if (ret == ACT_P_DELETED) {
375
			module_put(ops->owner);
376 377
			n_i++;
		} else if (ret < 0) {
378
			mutex_unlock(&idrinfo->lock);
379
			goto nla_put_failure;
380 381
		}
	}
382
	mutex_unlock(&idrinfo->lock);
383

384 385
	ret = nla_put_u32(skb, TCA_FCNT, n_i);
	if (ret)
386
		goto nla_put_failure;
387
	nla_nest_end(skb, nest);
388 389

	return n_i;
390
nla_put_failure:
391
	nla_nest_cancel(skb, nest);
392
	return ret;
393 394
}

395 396
int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,
		       struct netlink_callback *cb, int type,
397 398
		       const struct tc_action_ops *ops,
		       struct netlink_ext_ack *extack)
399
{
400
	struct tcf_idrinfo *idrinfo = tn->idrinfo;
401

402
	if (type == RTM_DELACTION) {
403
		return tcf_del_walker(idrinfo, skb, ops);
404
	} else if (type == RTM_GETACTION) {
405
		return tcf_dump_walker(idrinfo, skb, cb);
406
	} else {
407 408
		WARN(1, "tcf_generic_walker: unknown command %d\n", type);
		NL_SET_ERR_MSG(extack, "tcf_generic_walker: unknown command");
409 410 411
		return -EINVAL;
	}
}
412
EXPORT_SYMBOL(tcf_generic_walker);
413

414
int tcf_idr_search(struct tc_action_net *tn, struct tc_action **a, u32 index)
415
{
416 417
	struct tcf_idrinfo *idrinfo = tn->idrinfo;
	struct tc_action *p;
418

419
	mutex_lock(&idrinfo->lock);
420
	p = idr_find(&idrinfo->action_idr, index);
421
	if (IS_ERR(p))
422
		p = NULL;
423
	else if (p)
424
		refcount_inc(&p->tcfa_refcnt);
425
	mutex_unlock(&idrinfo->lock);
426

427 428 429 430 431
	if (p) {
		*a = p;
		return true;
	}
	return false;
432
}
433
EXPORT_SYMBOL(tcf_idr_search);
434

435
static int tcf_idr_delete_index(struct tcf_idrinfo *idrinfo, u32 index)
436 437 438 439
{
	struct tc_action *p;
	int ret = 0;

440
	mutex_lock(&idrinfo->lock);
441 442
	p = idr_find(&idrinfo->action_idr, index);
	if (!p) {
443
		mutex_unlock(&idrinfo->lock);
444 445 446 447 448 449 450 451 452
		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));
453
			mutex_unlock(&idrinfo->lock);
454

455
			tcf_action_cleanup(p);
456 457 458 459 460 461 462 463
			module_put(owner);
			return 0;
		}
		ret = 0;
	} else {
		ret = -EPERM;
	}

464
	mutex_unlock(&idrinfo->lock);
465 466 467
	return ret;
}

468 469
int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
		   struct tc_action **a, const struct tc_action_ops *ops,
470
		   int bind, bool cpustats, u32 flags)
471
{
472
	struct tc_action *p = kzalloc(ops->size, GFP_KERNEL);
473
	struct tcf_idrinfo *idrinfo = tn->idrinfo;
474
	int err = -ENOMEM;
475 476

	if (unlikely(!p))
477
		return -ENOMEM;
478
	refcount_set(&p->tcfa_refcnt, 1);
479
	if (bind)
480
		atomic_set(&p->tcfa_bindcnt, 1);
481

482 483
	if (cpustats) {
		p->cpu_bstats = netdev_alloc_pcpu_stats(struct gnet_stats_basic_cpu);
484
		if (!p->cpu_bstats)
485
			goto err1;
486 487 488
		p->cpu_bstats_hw = netdev_alloc_pcpu_stats(struct gnet_stats_basic_cpu);
		if (!p->cpu_bstats_hw)
			goto err2;
489 490
		p->cpu_qstats = alloc_percpu(struct gnet_stats_queue);
		if (!p->cpu_qstats)
491
			goto err3;
492
	}
493 494
	gnet_stats_basic_packed_init(&p->tcfa_bstats);
	gnet_stats_basic_packed_init(&p->tcfa_bstats_hw);
495
	spin_lock_init(&p->tcfa_lock);
496
	p->tcfa_index = index;
497 498 499
	p->tcfa_tm.install = jiffies;
	p->tcfa_tm.lastuse = jiffies;
	p->tcfa_tm.firstuse = 0;
500
	p->tcfa_flags = flags & TCA_ACT_FLAGS_USER_MASK;
501
	if (est) {
502 503 504
		err = gen_new_estimator(&p->tcfa_bstats, p->cpu_bstats,
					&p->tcfa_rate_est,
					&p->tcfa_lock, NULL, est);
505
		if (err)
506
			goto err4;
507 508
	}

509
	p->idrinfo = idrinfo;
510
	__module_get(ops->owner);
511 512
	p->ops = ops;
	*a = p;
513
	return 0;
514
err4:
515
	free_percpu(p->cpu_qstats);
516 517
err3:
	free_percpu(p->cpu_bstats_hw);
518 519 520 521 522
err2:
	free_percpu(p->cpu_bstats);
err1:
	kfree(p);
	return err;
523
}
524
EXPORT_SYMBOL(tcf_idr_create);
525

526 527 528 529 530 531 532 533 534 535 536
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);

537 538 539 540 541 542
/* 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;

543
	mutex_lock(&idrinfo->lock);
544 545
	/* Remove ERR_PTR(-EBUSY) allocated by tcf_idr_check_alloc */
	WARN_ON(!IS_ERR(idr_remove(&idrinfo->action_idr, index)));
546
	mutex_unlock(&idrinfo->lock);
547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563
}
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:
564
	mutex_lock(&idrinfo->lock);
565 566 567 568 569 570
	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.
			 */
571
			mutex_unlock(&idrinfo->lock);
572 573 574 575 576 577 578 579 580 581 582 583
			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,
584
					    *index, GFP_KERNEL);
585 586 587 588 589 590 591 592
			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,
593
				    UINT_MAX, GFP_KERNEL);
594 595 596 597
		if (!ret)
			idr_replace(&idrinfo->action_idr, ERR_PTR(-EBUSY),
				    *index);
	}
598
	mutex_unlock(&idrinfo->lock);
599 600 601 602
	return ret;
}
EXPORT_SYMBOL(tcf_idr_check_alloc);

603 604
void tcf_idrinfo_destroy(const struct tc_action_ops *ops,
			 struct tcf_idrinfo *idrinfo)
605
{
606 607 608 609
	struct idr *idr = &idrinfo->action_idr;
	struct tc_action *p;
	int ret;
	unsigned long id = 1;
610
	unsigned long tmp;
611

612
	idr_for_each_entry_ul(idr, p, tmp, id) {
613 614 615 616 617
		ret = __tcf_idr_release(p, false, true);
		if (ret == ACT_P_DELETED)
			module_put(ops->owner);
		else if (ret < 0)
			return;
618
	}
619
	idr_destroy(&idrinfo->action_idr);
620
}
621
EXPORT_SYMBOL(tcf_idrinfo_destroy);
622

623
static LIST_HEAD(act_base);
L
Linus Torvalds 已提交
624 625
static DEFINE_RWLOCK(act_mod_lock);

626 627
int tcf_register_action(struct tc_action_ops *act,
			struct pernet_operations *ops)
L
Linus Torvalds 已提交
628
{
629
	struct tc_action_ops *a;
630
	int ret;
L
Linus Torvalds 已提交
631

632
	if (!act->act || !act->dump || !act->init || !act->walk || !act->lookup)
633 634
		return -EINVAL;

635 636 637 638 639 640 641 642
	/* 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 已提交
643
	write_lock(&act_mod_lock);
644
	list_for_each_entry(a, &act_base, head) {
645
		if (act->id == a->id || (strcmp(act->kind, a->kind) == 0)) {
L
Linus Torvalds 已提交
646
			write_unlock(&act_mod_lock);
647
			unregister_pernet_subsys(ops);
L
Linus Torvalds 已提交
648 649 650
			return -EEXIST;
		}
	}
651
	list_add_tail(&act->head, &act_base);
L
Linus Torvalds 已提交
652
	write_unlock(&act_mod_lock);
653

L
Linus Torvalds 已提交
654 655
	return 0;
}
656
EXPORT_SYMBOL(tcf_register_action);
L
Linus Torvalds 已提交
657

658 659
int tcf_unregister_action(struct tc_action_ops *act,
			  struct pernet_operations *ops)
L
Linus Torvalds 已提交
660
{
661
	struct tc_action_ops *a;
L
Linus Torvalds 已提交
662 663 664
	int err = -ENOENT;

	write_lock(&act_mod_lock);
665 666 667 668
	list_for_each_entry(a, &act_base, head) {
		if (a == act) {
			list_del(&act->head);
			err = 0;
L
Linus Torvalds 已提交
669
			break;
670
		}
L
Linus Torvalds 已提交
671 672
	}
	write_unlock(&act_mod_lock);
673 674
	if (!err)
		unregister_pernet_subsys(ops);
L
Linus Torvalds 已提交
675 676
	return err;
}
677
EXPORT_SYMBOL(tcf_unregister_action);
L
Linus Torvalds 已提交
678 679 680 681

/* lookup by name */
static struct tc_action_ops *tc_lookup_action_n(char *kind)
{
682
	struct tc_action_ops *a, *res = NULL;
L
Linus Torvalds 已提交
683 684 685

	if (kind) {
		read_lock(&act_mod_lock);
686
		list_for_each_entry(a, &act_base, head) {
L
Linus Torvalds 已提交
687
			if (strcmp(kind, a->kind) == 0) {
688 689
				if (try_module_get(a->owner))
					res = a;
L
Linus Torvalds 已提交
690 691 692 693 694
				break;
			}
		}
		read_unlock(&act_mod_lock);
	}
695
	return res;
L
Linus Torvalds 已提交
696 697
}

698 699
/* lookup by nlattr */
static struct tc_action_ops *tc_lookup_action(struct nlattr *kind)
L
Linus Torvalds 已提交
700
{
701
	struct tc_action_ops *a, *res = NULL;
L
Linus Torvalds 已提交
702 703 704

	if (kind) {
		read_lock(&act_mod_lock);
705
		list_for_each_entry(a, &act_base, head) {
706
			if (nla_strcmp(kind, a->kind) == 0) {
707 708
				if (try_module_get(a->owner))
					res = a;
L
Linus Torvalds 已提交
709 710 711 712 713
				break;
			}
		}
		read_unlock(&act_mod_lock);
	}
714
	return res;
L
Linus Torvalds 已提交
715 716
}

717
/*TCA_ACT_MAX_PRIO is 32, there count up to 32 */
718
#define TCA_ACT_MAX_PRIO_MASK 0x1FF
719 720
int tcf_action_exec(struct sk_buff *skb, struct tc_action **actions,
		    int nr_actions, struct tcf_result *res)
L
Linus Torvalds 已提交
721
{
722 723
	u32 jmp_prgcnt = 0;
	u32 jmp_ttl = TCA_ACT_MAX_PRIO; /*matches actions per filter */
724 725
	int i;
	int ret = TC_ACT_OK;
L
Linus Torvalds 已提交
726

727 728 729
	if (skb_skip_tc_classify(skb))
		return TC_ACT_OK;

730
restart_act_graph:
731 732 733
	for (i = 0; i < nr_actions; i++) {
		const struct tc_action *a = actions[i];

734 735 736 737
		if (jmp_prgcnt > 0) {
			jmp_prgcnt -= 1;
			continue;
		}
L
Linus Torvalds 已提交
738
repeat:
739 740 741
		ret = a->ops->act(skb, a, res);
		if (ret == TC_ACT_REPEAT)
			goto repeat;	/* we need a ttl - JHS */
742

743
		if (TC_ACT_EXT_CMP(ret, TC_ACT_JUMP)) {
744 745 746 747 748 749 750 751 752 753 754
			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;
			}
755
		} else if (TC_ACT_EXT_CMP(ret, TC_ACT_GOTO_CHAIN)) {
756 757 758 759
			if (unlikely(!rcu_access_pointer(a->goto_chain))) {
				net_warn_ratelimited("can't go to NULL chain!\n");
				return TC_ACT_SHOT;
			}
760
			tcf_action_goto_chain_exec(a, res);
761 762
		}

763
		if (ret != TC_ACT_PIPE)
764
			break;
L
Linus Torvalds 已提交
765
	}
766

L
Linus Torvalds 已提交
767 768
	return ret;
}
769
EXPORT_SYMBOL(tcf_action_exec);
L
Linus Torvalds 已提交
770

771
int tcf_action_destroy(struct tc_action *actions[], int bind)
L
Linus Torvalds 已提交
772
{
773
	const struct tc_action_ops *ops;
774 775
	struct tc_action *a;
	int ret = 0, i;
L
Linus Torvalds 已提交
776

777 778 779
	for (i = 0; i < TCA_ACT_MAX_PRIO && actions[i]; i++) {
		a = actions[i];
		actions[i] = NULL;
780
		ops = a->ops;
781
		ret = __tcf_idr_release(a, bind, true);
782
		if (ret == ACT_P_DELETED)
783
			module_put(ops->owner);
784 785
		else if (ret < 0)
			return ret;
L
Linus Torvalds 已提交
786
	}
787
	return ret;
L
Linus Torvalds 已提交
788 789
}

790 791 792 793 794
static int tcf_action_put(struct tc_action *p)
{
	return __tcf_action_put(p, false);
}

795
/* Put all actions in this array, skip those NULL's. */
796
static void tcf_action_put_many(struct tc_action *actions[])
797
{
798
	int i;
799

800
	for (i = 0; i < TCA_ACT_MAX_PRIO; i++) {
801
		struct tc_action *a = actions[i];
802
		const struct tc_action_ops *ops;
803

804 805 806
		if (!a)
			continue;
		ops = a->ops;
807 808 809 810 811
		if (tcf_action_put(a))
			module_put(ops->owner);
	}
}

L
Linus Torvalds 已提交
812 813 814 815 816 817
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);
}

818 819 820 821 822 823 824
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;

825
	if (tcf_action_dump_terse(skb, a, false))
826 827
		goto nla_put_failure;

828 829 830 831
	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;
832

833 834 835 836 837
	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;

838 839 840 841
	if (a->tcfa_flags &&
	    nla_put_bitfield32(skb, TCA_ACT_FLAGS,
			       a->tcfa_flags, a->tcfa_flags))
		goto nla_put_failure;
842

843
	nest = nla_nest_start_noflag(skb, TCA_OPTIONS);
844 845
	if (nest == NULL)
		goto nla_put_failure;
E
Eric Dumazet 已提交
846 847
	err = tcf_action_dump_old(skb, a, bind, ref);
	if (err > 0) {
848
		nla_nest_end(skb, nest);
L
Linus Torvalds 已提交
849 850 851
		return err;
	}

852
nla_put_failure:
853
	nlmsg_trim(skb, b);
L
Linus Torvalds 已提交
854 855
	return -1;
}
856
EXPORT_SYMBOL(tcf_action_dump_1);
L
Linus Torvalds 已提交
857

858
int tcf_action_dump(struct sk_buff *skb, struct tc_action *actions[],
859
		    int bind, int ref, bool terse)
L
Linus Torvalds 已提交
860 861
{
	struct tc_action *a;
862
	int err = -EINVAL, i;
863
	struct nlattr *nest;
L
Linus Torvalds 已提交
864

865 866
	for (i = 0; i < TCA_ACT_MAX_PRIO && actions[i]; i++) {
		a = actions[i];
867
		nest = nla_nest_start_noflag(skb, i + 1);
868 869
		if (nest == NULL)
			goto nla_put_failure;
870
		err = terse ? tcf_action_dump_terse(skb, a, false) :
871
			tcf_action_dump_1(skb, a, bind, ref);
L
Linus Torvalds 已提交
872
		if (err < 0)
873
			goto errout;
874
		nla_nest_end(skb, nest);
L
Linus Torvalds 已提交
875 876 877 878
	}

	return 0;

879
nla_put_failure:
880 881
	err = -EINVAL;
errout:
882
	nla_nest_cancel(skb, nest);
883
	return err;
L
Linus Torvalds 已提交
884 885
}

886
static struct tc_cookie *nla_memdup_cookie(struct nlattr **tb)
887
{
888 889 890 891 892 893 894 895
	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;
896
	}
897
	c->len = nla_len(tb[TCA_ACT_COOKIE]);
898

899
	return c;
900 901
}

902
static u8 tcf_action_hw_stats_get(struct nlattr *hw_stats_attr)
903
{
904
	struct nla_bitfield32 hw_stats_bf;
905 906 907 908 909

	/* 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.
	 */
910 911 912 913
	if (!hw_stats_attr)
		return TCA_ACT_HW_STATS_ANY;
	hw_stats_bf = nla_get_bitfield32(hw_stats_attr);
	return hw_stats_bf.value;
914 915
}

916
static const struct nla_policy tcf_action_policy[TCA_ACT_MAX + 1] = {
917
	[TCA_ACT_KIND]		= { .type = NLA_STRING },
918 919 920 921
	[TCA_ACT_INDEX]		= { .type = NLA_U32 },
	[TCA_ACT_COOKIE]	= { .type = NLA_BINARY,
				    .len = TC_COOKIE_MAX_SIZE },
	[TCA_ACT_OPTIONS]	= { .type = NLA_NESTED },
922 923
	[TCA_ACT_FLAGS]		= NLA_POLICY_BITFIELD32(TCA_ACT_FLAGS_NO_PERCPU_STATS),
	[TCA_ACT_HW_STATS]	= NLA_POLICY_BITFIELD32(TCA_ACT_HW_STATS_ANY),
924 925
};

926
void tcf_idr_insert_many(struct tc_action *actions[])
927
{
928
	int i;
929

930 931 932 933 934 935 936 937 938 939 940 941 942 943
	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);
	}
944 945
}

946
struct tc_action_ops *tc_action_load_ops(struct nlattr *nla, bool police,
947 948
					 bool rtnl_held,
					 struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
949
{
950
	struct nlattr *tb[TCA_ACT_MAX + 1];
L
Linus Torvalds 已提交
951 952
	struct tc_action_ops *a_o;
	char act_name[IFNAMSIZ];
953
	struct nlattr *kind;
954
	int err;
L
Linus Torvalds 已提交
955

956
	if (!police) {
957 958
		err = nla_parse_nested_deprecated(tb, TCA_ACT_MAX, nla,
						  tcf_action_policy, extack);
959
		if (err < 0)
960
			return ERR_PTR(err);
961
		err = -EINVAL;
962
		kind = tb[TCA_ACT_KIND];
963 964
		if (!kind) {
			NL_SET_ERR_MSG(extack, "TC action kind must be specified");
965
			return ERR_PTR(err);
966
		}
967
		if (nla_strscpy(act_name, kind, IFNAMSIZ) < 0) {
968
			NL_SET_ERR_MSG(extack, "TC action name too long");
969
			return ERR_PTR(err);
970
		}
L
Linus Torvalds 已提交
971
	} else {
972
		if (strlcpy(act_name, "police", IFNAMSIZ) >= IFNAMSIZ) {
973
			NL_SET_ERR_MSG(extack, "TC action name too long");
974
			return ERR_PTR(-EINVAL);
975
		}
L
Linus Torvalds 已提交
976 977 978 979
	}

	a_o = tc_lookup_action_n(act_name);
	if (a_o == NULL) {
980
#ifdef CONFIG_MODULES
981 982
		if (rtnl_held)
			rtnl_unlock();
983
		request_module("act_%s", act_name);
984 985
		if (rtnl_held)
			rtnl_lock();
L
Linus Torvalds 已提交
986 987 988 989 990 991 992 993 994 995

		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) {
996 997
			module_put(a_o->owner);
			return ERR_PTR(-EAGAIN);
L
Linus Torvalds 已提交
998 999
		}
#endif
1000
		NL_SET_ERR_MSG(extack, "Failed to load TC action module");
1001
		return ERR_PTR(-ENOENT);
L
Linus Torvalds 已提交
1002 1003
	}

1004 1005 1006 1007 1008
	return a_o;
}

struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
				    struct nlattr *nla, struct nlattr *est,
1009
				    struct tc_action_ops *a_o, int *init_res,
1010
				    u32 flags, struct netlink_ext_ack *extack)
1011
{
1012 1013
	bool police = flags & TCA_ACT_FLAGS_POLICE;
	struct nla_bitfield32 userflags = { 0, 0 };
1014 1015 1016 1017 1018 1019
	u8 hw_stats = TCA_ACT_HW_STATS_ANY;
	struct nlattr *tb[TCA_ACT_MAX + 1];
	struct tc_cookie *cookie = NULL;
	struct tc_action *a;
	int err;

L
Linus Torvalds 已提交
1020
	/* backward compatibility for policer */
1021
	if (!police) {
1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035
		err = nla_parse_nested_deprecated(tb, TCA_ACT_MAX, nla,
						  tcf_action_policy, extack);
		if (err < 0)
			return ERR_PTR(err);
		if (tb[TCA_ACT_COOKIE]) {
			cookie = nla_memdup_cookie(tb);
			if (!cookie) {
				NL_SET_ERR_MSG(extack, "No memory to generate TC cookie");
				err = -ENOMEM;
				goto err_out;
			}
		}
		hw_stats = tcf_action_hw_stats_get(tb[TCA_ACT_HW_STATS]);
		if (tb[TCA_ACT_FLAGS])
1036
			userflags = nla_get_bitfield32(tb[TCA_ACT_FLAGS]);
1037

1038 1039
		err = a_o->init(net, tb[TCA_ACT_OPTIONS], est, &a, tp,
				userflags.value | flags, extack);
1040
	} else {
1041 1042
		err = a_o->init(net, nla, est, &a, tp, userflags.value | flags,
				extack);
1043
	}
1044
	if (err < 0)
1045
		goto err_out;
1046
	*init_res = err;
L
Linus Torvalds 已提交
1047

1048
	if (!police && tb[TCA_ACT_COOKIE])
1049
		tcf_set_action_cookie(&a->act_cookie, cookie);
1050

1051
	if (!police)
1052
		a->hw_stats = hw_stats;
1053

L
Linus Torvalds 已提交
1054 1055
	return a;

1056
err_out:
1057 1058 1059 1060
	if (cookie) {
		kfree(cookie->data);
		kfree(cookie);
	}
1061
	return ERR_PTR(err);
L
Linus Torvalds 已提交
1062 1063
}

1064 1065
/* Returns numbers of initialized actions or negative error. */

1066
int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
1067 1068 1069
		    struct nlattr *est, struct tc_action *actions[],
		    int init_res[], size_t *attr_size, u32 flags,
		    struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
1070
{
1071
	struct tc_action_ops *ops[TCA_ACT_MAX_PRIO] = {};
E
Eric Dumazet 已提交
1072
	struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
1073
	struct tc_action *act;
1074
	size_t sz = 0;
1075
	int err;
L
Linus Torvalds 已提交
1076 1077
	int i;

1078 1079
	err = nla_parse_nested_deprecated(tb, TCA_ACT_MAX_PRIO, nla, NULL,
					  extack);
1080
	if (err < 0)
1081
		return err;
L
Linus Torvalds 已提交
1082

1083 1084 1085
	for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
		struct tc_action_ops *a_o;

1086 1087 1088
		a_o = tc_action_load_ops(tb[i], flags & TCA_ACT_FLAGS_POLICE,
					 !(flags & TCA_ACT_FLAGS_NO_RTNL),
					 extack);
1089 1090 1091 1092 1093 1094 1095
		if (IS_ERR(a_o)) {
			err = PTR_ERR(a_o);
			goto err_mod;
		}
		ops[i - 1] = a_o;
	}

1096
	for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
1097 1098
		act = tcf_action_init_1(net, tp, tb[i], est, ops[i - 1],
					&init_res[i - 1], flags, extack);
1099 1100
		if (IS_ERR(act)) {
			err = PTR_ERR(act);
L
Linus Torvalds 已提交
1101
			goto err;
1102
		}
1103
		sz += tcf_action_fill_size(act);
1104 1105
		/* Start from index 0 */
		actions[i - 1] = act;
L
Linus Torvalds 已提交
1106
	}
1107

1108 1109 1110 1111 1112
	/* 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);

1113
	*attr_size = tcf_action_full_attrs_size(sz);
1114 1115
	err = i - 1;
	goto err_mod;
L
Linus Torvalds 已提交
1116 1117

err:
1118
	tcf_action_destroy(actions, flags & TCA_ACT_FLAGS_BIND);
1119 1120 1121 1122 1123
err_mod:
	for (i = 0; i < TCA_ACT_MAX_PRIO; i++) {
		if (ops[i])
			module_put(ops[i]->owner);
	}
1124
	return err;
L
Linus Torvalds 已提交
1125 1126
}

1127 1128
void tcf_action_update_stats(struct tc_action *a, u64 bytes, u64 packets,
			     u64 drops, bool hw)
1129
{
1130 1131
	if (a->cpu_bstats) {
		_bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), bytes, packets);
1132

1133
		this_cpu_ptr(a->cpu_qstats)->drops += drops;
1134 1135 1136 1137 1138 1139

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

1141
	_bstats_update(&a->tcfa_bstats, bytes, packets);
1142
	a->tcfa_qstats.drops += drops;
1143
	if (hw)
1144
		_bstats_update(&a->tcfa_bstats_hw, bytes, packets);
1145 1146 1147
}
EXPORT_SYMBOL(tcf_action_update_stats);

1148
int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *p,
L
Linus Torvalds 已提交
1149 1150 1151 1152
			  int compat_mode)
{
	int err = 0;
	struct gnet_dump d;
1153

1154
	if (p == NULL)
L
Linus Torvalds 已提交
1155 1156 1157
		goto errout;

	/* compat_mode being true specifies a call that is supposed
1158
	 * to add additional backward compatibility statistic TLVs.
L
Linus Torvalds 已提交
1159 1160
	 */
	if (compat_mode) {
1161
		if (p->type == TCA_OLD_COMPAT)
L
Linus Torvalds 已提交
1162
			err = gnet_stats_start_copy_compat(skb, 0,
1163 1164
							   TCA_STATS,
							   TCA_XSTATS,
1165
							   &p->tcfa_lock, &d,
1166
							   TCA_PAD);
L
Linus Torvalds 已提交
1167 1168 1169 1170
		else
			return 0;
	} else
		err = gnet_stats_start_copy(skb, TCA_ACT_STATS,
1171
					    &p->tcfa_lock, &d, TCA_ACT_PAD);
L
Linus Torvalds 已提交
1172 1173 1174 1175

	if (err < 0)
		goto errout;

1176
	if (gnet_stats_copy_basic(NULL, &d, p->cpu_bstats, &p->tcfa_bstats) < 0 ||
1177 1178
	    gnet_stats_copy_basic_hw(NULL, &d, p->cpu_bstats_hw,
				     &p->tcfa_bstats_hw) < 0 ||
1179
	    gnet_stats_copy_rate_est(&d, &p->tcfa_rate_est) < 0 ||
1180
	    gnet_stats_copy_queue(&d, p->cpu_qstats,
1181 1182
				  &p->tcfa_qstats,
				  p->tcfa_qstats.qlen) < 0)
L
Linus Torvalds 已提交
1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193
		goto errout;

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

	return 0;

errout:
	return -1;
}

1194
static int tca_get_fill(struct sk_buff *skb, struct tc_action *actions[],
1195 1196
			u32 portid, u32 seq, u16 flags, int event, int bind,
			int ref)
L
Linus Torvalds 已提交
1197 1198 1199
{
	struct tcamsg *t;
	struct nlmsghdr *nlh;
1200
	unsigned char *b = skb_tail_pointer(skb);
1201
	struct nlattr *nest;
L
Linus Torvalds 已提交
1202

1203
	nlh = nlmsg_put(skb, portid, seq, event, sizeof(*t), flags);
1204 1205 1206
	if (!nlh)
		goto out_nlmsg_trim;
	t = nlmsg_data(nlh);
L
Linus Torvalds 已提交
1207
	t->tca_family = AF_UNSPEC;
1208 1209
	t->tca__pad1 = 0;
	t->tca__pad2 = 0;
1210

1211
	nest = nla_nest_start_noflag(skb, TCA_ACT_TAB);
1212
	if (!nest)
1213
		goto out_nlmsg_trim;
L
Linus Torvalds 已提交
1214

1215
	if (tcf_action_dump(skb, actions, bind, ref, false) < 0)
1216
		goto out_nlmsg_trim;
L
Linus Torvalds 已提交
1217

1218
	nla_nest_end(skb, nest);
1219

1220
	nlh->nlmsg_len = skb_tail_pointer(skb) - b;
L
Linus Torvalds 已提交
1221 1222
	return skb->len;

1223
out_nlmsg_trim:
1224
	nlmsg_trim(skb, b);
L
Linus Torvalds 已提交
1225 1226 1227 1228
	return -1;
}

static int
1229
tcf_get_notify(struct net *net, u32 portid, struct nlmsghdr *n,
1230
	       struct tc_action *actions[], int event,
1231
	       struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
1232 1233 1234 1235 1236 1237
{
	struct sk_buff *skb;

	skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!skb)
		return -ENOBUFS;
1238
	if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, event,
1239
			 0, 1) <= 0) {
1240
		NL_SET_ERR_MSG(extack, "Failed to fill netlink attributes while adding TC action");
L
Linus Torvalds 已提交
1241 1242 1243
		kfree_skb(skb);
		return -EINVAL;
	}
1244

1245
	return rtnl_unicast(skb, net, portid);
L
Linus Torvalds 已提交
1246 1247
}

1248
static struct tc_action *tcf_action_get_1(struct net *net, struct nlattr *nla,
1249 1250
					  struct nlmsghdr *n, u32 portid,
					  struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
1251
{
E
Eric Dumazet 已提交
1252
	struct nlattr *tb[TCA_ACT_MAX + 1];
1253
	const struct tc_action_ops *ops;
L
Linus Torvalds 已提交
1254 1255
	struct tc_action *a;
	int index;
1256
	int err;
L
Linus Torvalds 已提交
1257

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

1263
	err = -EINVAL;
1264
	if (tb[TCA_ACT_INDEX] == NULL ||
1265 1266
	    nla_len(tb[TCA_ACT_INDEX]) < sizeof(index)) {
		NL_SET_ERR_MSG(extack, "Invalid TC action index value");
1267
		goto err_out;
1268
	}
1269
	index = nla_get_u32(tb[TCA_ACT_INDEX]);
L
Linus Torvalds 已提交
1270

1271
	err = -EINVAL;
1272
	ops = tc_lookup_action(tb[TCA_ACT_KIND]);
1273
	if (!ops) { /* could happen in batch of actions */
1274
		NL_SET_ERR_MSG(extack, "Specified TC action kind not found");
1275
		goto err_out;
1276
	}
1277
	err = -ENOENT;
1278 1279
	if (ops->lookup(net, &a, index) == 0) {
		NL_SET_ERR_MSG(extack, "TC action with specified index not found");
L
Linus Torvalds 已提交
1280
		goto err_mod;
1281
	}
L
Linus Torvalds 已提交
1282

1283
	module_put(ops->owner);
L
Linus Torvalds 已提交
1284
	return a;
1285

L
Linus Torvalds 已提交
1286
err_mod:
1287
	module_put(ops->owner);
1288 1289
err_out:
	return ERR_PTR(err);
L
Linus Torvalds 已提交
1290 1291
}

1292
static int tca_action_flush(struct net *net, struct nlattr *nla,
1293 1294
			    struct nlmsghdr *n, u32 portid,
			    struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
1295 1296 1297 1298 1299 1300
{
	struct sk_buff *skb;
	unsigned char *b;
	struct nlmsghdr *nlh;
	struct tcamsg *t;
	struct netlink_callback dcb;
1301
	struct nlattr *nest;
E
Eric Dumazet 已提交
1302
	struct nlattr *tb[TCA_ACT_MAX + 1];
1303
	const struct tc_action_ops *ops;
1304
	struct nlattr *kind;
1305
	int err = -ENOMEM;
L
Linus Torvalds 已提交
1306 1307

	skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
1308
	if (!skb)
1309
		return err;
L
Linus Torvalds 已提交
1310

1311
	b = skb_tail_pointer(skb);
L
Linus Torvalds 已提交
1312

1313 1314
	err = nla_parse_nested_deprecated(tb, TCA_ACT_MAX, nla,
					  tcf_action_policy, extack);
1315
	if (err < 0)
L
Linus Torvalds 已提交
1316 1317
		goto err_out;

1318
	err = -EINVAL;
1319
	kind = tb[TCA_ACT_KIND];
1320
	ops = tc_lookup_action(kind);
1321 1322
	if (!ops) { /*some idjot trying to flush unknown action */
		NL_SET_ERR_MSG(extack, "Cannot flush unknown TC action");
L
Linus Torvalds 已提交
1323
		goto err_out;
1324
	}
L
Linus Torvalds 已提交
1325

1326 1327
	nlh = nlmsg_put(skb, portid, n->nlmsg_seq, RTM_DELACTION,
			sizeof(*t), 0);
1328 1329
	if (!nlh) {
		NL_SET_ERR_MSG(extack, "Failed to create TC action flush notification");
1330
		goto out_module_put;
1331
	}
1332
	t = nlmsg_data(nlh);
L
Linus Torvalds 已提交
1333
	t->tca_family = AF_UNSPEC;
1334 1335
	t->tca__pad1 = 0;
	t->tca__pad2 = 0;
L
Linus Torvalds 已提交
1336

1337
	nest = nla_nest_start_noflag(skb, TCA_ACT_TAB);
1338 1339
	if (!nest) {
		NL_SET_ERR_MSG(extack, "Failed to add new netlink message");
1340
		goto out_module_put;
1341
	}
L
Linus Torvalds 已提交
1342

1343
	err = ops->walk(net, skb, &dcb, RTM_DELACTION, ops, extack);
1344 1345
	if (err <= 0) {
		nla_nest_cancel(skb, nest);
1346
		goto out_module_put;
1347
	}
L
Linus Torvalds 已提交
1348

1349
	nla_nest_end(skb, nest);
L
Linus Torvalds 已提交
1350

1351
	nlh->nlmsg_len = skb_tail_pointer(skb) - b;
L
Linus Torvalds 已提交
1352
	nlh->nlmsg_flags |= NLM_F_ROOT;
1353
	module_put(ops->owner);
1354
	err = rtnetlink_send(skb, net, portid, RTNLGRP_TC,
E
Eric Dumazet 已提交
1355
			     n->nlmsg_flags & NLM_F_ECHO);
1356 1357
	if (err < 0)
		NL_SET_ERR_MSG(extack, "Failed to send TC action flush notification");
L
Linus Torvalds 已提交
1358 1359 1360

	return err;

1361
out_module_put:
1362
	module_put(ops->owner);
L
Linus Torvalds 已提交
1363 1364 1365 1366 1367
err_out:
	kfree_skb(skb);
	return err;
}

1368
static int tcf_action_delete(struct net *net, struct tc_action *actions[])
1369
{
1370
	int i;
1371

1372 1373
	for (i = 0; i < TCA_ACT_MAX_PRIO && actions[i]; i++) {
		struct tc_action *a = actions[i];
1374 1375 1376 1377
		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.
		 */
1378 1379
		struct tcf_idrinfo *idrinfo = a->idrinfo;
		u32 act_index = a->tcfa_index;
1380

1381
		actions[i] = NULL;
1382 1383 1384 1385
		if (tcf_action_put(a)) {
			/* last reference, action was deleted concurrently */
			module_put(ops->owner);
		} else  {
1386 1387
			int ret;

1388
			/* now do the delete */
1389
			ret = tcf_idr_delete_index(idrinfo, act_index);
1390
			if (ret < 0)
1391 1392 1393 1394 1395 1396
				return ret;
		}
	}
	return 0;
}

1397
static int
1398
tcf_del_notify(struct net *net, struct nlmsghdr *n, struct tc_action *actions[],
1399
	       u32 portid, size_t attr_size, struct netlink_ext_ack *extack)
1400 1401 1402 1403
{
	int ret;
	struct sk_buff *skb;

1404 1405
	skb = alloc_skb(attr_size <= NLMSG_GOODSIZE ? NLMSG_GOODSIZE : attr_size,
			GFP_KERNEL);
1406 1407 1408 1409
	if (!skb)
		return -ENOBUFS;

	if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, RTM_DELACTION,
1410
			 0, 2) <= 0) {
1411
		NL_SET_ERR_MSG(extack, "Failed to fill netlink TC action attributes");
1412 1413 1414 1415 1416
		kfree_skb(skb);
		return -EINVAL;
	}

	/* now do the delete */
1417
	ret = tcf_action_delete(net, actions);
1418
	if (ret < 0) {
1419
		NL_SET_ERR_MSG(extack, "Failed to delete TC action");
1420 1421 1422
		kfree_skb(skb);
		return ret;
	}
1423 1424 1425 1426 1427 1428

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

L
Linus Torvalds 已提交
1429
static int
1430
tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
1431
	      u32 portid, int event, struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
1432
{
1433
	int i, ret;
E
Eric Dumazet 已提交
1434
	struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
1435
	struct tc_action *act;
1436
	size_t attr_size = 0;
1437
	struct tc_action *actions[TCA_ACT_MAX_PRIO] = {};
L
Linus Torvalds 已提交
1438

1439 1440
	ret = nla_parse_nested_deprecated(tb, TCA_ACT_MAX_PRIO, nla, NULL,
					  extack);
1441 1442
	if (ret < 0)
		return ret;
L
Linus Torvalds 已提交
1443

E
Eric Dumazet 已提交
1444
	if (event == RTM_DELACTION && n->nlmsg_flags & NLM_F_ROOT) {
1445
		if (tb[1])
1446
			return tca_action_flush(net, tb[1], n, portid, extack);
1447

1448
		NL_SET_ERR_MSG(extack, "Invalid netlink attributes while flushing TC action");
1449
		return -EINVAL;
L
Linus Torvalds 已提交
1450 1451
	}

1452
	for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
1453
		act = tcf_action_get_1(net, tb[i], n, portid, extack);
1454 1455
		if (IS_ERR(act)) {
			ret = PTR_ERR(act);
L
Linus Torvalds 已提交
1456
			goto err;
1457
		}
1458
		attr_size += tcf_action_fill_size(act);
1459
		actions[i - 1] = act;
L
Linus Torvalds 已提交
1460
	}
1461 1462

	attr_size = tcf_action_full_attrs_size(attr_size);
L
Linus Torvalds 已提交
1463 1464

	if (event == RTM_GETACTION)
1465
		ret = tcf_get_notify(net, portid, n, actions, event, extack);
L
Linus Torvalds 已提交
1466
	else { /* delete */
1467
		ret = tcf_del_notify(net, n, actions, portid, attr_size, extack);
1468
		if (ret)
L
Linus Torvalds 已提交
1469
			goto err;
1470
		return 0;
L
Linus Torvalds 已提交
1471 1472
	}
err:
1473
	tcf_action_put_many(actions);
L
Linus Torvalds 已提交
1474 1475 1476
	return ret;
}

1477
static int
1478
tcf_add_notify(struct net *net, struct nlmsghdr *n, struct tc_action *actions[],
1479
	       u32 portid, size_t attr_size, struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
1480 1481 1482
{
	struct sk_buff *skb;

1483 1484
	skb = alloc_skb(attr_size <= NLMSG_GOODSIZE ? NLMSG_GOODSIZE : attr_size,
			GFP_KERNEL);
L
Linus Torvalds 已提交
1485 1486 1487
	if (!skb)
		return -ENOBUFS;

1488 1489
	if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, n->nlmsg_flags,
			 RTM_NEWACTION, 0, 0) <= 0) {
1490
		NL_SET_ERR_MSG(extack, "Failed to fill netlink attributes while adding TC action");
1491 1492 1493
		kfree_skb(skb);
		return -EINVAL;
	}
1494

1495 1496
	return rtnetlink_send(skb, net, portid, RTNLGRP_TC,
			      n->nlmsg_flags & NLM_F_ECHO);
L
Linus Torvalds 已提交
1497 1498
}

J
Jamal Hadi Salim 已提交
1499
static int tcf_action_add(struct net *net, struct nlattr *nla,
1500
			  struct nlmsghdr *n, u32 portid, u32 flags,
1501
			  struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
1502
{
1503
	size_t attr_size = 0;
1504
	int loop, ret, i;
1505
	struct tc_action *actions[TCA_ACT_MAX_PRIO] = {};
1506
	int init_res[TCA_ACT_MAX_PRIO] = {};
L
Linus Torvalds 已提交
1507

1508
	for (loop = 0; loop < 10; loop++) {
1509 1510
		ret = tcf_action_init(net, NULL, nla, NULL, actions, init_res,
				      &attr_size, flags, extack);
1511 1512 1513 1514
		if (ret != -EAGAIN)
			break;
	}

1515
	if (ret < 0)
1516
		return ret;
1517
	ret = tcf_add_notify(net, n, actions, portid, attr_size, extack);
1518 1519 1520 1521 1522 1523

	/* only put existing actions */
	for (i = 0; i < TCA_ACT_MAX_PRIO; i++)
		if (init_res[i] == ACT_P_CREATED)
			actions[i] = NULL;
	tcf_action_put_many(actions);
L
Linus Torvalds 已提交
1524

1525
	return ret;
L
Linus Torvalds 已提交
1526 1527
}

1528
static const struct nla_policy tcaa_policy[TCA_ROOT_MAX + 1] = {
1529 1530
	[TCA_ROOT_FLAGS] = NLA_POLICY_BITFIELD32(TCA_ACT_FLAG_LARGE_DUMP_ON |
						 TCA_ACT_FLAG_TERSE_DUMP),
1531
	[TCA_ROOT_TIME_DELTA]      = { .type = NLA_U32 },
1532 1533
};

1534 1535
static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
			 struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
1536
{
1537
	struct net *net = sock_net(skb->sk);
1538
	struct nlattr *tca[TCA_ROOT_MAX + 1];
G
Gaurav Singh 已提交
1539
	u32 portid = NETLINK_CB(skb).portid;
1540 1541
	u32 flags = 0;
	int ret = 0;
L
Linus Torvalds 已提交
1542

1543 1544
	if ((n->nlmsg_type != RTM_GETACTION) &&
	    !netlink_capable(skb, CAP_NET_ADMIN))
1545 1546
		return -EPERM;

1547 1548
	ret = nlmsg_parse_deprecated(n, sizeof(struct tcamsg), tca,
				     TCA_ROOT_MAX, NULL, extack);
1549 1550 1551 1552
	if (ret < 0)
		return ret;

	if (tca[TCA_ACT_TAB] == NULL) {
1553
		NL_SET_ERR_MSG(extack, "Netlink action attributes missing");
L
Linus Torvalds 已提交
1554 1555 1556
		return -EINVAL;
	}

E
Eric Dumazet 已提交
1557
	/* n->nlmsg_flags & NLM_F_CREATE */
L
Linus Torvalds 已提交
1558 1559 1560
	switch (n->nlmsg_type) {
	case RTM_NEWACTION:
		/* we are going to assume all other flags
L
Lucas De Marchi 已提交
1561
		 * imply create only if it doesn't exist
L
Linus Torvalds 已提交
1562 1563 1564 1565
		 * Note that CREATE | EXCL implies that
		 * but since we want avoid ambiguity (eg when flags
		 * is zero) then just set this
		 */
E
Eric Dumazet 已提交
1566
		if (n->nlmsg_flags & NLM_F_REPLACE)
1567 1568
			flags = TCA_ACT_FLAGS_REPLACE;
		ret = tcf_action_add(net, tca[TCA_ACT_TAB], n, portid, flags,
1569
				     extack);
L
Linus Torvalds 已提交
1570 1571
		break;
	case RTM_DELACTION:
1572
		ret = tca_action_gd(net, tca[TCA_ACT_TAB], n,
1573
				    portid, RTM_DELACTION, extack);
L
Linus Torvalds 已提交
1574 1575
		break;
	case RTM_GETACTION:
1576
		ret = tca_action_gd(net, tca[TCA_ACT_TAB], n,
1577
				    portid, RTM_GETACTION, extack);
L
Linus Torvalds 已提交
1578 1579 1580 1581 1582 1583 1584 1585
		break;
	default:
		BUG();
	}

	return ret;
}

1586
static struct nlattr *find_dump_kind(struct nlattr **nla)
L
Linus Torvalds 已提交
1587
{
E
Eric Dumazet 已提交
1588
	struct nlattr *tb1, *tb2[TCA_ACT_MAX + 1];
1589 1590
	struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
	struct nlattr *kind;
L
Linus Torvalds 已提交
1591

1592
	tb1 = nla[TCA_ACT_TAB];
L
Linus Torvalds 已提交
1593 1594 1595
	if (tb1 == NULL)
		return NULL;

1596
	if (nla_parse_deprecated(tb, TCA_ACT_MAX_PRIO, nla_data(tb1), NLMSG_ALIGN(nla_len(tb1)), NULL, NULL) < 0)
L
Linus Torvalds 已提交
1597 1598
		return NULL;

1599 1600
	if (tb[1] == NULL)
		return NULL;
1601
	if (nla_parse_nested_deprecated(tb2, TCA_ACT_MAX, tb[1], tcf_action_policy, NULL) < 0)
L
Linus Torvalds 已提交
1602
		return NULL;
1603
	kind = tb2[TCA_ACT_KIND];
L
Linus Torvalds 已提交
1604

1605
	return kind;
L
Linus Torvalds 已提交
1606 1607
}

J
Jamal Hadi Salim 已提交
1608
static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
L
Linus Torvalds 已提交
1609
{
1610
	struct net *net = sock_net(skb->sk);
L
Linus Torvalds 已提交
1611
	struct nlmsghdr *nlh;
1612
	unsigned char *b = skb_tail_pointer(skb);
1613
	struct nlattr *nest;
L
Linus Torvalds 已提交
1614 1615
	struct tc_action_ops *a_o;
	int ret = 0;
1616
	struct tcamsg *t = (struct tcamsg *) nlmsg_data(cb->nlh);
1617 1618
	struct nlattr *tb[TCA_ROOT_MAX + 1];
	struct nlattr *count_attr = NULL;
1619
	unsigned long jiffy_since = 0;
1620 1621
	struct nlattr *kind = NULL;
	struct nla_bitfield32 bf;
1622
	u32 msecs_since = 0;
1623 1624
	u32 act_count = 0;

1625 1626
	ret = nlmsg_parse_deprecated(cb->nlh, sizeof(struct tcamsg), tb,
				     TCA_ROOT_MAX, tcaa_policy, cb->extack);
1627 1628
	if (ret < 0)
		return ret;
L
Linus Torvalds 已提交
1629

1630
	kind = find_dump_kind(tb);
L
Linus Torvalds 已提交
1631
	if (kind == NULL) {
1632
		pr_info("tc_dump_action: action bad kind\n");
L
Linus Torvalds 已提交
1633 1634 1635
		return 0;
	}

1636
	a_o = tc_lookup_action(kind);
E
Eric Dumazet 已提交
1637
	if (a_o == NULL)
L
Linus Torvalds 已提交
1638 1639
		return 0;

1640 1641 1642 1643 1644 1645
	cb->args[2] = 0;
	if (tb[TCA_ROOT_FLAGS]) {
		bf = nla_get_bitfield32(tb[TCA_ROOT_FLAGS]);
		cb->args[2] = bf.value;
	}

1646 1647 1648 1649
	if (tb[TCA_ROOT_TIME_DELTA]) {
		msecs_since = nla_get_u32(tb[TCA_ROOT_TIME_DELTA]);
	}

1650
	nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
1651 1652 1653
			cb->nlh->nlmsg_type, sizeof(*t), 0);
	if (!nlh)
		goto out_module_put;
1654

1655 1656 1657
	if (msecs_since)
		jiffy_since = jiffies - msecs_to_jiffies(msecs_since);

1658
	t = nlmsg_data(nlh);
L
Linus Torvalds 已提交
1659
	t->tca_family = AF_UNSPEC;
1660 1661
	t->tca__pad1 = 0;
	t->tca__pad2 = 0;
1662
	cb->args[3] = jiffy_since;
1663 1664 1665
	count_attr = nla_reserve(skb, TCA_ROOT_COUNT, sizeof(u32));
	if (!count_attr)
		goto out_module_put;
L
Linus Torvalds 已提交
1666

1667
	nest = nla_nest_start_noflag(skb, TCA_ACT_TAB);
1668
	if (nest == NULL)
1669
		goto out_module_put;
L
Linus Torvalds 已提交
1670

1671
	ret = a_o->walk(net, skb, cb, RTM_GETACTION, a_o, NULL);
L
Linus Torvalds 已提交
1672
	if (ret < 0)
1673
		goto out_module_put;
L
Linus Torvalds 已提交
1674 1675

	if (ret > 0) {
1676
		nla_nest_end(skb, nest);
L
Linus Torvalds 已提交
1677
		ret = skb->len;
1678 1679 1680
		act_count = cb->args[1];
		memcpy(nla_data(count_attr), &act_count, sizeof(u32));
		cb->args[1] = 0;
L
Linus Torvalds 已提交
1681
	} else
1682
		nlmsg_trim(skb, b);
L
Linus Torvalds 已提交
1683

1684
	nlh->nlmsg_len = skb_tail_pointer(skb) - b;
1685
	if (NETLINK_CB(cb->skb).portid && ret)
L
Linus Torvalds 已提交
1686 1687 1688 1689
		nlh->nlmsg_flags |= NLM_F_MULTI;
	module_put(a_o->owner);
	return skb->len;

1690
out_module_put:
L
Linus Torvalds 已提交
1691
	module_put(a_o->owner);
1692
	nlmsg_trim(skb, b);
L
Linus Torvalds 已提交
1693 1694 1695 1696 1697
	return skb->len;
}

static int __init tc_action_init(void)
{
1698 1699
	rtnl_register(PF_UNSPEC, RTM_NEWACTION, tc_ctl_action, NULL, 0);
	rtnl_register(PF_UNSPEC, RTM_DELACTION, tc_ctl_action, NULL, 0);
1700
	rtnl_register(PF_UNSPEC, RTM_GETACTION, tc_ctl_action, tc_dump_action,
1701
		      0);
L
Linus Torvalds 已提交
1702 1703 1704 1705 1706

	return 0;
}

subsys_initcall(tc_action_init);