sch_api.c (62e3ba1b558e5f393ef746880613fb8222e64d03) | sch_api.c (1e90474c377e92db7262a8968a45c1dd980ca9e5) |
---|---|
1/* 2 * net/sched/sch_api.c Packet scheduler 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 * --- 199 unchanged lines hidden (view full) --- 208 return NULL; 209 leaf = cops->leaf(p, cl); 210 cops->put(p, cl); 211 return leaf; 212} 213 214/* Find queueing discipline by name */ 215 | 1/* 2 * net/sched/sch_api.c Packet scheduler 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 * --- 199 unchanged lines hidden (view full) --- 208 return NULL; 209 leaf = cops->leaf(p, cl); 210 cops->put(p, cl); 211 return leaf; 212} 213 214/* Find queueing discipline by name */ 215 |
216static struct Qdisc_ops *qdisc_lookup_ops(struct rtattr *kind) | 216static struct Qdisc_ops *qdisc_lookup_ops(struct nlattr *kind) |
217{ 218 struct Qdisc_ops *q = NULL; 219 220 if (kind) { 221 read_lock(&qdisc_mod_lock); 222 for (q = qdisc_base; q; q = q->next) { | 217{ 218 struct Qdisc_ops *q = NULL; 219 220 if (kind) { 221 read_lock(&qdisc_mod_lock); 222 for (q = qdisc_base; q; q = q->next) { |
223 if (rtattr_strcmp(kind, q->id) == 0) { | 223 if (nla_strcmp(kind, q->id) == 0) { |
224 if (!try_module_get(q->owner)) 225 q = NULL; 226 break; 227 } 228 } 229 read_unlock(&qdisc_mod_lock); 230 } 231 return q; 232} 233 234static struct qdisc_rate_table *qdisc_rtab_list; 235 | 224 if (!try_module_get(q->owner)) 225 q = NULL; 226 break; 227 } 228 } 229 read_unlock(&qdisc_mod_lock); 230 } 231 return q; 232} 233 234static struct qdisc_rate_table *qdisc_rtab_list; 235 |
236struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct rtattr *tab) | 236struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct nlattr *tab) |
237{ 238 struct qdisc_rate_table *rtab; 239 240 for (rtab = qdisc_rtab_list; rtab; rtab = rtab->next) { 241 if (memcmp(&rtab->rate, r, sizeof(struct tc_ratespec)) == 0) { 242 rtab->refcnt++; 243 return rtab; 244 } 245 } 246 | 237{ 238 struct qdisc_rate_table *rtab; 239 240 for (rtab = qdisc_rtab_list; rtab; rtab = rtab->next) { 241 if (memcmp(&rtab->rate, r, sizeof(struct tc_ratespec)) == 0) { 242 rtab->refcnt++; 243 return rtab; 244 } 245 } 246 |
247 if (tab == NULL || r->rate == 0 || r->cell_log == 0 || RTA_PAYLOAD(tab) != 1024) | 247 if (tab == NULL || r->rate == 0 || r->cell_log == 0 || nla_len(tab) != 1024) |
248 return NULL; 249 250 rtab = kmalloc(sizeof(*rtab), GFP_KERNEL); 251 if (rtab) { 252 rtab->rate = *r; 253 rtab->refcnt = 1; | 248 return NULL; 249 250 rtab = kmalloc(sizeof(*rtab), GFP_KERNEL); 251 if (rtab) { 252 rtab->rate = *r; 253 rtab->refcnt = 1; |
254 memcpy(rtab->data, RTA_DATA(tab), 1024); | 254 memcpy(rtab->data, nla_data(tab), 1024); |
255 rtab->next = qdisc_rtab_list; 256 qdisc_rtab_list = rtab; 257 } 258 return rtab; 259} 260EXPORT_SYMBOL(qdisc_get_rtab); 261 262void qdisc_put_rtab(struct qdisc_rate_table *tab) --- 177 unchanged lines hidden (view full) --- 440/* 441 Allocate and initialize new qdisc. 442 443 Parameters are passed via opt. 444 */ 445 446static struct Qdisc * 447qdisc_create(struct net_device *dev, u32 parent, u32 handle, | 255 rtab->next = qdisc_rtab_list; 256 qdisc_rtab_list = rtab; 257 } 258 return rtab; 259} 260EXPORT_SYMBOL(qdisc_get_rtab); 261 262void qdisc_put_rtab(struct qdisc_rate_table *tab) --- 177 unchanged lines hidden (view full) --- 440/* 441 Allocate and initialize new qdisc. 442 443 Parameters are passed via opt. 444 */ 445 446static struct Qdisc * 447qdisc_create(struct net_device *dev, u32 parent, u32 handle, |
448 struct rtattr **tca, int *errp) | 448 struct nlattr **tca, int *errp) |
449{ 450 int err; | 449{ 450 int err; |
451 struct rtattr *kind = tca[TCA_KIND-1]; | 451 struct nlattr *kind = tca[TCA_KIND]; |
452 struct Qdisc *sch; 453 struct Qdisc_ops *ops; 454 455 ops = qdisc_lookup_ops(kind); 456#ifdef CONFIG_KMOD 457 if (ops == NULL && kind != NULL) { 458 char name[IFNAMSIZ]; | 452 struct Qdisc *sch; 453 struct Qdisc_ops *ops; 454 455 ops = qdisc_lookup_ops(kind); 456#ifdef CONFIG_KMOD 457 if (ops == NULL && kind != NULL) { 458 char name[IFNAMSIZ]; |
459 if (rtattr_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) { | 459 if (nla_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) { |
460 /* We dropped the RTNL semaphore in order to 461 * perform the module load. So, even if we 462 * succeeded in loading the module we have to 463 * tell the caller to replay the request. We 464 * indicate this using -EAGAIN. 465 * We replay the request because the device may 466 * go away in the mean time. 467 */ --- 36 unchanged lines hidden (view full) --- 504 err = -ENOMEM; 505 if (handle == 0) 506 goto err_out3; 507 } 508 } 509 510 sch->handle = handle; 511 | 460 /* We dropped the RTNL semaphore in order to 461 * perform the module load. So, even if we 462 * succeeded in loading the module we have to 463 * tell the caller to replay the request. We 464 * indicate this using -EAGAIN. 465 * We replay the request because the device may 466 * go away in the mean time. 467 */ --- 36 unchanged lines hidden (view full) --- 504 err = -ENOMEM; 505 if (handle == 0) 506 goto err_out3; 507 } 508 } 509 510 sch->handle = handle; 511 |
512 if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) { 513 if (tca[TCA_RATE-1]) { | 512 if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS])) == 0) { 513 if (tca[TCA_RATE]) { |
514 err = gen_new_estimator(&sch->bstats, &sch->rate_est, 515 sch->stats_lock, | 514 err = gen_new_estimator(&sch->bstats, &sch->rate_est, 515 sch->stats_lock, |
516 tca[TCA_RATE-1]); | 516 tca[TCA_RATE]); |
517 if (err) { 518 /* 519 * Any broken qdiscs that would require 520 * a ops->reset() here? The qdisc was never 521 * in action so it shouldn't be necessary. 522 */ 523 if (ops->destroy) 524 ops->destroy(sch); --- 11 unchanged lines hidden (view full) --- 536 kfree((char *) sch - sch->padded); 537err_out2: 538 module_put(ops->owner); 539err_out: 540 *errp = err; 541 return NULL; 542} 543 | 517 if (err) { 518 /* 519 * Any broken qdiscs that would require 520 * a ops->reset() here? The qdisc was never 521 * in action so it shouldn't be necessary. 522 */ 523 if (ops->destroy) 524 ops->destroy(sch); --- 11 unchanged lines hidden (view full) --- 536 kfree((char *) sch - sch->padded); 537err_out2: 538 module_put(ops->owner); 539err_out: 540 *errp = err; 541 return NULL; 542} 543 |
544static int qdisc_change(struct Qdisc *sch, struct rtattr **tca) | 544static int qdisc_change(struct Qdisc *sch, struct nlattr **tca) |
545{ | 545{ |
546 if (tca[TCA_OPTIONS-1]) { | 546 if (tca[TCA_OPTIONS]) { |
547 int err; 548 549 if (sch->ops->change == NULL) 550 return -EINVAL; | 547 int err; 548 549 if (sch->ops->change == NULL) 550 return -EINVAL; |
551 err = sch->ops->change(sch, tca[TCA_OPTIONS-1]); | 551 err = sch->ops->change(sch, tca[TCA_OPTIONS]); |
552 if (err) 553 return err; 554 } | 552 if (err) 553 return err; 554 } |
555 if (tca[TCA_RATE-1]) | 555 if (tca[TCA_RATE]) |
556 gen_replace_estimator(&sch->bstats, &sch->rate_est, | 556 gen_replace_estimator(&sch->bstats, &sch->rate_est, |
557 sch->stats_lock, tca[TCA_RATE-1]); | 557 sch->stats_lock, tca[TCA_RATE]); |
558 return 0; 559} 560 561struct check_loop_arg 562{ 563 struct qdisc_walker w; 564 struct Qdisc *p; 565 int depth; --- 35 unchanged lines hidden (view full) --- 601/* 602 * Delete/get qdisc. 603 */ 604 605static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) 606{ 607 struct net *net = skb->sk->sk_net; 608 struct tcmsg *tcm = NLMSG_DATA(n); | 558 return 0; 559} 560 561struct check_loop_arg 562{ 563 struct qdisc_walker w; 564 struct Qdisc *p; 565 int depth; --- 35 unchanged lines hidden (view full) --- 601/* 602 * Delete/get qdisc. 603 */ 604 605static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) 606{ 607 struct net *net = skb->sk->sk_net; 608 struct tcmsg *tcm = NLMSG_DATA(n); |
609 struct rtattr **tca = arg; | 609 struct nlattr *tca[TCA_MAX + 1]; |
610 struct net_device *dev; 611 u32 clid = tcm->tcm_parent; 612 struct Qdisc *q = NULL; 613 struct Qdisc *p = NULL; 614 int err; 615 616 if (net != &init_net) 617 return -EINVAL; 618 619 if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) 620 return -ENODEV; 621 | 610 struct net_device *dev; 611 u32 clid = tcm->tcm_parent; 612 struct Qdisc *q = NULL; 613 struct Qdisc *p = NULL; 614 int err; 615 616 if (net != &init_net) 617 return -EINVAL; 618 619 if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) 620 return -ENODEV; 621 |
622 err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); 623 if (err < 0) 624 return err; 625 |
|
622 if (clid) { 623 if (clid != TC_H_ROOT) { 624 if (TC_H_MAJ(clid) != TC_H_MAJ(TC_H_INGRESS)) { 625 if ((p = qdisc_lookup(dev, TC_H_MAJ(clid))) == NULL) 626 return -ENOENT; 627 q = qdisc_leaf(p, clid); 628 } else { /* ingress */ 629 q = dev->qdisc_ingress; --- 6 unchanged lines hidden (view full) --- 636 637 if (tcm->tcm_handle && q->handle != tcm->tcm_handle) 638 return -EINVAL; 639 } else { 640 if ((q = qdisc_lookup(dev, tcm->tcm_handle)) == NULL) 641 return -ENOENT; 642 } 643 | 626 if (clid) { 627 if (clid != TC_H_ROOT) { 628 if (TC_H_MAJ(clid) != TC_H_MAJ(TC_H_INGRESS)) { 629 if ((p = qdisc_lookup(dev, TC_H_MAJ(clid))) == NULL) 630 return -ENOENT; 631 q = qdisc_leaf(p, clid); 632 } else { /* ingress */ 633 q = dev->qdisc_ingress; --- 6 unchanged lines hidden (view full) --- 640 641 if (tcm->tcm_handle && q->handle != tcm->tcm_handle) 642 return -EINVAL; 643 } else { 644 if ((q = qdisc_lookup(dev, tcm->tcm_handle)) == NULL) 645 return -ENOENT; 646 } 647 |
644 if (tca[TCA_KIND-1] && rtattr_strcmp(tca[TCA_KIND-1], q->ops->id)) | 648 if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], q->ops->id)) |
645 return -EINVAL; 646 647 if (n->nlmsg_type == RTM_DELQDISC) { 648 if (!clid) 649 return -EINVAL; 650 if (q->handle == 0) 651 return -ENOENT; 652 if ((err = qdisc_graft(dev, p, clid, NULL, &q)) != 0) --- 13 unchanged lines hidden (view full) --- 666/* 667 Create/change qdisc. 668 */ 669 670static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) 671{ 672 struct net *net = skb->sk->sk_net; 673 struct tcmsg *tcm; | 649 return -EINVAL; 650 651 if (n->nlmsg_type == RTM_DELQDISC) { 652 if (!clid) 653 return -EINVAL; 654 if (q->handle == 0) 655 return -ENOENT; 656 if ((err = qdisc_graft(dev, p, clid, NULL, &q)) != 0) --- 13 unchanged lines hidden (view full) --- 670/* 671 Create/change qdisc. 672 */ 673 674static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) 675{ 676 struct net *net = skb->sk->sk_net; 677 struct tcmsg *tcm; |
674 struct rtattr **tca; | 678 struct nlattr *tca[TCA_MAX + 1]; |
675 struct net_device *dev; 676 u32 clid; 677 struct Qdisc *q, *p; 678 int err; 679 680 if (net != &init_net) 681 return -EINVAL; 682 683replay: 684 /* Reinit, just in case something touches this. */ 685 tcm = NLMSG_DATA(n); | 679 struct net_device *dev; 680 u32 clid; 681 struct Qdisc *q, *p; 682 int err; 683 684 if (net != &init_net) 685 return -EINVAL; 686 687replay: 688 /* Reinit, just in case something touches this. */ 689 tcm = NLMSG_DATA(n); |
686 tca = arg; | |
687 clid = tcm->tcm_parent; 688 q = p = NULL; 689 690 if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) 691 return -ENODEV; 692 | 690 clid = tcm->tcm_parent; 691 q = p = NULL; 692 693 if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) 694 return -ENODEV; 695 |
696 err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); 697 if (err < 0) 698 return err; 699 |
|
693 if (clid) { 694 if (clid != TC_H_ROOT) { 695 if (clid != TC_H_INGRESS) { 696 if ((p = qdisc_lookup(dev, TC_H_MAJ(clid))) == NULL) 697 return -ENOENT; 698 q = qdisc_leaf(p, clid); 699 } else { /*ingress */ 700 q = dev->qdisc_ingress; --- 11 unchanged lines hidden (view full) --- 712 if (q && !(n->nlmsg_flags&NLM_F_REPLACE)) 713 return -EEXIST; 714 if (TC_H_MIN(tcm->tcm_handle)) 715 return -EINVAL; 716 if ((q = qdisc_lookup(dev, tcm->tcm_handle)) == NULL) 717 goto create_n_graft; 718 if (n->nlmsg_flags&NLM_F_EXCL) 719 return -EEXIST; | 700 if (clid) { 701 if (clid != TC_H_ROOT) { 702 if (clid != TC_H_INGRESS) { 703 if ((p = qdisc_lookup(dev, TC_H_MAJ(clid))) == NULL) 704 return -ENOENT; 705 q = qdisc_leaf(p, clid); 706 } else { /*ingress */ 707 q = dev->qdisc_ingress; --- 11 unchanged lines hidden (view full) --- 719 if (q && !(n->nlmsg_flags&NLM_F_REPLACE)) 720 return -EEXIST; 721 if (TC_H_MIN(tcm->tcm_handle)) 722 return -EINVAL; 723 if ((q = qdisc_lookup(dev, tcm->tcm_handle)) == NULL) 724 goto create_n_graft; 725 if (n->nlmsg_flags&NLM_F_EXCL) 726 return -EEXIST; |
720 if (tca[TCA_KIND-1] && rtattr_strcmp(tca[TCA_KIND-1], q->ops->id)) | 727 if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], q->ops->id)) |
721 return -EINVAL; 722 if (q == p || 723 (p && check_loop(q, p, 0))) 724 return -ELOOP; 725 atomic_inc(&q->refcnt); 726 goto graft; 727 } else { 728 if (q == NULL) --- 16 unchanged lines hidden (view full) --- 745 * Alas, it is sort of hole in API, we 746 * cannot decide what to do unambiguously. 747 * For now we select create/graft, if 748 * user gave KIND, which does not match existing. 749 */ 750 if ((n->nlmsg_flags&NLM_F_CREATE) && 751 (n->nlmsg_flags&NLM_F_REPLACE) && 752 ((n->nlmsg_flags&NLM_F_EXCL) || | 728 return -EINVAL; 729 if (q == p || 730 (p && check_loop(q, p, 0))) 731 return -ELOOP; 732 atomic_inc(&q->refcnt); 733 goto graft; 734 } else { 735 if (q == NULL) --- 16 unchanged lines hidden (view full) --- 752 * Alas, it is sort of hole in API, we 753 * cannot decide what to do unambiguously. 754 * For now we select create/graft, if 755 * user gave KIND, which does not match existing. 756 */ 757 if ((n->nlmsg_flags&NLM_F_CREATE) && 758 (n->nlmsg_flags&NLM_F_REPLACE) && 759 ((n->nlmsg_flags&NLM_F_EXCL) || |
753 (tca[TCA_KIND-1] && 754 rtattr_strcmp(tca[TCA_KIND-1], q->ops->id)))) | 760 (tca[TCA_KIND] && 761 nla_strcmp(tca[TCA_KIND], q->ops->id)))) |
755 goto create_n_graft; 756 } 757 } 758 } else { 759 if (!tcm->tcm_handle) 760 return -EINVAL; 761 q = qdisc_lookup(dev, tcm->tcm_handle); 762 } 763 764 /* Change qdisc parameters */ 765 if (q == NULL) 766 return -ENOENT; 767 if (n->nlmsg_flags&NLM_F_EXCL) 768 return -EEXIST; | 762 goto create_n_graft; 763 } 764 } 765 } else { 766 if (!tcm->tcm_handle) 767 return -EINVAL; 768 q = qdisc_lookup(dev, tcm->tcm_handle); 769 } 770 771 /* Change qdisc parameters */ 772 if (q == NULL) 773 return -ENOENT; 774 if (n->nlmsg_flags&NLM_F_EXCL) 775 return -EEXIST; |
769 if (tca[TCA_KIND-1] && rtattr_strcmp(tca[TCA_KIND-1], q->ops->id)) | 776 if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], q->ops->id)) |
770 return -EINVAL; 771 err = qdisc_change(q, tca); 772 if (err == 0) 773 qdisc_notify(skb, n, clid, NULL, q); 774 return err; 775 776create_n_graft: 777 if (!(n->nlmsg_flags&NLM_F_CREATE)) --- 44 unchanged lines hidden (view full) --- 822 tcm = NLMSG_DATA(nlh); 823 tcm->tcm_family = AF_UNSPEC; 824 tcm->tcm__pad1 = 0; 825 tcm->tcm__pad2 = 0; 826 tcm->tcm_ifindex = q->dev->ifindex; 827 tcm->tcm_parent = clid; 828 tcm->tcm_handle = q->handle; 829 tcm->tcm_info = atomic_read(&q->refcnt); | 777 return -EINVAL; 778 err = qdisc_change(q, tca); 779 if (err == 0) 780 qdisc_notify(skb, n, clid, NULL, q); 781 return err; 782 783create_n_graft: 784 if (!(n->nlmsg_flags&NLM_F_CREATE)) --- 44 unchanged lines hidden (view full) --- 829 tcm = NLMSG_DATA(nlh); 830 tcm->tcm_family = AF_UNSPEC; 831 tcm->tcm__pad1 = 0; 832 tcm->tcm__pad2 = 0; 833 tcm->tcm_ifindex = q->dev->ifindex; 834 tcm->tcm_parent = clid; 835 tcm->tcm_handle = q->handle; 836 tcm->tcm_info = atomic_read(&q->refcnt); |
830 RTA_PUT(skb, TCA_KIND, IFNAMSIZ, q->ops->id); | 837 NLA_PUT(skb, TCA_KIND, IFNAMSIZ, q->ops->id); |
831 if (q->ops->dump && q->ops->dump(q, skb) < 0) | 838 if (q->ops->dump && q->ops->dump(q, skb) < 0) |
832 goto rtattr_failure; | 839 goto nla_put_failure; |
833 q->qstats.qlen = q->q.qlen; 834 835 if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, 836 TCA_XSTATS, q->stats_lock, &d) < 0) | 840 q->qstats.qlen = q->q.qlen; 841 842 if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, 843 TCA_XSTATS, q->stats_lock, &d) < 0) |
837 goto rtattr_failure; | 844 goto nla_put_failure; |
838 839 if (q->ops->dump_stats && q->ops->dump_stats(q, &d) < 0) | 845 846 if (q->ops->dump_stats && q->ops->dump_stats(q, &d) < 0) |
840 goto rtattr_failure; | 847 goto nla_put_failure; |
841 842 if (gnet_stats_copy_basic(&d, &q->bstats) < 0 || 843 gnet_stats_copy_rate_est(&d, &q->rate_est) < 0 || 844 gnet_stats_copy_queue(&d, &q->qstats) < 0) | 848 849 if (gnet_stats_copy_basic(&d, &q->bstats) < 0 || 850 gnet_stats_copy_rate_est(&d, &q->rate_est) < 0 || 851 gnet_stats_copy_queue(&d, &q->qstats) < 0) |
845 goto rtattr_failure; | 852 goto nla_put_failure; |
846 847 if (gnet_stats_finish_copy(&d) < 0) | 853 854 if (gnet_stats_finish_copy(&d) < 0) |
848 goto rtattr_failure; | 855 goto nla_put_failure; |
849 850 nlh->nlmsg_len = skb_tail_pointer(skb) - b; 851 return skb->len; 852 853nlmsg_failure: | 856 857 nlh->nlmsg_len = skb_tail_pointer(skb) - b; 858 return skb->len; 859 860nlmsg_failure: |
854rtattr_failure: | 861nla_put_failure: |
855 nlmsg_trim(skb, b); 856 return -1; 857} 858 859static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n, 860 u32 clid, struct Qdisc *old, struct Qdisc *new) 861{ 862 struct sk_buff *skb; --- 71 unchanged lines hidden (view full) --- 934 ************************************************/ 935 936 937 938static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) 939{ 940 struct net *net = skb->sk->sk_net; 941 struct tcmsg *tcm = NLMSG_DATA(n); | 862 nlmsg_trim(skb, b); 863 return -1; 864} 865 866static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n, 867 u32 clid, struct Qdisc *old, struct Qdisc *new) 868{ 869 struct sk_buff *skb; --- 71 unchanged lines hidden (view full) --- 941 ************************************************/ 942 943 944 945static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) 946{ 947 struct net *net = skb->sk->sk_net; 948 struct tcmsg *tcm = NLMSG_DATA(n); |
942 struct rtattr **tca = arg; | 949 struct nlattr *tca[TCA_MAX + 1]; |
943 struct net_device *dev; 944 struct Qdisc *q = NULL; 945 const struct Qdisc_class_ops *cops; 946 unsigned long cl = 0; 947 unsigned long new_cl; 948 u32 pid = tcm->tcm_parent; 949 u32 clid = tcm->tcm_handle; 950 u32 qid = TC_H_MAJ(clid); 951 int err; 952 953 if (net != &init_net) 954 return -EINVAL; 955 956 if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) 957 return -ENODEV; 958 | 950 struct net_device *dev; 951 struct Qdisc *q = NULL; 952 const struct Qdisc_class_ops *cops; 953 unsigned long cl = 0; 954 unsigned long new_cl; 955 u32 pid = tcm->tcm_parent; 956 u32 clid = tcm->tcm_handle; 957 u32 qid = TC_H_MAJ(clid); 958 int err; 959 960 if (net != &init_net) 961 return -EINVAL; 962 963 if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) 964 return -ENODEV; 965 |
966 err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); 967 if (err < 0) 968 return err; 969 |
|
959 /* 960 parent == TC_H_UNSPEC - unspecified parent. 961 parent == TC_H_ROOT - class is root, which has no parent. 962 parent == X:0 - parent is root class. 963 parent == X:Y - parent is a node in hierarchy. 964 parent == 0:Y - parent is X:Y, where X:0 is qdisc. 965 966 handle == 0:0 - generate handle from kernel pool. --- 97 unchanged lines hidden (view full) --- 1064 1065 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags); 1066 tcm = NLMSG_DATA(nlh); 1067 tcm->tcm_family = AF_UNSPEC; 1068 tcm->tcm_ifindex = q->dev->ifindex; 1069 tcm->tcm_parent = q->handle; 1070 tcm->tcm_handle = q->handle; 1071 tcm->tcm_info = 0; | 970 /* 971 parent == TC_H_UNSPEC - unspecified parent. 972 parent == TC_H_ROOT - class is root, which has no parent. 973 parent == X:0 - parent is root class. 974 parent == X:Y - parent is a node in hierarchy. 975 parent == 0:Y - parent is X:Y, where X:0 is qdisc. 976 977 handle == 0:0 - generate handle from kernel pool. --- 97 unchanged lines hidden (view full) --- 1075 1076 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags); 1077 tcm = NLMSG_DATA(nlh); 1078 tcm->tcm_family = AF_UNSPEC; 1079 tcm->tcm_ifindex = q->dev->ifindex; 1080 tcm->tcm_parent = q->handle; 1081 tcm->tcm_handle = q->handle; 1082 tcm->tcm_info = 0; |
1072 RTA_PUT(skb, TCA_KIND, IFNAMSIZ, q->ops->id); | 1083 NLA_PUT(skb, TCA_KIND, IFNAMSIZ, q->ops->id); |
1073 if (cl_ops->dump && cl_ops->dump(q, cl, skb, tcm) < 0) | 1084 if (cl_ops->dump && cl_ops->dump(q, cl, skb, tcm) < 0) |
1074 goto rtattr_failure; | 1085 goto nla_put_failure; |
1075 1076 if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, 1077 TCA_XSTATS, q->stats_lock, &d) < 0) | 1086 1087 if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, 1088 TCA_XSTATS, q->stats_lock, &d) < 0) |
1078 goto rtattr_failure; | 1089 goto nla_put_failure; |
1079 1080 if (cl_ops->dump_stats && cl_ops->dump_stats(q, cl, &d) < 0) | 1090 1091 if (cl_ops->dump_stats && cl_ops->dump_stats(q, cl, &d) < 0) |
1081 goto rtattr_failure; | 1092 goto nla_put_failure; |
1082 1083 if (gnet_stats_finish_copy(&d) < 0) | 1093 1094 if (gnet_stats_finish_copy(&d) < 0) |
1084 goto rtattr_failure; | 1095 goto nla_put_failure; |
1085 1086 nlh->nlmsg_len = skb_tail_pointer(skb) - b; 1087 return skb->len; 1088 1089nlmsg_failure: | 1096 1097 nlh->nlmsg_len = skb_tail_pointer(skb) - b; 1098 return skb->len; 1099 1100nlmsg_failure: |
1090rtattr_failure: | 1101nla_put_failure: |
1091 nlmsg_trim(skb, b); 1092 return -1; 1093} 1094 1095static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n, 1096 struct Qdisc *q, unsigned long cl, int event) 1097{ 1098 struct sk_buff *skb; --- 197 unchanged lines hidden --- | 1102 nlmsg_trim(skb, b); 1103 return -1; 1104} 1105 1106static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n, 1107 struct Qdisc *q, unsigned long cl, int event) 1108{ 1109 struct sk_buff *skb; --- 197 unchanged lines hidden --- |