aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/sch_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/sch_api.c')
-rw-r--r--net/sched/sch_api.c87
1 files changed, 49 insertions, 38 deletions
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index dc89a9343f30..7abb028dd96b 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -213,14 +213,14 @@ static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid)
213 213
214/* Find queueing discipline by name */ 214/* Find queueing discipline by name */
215 215
216static struct Qdisc_ops *qdisc_lookup_ops(struct rtattr *kind) 216static struct Qdisc_ops *qdisc_lookup_ops(struct nlattr *kind)
217{ 217{
218 struct Qdisc_ops *q = NULL; 218 struct Qdisc_ops *q = NULL;
219 219
220 if (kind) { 220 if (kind) {
221 read_lock(&qdisc_mod_lock); 221 read_lock(&qdisc_mod_lock);
222 for (q = qdisc_base; q; q = q->next) { 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)) 224 if (!try_module_get(q->owner))
225 q = NULL; 225 q = NULL;
226 break; 226 break;
@@ -233,7 +233,7 @@ static struct Qdisc_ops *qdisc_lookup_ops(struct rtattr *kind)
233 233
234static struct qdisc_rate_table *qdisc_rtab_list; 234static struct qdisc_rate_table *qdisc_rtab_list;
235 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{ 237{
238 struct qdisc_rate_table *rtab; 238 struct qdisc_rate_table *rtab;
239 239
@@ -244,14 +244,14 @@ struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct rtattr *ta
244 } 244 }
245 } 245 }
246 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; 248 return NULL;
249 249
250 rtab = kmalloc(sizeof(*rtab), GFP_KERNEL); 250 rtab = kmalloc(sizeof(*rtab), GFP_KERNEL);
251 if (rtab) { 251 if (rtab) {
252 rtab->rate = *r; 252 rtab->rate = *r;
253 rtab->refcnt = 1; 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; 255 rtab->next = qdisc_rtab_list;
256 qdisc_rtab_list = rtab; 256 qdisc_rtab_list = rtab;
257 } 257 }
@@ -445,10 +445,10 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
445 445
446static struct Qdisc * 446static struct Qdisc *
447qdisc_create(struct net_device *dev, u32 parent, u32 handle, 447qdisc_create(struct net_device *dev, u32 parent, u32 handle,
448 struct rtattr **tca, int *errp) 448 struct nlattr **tca, int *errp)
449{ 449{
450 int err; 450 int err;
451 struct rtattr *kind = tca[TCA_KIND-1]; 451 struct nlattr *kind = tca[TCA_KIND];
452 struct Qdisc *sch; 452 struct Qdisc *sch;
453 struct Qdisc_ops *ops; 453 struct Qdisc_ops *ops;
454 454
@@ -456,7 +456,7 @@ qdisc_create(struct net_device *dev, u32 parent, u32 handle,
456#ifdef CONFIG_KMOD 456#ifdef CONFIG_KMOD
457 if (ops == NULL && kind != NULL) { 457 if (ops == NULL && kind != NULL) {
458 char name[IFNAMSIZ]; 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 460 /* We dropped the RTNL semaphore in order to
461 * perform the module load. So, even if we 461 * perform the module load. So, even if we
462 * succeeded in loading the module we have to 462 * succeeded in loading the module we have to
@@ -509,11 +509,11 @@ qdisc_create(struct net_device *dev, u32 parent, u32 handle,
509 509
510 sch->handle = handle; 510 sch->handle = handle;
511 511
512 if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) { 512 if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS])) == 0) {
513 if (tca[TCA_RATE-1]) { 513 if (tca[TCA_RATE]) {
514 err = gen_new_estimator(&sch->bstats, &sch->rate_est, 514 err = gen_new_estimator(&sch->bstats, &sch->rate_est,
515 sch->stats_lock, 515 sch->stats_lock,
516 tca[TCA_RATE-1]); 516 tca[TCA_RATE]);
517 if (err) { 517 if (err) {
518 /* 518 /*
519 * Any broken qdiscs that would require 519 * Any broken qdiscs that would require
@@ -541,20 +541,20 @@ err_out:
541 return NULL; 541 return NULL;
542} 542}
543 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; 547 int err;
548 548
549 if (sch->ops->change == NULL) 549 if (sch->ops->change == NULL)
550 return -EINVAL; 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) 552 if (err)
553 return err; 553 return err;
554 } 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; 558 return 0;
559} 559}
560 560
@@ -606,7 +606,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
606{ 606{
607 struct net *net = skb->sk->sk_net; 607 struct net *net = skb->sk->sk_net;
608 struct tcmsg *tcm = NLMSG_DATA(n); 608 struct tcmsg *tcm = NLMSG_DATA(n);
609 struct rtattr **tca = arg; 609 struct nlattr *tca[TCA_MAX + 1];
610 struct net_device *dev; 610 struct net_device *dev;
611 u32 clid = tcm->tcm_parent; 611 u32 clid = tcm->tcm_parent;
612 struct Qdisc *q = NULL; 612 struct Qdisc *q = NULL;
@@ -619,6 +619,10 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
619 if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) 619 if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
620 return -ENODEV; 620 return -ENODEV;
621 621
622 err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);
623 if (err < 0)
624 return err;
625
622 if (clid) { 626 if (clid) {
623 if (clid != TC_H_ROOT) { 627 if (clid != TC_H_ROOT) {
624 if (TC_H_MAJ(clid) != TC_H_MAJ(TC_H_INGRESS)) { 628 if (TC_H_MAJ(clid) != TC_H_MAJ(TC_H_INGRESS)) {
@@ -641,7 +645,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
641 return -ENOENT; 645 return -ENOENT;
642 } 646 }
643 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; 649 return -EINVAL;
646 650
647 if (n->nlmsg_type == RTM_DELQDISC) { 651 if (n->nlmsg_type == RTM_DELQDISC) {
@@ -671,7 +675,7 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
671{ 675{
672 struct net *net = skb->sk->sk_net; 676 struct net *net = skb->sk->sk_net;
673 struct tcmsg *tcm; 677 struct tcmsg *tcm;
674 struct rtattr **tca; 678 struct nlattr *tca[TCA_MAX + 1];
675 struct net_device *dev; 679 struct net_device *dev;
676 u32 clid; 680 u32 clid;
677 struct Qdisc *q, *p; 681 struct Qdisc *q, *p;
@@ -683,13 +687,16 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
683replay: 687replay:
684 /* Reinit, just in case something touches this. */ 688 /* Reinit, just in case something touches this. */
685 tcm = NLMSG_DATA(n); 689 tcm = NLMSG_DATA(n);
686 tca = arg;
687 clid = tcm->tcm_parent; 690 clid = tcm->tcm_parent;
688 q = p = NULL; 691 q = p = NULL;
689 692
690 if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) 693 if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
691 return -ENODEV; 694 return -ENODEV;
692 695
696 err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);
697 if (err < 0)
698 return err;
699
693 if (clid) { 700 if (clid) {
694 if (clid != TC_H_ROOT) { 701 if (clid != TC_H_ROOT) {
695 if (clid != TC_H_INGRESS) { 702 if (clid != TC_H_INGRESS) {
@@ -717,7 +724,7 @@ replay:
717 goto create_n_graft; 724 goto create_n_graft;
718 if (n->nlmsg_flags&NLM_F_EXCL) 725 if (n->nlmsg_flags&NLM_F_EXCL)
719 return -EEXIST; 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; 728 return -EINVAL;
722 if (q == p || 729 if (q == p ||
723 (p && check_loop(q, p, 0))) 730 (p && check_loop(q, p, 0)))
@@ -750,8 +757,8 @@ replay:
750 if ((n->nlmsg_flags&NLM_F_CREATE) && 757 if ((n->nlmsg_flags&NLM_F_CREATE) &&
751 (n->nlmsg_flags&NLM_F_REPLACE) && 758 (n->nlmsg_flags&NLM_F_REPLACE) &&
752 ((n->nlmsg_flags&NLM_F_EXCL) || 759 ((n->nlmsg_flags&NLM_F_EXCL) ||
753 (tca[TCA_KIND-1] && 760 (tca[TCA_KIND] &&
754 rtattr_strcmp(tca[TCA_KIND-1], q->ops->id)))) 761 nla_strcmp(tca[TCA_KIND], q->ops->id))))
755 goto create_n_graft; 762 goto create_n_graft;
756 } 763 }
757 } 764 }
@@ -766,7 +773,7 @@ replay:
766 return -ENOENT; 773 return -ENOENT;
767 if (n->nlmsg_flags&NLM_F_EXCL) 774 if (n->nlmsg_flags&NLM_F_EXCL)
768 return -EEXIST; 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; 777 return -EINVAL;
771 err = qdisc_change(q, tca); 778 err = qdisc_change(q, tca);
772 if (err == 0) 779 if (err == 0)
@@ -827,31 +834,31 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
827 tcm->tcm_parent = clid; 834 tcm->tcm_parent = clid;
828 tcm->tcm_handle = q->handle; 835 tcm->tcm_handle = q->handle;
829 tcm->tcm_info = atomic_read(&q->refcnt); 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; 840 q->qstats.qlen = q->q.qlen;
834 841
835 if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, 842 if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS,
836 TCA_XSTATS, q->stats_lock, &d) < 0) 843 TCA_XSTATS, q->stats_lock, &d) < 0)
837 goto rtattr_failure; 844 goto nla_put_failure;
838 845
839 if (q->ops->dump_stats && q->ops->dump_stats(q, &d) < 0) 846 if (q->ops->dump_stats && q->ops->dump_stats(q, &d) < 0)
840 goto rtattr_failure; 847 goto nla_put_failure;
841 848
842 if (gnet_stats_copy_basic(&d, &q->bstats) < 0 || 849 if (gnet_stats_copy_basic(&d, &q->bstats) < 0 ||
843 gnet_stats_copy_rate_est(&d, &q->rate_est) < 0 || 850 gnet_stats_copy_rate_est(&d, &q->rate_est) < 0 ||
844 gnet_stats_copy_queue(&d, &q->qstats) < 0) 851 gnet_stats_copy_queue(&d, &q->qstats) < 0)
845 goto rtattr_failure; 852 goto nla_put_failure;
846 853
847 if (gnet_stats_finish_copy(&d) < 0) 854 if (gnet_stats_finish_copy(&d) < 0)
848 goto rtattr_failure; 855 goto nla_put_failure;
849 856
850 nlh->nlmsg_len = skb_tail_pointer(skb) - b; 857 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
851 return skb->len; 858 return skb->len;
852 859
853nlmsg_failure: 860nlmsg_failure:
854rtattr_failure: 861nla_put_failure:
855 nlmsg_trim(skb, b); 862 nlmsg_trim(skb, b);
856 return -1; 863 return -1;
857} 864}
@@ -939,7 +946,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
939{ 946{
940 struct net *net = skb->sk->sk_net; 947 struct net *net = skb->sk->sk_net;
941 struct tcmsg *tcm = NLMSG_DATA(n); 948 struct tcmsg *tcm = NLMSG_DATA(n);
942 struct rtattr **tca = arg; 949 struct nlattr *tca[TCA_MAX + 1];
943 struct net_device *dev; 950 struct net_device *dev;
944 struct Qdisc *q = NULL; 951 struct Qdisc *q = NULL;
945 const struct Qdisc_class_ops *cops; 952 const struct Qdisc_class_ops *cops;
@@ -956,6 +963,10 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
956 if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) 963 if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
957 return -ENODEV; 964 return -ENODEV;
958 965
966 err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);
967 if (err < 0)
968 return err;
969
959 /* 970 /*
960 parent == TC_H_UNSPEC - unspecified parent. 971 parent == TC_H_UNSPEC - unspecified parent.
961 parent == TC_H_ROOT - class is root, which has no parent. 972 parent == TC_H_ROOT - class is root, which has no parent.
@@ -1069,25 +1080,25 @@ static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q,
1069 tcm->tcm_parent = q->handle; 1080 tcm->tcm_parent = q->handle;
1070 tcm->tcm_handle = q->handle; 1081 tcm->tcm_handle = q->handle;
1071 tcm->tcm_info = 0; 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 1086
1076 if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, 1087 if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS,
1077 TCA_XSTATS, q->stats_lock, &d) < 0) 1088 TCA_XSTATS, q->stats_lock, &d) < 0)
1078 goto rtattr_failure; 1089 goto nla_put_failure;
1079 1090
1080 if (cl_ops->dump_stats && cl_ops->dump_stats(q, cl, &d) < 0) 1091 if (cl_ops->dump_stats && cl_ops->dump_stats(q, cl, &d) < 0)
1081 goto rtattr_failure; 1092 goto nla_put_failure;
1082 1093
1083 if (gnet_stats_finish_copy(&d) < 0) 1094 if (gnet_stats_finish_copy(&d) < 0)
1084 goto rtattr_failure; 1095 goto nla_put_failure;
1085 1096
1086 nlh->nlmsg_len = skb_tail_pointer(skb) - b; 1097 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
1087 return skb->len; 1098 return skb->len;
1088 1099
1089nlmsg_failure: 1100nlmsg_failure:
1090rtattr_failure: 1101nla_put_failure:
1091 nlmsg_trim(skb, b); 1102 nlmsg_trim(skb, b);
1092 return -1; 1103 return -1;
1093} 1104}