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 <asm/uaccess.h> 15 #include <asm/system.h> 16 #include <linux/bitops.h> 17 #include <linux/types.h> 18 #include <linux/kernel.h> 19 #include <linux/sched.h> 20 #include <linux/string.h> 21 #include <linux/mm.h> 22 #include <linux/socket.h> 23 #include <linux/sockios.h> 24 #include <linux/in.h> 25 #include <linux/errno.h> 26 #include <linux/interrupt.h> 27 #include <linux/netdevice.h> 28 #include <linux/skbuff.h> 29 #include <linux/rtnetlink.h> 30 #include <linux/init.h> 31 #include <linux/kmod.h> 32 #include <net/sock.h> 33 #include <net/sch_generic.h> 34 #include <net/act_api.h> 35 36 #if 0 /* control */ 37 #define DPRINTK(format, args...) printk(KERN_DEBUG format, ##args) 38 #else 39 #define DPRINTK(format, args...) 40 #endif 41 #if 0 /* data */ 42 #define D2PRINTK(format, args...) printk(KERN_DEBUG format, ##args) 43 #else 44 #define D2PRINTK(format, args...) 45 #endif 46 47 static struct tc_action_ops *act_base = NULL; 48 static DEFINE_RWLOCK(act_mod_lock); 49 50 int tcf_register_action(struct tc_action_ops *act) 51 { 52 struct tc_action_ops *a, **ap; 53 54 write_lock(&act_mod_lock); 55 for (ap = &act_base; (a = *ap) != NULL; ap = &a->next) { 56 if (act->type == a->type || (strcmp(act->kind, a->kind) == 0)) { 57 write_unlock(&act_mod_lock); 58 return -EEXIST; 59 } 60 } 61 act->next = NULL; 62 *ap = act; 63 write_unlock(&act_mod_lock); 64 return 0; 65 } 66 67 int tcf_unregister_action(struct tc_action_ops *act) 68 { 69 struct tc_action_ops *a, **ap; 70 int err = -ENOENT; 71 72 write_lock(&act_mod_lock); 73 for (ap = &act_base; (a = *ap) != NULL; ap = &a->next) 74 if (a == act) 75 break; 76 if (a) { 77 *ap = a->next; 78 a->next = NULL; 79 err = 0; 80 } 81 write_unlock(&act_mod_lock); 82 return err; 83 } 84 85 /* lookup by name */ 86 static struct tc_action_ops *tc_lookup_action_n(char *kind) 87 { 88 struct tc_action_ops *a = NULL; 89 90 if (kind) { 91 read_lock(&act_mod_lock); 92 for (a = act_base; a; a = a->next) { 93 if (strcmp(kind, a->kind) == 0) { 94 if (!try_module_get(a->owner)) { 95 read_unlock(&act_mod_lock); 96 return NULL; 97 } 98 break; 99 } 100 } 101 read_unlock(&act_mod_lock); 102 } 103 return a; 104 } 105 106 /* lookup by rtattr */ 107 static struct tc_action_ops *tc_lookup_action(struct rtattr *kind) 108 { 109 struct tc_action_ops *a = NULL; 110 111 if (kind) { 112 read_lock(&act_mod_lock); 113 for (a = act_base; a; a = a->next) { 114 if (rtattr_strcmp(kind, a->kind) == 0) { 115 if (!try_module_get(a->owner)) { 116 read_unlock(&act_mod_lock); 117 return NULL; 118 } 119 break; 120 } 121 } 122 read_unlock(&act_mod_lock); 123 } 124 return a; 125 } 126 127 #if 0 128 /* lookup by id */ 129 static struct tc_action_ops *tc_lookup_action_id(u32 type) 130 { 131 struct tc_action_ops *a = NULL; 132 133 if (type) { 134 read_lock(&act_mod_lock); 135 for (a = act_base; a; a = a->next) { 136 if (a->type == type) { 137 if (!try_module_get(a->owner)) { 138 read_unlock(&act_mod_lock); 139 return NULL; 140 } 141 break; 142 } 143 } 144 read_unlock(&act_mod_lock); 145 } 146 return a; 147 } 148 #endif 149 150 int tcf_action_exec(struct sk_buff *skb, struct tc_action *act, 151 struct tcf_result *res) 152 { 153 struct tc_action *a; 154 int ret = -1; 155 156 if (skb->tc_verd & TC_NCLS) { 157 skb->tc_verd = CLR_TC_NCLS(skb->tc_verd); 158 D2PRINTK("(%p)tcf_action_exec: cleared TC_NCLS in %s out %s\n", 159 skb, skb->input_dev ? skb->input_dev->name : "xxx", 160 skb->dev->name); 161 ret = TC_ACT_OK; 162 goto exec_done; 163 } 164 while ((a = act) != NULL) { 165 repeat: 166 if (a->ops && a->ops->act) { 167 ret = a->ops->act(skb, a, res); 168 if (TC_MUNGED & skb->tc_verd) { 169 /* copied already, allow trampling */ 170 skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd); 171 skb->tc_verd = CLR_TC_MUNGED(skb->tc_verd); 172 } 173 if (ret == TC_ACT_REPEAT) 174 goto repeat; /* we need a ttl - JHS */ 175 if (ret != TC_ACT_PIPE) 176 goto exec_done; 177 } 178 act = a->next; 179 } 180 exec_done: 181 return ret; 182 } 183 184 void tcf_action_destroy(struct tc_action *act, int bind) 185 { 186 struct tc_action *a; 187 188 for (a = act; a; a = act) { 189 if (a->ops && a->ops->cleanup) { 190 DPRINTK("tcf_action_destroy destroying %p next %p\n", 191 a, a->next); 192 if (a->ops->cleanup(a, bind) == ACT_P_DELETED) 193 module_put(a->ops->owner); 194 act = act->next; 195 kfree(a); 196 } else { /*FIXME: Remove later - catch insertion bugs*/ 197 printk("tcf_action_destroy: BUG? destroying NULL ops\n"); 198 act = act->next; 199 kfree(a); 200 } 201 } 202 } 203 204 int 205 tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int bind, int ref) 206 { 207 int err = -EINVAL; 208 209 if (a->ops == NULL || a->ops->dump == NULL) 210 return err; 211 return a->ops->dump(skb, a, bind, ref); 212 } 213 214 int 215 tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref) 216 { 217 int err = -EINVAL; 218 unsigned char *b = skb->tail; 219 struct rtattr *r; 220 221 if (a->ops == NULL || a->ops->dump == NULL) 222 return err; 223 224 RTA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind); 225 if (tcf_action_copy_stats(skb, a, 0)) 226 goto rtattr_failure; 227 r = (struct rtattr*) skb->tail; 228 RTA_PUT(skb, TCA_OPTIONS, 0, NULL); 229 if ((err = tcf_action_dump_old(skb, a, bind, ref)) > 0) { 230 r->rta_len = skb->tail - (u8*)r; 231 return err; 232 } 233 234 rtattr_failure: 235 skb_trim(skb, b - skb->data); 236 return -1; 237 } 238 239 int 240 tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int ref) 241 { 242 struct tc_action *a; 243 int err = -EINVAL; 244 unsigned char *b = skb->tail; 245 struct rtattr *r ; 246 247 while ((a = act) != NULL) { 248 r = (struct rtattr*) skb->tail; 249 act = a->next; 250 RTA_PUT(skb, a->order, 0, NULL); 251 err = tcf_action_dump_1(skb, a, bind, ref); 252 if (err < 0) 253 goto errout; 254 r->rta_len = skb->tail - (u8*)r; 255 } 256 257 return 0; 258 259 rtattr_failure: 260 err = -EINVAL; 261 errout: 262 skb_trim(skb, b - skb->data); 263 return err; 264 } 265 266 struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est, 267 char *name, int ovr, int bind, int *err) 268 { 269 struct tc_action *a; 270 struct tc_action_ops *a_o; 271 char act_name[IFNAMSIZ]; 272 struct rtattr *tb[TCA_ACT_MAX+1]; 273 struct rtattr *kind; 274 275 *err = -EINVAL; 276 277 if (name == NULL) { 278 if (rtattr_parse_nested(tb, TCA_ACT_MAX, rta) < 0) 279 goto err_out; 280 kind = tb[TCA_ACT_KIND-1]; 281 if (kind == NULL) 282 goto err_out; 283 if (rtattr_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ) 284 goto err_out; 285 } else { 286 if (strlcpy(act_name, name, IFNAMSIZ) >= IFNAMSIZ) 287 goto err_out; 288 } 289 290 a_o = tc_lookup_action_n(act_name); 291 if (a_o == NULL) { 292 #ifdef CONFIG_KMOD 293 rtnl_unlock(); 294 request_module("act_%s", act_name); 295 rtnl_lock(); 296 297 a_o = tc_lookup_action_n(act_name); 298 299 /* We dropped the RTNL semaphore in order to 300 * perform the module load. So, even if we 301 * succeeded in loading the module we have to 302 * tell the caller to replay the request. We 303 * indicate this using -EAGAIN. 304 */ 305 if (a_o != NULL) { 306 *err = -EAGAIN; 307 goto err_mod; 308 } 309 #endif 310 *err = -ENOENT; 311 goto err_out; 312 } 313 314 *err = -ENOMEM; 315 a = kmalloc(sizeof(*a), GFP_KERNEL); 316 if (a == NULL) 317 goto err_mod; 318 memset(a, 0, sizeof(*a)); 319 320 /* backward compatibility for policer */ 321 if (name == NULL) 322 *err = a_o->init(tb[TCA_ACT_OPTIONS-1], est, a, ovr, bind); 323 else 324 *err = a_o->init(rta, est, a, ovr, bind); 325 if (*err < 0) 326 goto err_free; 327 328 /* module count goes up only when brand new policy is created 329 if it exists and is only bound to in a_o->init() then 330 ACT_P_CREATED is not returned (a zero is). 331 */ 332 if (*err != ACT_P_CREATED) 333 module_put(a_o->owner); 334 a->ops = a_o; 335 DPRINTK("tcf_action_init_1: successfull %s\n", act_name); 336 337 *err = 0; 338 return a; 339 340 err_free: 341 kfree(a); 342 err_mod: 343 module_put(a_o->owner); 344 err_out: 345 return NULL; 346 } 347 348 struct tc_action *tcf_action_init(struct rtattr *rta, struct rtattr *est, 349 char *name, int ovr, int bind, int *err) 350 { 351 struct rtattr *tb[TCA_ACT_MAX_PRIO+1]; 352 struct tc_action *head = NULL, *act, *act_prev = NULL; 353 int i; 354 355 if (rtattr_parse_nested(tb, TCA_ACT_MAX_PRIO, rta) < 0) { 356 *err = -EINVAL; 357 return head; 358 } 359 360 for (i=0; i < TCA_ACT_MAX_PRIO && tb[i]; i++) { 361 act = tcf_action_init_1(tb[i], est, name, ovr, bind, err); 362 if (act == NULL) 363 goto err; 364 act->order = i+1; 365 366 if (head == NULL) 367 head = act; 368 else 369 act_prev->next = act; 370 act_prev = act; 371 } 372 return head; 373 374 err: 375 if (head != NULL) 376 tcf_action_destroy(head, bind); 377 return NULL; 378 } 379 380 int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a, 381 int compat_mode) 382 { 383 int err = 0; 384 struct gnet_dump d; 385 struct tcf_act_hdr *h = a->priv; 386 387 if (h == NULL) 388 goto errout; 389 390 /* compat_mode being true specifies a call that is supposed 391 * to add additional backward compatiblity statistic TLVs. 392 */ 393 if (compat_mode) { 394 if (a->type == TCA_OLD_COMPAT) 395 err = gnet_stats_start_copy_compat(skb, 0, 396 TCA_STATS, TCA_XSTATS, h->stats_lock, &d); 397 else 398 return 0; 399 } else 400 err = gnet_stats_start_copy(skb, TCA_ACT_STATS, 401 h->stats_lock, &d); 402 403 if (err < 0) 404 goto errout; 405 406 if (a->ops != NULL && a->ops->get_stats != NULL) 407 if (a->ops->get_stats(skb, a) < 0) 408 goto errout; 409 410 if (gnet_stats_copy_basic(&d, &h->bstats) < 0 || 411 #ifdef CONFIG_NET_ESTIMATOR 412 gnet_stats_copy_rate_est(&d, &h->rate_est) < 0 || 413 #endif 414 gnet_stats_copy_queue(&d, &h->qstats) < 0) 415 goto errout; 416 417 if (gnet_stats_finish_copy(&d) < 0) 418 goto errout; 419 420 return 0; 421 422 errout: 423 return -1; 424 } 425 426 static int 427 tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq, 428 u16 flags, int event, int bind, int ref) 429 { 430 struct tcamsg *t; 431 struct nlmsghdr *nlh; 432 unsigned char *b = skb->tail; 433 struct rtattr *x; 434 435 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags); 436 437 t = NLMSG_DATA(nlh); 438 t->tca_family = AF_UNSPEC; 439 t->tca__pad1 = 0; 440 t->tca__pad2 = 0; 441 442 x = (struct rtattr*) skb->tail; 443 RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); 444 445 if (tcf_action_dump(skb, a, bind, ref) < 0) 446 goto rtattr_failure; 447 448 x->rta_len = skb->tail - (u8*)x; 449 450 nlh->nlmsg_len = skb->tail - b; 451 return skb->len; 452 453 rtattr_failure: 454 nlmsg_failure: 455 skb_trim(skb, b - skb->data); 456 return -1; 457 } 458 459 static int 460 act_get_notify(u32 pid, struct nlmsghdr *n, struct tc_action *a, int event) 461 { 462 struct sk_buff *skb; 463 int err = 0; 464 465 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 466 if (!skb) 467 return -ENOBUFS; 468 if (tca_get_fill(skb, a, pid, n->nlmsg_seq, 0, event, 0, 0) <= 0) { 469 kfree_skb(skb); 470 return -EINVAL; 471 } 472 err = netlink_unicast(rtnl, skb, pid, MSG_DONTWAIT); 473 if (err > 0) 474 err = 0; 475 return err; 476 } 477 478 static struct tc_action * 479 tcf_action_get_1(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int *err) 480 { 481 struct rtattr *tb[TCA_ACT_MAX+1]; 482 struct tc_action *a; 483 int index; 484 485 *err = -EINVAL; 486 if (rtattr_parse_nested(tb, TCA_ACT_MAX, rta) < 0) 487 return NULL; 488 489 if (tb[TCA_ACT_INDEX - 1] == NULL || 490 RTA_PAYLOAD(tb[TCA_ACT_INDEX - 1]) < sizeof(index)) 491 return NULL; 492 index = *(int *)RTA_DATA(tb[TCA_ACT_INDEX - 1]); 493 494 *err = -ENOMEM; 495 a = kmalloc(sizeof(struct tc_action), GFP_KERNEL); 496 if (a == NULL) 497 return NULL; 498 memset(a, 0, sizeof(struct tc_action)); 499 500 *err = -EINVAL; 501 a->ops = tc_lookup_action(tb[TCA_ACT_KIND - 1]); 502 if (a->ops == NULL) 503 goto err_free; 504 if (a->ops->lookup == NULL) 505 goto err_mod; 506 *err = -ENOENT; 507 if (a->ops->lookup(a, index) == 0) 508 goto err_mod; 509 510 module_put(a->ops->owner); 511 *err = 0; 512 return a; 513 err_mod: 514 module_put(a->ops->owner); 515 err_free: 516 kfree(a); 517 return NULL; 518 } 519 520 static void cleanup_a(struct tc_action *act) 521 { 522 struct tc_action *a; 523 524 for (a = act; a; a = act) { 525 act = a->next; 526 kfree(a); 527 } 528 } 529 530 static struct tc_action *create_a(int i) 531 { 532 struct tc_action *act; 533 534 act = kmalloc(sizeof(*act), GFP_KERNEL); 535 if (act == NULL) { 536 printk("create_a: failed to alloc!\n"); 537 return NULL; 538 } 539 memset(act, 0, sizeof(*act)); 540 act->order = i; 541 return act; 542 } 543 544 static int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid) 545 { 546 struct sk_buff *skb; 547 unsigned char *b; 548 struct nlmsghdr *nlh; 549 struct tcamsg *t; 550 struct netlink_callback dcb; 551 struct rtattr *x; 552 struct rtattr *tb[TCA_ACT_MAX+1]; 553 struct rtattr *kind; 554 struct tc_action *a = create_a(0); 555 int err = -EINVAL; 556 557 if (a == NULL) { 558 printk("tca_action_flush: couldnt create tc_action\n"); 559 return err; 560 } 561 562 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 563 if (!skb) { 564 printk("tca_action_flush: failed skb alloc\n"); 565 kfree(a); 566 return -ENOBUFS; 567 } 568 569 b = (unsigned char *)skb->tail; 570 571 if (rtattr_parse_nested(tb, TCA_ACT_MAX, rta) < 0) 572 goto err_out; 573 574 kind = tb[TCA_ACT_KIND-1]; 575 a->ops = tc_lookup_action(kind); 576 if (a->ops == NULL) 577 goto err_out; 578 579 nlh = NLMSG_PUT(skb, pid, n->nlmsg_seq, RTM_DELACTION, sizeof(*t)); 580 t = NLMSG_DATA(nlh); 581 t->tca_family = AF_UNSPEC; 582 t->tca__pad1 = 0; 583 t->tca__pad2 = 0; 584 585 x = (struct rtattr *) skb->tail; 586 RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); 587 588 err = a->ops->walk(skb, &dcb, RTM_DELACTION, a); 589 if (err < 0) 590 goto rtattr_failure; 591 592 x->rta_len = skb->tail - (u8 *) x; 593 594 nlh->nlmsg_len = skb->tail - b; 595 nlh->nlmsg_flags |= NLM_F_ROOT; 596 module_put(a->ops->owner); 597 kfree(a); 598 err = rtnetlink_send(skb, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO); 599 if (err > 0) 600 return 0; 601 602 return err; 603 604 rtattr_failure: 605 nlmsg_failure: 606 module_put(a->ops->owner); 607 err_out: 608 kfree_skb(skb); 609 kfree(a); 610 return err; 611 } 612 613 static int 614 tca_action_gd(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int event) 615 { 616 int i, ret = 0; 617 struct rtattr *tb[TCA_ACT_MAX_PRIO+1]; 618 struct tc_action *head = NULL, *act, *act_prev = NULL; 619 620 if (rtattr_parse_nested(tb, TCA_ACT_MAX_PRIO, rta) < 0) 621 return -EINVAL; 622 623 if (event == RTM_DELACTION && n->nlmsg_flags&NLM_F_ROOT) { 624 if (tb[0] != NULL && tb[1] == NULL) 625 return tca_action_flush(tb[0], n, pid); 626 } 627 628 for (i=0; i < TCA_ACT_MAX_PRIO && tb[i]; i++) { 629 act = tcf_action_get_1(tb[i], n, pid, &ret); 630 if (act == NULL) 631 goto err; 632 act->order = i+1; 633 634 if (head == NULL) 635 head = act; 636 else 637 act_prev->next = act; 638 act_prev = act; 639 } 640 641 if (event == RTM_GETACTION) 642 ret = act_get_notify(pid, n, head, event); 643 else { /* delete */ 644 struct sk_buff *skb; 645 646 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 647 if (!skb) { 648 ret = -ENOBUFS; 649 goto err; 650 } 651 652 if (tca_get_fill(skb, head, pid, n->nlmsg_seq, 0, event, 653 0, 1) <= 0) { 654 kfree_skb(skb); 655 ret = -EINVAL; 656 goto err; 657 } 658 659 /* now do the delete */ 660 tcf_action_destroy(head, 0); 661 ret = rtnetlink_send(skb, pid, RTNLGRP_TC, 662 n->nlmsg_flags&NLM_F_ECHO); 663 if (ret > 0) 664 return 0; 665 return ret; 666 } 667 err: 668 cleanup_a(head); 669 return ret; 670 } 671 672 static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event, 673 u16 flags) 674 { 675 struct tcamsg *t; 676 struct nlmsghdr *nlh; 677 struct sk_buff *skb; 678 struct rtattr *x; 679 unsigned char *b; 680 int err = 0; 681 682 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 683 if (!skb) 684 return -ENOBUFS; 685 686 b = (unsigned char *)skb->tail; 687 688 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags); 689 t = NLMSG_DATA(nlh); 690 t->tca_family = AF_UNSPEC; 691 t->tca__pad1 = 0; 692 t->tca__pad2 = 0; 693 694 x = (struct rtattr*) skb->tail; 695 RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); 696 697 if (tcf_action_dump(skb, a, 0, 0) < 0) 698 goto rtattr_failure; 699 700 x->rta_len = skb->tail - (u8*)x; 701 702 nlh->nlmsg_len = skb->tail - b; 703 NETLINK_CB(skb).dst_group = RTNLGRP_TC; 704 705 err = rtnetlink_send(skb, pid, RTNLGRP_TC, flags&NLM_F_ECHO); 706 if (err > 0) 707 err = 0; 708 return err; 709 710 rtattr_failure: 711 nlmsg_failure: 712 kfree_skb(skb); 713 return -1; 714 } 715 716 717 static int 718 tcf_action_add(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int ovr) 719 { 720 int ret = 0; 721 struct tc_action *act; 722 struct tc_action *a; 723 u32 seq = n->nlmsg_seq; 724 725 act = tcf_action_init(rta, NULL, NULL, ovr, 0, &ret); 726 if (act == NULL) 727 goto done; 728 729 /* dump then free all the actions after update; inserted policy 730 * stays intact 731 * */ 732 ret = tcf_add_notify(act, pid, seq, RTM_NEWACTION, n->nlmsg_flags); 733 for (a = act; a; a = act) { 734 act = a->next; 735 kfree(a); 736 } 737 done: 738 return ret; 739 } 740 741 static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg) 742 { 743 struct rtattr **tca = arg; 744 u32 pid = skb ? NETLINK_CB(skb).pid : 0; 745 int ret = 0, ovr = 0; 746 747 if (tca[TCA_ACT_TAB-1] == NULL) { 748 printk("tc_ctl_action: received NO action attribs\n"); 749 return -EINVAL; 750 } 751 752 /* n->nlmsg_flags&NLM_F_CREATE 753 * */ 754 switch (n->nlmsg_type) { 755 case RTM_NEWACTION: 756 /* we are going to assume all other flags 757 * imply create only if it doesnt exist 758 * Note that CREATE | EXCL implies that 759 * but since we want avoid ambiguity (eg when flags 760 * is zero) then just set this 761 */ 762 if (n->nlmsg_flags&NLM_F_REPLACE) 763 ovr = 1; 764 replay: 765 ret = tcf_action_add(tca[TCA_ACT_TAB-1], n, pid, ovr); 766 if (ret == -EAGAIN) 767 goto replay; 768 break; 769 case RTM_DELACTION: 770 ret = tca_action_gd(tca[TCA_ACT_TAB-1], n, pid, RTM_DELACTION); 771 break; 772 case RTM_GETACTION: 773 ret = tca_action_gd(tca[TCA_ACT_TAB-1], n, pid, RTM_GETACTION); 774 break; 775 default: 776 BUG(); 777 } 778 779 return ret; 780 } 781 782 static struct rtattr * 783 find_dump_kind(struct nlmsghdr *n) 784 { 785 struct rtattr *tb1, *tb2[TCA_ACT_MAX+1]; 786 struct rtattr *tb[TCA_ACT_MAX_PRIO + 1]; 787 struct rtattr *rta[TCAA_MAX + 1]; 788 struct rtattr *kind; 789 int min_len = NLMSG_LENGTH(sizeof(struct tcamsg)); 790 int attrlen = n->nlmsg_len - NLMSG_ALIGN(min_len); 791 struct rtattr *attr = (void *) n + NLMSG_ALIGN(min_len); 792 793 if (rtattr_parse(rta, TCAA_MAX, attr, attrlen) < 0) 794 return NULL; 795 tb1 = rta[TCA_ACT_TAB - 1]; 796 if (tb1 == NULL) 797 return NULL; 798 799 if (rtattr_parse(tb, TCA_ACT_MAX_PRIO, RTA_DATA(tb1), 800 NLMSG_ALIGN(RTA_PAYLOAD(tb1))) < 0) 801 return NULL; 802 if (tb[0] == NULL) 803 return NULL; 804 805 if (rtattr_parse(tb2, TCA_ACT_MAX, RTA_DATA(tb[0]), 806 RTA_PAYLOAD(tb[0])) < 0) 807 return NULL; 808 kind = tb2[TCA_ACT_KIND-1]; 809 810 return kind; 811 } 812 813 static int 814 tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) 815 { 816 struct nlmsghdr *nlh; 817 unsigned char *b = skb->tail; 818 struct rtattr *x; 819 struct tc_action_ops *a_o; 820 struct tc_action a; 821 int ret = 0; 822 struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh); 823 struct rtattr *kind = find_dump_kind(cb->nlh); 824 825 if (kind == NULL) { 826 printk("tc_dump_action: action bad kind\n"); 827 return 0; 828 } 829 830 a_o = tc_lookup_action(kind); 831 if (a_o == NULL) { 832 return 0; 833 } 834 835 memset(&a, 0, sizeof(struct tc_action)); 836 a.ops = a_o; 837 838 if (a_o->walk == NULL) { 839 printk("tc_dump_action: %s !capable of dumping table\n", a_o->kind); 840 goto rtattr_failure; 841 } 842 843 nlh = NLMSG_PUT(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, 844 cb->nlh->nlmsg_type, sizeof(*t)); 845 t = NLMSG_DATA(nlh); 846 t->tca_family = AF_UNSPEC; 847 t->tca__pad1 = 0; 848 t->tca__pad2 = 0; 849 850 x = (struct rtattr *) skb->tail; 851 RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); 852 853 ret = a_o->walk(skb, cb, RTM_GETACTION, &a); 854 if (ret < 0) 855 goto rtattr_failure; 856 857 if (ret > 0) { 858 x->rta_len = skb->tail - (u8 *) x; 859 ret = skb->len; 860 } else 861 skb_trim(skb, (u8*)x - skb->data); 862 863 nlh->nlmsg_len = skb->tail - b; 864 if (NETLINK_CB(cb->skb).pid && ret) 865 nlh->nlmsg_flags |= NLM_F_MULTI; 866 module_put(a_o->owner); 867 return skb->len; 868 869 rtattr_failure: 870 nlmsg_failure: 871 module_put(a_o->owner); 872 skb_trim(skb, b - skb->data); 873 return skb->len; 874 } 875 876 static int __init tc_action_init(void) 877 { 878 struct rtnetlink_link *link_p = rtnetlink_links[PF_UNSPEC]; 879 880 if (link_p) { 881 link_p[RTM_NEWACTION-RTM_BASE].doit = tc_ctl_action; 882 link_p[RTM_DELACTION-RTM_BASE].doit = tc_ctl_action; 883 link_p[RTM_GETACTION-RTM_BASE].doit = tc_ctl_action; 884 link_p[RTM_GETACTION-RTM_BASE].dumpit = tc_dump_action; 885 } 886 887 printk("TC classifier action (bugs to netdev@vger.kernel.org cc " 888 "hadi@cyberus.ca)\n"); 889 return 0; 890 } 891 892 subsys_initcall(tc_action_init); 893 894 EXPORT_SYMBOL(tcf_register_action); 895 EXPORT_SYMBOL(tcf_unregister_action); 896 EXPORT_SYMBOL(tcf_action_exec); 897 EXPORT_SYMBOL(tcf_action_dump_1); 898