sch_api.c (4e1a606d552de03aec2b1fd157011bf012fcc870) sch_api.c (dac9c9790e542777079999900594fd069ba10489)
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 *

--- 13 unchanged lines hidden (view full) ---

22#include <linux/errno.h>
23#include <linux/skbuff.h>
24#include <linux/init.h>
25#include <linux/proc_fs.h>
26#include <linux/seq_file.h>
27#include <linux/kmod.h>
28#include <linux/list.h>
29#include <linux/hrtimer.h>
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 *

--- 13 unchanged lines hidden (view full) ---

22#include <linux/errno.h>
23#include <linux/skbuff.h>
24#include <linux/init.h>
25#include <linux/proc_fs.h>
26#include <linux/seq_file.h>
27#include <linux/kmod.h>
28#include <linux/list.h>
29#include <linux/hrtimer.h>
30#include <linux/lockdep.h>
31#include <linux/slab.h>
32#include <linux/hashtable.h>
33
34#include <net/net_namespace.h>
35#include <net/sock.h>
36#include <net/netlink.h>
37#include <net/pkt_sched.h>
38#include <net/pkt_cls.h>

--- 271 unchanged lines hidden (view full) ---

310 if (dev_ingress_queue(dev))
311 q = qdisc_match_from_root(
312 dev_ingress_queue(dev)->qdisc_sleeping,
313 handle);
314out:
315 return q;
316}
317
30#include <linux/slab.h>
31#include <linux/hashtable.h>
32
33#include <net/net_namespace.h>
34#include <net/sock.h>
35#include <net/netlink.h>
36#include <net/pkt_sched.h>
37#include <net/pkt_cls.h>

--- 271 unchanged lines hidden (view full) ---

309 if (dev_ingress_queue(dev))
310 q = qdisc_match_from_root(
311 dev_ingress_queue(dev)->qdisc_sleeping,
312 handle);
313out:
314 return q;
315}
316
317struct Qdisc *qdisc_lookup_rcu(struct net_device *dev, u32 handle)
318{
319 struct netdev_queue *nq;
320 struct Qdisc *q;
321
322 if (!handle)
323 return NULL;
324 q = qdisc_match_from_root(dev->qdisc, handle);
325 if (q)
326 goto out;
327
328 nq = dev_ingress_queue_rcu(dev);
329 if (nq)
330 q = qdisc_match_from_root(nq->qdisc_sleeping, handle);
331out:
332 return q;
333}
334
318static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid)
319{
320 unsigned long cl;
321 struct Qdisc *leaf;
322 const struct Qdisc_class_ops *cops = p->ops->cl_ops;
323
324 if (cops == NULL)
325 return NULL;

--- 590 unchanged lines hidden (view full) ---

916static void notify_and_destroy(struct net *net, struct sk_buff *skb,
917 struct nlmsghdr *n, u32 clid,
918 struct Qdisc *old, struct Qdisc *new)
919{
920 if (new || old)
921 qdisc_notify(net, skb, n, clid, old, new);
922
923 if (old)
335static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid)
336{
337 unsigned long cl;
338 struct Qdisc *leaf;
339 const struct Qdisc_class_ops *cops = p->ops->cl_ops;
340
341 if (cops == NULL)
342 return NULL;

--- 590 unchanged lines hidden (view full) ---

933static void notify_and_destroy(struct net *net, struct sk_buff *skb,
934 struct nlmsghdr *n, u32 clid,
935 struct Qdisc *old, struct Qdisc *new)
936{
937 if (new || old)
938 qdisc_notify(net, skb, n, clid, old, new);
939
940 if (old)
924 qdisc_destroy(old);
941 qdisc_put(old);
925}
926
927/* Graft qdisc "new" to class "classid" of qdisc "parent" or
928 * to device "dev".
929 *
930 * When appropriate send a netlink notification using 'skb'
931 * and "n".
932 *

--- 36 unchanged lines hidden (view full) ---

969 if (!ingress)
970 dev_queue = netdev_get_tx_queue(dev, i);
971
972 old = dev_graft_qdisc(dev_queue, new);
973 if (new && i > 0)
974 qdisc_refcount_inc(new);
975
976 if (!ingress)
942}
943
944/* Graft qdisc "new" to class "classid" of qdisc "parent" or
945 * to device "dev".
946 *
947 * When appropriate send a netlink notification using 'skb'
948 * and "n".
949 *

--- 36 unchanged lines hidden (view full) ---

986 if (!ingress)
987 dev_queue = netdev_get_tx_queue(dev, i);
988
989 old = dev_graft_qdisc(dev_queue, new);
990 if (new && i > 0)
991 qdisc_refcount_inc(new);
992
993 if (!ingress)
977 qdisc_destroy(old);
994 qdisc_put(old);
978 }
979
980skip:
981 if (!ingress) {
982 notify_and_destroy(net, skb, n, classid,
983 dev->qdisc, new);
984 if (new && !new->ops->attach)
985 qdisc_refcount_inc(new);

--- 62 unchanged lines hidden (view full) ---

1048 NL_SET_ERR_MSG(extack, "Egress block sharing is not supported");
1049 return -EOPNOTSUPP;
1050 }
1051 sch->ops->egress_block_set(sch, block_index);
1052 }
1053 return 0;
1054}
1055
995 }
996
997skip:
998 if (!ingress) {
999 notify_and_destroy(net, skb, n, classid,
1000 dev->qdisc, new);
1001 if (new && !new->ops->attach)
1002 qdisc_refcount_inc(new);

--- 62 unchanged lines hidden (view full) ---

1065 NL_SET_ERR_MSG(extack, "Egress block sharing is not supported");
1066 return -EOPNOTSUPP;
1067 }
1068 sch->ops->egress_block_set(sch, block_index);
1069 }
1070 return 0;
1071}
1072
1056/* lockdep annotation is needed for ingress; egress gets it only for name */
1057static struct lock_class_key qdisc_tx_lock;
1058static struct lock_class_key qdisc_rx_lock;
1059
1060/*
1061 Allocate and initialize new qdisc.
1062
1063 Parameters are passed via opt.
1064 */
1065
1066static struct Qdisc *qdisc_create(struct net_device *dev,
1067 struct netdev_queue *dev_queue,

--- 48 unchanged lines hidden (view full) ---

1116 goto err_out2;
1117 }
1118
1119 sch->parent = parent;
1120
1121 if (handle == TC_H_INGRESS) {
1122 sch->flags |= TCQ_F_INGRESS;
1123 handle = TC_H_MAKE(TC_H_INGRESS, 0);
1073/*
1074 Allocate and initialize new qdisc.
1075
1076 Parameters are passed via opt.
1077 */
1078
1079static struct Qdisc *qdisc_create(struct net_device *dev,
1080 struct netdev_queue *dev_queue,

--- 48 unchanged lines hidden (view full) ---

1129 goto err_out2;
1130 }
1131
1132 sch->parent = parent;
1133
1134 if (handle == TC_H_INGRESS) {
1135 sch->flags |= TCQ_F_INGRESS;
1136 handle = TC_H_MAKE(TC_H_INGRESS, 0);
1124 lockdep_set_class(qdisc_lock(sch), &qdisc_rx_lock);
1125 } else {
1126 if (handle == 0) {
1127 handle = qdisc_alloc_handle(dev);
1128 err = -ENOMEM;
1129 if (handle == 0)
1130 goto err_out3;
1131 }
1137 } else {
1138 if (handle == 0) {
1139 handle = qdisc_alloc_handle(dev);
1140 err = -ENOMEM;
1141 if (handle == 0)
1142 goto err_out3;
1143 }
1132 lockdep_set_class(qdisc_lock(sch), &qdisc_tx_lock);
1133 if (!netif_is_multiqueue(dev))
1134 sch->flags |= TCQ_F_ONETXQUEUE;
1135 }
1136
1137 sch->handle = handle;
1138
1139 /* This exist to keep backward compatible with a userspace
1140 * loophole, what allowed userspace to get IFF_NO_QUEUE

--- 436 unchanged lines hidden (view full) ---

1577 goto replay;
1578 return err;
1579 }
1580
1581graft:
1582 err = qdisc_graft(dev, p, skb, n, clid, q, NULL, extack);
1583 if (err) {
1584 if (q)
1144 if (!netif_is_multiqueue(dev))
1145 sch->flags |= TCQ_F_ONETXQUEUE;
1146 }
1147
1148 sch->handle = handle;
1149
1150 /* This exist to keep backward compatible with a userspace
1151 * loophole, what allowed userspace to get IFF_NO_QUEUE

--- 436 unchanged lines hidden (view full) ---

1588 goto replay;
1589 return err;
1590 }
1591
1592graft:
1593 err = qdisc_graft(dev, p, skb, n, clid, q, NULL, extack);
1594 if (err) {
1595 if (q)
1585 qdisc_destroy(q);
1596 qdisc_put(q);
1586 return err;
1587 }
1588
1589 return 0;
1590}
1591
1592static int tc_dump_qdisc_root(struct Qdisc *root, struct sk_buff *skb,
1593 struct netlink_callback *cb,

--- 61 unchanged lines hidden (view full) ---

1655
1656 s_idx = cb->args[0];
1657 s_q_idx = q_idx = cb->args[1];
1658
1659 idx = 0;
1660 ASSERT_RTNL();
1661
1662 err = nlmsg_parse(nlh, sizeof(struct tcmsg), tca, TCA_MAX,
1597 return err;
1598 }
1599
1600 return 0;
1601}
1602
1603static int tc_dump_qdisc_root(struct Qdisc *root, struct sk_buff *skb,
1604 struct netlink_callback *cb,

--- 61 unchanged lines hidden (view full) ---

1666
1667 s_idx = cb->args[0];
1668 s_q_idx = q_idx = cb->args[1];
1669
1670 idx = 0;
1671 ASSERT_RTNL();
1672
1673 err = nlmsg_parse(nlh, sizeof(struct tcmsg), tca, TCA_MAX,
1663 rtm_tca_policy, NULL);
1674 rtm_tca_policy, cb->extack);
1664 if (err < 0)
1665 return err;
1666
1667 for_each_netdev(net, dev) {
1668 struct netdev_queue *dev_queue;
1669
1670 if (idx < s_idx)
1671 goto cont;

--- 508 unchanged lines hidden ---
1675 if (err < 0)
1676 return err;
1677
1678 for_each_netdev(net, dev) {
1679 struct netdev_queue *dev_queue;
1680
1681 if (idx < s_idx)
1682 goto cont;

--- 508 unchanged lines hidden ---