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 ---