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