diff options
Diffstat (limited to 'net/sched/sch_api.c')
-rw-r--r-- | net/sched/sch_api.c | 87 |
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 | ||
216 | static struct Qdisc_ops *qdisc_lookup_ops(struct rtattr *kind) | 216 | static 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 | ||
234 | static struct qdisc_rate_table *qdisc_rtab_list; | 234 | static struct qdisc_rate_table *qdisc_rtab_list; |
235 | 235 | ||
236 | struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct rtattr *tab) | 236 | struct 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 | ||
446 | static struct Qdisc * | 446 | static struct Qdisc * |
447 | qdisc_create(struct net_device *dev, u32 parent, u32 handle, | 447 | qdisc_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 | ||
544 | static int qdisc_change(struct Qdisc *sch, struct rtattr **tca) | 544 | static 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) | |||
683 | replay: | 687 | replay: |
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 | ||
853 | nlmsg_failure: | 860 | nlmsg_failure: |
854 | rtattr_failure: | 861 | nla_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 | ||
1089 | nlmsg_failure: | 1100 | nlmsg_failure: |
1090 | rtattr_failure: | 1101 | nla_put_failure: |
1091 | nlmsg_trim(skb, b); | 1102 | nlmsg_trim(skb, b); |
1092 | return -1; | 1103 | return -1; |
1093 | } | 1104 | } |