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