act_api.c revision 1f747c26c48bb290c79c34e155860c7e2ec3926a
1/* 2 * net/sched/act_api.c Packet action API. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 7 * 2 of the License, or (at your option) any later version. 8 * 9 * Author: Jamal Hadi Salim 10 * 11 * 12 */ 13 14#include <linux/types.h> 15#include <linux/kernel.h> 16#include <linux/string.h> 17#include <linux/errno.h> 18#include <linux/slab.h> 19#include <linux/skbuff.h> 20#include <linux/init.h> 21#include <linux/kmod.h> 22#include <linux/err.h> 23#include <linux/module.h> 24#include <net/net_namespace.h> 25#include <net/sock.h> 26#include <net/sch_generic.h> 27#include <net/act_api.h> 28#include <net/netlink.h> 29 30void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo) 31{ 32 spin_lock_bh(&hinfo->lock); 33 hlist_del(&p->tcfc_head); 34 spin_unlock_bh(&hinfo->lock); 35 gen_kill_estimator(&p->tcfc_bstats, 36 &p->tcfc_rate_est); 37 /* 38 * gen_estimator est_timer() might access p->tcfc_lock 39 * or bstats, wait a RCU grace period before freeing p 40 */ 41 kfree_rcu(p, tcfc_rcu); 42} 43EXPORT_SYMBOL(tcf_hash_destroy); 44 45int tcf_hash_release(struct tcf_common *p, int bind, 46 struct tcf_hashinfo *hinfo) 47{ 48 int ret = 0; 49 50 if (p) { 51 if (bind) 52 p->tcfc_bindcnt--; 53 54 p->tcfc_refcnt--; 55 if (p->tcfc_bindcnt <= 0 && p->tcfc_refcnt <= 0) { 56 tcf_hash_destroy(p, hinfo); 57 ret = 1; 58 } 59 } 60 return ret; 61} 62EXPORT_SYMBOL(tcf_hash_release); 63 64static int tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb, 65 struct tc_action *a, struct tcf_hashinfo *hinfo) 66{ 67 struct hlist_head *head; 68 struct tcf_common *p; 69 int err = 0, index = -1, i = 0, s_i = 0, n_i = 0; 70 struct nlattr *nest; 71 72 spin_lock_bh(&hinfo->lock); 73 74 s_i = cb->args[0]; 75 76 for (i = 0; i < (hinfo->hmask + 1); i++) { 77 head = &hinfo->htab[tcf_hash(i, hinfo->hmask)]; 78 79 hlist_for_each_entry_rcu(p, head, tcfc_head) { 80 index++; 81 if (index < s_i) 82 continue; 83 a->priv = p; 84 a->order = n_i; 85 86 nest = nla_nest_start(skb, a->order); 87 if (nest == NULL) 88 goto nla_put_failure; 89 err = tcf_action_dump_1(skb, a, 0, 0); 90 if (err < 0) { 91 index--; 92 nlmsg_trim(skb, nest); 93 goto done; 94 } 95 nla_nest_end(skb, nest); 96 n_i++; 97 if (n_i >= TCA_ACT_MAX_PRIO) 98 goto done; 99 } 100 } 101done: 102 spin_unlock_bh(&hinfo->lock); 103 if (n_i) 104 cb->args[0] += n_i; 105 return n_i; 106 107nla_put_failure: 108 nla_nest_cancel(skb, nest); 109 goto done; 110} 111 112static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a, 113 struct tcf_hashinfo *hinfo) 114{ 115 struct hlist_head *head; 116 struct hlist_node *n; 117 struct tcf_common *p; 118 struct nlattr *nest; 119 int i = 0, n_i = 0; 120 121 nest = nla_nest_start(skb, a->order); 122 if (nest == NULL) 123 goto nla_put_failure; 124 if (nla_put_string(skb, TCA_KIND, a->ops->kind)) 125 goto nla_put_failure; 126 for (i = 0; i < (hinfo->hmask + 1); i++) { 127 head = &hinfo->htab[tcf_hash(i, hinfo->hmask)]; 128 hlist_for_each_entry_safe(p, n, head, tcfc_head) { 129 if (ACT_P_DELETED == tcf_hash_release(p, 0, hinfo)) 130 module_put(a->ops->owner); 131 n_i++; 132 } 133 } 134 if (nla_put_u32(skb, TCA_FCNT, n_i)) 135 goto nla_put_failure; 136 nla_nest_end(skb, nest); 137 138 return n_i; 139nla_put_failure: 140 nla_nest_cancel(skb, nest); 141 return -EINVAL; 142} 143 144int tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb, 145 int type, struct tc_action *a) 146{ 147 struct tcf_hashinfo *hinfo = a->ops->hinfo; 148 149 if (type == RTM_DELACTION) { 150 return tcf_del_walker(skb, a, hinfo); 151 } else if (type == RTM_GETACTION) { 152 return tcf_dump_walker(skb, cb, a, hinfo); 153 } else { 154 WARN(1, "tcf_generic_walker: unknown action %d\n", type); 155 return -EINVAL; 156 } 157} 158EXPORT_SYMBOL(tcf_generic_walker); 159 160struct tcf_common *tcf_hash_lookup(u32 index, struct tcf_hashinfo *hinfo) 161{ 162 struct tcf_common *p = NULL; 163 struct hlist_head *head; 164 165 spin_lock_bh(&hinfo->lock); 166 head = &hinfo->htab[tcf_hash(index, hinfo->hmask)]; 167 hlist_for_each_entry_rcu(p, head, tcfc_head) 168 if (p->tcfc_index == index) 169 break; 170 spin_unlock_bh(&hinfo->lock); 171 172 return p; 173} 174EXPORT_SYMBOL(tcf_hash_lookup); 175 176u32 tcf_hash_new_index(u32 *idx_gen, struct tcf_hashinfo *hinfo) 177{ 178 u32 val = *idx_gen; 179 180 do { 181 if (++val == 0) 182 val = 1; 183 } while (tcf_hash_lookup(val, hinfo)); 184 185 *idx_gen = val; 186 return val; 187} 188EXPORT_SYMBOL(tcf_hash_new_index); 189 190int tcf_hash_search(struct tc_action *a, u32 index) 191{ 192 struct tcf_hashinfo *hinfo = a->ops->hinfo; 193 struct tcf_common *p = tcf_hash_lookup(index, hinfo); 194 195 if (p) { 196 a->priv = p; 197 return 1; 198 } 199 return 0; 200} 201EXPORT_SYMBOL(tcf_hash_search); 202 203struct tcf_common *tcf_hash_check(u32 index, struct tc_action *a, int bind, 204 struct tcf_hashinfo *hinfo) 205{ 206 struct tcf_common *p = NULL; 207 if (index && (p = tcf_hash_lookup(index, hinfo)) != NULL) { 208 if (bind) 209 p->tcfc_bindcnt++; 210 p->tcfc_refcnt++; 211 a->priv = p; 212 } 213 return p; 214} 215EXPORT_SYMBOL(tcf_hash_check); 216 217struct tcf_common *tcf_hash_create(u32 index, struct nlattr *est, 218 struct tc_action *a, int size, int bind, 219 u32 *idx_gen, struct tcf_hashinfo *hinfo) 220{ 221 struct tcf_common *p = kzalloc(size, GFP_KERNEL); 222 223 if (unlikely(!p)) 224 return ERR_PTR(-ENOMEM); 225 p->tcfc_refcnt = 1; 226 if (bind) 227 p->tcfc_bindcnt = 1; 228 229 spin_lock_init(&p->tcfc_lock); 230 INIT_HLIST_NODE(&p->tcfc_head); 231 p->tcfc_index = index ? index : tcf_hash_new_index(idx_gen, hinfo); 232 p->tcfc_tm.install = jiffies; 233 p->tcfc_tm.lastuse = jiffies; 234 if (est) { 235 int err = gen_new_estimator(&p->tcfc_bstats, &p->tcfc_rate_est, 236 &p->tcfc_lock, est); 237 if (err) { 238 kfree(p); 239 return ERR_PTR(err); 240 } 241 } 242 243 a->priv = (void *) p; 244 return p; 245} 246EXPORT_SYMBOL(tcf_hash_create); 247 248void tcf_hash_insert(struct tcf_common *p, struct tcf_hashinfo *hinfo) 249{ 250 unsigned int h = tcf_hash(p->tcfc_index, hinfo->hmask); 251 252 spin_lock_bh(&hinfo->lock); 253 hlist_add_head(&p->tcfc_head, &hinfo->htab[h]); 254 spin_unlock_bh(&hinfo->lock); 255} 256EXPORT_SYMBOL(tcf_hash_insert); 257 258static LIST_HEAD(act_base); 259static DEFINE_RWLOCK(act_mod_lock); 260 261int tcf_register_action(struct tc_action_ops *act) 262{ 263 struct tc_action_ops *a; 264 265 /* Must supply act, dump, cleanup and init */ 266 if (!act->act || !act->dump || !act->cleanup || !act->init) 267 return -EINVAL; 268 269 /* Supply defaults */ 270 if (!act->lookup) 271 act->lookup = tcf_hash_search; 272 if (!act->walk) 273 act->walk = tcf_generic_walker; 274 275 write_lock(&act_mod_lock); 276 list_for_each_entry(a, &act_base, head) { 277 if (act->type == a->type || (strcmp(act->kind, a->kind) == 0)) { 278 write_unlock(&act_mod_lock); 279 return -EEXIST; 280 } 281 } 282 list_add_tail(&act->head, &act_base); 283 write_unlock(&act_mod_lock); 284 return 0; 285} 286EXPORT_SYMBOL(tcf_register_action); 287 288int tcf_unregister_action(struct tc_action_ops *act) 289{ 290 struct tc_action_ops *a; 291 int err = -ENOENT; 292 293 write_lock(&act_mod_lock); 294 list_for_each_entry(a, &act_base, head) 295 if (a == act) 296 break; 297 if (a) { 298 list_del(&act->head); 299 err = 0; 300 } 301 write_unlock(&act_mod_lock); 302 return err; 303} 304EXPORT_SYMBOL(tcf_unregister_action); 305 306/* lookup by name */ 307static struct tc_action_ops *tc_lookup_action_n(char *kind) 308{ 309 struct tc_action_ops *a = NULL; 310 311 if (kind) { 312 read_lock(&act_mod_lock); 313 list_for_each_entry(a, &act_base, head) { 314 if (strcmp(kind, a->kind) == 0) { 315 if (!try_module_get(a->owner)) { 316 read_unlock(&act_mod_lock); 317 return NULL; 318 } 319 break; 320 } 321 } 322 read_unlock(&act_mod_lock); 323 } 324 return a; 325} 326 327/* lookup by nlattr */ 328static struct tc_action_ops *tc_lookup_action(struct nlattr *kind) 329{ 330 struct tc_action_ops *a = NULL; 331 332 if (kind) { 333 read_lock(&act_mod_lock); 334 list_for_each_entry(a, &act_base, head) { 335 if (nla_strcmp(kind, a->kind) == 0) { 336 if (!try_module_get(a->owner)) { 337 read_unlock(&act_mod_lock); 338 return NULL; 339 } 340 break; 341 } 342 } 343 read_unlock(&act_mod_lock); 344 } 345 return a; 346} 347 348#if 0 349/* lookup by id */ 350static struct tc_action_ops *tc_lookup_action_id(u32 type) 351{ 352 struct tc_action_ops *a = NULL; 353 354 if (type) { 355 read_lock(&act_mod_lock); 356 for (a = act_base; a; a = a->next) { 357 if (a->type == type) { 358 if (!try_module_get(a->owner)) { 359 read_unlock(&act_mod_lock); 360 return NULL; 361 } 362 break; 363 } 364 } 365 read_unlock(&act_mod_lock); 366 } 367 return a; 368} 369#endif 370 371int tcf_action_exec(struct sk_buff *skb, const struct list_head *actions, 372 struct tcf_result *res) 373{ 374 const struct tc_action *a; 375 int ret = -1; 376 377 if (skb->tc_verd & TC_NCLS) { 378 skb->tc_verd = CLR_TC_NCLS(skb->tc_verd); 379 ret = TC_ACT_OK; 380 goto exec_done; 381 } 382 list_for_each_entry(a, actions, list) { 383repeat: 384 if (a->ops) { 385 ret = a->ops->act(skb, a, res); 386 if (TC_MUNGED & skb->tc_verd) { 387 /* copied already, allow trampling */ 388 skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd); 389 skb->tc_verd = CLR_TC_MUNGED(skb->tc_verd); 390 } 391 if (ret == TC_ACT_REPEAT) 392 goto repeat; /* we need a ttl - JHS */ 393 if (ret != TC_ACT_PIPE) 394 goto exec_done; 395 } 396 } 397exec_done: 398 return ret; 399} 400EXPORT_SYMBOL(tcf_action_exec); 401 402void tcf_action_destroy(struct list_head *actions, int bind) 403{ 404 struct tc_action *a, *tmp; 405 406 list_for_each_entry_safe(a, tmp, actions, list) { 407 if (a->ops) { 408 if (a->ops->cleanup(a, bind) == ACT_P_DELETED) 409 module_put(a->ops->owner); 410 list_del(&a->list); 411 kfree(a); 412 } else { 413 /*FIXME: Remove later - catch insertion bugs*/ 414 WARN(1, "tcf_action_destroy: BUG? destroying NULL ops\n"); 415 list_del(&a->list); 416 kfree(a); 417 } 418 } 419} 420 421int 422tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int bind, int ref) 423{ 424 int err = -EINVAL; 425 426 if (a->ops == NULL) 427 return err; 428 return a->ops->dump(skb, a, bind, ref); 429} 430 431int 432tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref) 433{ 434 int err = -EINVAL; 435 unsigned char *b = skb_tail_pointer(skb); 436 struct nlattr *nest; 437 438 if (a->ops == NULL) 439 return err; 440 441 if (nla_put_string(skb, TCA_KIND, a->ops->kind)) 442 goto nla_put_failure; 443 if (tcf_action_copy_stats(skb, a, 0)) 444 goto nla_put_failure; 445 nest = nla_nest_start(skb, TCA_OPTIONS); 446 if (nest == NULL) 447 goto nla_put_failure; 448 err = tcf_action_dump_old(skb, a, bind, ref); 449 if (err > 0) { 450 nla_nest_end(skb, nest); 451 return err; 452 } 453 454nla_put_failure: 455 nlmsg_trim(skb, b); 456 return -1; 457} 458EXPORT_SYMBOL(tcf_action_dump_1); 459 460int 461tcf_action_dump(struct sk_buff *skb, struct list_head *actions, int bind, int ref) 462{ 463 struct tc_action *a; 464 int err = -EINVAL; 465 struct nlattr *nest; 466 467 list_for_each_entry(a, actions, list) { 468 nest = nla_nest_start(skb, a->order); 469 if (nest == NULL) 470 goto nla_put_failure; 471 err = tcf_action_dump_1(skb, a, bind, ref); 472 if (err < 0) 473 goto errout; 474 nla_nest_end(skb, nest); 475 } 476 477 return 0; 478 479nla_put_failure: 480 err = -EINVAL; 481errout: 482 nla_nest_cancel(skb, nest); 483 return err; 484} 485 486struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla, 487 struct nlattr *est, char *name, int ovr, 488 int bind) 489{ 490 struct tc_action *a; 491 struct tc_action_ops *a_o; 492 char act_name[IFNAMSIZ]; 493 struct nlattr *tb[TCA_ACT_MAX + 1]; 494 struct nlattr *kind; 495 int err; 496 497 if (name == NULL) { 498 err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL); 499 if (err < 0) 500 goto err_out; 501 err = -EINVAL; 502 kind = tb[TCA_ACT_KIND]; 503 if (kind == NULL) 504 goto err_out; 505 if (nla_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ) 506 goto err_out; 507 } else { 508 err = -EINVAL; 509 if (strlcpy(act_name, name, IFNAMSIZ) >= IFNAMSIZ) 510 goto err_out; 511 } 512 513 a_o = tc_lookup_action_n(act_name); 514 if (a_o == NULL) { 515#ifdef CONFIG_MODULES 516 rtnl_unlock(); 517 request_module("act_%s", act_name); 518 rtnl_lock(); 519 520 a_o = tc_lookup_action_n(act_name); 521 522 /* We dropped the RTNL semaphore in order to 523 * perform the module load. So, even if we 524 * succeeded in loading the module we have to 525 * tell the caller to replay the request. We 526 * indicate this using -EAGAIN. 527 */ 528 if (a_o != NULL) { 529 err = -EAGAIN; 530 goto err_mod; 531 } 532#endif 533 err = -ENOENT; 534 goto err_out; 535 } 536 537 err = -ENOMEM; 538 a = kzalloc(sizeof(*a), GFP_KERNEL); 539 if (a == NULL) 540 goto err_mod; 541 542 INIT_LIST_HEAD(&a->list); 543 /* backward compatibility for policer */ 544 if (name == NULL) 545 err = a_o->init(net, tb[TCA_ACT_OPTIONS], est, a, ovr, bind); 546 else 547 err = a_o->init(net, nla, est, a, ovr, bind); 548 if (err < 0) 549 goto err_free; 550 551 /* module count goes up only when brand new policy is created 552 * if it exists and is only bound to in a_o->init() then 553 * ACT_P_CREATED is not returned (a zero is). 554 */ 555 if (err != ACT_P_CREATED) 556 module_put(a_o->owner); 557 a->ops = a_o; 558 559 return a; 560 561err_free: 562 kfree(a); 563err_mod: 564 module_put(a_o->owner); 565err_out: 566 return ERR_PTR(err); 567} 568 569int tcf_action_init(struct net *net, struct nlattr *nla, 570 struct nlattr *est, char *name, int ovr, 571 int bind, struct list_head *actions) 572{ 573 struct nlattr *tb[TCA_ACT_MAX_PRIO + 1]; 574 struct tc_action *act; 575 int err; 576 int i; 577 578 err = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL); 579 if (err < 0) 580 return err; 581 582 for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) { 583 act = tcf_action_init_1(net, tb[i], est, name, ovr, bind); 584 if (IS_ERR(act)) { 585 err = PTR_ERR(act); 586 goto err; 587 } 588 act->order = i; 589 list_add_tail(&act->list, actions); 590 } 591 return 0; 592 593err: 594 tcf_action_destroy(actions, bind); 595 return err; 596} 597 598int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a, 599 int compat_mode) 600{ 601 int err = 0; 602 struct gnet_dump d; 603 struct tcf_act_hdr *h = a->priv; 604 605 if (h == NULL) 606 goto errout; 607 608 /* compat_mode being true specifies a call that is supposed 609 * to add additional backward compatibility statistic TLVs. 610 */ 611 if (compat_mode) { 612 if (a->type == TCA_OLD_COMPAT) 613 err = gnet_stats_start_copy_compat(skb, 0, 614 TCA_STATS, TCA_XSTATS, &h->tcf_lock, &d); 615 else 616 return 0; 617 } else 618 err = gnet_stats_start_copy(skb, TCA_ACT_STATS, 619 &h->tcf_lock, &d); 620 621 if (err < 0) 622 goto errout; 623 624 if (gnet_stats_copy_basic(&d, &h->tcf_bstats) < 0 || 625 gnet_stats_copy_rate_est(&d, &h->tcf_bstats, 626 &h->tcf_rate_est) < 0 || 627 gnet_stats_copy_queue(&d, &h->tcf_qstats) < 0) 628 goto errout; 629 630 if (gnet_stats_finish_copy(&d) < 0) 631 goto errout; 632 633 return 0; 634 635errout: 636 return -1; 637} 638 639static int 640tca_get_fill(struct sk_buff *skb, struct list_head *actions, u32 portid, u32 seq, 641 u16 flags, int event, int bind, int ref) 642{ 643 struct tcamsg *t; 644 struct nlmsghdr *nlh; 645 unsigned char *b = skb_tail_pointer(skb); 646 struct nlattr *nest; 647 648 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*t), flags); 649 if (!nlh) 650 goto out_nlmsg_trim; 651 t = nlmsg_data(nlh); 652 t->tca_family = AF_UNSPEC; 653 t->tca__pad1 = 0; 654 t->tca__pad2 = 0; 655 656 nest = nla_nest_start(skb, TCA_ACT_TAB); 657 if (nest == NULL) 658 goto out_nlmsg_trim; 659 660 if (tcf_action_dump(skb, actions, bind, ref) < 0) 661 goto out_nlmsg_trim; 662 663 nla_nest_end(skb, nest); 664 665 nlh->nlmsg_len = skb_tail_pointer(skb) - b; 666 return skb->len; 667 668out_nlmsg_trim: 669 nlmsg_trim(skb, b); 670 return -1; 671} 672 673static int 674act_get_notify(struct net *net, u32 portid, struct nlmsghdr *n, 675 struct list_head *actions, int event) 676{ 677 struct sk_buff *skb; 678 679 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 680 if (!skb) 681 return -ENOBUFS; 682 if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, event, 0, 0) <= 0) { 683 kfree_skb(skb); 684 return -EINVAL; 685 } 686 687 return rtnl_unicast(skb, net, portid); 688} 689 690static struct tc_action * 691tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 portid) 692{ 693 struct nlattr *tb[TCA_ACT_MAX + 1]; 694 struct tc_action *a; 695 int index; 696 int err; 697 698 err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL); 699 if (err < 0) 700 goto err_out; 701 702 err = -EINVAL; 703 if (tb[TCA_ACT_INDEX] == NULL || 704 nla_len(tb[TCA_ACT_INDEX]) < sizeof(index)) 705 goto err_out; 706 index = nla_get_u32(tb[TCA_ACT_INDEX]); 707 708 err = -ENOMEM; 709 a = kzalloc(sizeof(struct tc_action), GFP_KERNEL); 710 if (a == NULL) 711 goto err_out; 712 713 INIT_LIST_HEAD(&a->list); 714 err = -EINVAL; 715 a->ops = tc_lookup_action(tb[TCA_ACT_KIND]); 716 if (a->ops == NULL) 717 goto err_free; 718 err = -ENOENT; 719 if (a->ops->lookup(a, index) == 0) 720 goto err_mod; 721 722 module_put(a->ops->owner); 723 return a; 724 725err_mod: 726 module_put(a->ops->owner); 727err_free: 728 kfree(a); 729err_out: 730 return ERR_PTR(err); 731} 732 733static void cleanup_a(struct list_head *actions) 734{ 735 struct tc_action *a, *tmp; 736 737 list_for_each_entry_safe(a, tmp, actions, list) { 738 list_del(&a->list); 739 kfree(a); 740 } 741} 742 743static struct tc_action *create_a(int i) 744{ 745 struct tc_action *act; 746 747 act = kzalloc(sizeof(*act), GFP_KERNEL); 748 if (act == NULL) { 749 pr_debug("create_a: failed to alloc!\n"); 750 return NULL; 751 } 752 act->order = i; 753 INIT_LIST_HEAD(&act->list); 754 return act; 755} 756 757static int tca_action_flush(struct net *net, struct nlattr *nla, 758 struct nlmsghdr *n, u32 portid) 759{ 760 struct sk_buff *skb; 761 unsigned char *b; 762 struct nlmsghdr *nlh; 763 struct tcamsg *t; 764 struct netlink_callback dcb; 765 struct nlattr *nest; 766 struct nlattr *tb[TCA_ACT_MAX + 1]; 767 struct nlattr *kind; 768 struct tc_action *a = create_a(0); 769 int err = -ENOMEM; 770 771 if (a == NULL) { 772 pr_debug("tca_action_flush: couldnt create tc_action\n"); 773 return err; 774 } 775 776 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 777 if (!skb) { 778 pr_debug("tca_action_flush: failed skb alloc\n"); 779 kfree(a); 780 return err; 781 } 782 783 b = skb_tail_pointer(skb); 784 785 err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL); 786 if (err < 0) 787 goto err_out; 788 789 err = -EINVAL; 790 kind = tb[TCA_ACT_KIND]; 791 a->ops = tc_lookup_action(kind); 792 if (a->ops == NULL) 793 goto err_out; 794 795 nlh = nlmsg_put(skb, portid, n->nlmsg_seq, RTM_DELACTION, sizeof(*t), 0); 796 if (!nlh) 797 goto out_module_put; 798 t = nlmsg_data(nlh); 799 t->tca_family = AF_UNSPEC; 800 t->tca__pad1 = 0; 801 t->tca__pad2 = 0; 802 803 nest = nla_nest_start(skb, TCA_ACT_TAB); 804 if (nest == NULL) 805 goto out_module_put; 806 807 err = a->ops->walk(skb, &dcb, RTM_DELACTION, a); 808 if (err < 0) 809 goto out_module_put; 810 if (err == 0) 811 goto noflush_out; 812 813 nla_nest_end(skb, nest); 814 815 nlh->nlmsg_len = skb_tail_pointer(skb) - b; 816 nlh->nlmsg_flags |= NLM_F_ROOT; 817 module_put(a->ops->owner); 818 kfree(a); 819 err = rtnetlink_send(skb, net, portid, RTNLGRP_TC, 820 n->nlmsg_flags & NLM_F_ECHO); 821 if (err > 0) 822 return 0; 823 824 return err; 825 826out_module_put: 827 module_put(a->ops->owner); 828err_out: 829noflush_out: 830 kfree_skb(skb); 831 kfree(a); 832 return err; 833} 834 835static int 836tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n, 837 u32 portid, int event) 838{ 839 int i, ret; 840 struct nlattr *tb[TCA_ACT_MAX_PRIO + 1]; 841 struct tc_action *act; 842 LIST_HEAD(actions); 843 844 ret = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL); 845 if (ret < 0) 846 return ret; 847 848 if (event == RTM_DELACTION && n->nlmsg_flags & NLM_F_ROOT) { 849 if (tb[1] != NULL) 850 return tca_action_flush(net, tb[1], n, portid); 851 else 852 return -EINVAL; 853 } 854 855 for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) { 856 act = tcf_action_get_1(tb[i], n, portid); 857 if (IS_ERR(act)) { 858 ret = PTR_ERR(act); 859 goto err; 860 } 861 act->order = i; 862 list_add_tail(&act->list, &actions); 863 } 864 865 if (event == RTM_GETACTION) 866 ret = act_get_notify(net, portid, n, &actions, event); 867 else { /* delete */ 868 struct sk_buff *skb; 869 870 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 871 if (!skb) { 872 ret = -ENOBUFS; 873 goto err; 874 } 875 876 if (tca_get_fill(skb, &actions, portid, n->nlmsg_seq, 0, event, 877 0, 1) <= 0) { 878 kfree_skb(skb); 879 ret = -EINVAL; 880 goto err; 881 } 882 883 /* now do the delete */ 884 tcf_action_destroy(&actions, 0); 885 ret = rtnetlink_send(skb, net, portid, RTNLGRP_TC, 886 n->nlmsg_flags & NLM_F_ECHO); 887 if (ret > 0) 888 return 0; 889 return ret; 890 } 891err: 892 cleanup_a(&actions); 893 return ret; 894} 895 896static int tcf_add_notify(struct net *net, struct list_head *actions, 897 u32 portid, u32 seq, int event, u16 flags) 898{ 899 struct tcamsg *t; 900 struct nlmsghdr *nlh; 901 struct sk_buff *skb; 902 struct nlattr *nest; 903 unsigned char *b; 904 int err = 0; 905 906 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 907 if (!skb) 908 return -ENOBUFS; 909 910 b = skb_tail_pointer(skb); 911 912 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*t), flags); 913 if (!nlh) 914 goto out_kfree_skb; 915 t = nlmsg_data(nlh); 916 t->tca_family = AF_UNSPEC; 917 t->tca__pad1 = 0; 918 t->tca__pad2 = 0; 919 920 nest = nla_nest_start(skb, TCA_ACT_TAB); 921 if (nest == NULL) 922 goto out_kfree_skb; 923 924 if (tcf_action_dump(skb, actions, 0, 0) < 0) 925 goto out_kfree_skb; 926 927 nla_nest_end(skb, nest); 928 929 nlh->nlmsg_len = skb_tail_pointer(skb) - b; 930 NETLINK_CB(skb).dst_group = RTNLGRP_TC; 931 932 err = rtnetlink_send(skb, net, portid, RTNLGRP_TC, flags & NLM_F_ECHO); 933 if (err > 0) 934 err = 0; 935 return err; 936 937out_kfree_skb: 938 kfree_skb(skb); 939 return -1; 940} 941 942 943static int 944tcf_action_add(struct net *net, struct nlattr *nla, struct nlmsghdr *n, 945 u32 portid, int ovr) 946{ 947 int ret = 0; 948 LIST_HEAD(actions); 949 u32 seq = n->nlmsg_seq; 950 951 ret = tcf_action_init(net, nla, NULL, NULL, ovr, 0, &actions); 952 if (ret) 953 goto done; 954 955 /* dump then free all the actions after update; inserted policy 956 * stays intact 957 */ 958 ret = tcf_add_notify(net, &actions, portid, seq, RTM_NEWACTION, n->nlmsg_flags); 959 cleanup_a(&actions); 960done: 961 return ret; 962} 963 964static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n) 965{ 966 struct net *net = sock_net(skb->sk); 967 struct nlattr *tca[TCA_ACT_MAX + 1]; 968 u32 portid = skb ? NETLINK_CB(skb).portid : 0; 969 int ret = 0, ovr = 0; 970 971 if ((n->nlmsg_type != RTM_GETACTION) && !capable(CAP_NET_ADMIN)) 972 return -EPERM; 973 974 ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL); 975 if (ret < 0) 976 return ret; 977 978 if (tca[TCA_ACT_TAB] == NULL) { 979 pr_notice("tc_ctl_action: received NO action attribs\n"); 980 return -EINVAL; 981 } 982 983 /* n->nlmsg_flags & NLM_F_CREATE */ 984 switch (n->nlmsg_type) { 985 case RTM_NEWACTION: 986 /* we are going to assume all other flags 987 * imply create only if it doesn't exist 988 * Note that CREATE | EXCL implies that 989 * but since we want avoid ambiguity (eg when flags 990 * is zero) then just set this 991 */ 992 if (n->nlmsg_flags & NLM_F_REPLACE) 993 ovr = 1; 994replay: 995 ret = tcf_action_add(net, tca[TCA_ACT_TAB], n, portid, ovr); 996 if (ret == -EAGAIN) 997 goto replay; 998 break; 999 case RTM_DELACTION: 1000 ret = tca_action_gd(net, tca[TCA_ACT_TAB], n, 1001 portid, RTM_DELACTION); 1002 break; 1003 case RTM_GETACTION: 1004 ret = tca_action_gd(net, tca[TCA_ACT_TAB], n, 1005 portid, RTM_GETACTION); 1006 break; 1007 default: 1008 BUG(); 1009 } 1010 1011 return ret; 1012} 1013 1014static struct nlattr * 1015find_dump_kind(const struct nlmsghdr *n) 1016{ 1017 struct nlattr *tb1, *tb2[TCA_ACT_MAX + 1]; 1018 struct nlattr *tb[TCA_ACT_MAX_PRIO + 1]; 1019 struct nlattr *nla[TCAA_MAX + 1]; 1020 struct nlattr *kind; 1021 1022 if (nlmsg_parse(n, sizeof(struct tcamsg), nla, TCAA_MAX, NULL) < 0) 1023 return NULL; 1024 tb1 = nla[TCA_ACT_TAB]; 1025 if (tb1 == NULL) 1026 return NULL; 1027 1028 if (nla_parse(tb, TCA_ACT_MAX_PRIO, nla_data(tb1), 1029 NLMSG_ALIGN(nla_len(tb1)), NULL) < 0) 1030 return NULL; 1031 1032 if (tb[1] == NULL) 1033 return NULL; 1034 if (nla_parse(tb2, TCA_ACT_MAX, nla_data(tb[1]), 1035 nla_len(tb[1]), NULL) < 0) 1036 return NULL; 1037 kind = tb2[TCA_ACT_KIND]; 1038 1039 return kind; 1040} 1041 1042static int 1043tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) 1044{ 1045 struct nlmsghdr *nlh; 1046 unsigned char *b = skb_tail_pointer(skb); 1047 struct nlattr *nest; 1048 struct tc_action_ops *a_o; 1049 struct tc_action a; 1050 int ret = 0; 1051 struct tcamsg *t = (struct tcamsg *) nlmsg_data(cb->nlh); 1052 struct nlattr *kind = find_dump_kind(cb->nlh); 1053 1054 if (kind == NULL) { 1055 pr_info("tc_dump_action: action bad kind\n"); 1056 return 0; 1057 } 1058 1059 a_o = tc_lookup_action(kind); 1060 if (a_o == NULL) 1061 return 0; 1062 1063 memset(&a, 0, sizeof(struct tc_action)); 1064 a.ops = a_o; 1065 1066 nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, 1067 cb->nlh->nlmsg_type, sizeof(*t), 0); 1068 if (!nlh) 1069 goto out_module_put; 1070 t = nlmsg_data(nlh); 1071 t->tca_family = AF_UNSPEC; 1072 t->tca__pad1 = 0; 1073 t->tca__pad2 = 0; 1074 1075 nest = nla_nest_start(skb, TCA_ACT_TAB); 1076 if (nest == NULL) 1077 goto out_module_put; 1078 1079 ret = a_o->walk(skb, cb, RTM_GETACTION, &a); 1080 if (ret < 0) 1081 goto out_module_put; 1082 1083 if (ret > 0) { 1084 nla_nest_end(skb, nest); 1085 ret = skb->len; 1086 } else 1087 nla_nest_cancel(skb, nest); 1088 1089 nlh->nlmsg_len = skb_tail_pointer(skb) - b; 1090 if (NETLINK_CB(cb->skb).portid && ret) 1091 nlh->nlmsg_flags |= NLM_F_MULTI; 1092 module_put(a_o->owner); 1093 return skb->len; 1094 1095out_module_put: 1096 module_put(a_o->owner); 1097 nlmsg_trim(skb, b); 1098 return skb->len; 1099} 1100 1101static int __init tc_action_init(void) 1102{ 1103 rtnl_register(PF_UNSPEC, RTM_NEWACTION, tc_ctl_action, NULL, NULL); 1104 rtnl_register(PF_UNSPEC, RTM_DELACTION, tc_ctl_action, NULL, NULL); 1105 rtnl_register(PF_UNSPEC, RTM_GETACTION, tc_ctl_action, tc_dump_action, 1106 NULL); 1107 1108 return 0; 1109} 1110 1111subsys_initcall(tc_action_init); 1112