diff options
Diffstat (limited to 'net/sched/sch_api.c')
| -rw-r--r-- | net/sched/sch_api.c | 159 |
1 files changed, 103 insertions, 56 deletions
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 75fd1c672c61..408eea7086aa 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
| @@ -28,16 +28,19 @@ | |||
| 28 | #include <linux/list.h> | 28 | #include <linux/list.h> |
| 29 | #include <linux/hrtimer.h> | 29 | #include <linux/hrtimer.h> |
| 30 | #include <linux/lockdep.h> | 30 | #include <linux/lockdep.h> |
| 31 | #include <linux/slab.h> | ||
| 31 | 32 | ||
| 32 | #include <net/net_namespace.h> | 33 | #include <net/net_namespace.h> |
| 33 | #include <net/sock.h> | 34 | #include <net/sock.h> |
| 34 | #include <net/netlink.h> | 35 | #include <net/netlink.h> |
| 35 | #include <net/pkt_sched.h> | 36 | #include <net/pkt_sched.h> |
| 36 | 37 | ||
| 37 | static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n, u32 clid, | 38 | static int qdisc_notify(struct net *net, struct sk_buff *oskb, |
| 39 | struct nlmsghdr *n, u32 clid, | ||
| 38 | struct Qdisc *old, struct Qdisc *new); | 40 | struct Qdisc *old, struct Qdisc *new); |
| 39 | static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n, | 41 | static int tclass_notify(struct net *net, struct sk_buff *oskb, |
| 40 | struct Qdisc *q, unsigned long cl, int event); | 42 | struct nlmsghdr *n, struct Qdisc *q, |
| 43 | unsigned long cl, int event); | ||
| 41 | 44 | ||
| 42 | /* | 45 | /* |
| 43 | 46 | ||
| @@ -147,22 +150,34 @@ int register_qdisc(struct Qdisc_ops *qops) | |||
| 147 | if (qops->enqueue == NULL) | 150 | if (qops->enqueue == NULL) |
| 148 | qops->enqueue = noop_qdisc_ops.enqueue; | 151 | qops->enqueue = noop_qdisc_ops.enqueue; |
| 149 | if (qops->peek == NULL) { | 152 | if (qops->peek == NULL) { |
| 150 | if (qops->dequeue == NULL) { | 153 | if (qops->dequeue == NULL) |
| 151 | qops->peek = noop_qdisc_ops.peek; | 154 | qops->peek = noop_qdisc_ops.peek; |
| 152 | } else { | 155 | else |
| 153 | rc = -EINVAL; | 156 | goto out_einval; |
| 154 | goto out; | ||
| 155 | } | ||
| 156 | } | 157 | } |
| 157 | if (qops->dequeue == NULL) | 158 | if (qops->dequeue == NULL) |
| 158 | qops->dequeue = noop_qdisc_ops.dequeue; | 159 | qops->dequeue = noop_qdisc_ops.dequeue; |
| 159 | 160 | ||
| 161 | if (qops->cl_ops) { | ||
| 162 | const struct Qdisc_class_ops *cops = qops->cl_ops; | ||
| 163 | |||
| 164 | if (!(cops->get && cops->put && cops->walk && cops->leaf)) | ||
| 165 | goto out_einval; | ||
| 166 | |||
| 167 | if (cops->tcf_chain && !(cops->bind_tcf && cops->unbind_tcf)) | ||
| 168 | goto out_einval; | ||
| 169 | } | ||
| 170 | |||
| 160 | qops->next = NULL; | 171 | qops->next = NULL; |
| 161 | *qp = qops; | 172 | *qp = qops; |
| 162 | rc = 0; | 173 | rc = 0; |
| 163 | out: | 174 | out: |
| 164 | write_unlock(&qdisc_mod_lock); | 175 | write_unlock(&qdisc_mod_lock); |
| 165 | return rc; | 176 | return rc; |
| 177 | |||
| 178 | out_einval: | ||
| 179 | rc = -EINVAL; | ||
| 180 | goto out; | ||
| 166 | } | 181 | } |
| 167 | EXPORT_SYMBOL(register_qdisc); | 182 | EXPORT_SYMBOL(register_qdisc); |
| 168 | 183 | ||
| @@ -638,11 +653,12 @@ void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n) | |||
| 638 | } | 653 | } |
| 639 | EXPORT_SYMBOL(qdisc_tree_decrease_qlen); | 654 | EXPORT_SYMBOL(qdisc_tree_decrease_qlen); |
| 640 | 655 | ||
| 641 | static void notify_and_destroy(struct sk_buff *skb, struct nlmsghdr *n, u32 clid, | 656 | static void notify_and_destroy(struct net *net, struct sk_buff *skb, |
| 657 | struct nlmsghdr *n, u32 clid, | ||
| 642 | struct Qdisc *old, struct Qdisc *new) | 658 | struct Qdisc *old, struct Qdisc *new) |
| 643 | { | 659 | { |
| 644 | if (new || old) | 660 | if (new || old) |
| 645 | qdisc_notify(skb, n, clid, old, new); | 661 | qdisc_notify(net, skb, n, clid, old, new); |
| 646 | 662 | ||
| 647 | if (old) | 663 | if (old) |
| 648 | qdisc_destroy(old); | 664 | qdisc_destroy(old); |
| @@ -662,6 +678,7 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, | |||
| 662 | struct Qdisc *new, struct Qdisc *old) | 678 | struct Qdisc *new, struct Qdisc *old) |
| 663 | { | 679 | { |
| 664 | struct Qdisc *q = old; | 680 | struct Qdisc *q = old; |
| 681 | struct net *net = dev_net(dev); | ||
| 665 | int err = 0; | 682 | int err = 0; |
| 666 | 683 | ||
| 667 | if (parent == NULL) { | 684 | if (parent == NULL) { |
| @@ -698,12 +715,13 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, | |||
| 698 | } | 715 | } |
| 699 | 716 | ||
| 700 | if (!ingress) { | 717 | if (!ingress) { |
| 701 | notify_and_destroy(skb, n, classid, dev->qdisc, new); | 718 | notify_and_destroy(net, skb, n, classid, |
| 719 | dev->qdisc, new); | ||
| 702 | if (new && !new->ops->attach) | 720 | if (new && !new->ops->attach) |
| 703 | atomic_inc(&new->refcnt); | 721 | atomic_inc(&new->refcnt); |
| 704 | dev->qdisc = new ? : &noop_qdisc; | 722 | dev->qdisc = new ? : &noop_qdisc; |
| 705 | } else { | 723 | } else { |
| 706 | notify_and_destroy(skb, n, classid, old, new); | 724 | notify_and_destroy(net, skb, n, classid, old, new); |
| 707 | } | 725 | } |
| 708 | 726 | ||
| 709 | if (dev->flags & IFF_UP) | 727 | if (dev->flags & IFF_UP) |
| @@ -721,7 +739,7 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, | |||
| 721 | err = -ENOENT; | 739 | err = -ENOENT; |
| 722 | } | 740 | } |
| 723 | if (!err) | 741 | if (!err) |
| 724 | notify_and_destroy(skb, n, classid, old, new); | 742 | notify_and_destroy(net, skb, n, classid, old, new); |
| 725 | } | 743 | } |
| 726 | return err; | 744 | return err; |
| 727 | } | 745 | } |
| @@ -947,10 +965,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
| 947 | struct Qdisc *p = NULL; | 965 | struct Qdisc *p = NULL; |
| 948 | int err; | 966 | int err; |
| 949 | 967 | ||
| 950 | if (!net_eq(net, &init_net)) | 968 | if ((dev = __dev_get_by_index(net, tcm->tcm_ifindex)) == NULL) |
| 951 | return -EINVAL; | ||
| 952 | |||
| 953 | if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) | ||
| 954 | return -ENODEV; | 969 | return -ENODEV; |
| 955 | 970 | ||
| 956 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); | 971 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); |
| @@ -990,7 +1005,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
| 990 | if ((err = qdisc_graft(dev, p, skb, n, clid, NULL, q)) != 0) | 1005 | if ((err = qdisc_graft(dev, p, skb, n, clid, NULL, q)) != 0) |
| 991 | return err; | 1006 | return err; |
| 992 | } else { | 1007 | } else { |
| 993 | qdisc_notify(skb, n, clid, NULL, q); | 1008 | qdisc_notify(net, skb, n, clid, NULL, q); |
| 994 | } | 1009 | } |
| 995 | return 0; | 1010 | return 0; |
| 996 | } | 1011 | } |
| @@ -1009,16 +1024,13 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
| 1009 | struct Qdisc *q, *p; | 1024 | struct Qdisc *q, *p; |
| 1010 | int err; | 1025 | int err; |
| 1011 | 1026 | ||
| 1012 | if (!net_eq(net, &init_net)) | ||
| 1013 | return -EINVAL; | ||
| 1014 | |||
| 1015 | replay: | 1027 | replay: |
| 1016 | /* Reinit, just in case something touches this. */ | 1028 | /* Reinit, just in case something touches this. */ |
| 1017 | tcm = NLMSG_DATA(n); | 1029 | tcm = NLMSG_DATA(n); |
| 1018 | clid = tcm->tcm_parent; | 1030 | clid = tcm->tcm_parent; |
| 1019 | q = p = NULL; | 1031 | q = p = NULL; |
| 1020 | 1032 | ||
| 1021 | if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) | 1033 | if ((dev = __dev_get_by_index(net, tcm->tcm_ifindex)) == NULL) |
| 1022 | return -ENODEV; | 1034 | return -ENODEV; |
| 1023 | 1035 | ||
| 1024 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); | 1036 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); |
| @@ -1105,7 +1117,7 @@ replay: | |||
| 1105 | return -EINVAL; | 1117 | return -EINVAL; |
| 1106 | err = qdisc_change(q, tca); | 1118 | err = qdisc_change(q, tca); |
| 1107 | if (err == 0) | 1119 | if (err == 0) |
| 1108 | qdisc_notify(skb, n, clid, NULL, q); | 1120 | qdisc_notify(net, skb, n, clid, NULL, q); |
| 1109 | return err; | 1121 | return err; |
| 1110 | 1122 | ||
| 1111 | create_n_graft: | 1123 | create_n_graft: |
| @@ -1195,8 +1207,14 @@ nla_put_failure: | |||
| 1195 | return -1; | 1207 | return -1; |
| 1196 | } | 1208 | } |
| 1197 | 1209 | ||
| 1198 | static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n, | 1210 | static bool tc_qdisc_dump_ignore(struct Qdisc *q) |
| 1199 | u32 clid, struct Qdisc *old, struct Qdisc *new) | 1211 | { |
| 1212 | return (q->flags & TCQ_F_BUILTIN) ? true : false; | ||
| 1213 | } | ||
| 1214 | |||
| 1215 | static int qdisc_notify(struct net *net, struct sk_buff *oskb, | ||
| 1216 | struct nlmsghdr *n, u32 clid, | ||
| 1217 | struct Qdisc *old, struct Qdisc *new) | ||
| 1200 | { | 1218 | { |
| 1201 | struct sk_buff *skb; | 1219 | struct sk_buff *skb; |
| 1202 | u32 pid = oskb ? NETLINK_CB(oskb).pid : 0; | 1220 | u32 pid = oskb ? NETLINK_CB(oskb).pid : 0; |
| @@ -1205,28 +1223,23 @@ static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n, | |||
| 1205 | if (!skb) | 1223 | if (!skb) |
| 1206 | return -ENOBUFS; | 1224 | return -ENOBUFS; |
| 1207 | 1225 | ||
| 1208 | if (old && old->handle) { | 1226 | if (old && !tc_qdisc_dump_ignore(old)) { |
| 1209 | if (tc_fill_qdisc(skb, old, clid, pid, n->nlmsg_seq, 0, RTM_DELQDISC) < 0) | 1227 | if (tc_fill_qdisc(skb, old, clid, pid, n->nlmsg_seq, 0, RTM_DELQDISC) < 0) |
| 1210 | goto err_out; | 1228 | goto err_out; |
| 1211 | } | 1229 | } |
| 1212 | if (new) { | 1230 | if (new && !tc_qdisc_dump_ignore(new)) { |
| 1213 | if (tc_fill_qdisc(skb, new, clid, pid, n->nlmsg_seq, old ? NLM_F_REPLACE : 0, RTM_NEWQDISC) < 0) | 1231 | if (tc_fill_qdisc(skb, new, clid, pid, n->nlmsg_seq, old ? NLM_F_REPLACE : 0, RTM_NEWQDISC) < 0) |
| 1214 | goto err_out; | 1232 | goto err_out; |
| 1215 | } | 1233 | } |
| 1216 | 1234 | ||
| 1217 | if (skb->len) | 1235 | if (skb->len) |
| 1218 | return rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO); | 1236 | return rtnetlink_send(skb, net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO); |
| 1219 | 1237 | ||
| 1220 | err_out: | 1238 | err_out: |
| 1221 | kfree_skb(skb); | 1239 | kfree_skb(skb); |
| 1222 | return -EINVAL; | 1240 | return -EINVAL; |
| 1223 | } | 1241 | } |
| 1224 | 1242 | ||
| 1225 | static bool tc_qdisc_dump_ignore(struct Qdisc *q) | ||
| 1226 | { | ||
| 1227 | return (q->flags & TCQ_F_BUILTIN) ? true : false; | ||
| 1228 | } | ||
| 1229 | |||
| 1230 | static int tc_dump_qdisc_root(struct Qdisc *root, struct sk_buff *skb, | 1243 | static int tc_dump_qdisc_root(struct Qdisc *root, struct sk_buff *skb, |
| 1231 | struct netlink_callback *cb, | 1244 | struct netlink_callback *cb, |
| 1232 | int *q_idx_p, int s_q_idx) | 1245 | int *q_idx_p, int s_q_idx) |
| @@ -1274,15 +1287,12 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 1274 | int s_idx, s_q_idx; | 1287 | int s_idx, s_q_idx; |
| 1275 | struct net_device *dev; | 1288 | struct net_device *dev; |
| 1276 | 1289 | ||
| 1277 | if (!net_eq(net, &init_net)) | ||
| 1278 | return 0; | ||
| 1279 | |||
| 1280 | s_idx = cb->args[0]; | 1290 | s_idx = cb->args[0]; |
| 1281 | s_q_idx = q_idx = cb->args[1]; | 1291 | s_q_idx = q_idx = cb->args[1]; |
| 1282 | 1292 | ||
| 1283 | rcu_read_lock(); | 1293 | rcu_read_lock(); |
| 1284 | idx = 0; | 1294 | idx = 0; |
| 1285 | for_each_netdev_rcu(&init_net, dev) { | 1295 | for_each_netdev_rcu(net, dev) { |
| 1286 | struct netdev_queue *dev_queue; | 1296 | struct netdev_queue *dev_queue; |
| 1287 | 1297 | ||
| 1288 | if (idx < s_idx) | 1298 | if (idx < s_idx) |
| @@ -1334,10 +1344,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
| 1334 | u32 qid = TC_H_MAJ(clid); | 1344 | u32 qid = TC_H_MAJ(clid); |
| 1335 | int err; | 1345 | int err; |
| 1336 | 1346 | ||
| 1337 | if (!net_eq(net, &init_net)) | 1347 | if ((dev = __dev_get_by_index(net, tcm->tcm_ifindex)) == NULL) |
| 1338 | return -EINVAL; | ||
| 1339 | |||
| 1340 | if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) | ||
| 1341 | return -ENODEV; | 1348 | return -ENODEV; |
| 1342 | 1349 | ||
| 1343 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); | 1350 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); |
| @@ -1418,10 +1425,10 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
| 1418 | if (cops->delete) | 1425 | if (cops->delete) |
| 1419 | err = cops->delete(q, cl); | 1426 | err = cops->delete(q, cl); |
| 1420 | if (err == 0) | 1427 | if (err == 0) |
| 1421 | tclass_notify(skb, n, q, cl, RTM_DELTCLASS); | 1428 | tclass_notify(net, skb, n, q, cl, RTM_DELTCLASS); |
| 1422 | goto out; | 1429 | goto out; |
| 1423 | case RTM_GETTCLASS: | 1430 | case RTM_GETTCLASS: |
| 1424 | err = tclass_notify(skb, n, q, cl, RTM_NEWTCLASS); | 1431 | err = tclass_notify(net, skb, n, q, cl, RTM_NEWTCLASS); |
| 1425 | goto out; | 1432 | goto out; |
| 1426 | default: | 1433 | default: |
| 1427 | err = -EINVAL; | 1434 | err = -EINVAL; |
| @@ -1434,7 +1441,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
| 1434 | if (cops->change) | 1441 | if (cops->change) |
| 1435 | err = cops->change(q, clid, pid, tca, &new_cl); | 1442 | err = cops->change(q, clid, pid, tca, &new_cl); |
| 1436 | if (err == 0) | 1443 | if (err == 0) |
| 1437 | tclass_notify(skb, n, q, new_cl, RTM_NEWTCLASS); | 1444 | tclass_notify(net, skb, n, q, new_cl, RTM_NEWTCLASS); |
| 1438 | 1445 | ||
| 1439 | out: | 1446 | out: |
| 1440 | if (cl) | 1447 | if (cl) |
| @@ -1486,8 +1493,9 @@ nla_put_failure: | |||
| 1486 | return -1; | 1493 | return -1; |
| 1487 | } | 1494 | } |
| 1488 | 1495 | ||
| 1489 | static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n, | 1496 | static int tclass_notify(struct net *net, struct sk_buff *oskb, |
| 1490 | struct Qdisc *q, unsigned long cl, int event) | 1497 | struct nlmsghdr *n, struct Qdisc *q, |
| 1498 | unsigned long cl, int event) | ||
| 1491 | { | 1499 | { |
| 1492 | struct sk_buff *skb; | 1500 | struct sk_buff *skb; |
| 1493 | u32 pid = oskb ? NETLINK_CB(oskb).pid : 0; | 1501 | u32 pid = oskb ? NETLINK_CB(oskb).pid : 0; |
| @@ -1501,7 +1509,7 @@ static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n, | |||
| 1501 | return -EINVAL; | 1509 | return -EINVAL; |
| 1502 | } | 1510 | } |
| 1503 | 1511 | ||
| 1504 | return rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO); | 1512 | return rtnetlink_send(skb, net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO); |
| 1505 | } | 1513 | } |
| 1506 | 1514 | ||
| 1507 | struct qdisc_dump_args | 1515 | struct qdisc_dump_args |
| @@ -1576,12 +1584,9 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 1576 | struct net_device *dev; | 1584 | struct net_device *dev; |
| 1577 | int t, s_t; | 1585 | int t, s_t; |
| 1578 | 1586 | ||
| 1579 | if (!net_eq(net, &init_net)) | ||
| 1580 | return 0; | ||
| 1581 | |||
| 1582 | if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm))) | 1587 | if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm))) |
| 1583 | return 0; | 1588 | return 0; |
| 1584 | if ((dev = dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) | 1589 | if ((dev = dev_get_by_index(net, tcm->tcm_ifindex)) == NULL) |
| 1585 | return 0; | 1590 | return 0; |
| 1586 | 1591 | ||
| 1587 | s_t = cb->args[0]; | 1592 | s_t = cb->args[0]; |
| @@ -1644,9 +1649,12 @@ reclassify: | |||
| 1644 | tp = otp; | 1649 | tp = otp; |
| 1645 | 1650 | ||
| 1646 | if (verd++ >= MAX_REC_LOOP) { | 1651 | if (verd++ >= MAX_REC_LOOP) { |
| 1647 | printk("rule prio %u protocol %02x reclassify loop, " | 1652 | if (net_ratelimit()) |
| 1648 | "packet dropped\n", | 1653 | printk(KERN_NOTICE |
| 1649 | tp->prio&0xffff, ntohs(tp->protocol)); | 1654 | "%s: packet reclassify loop" |
| 1655 | " rule prio %u protocol %02x\n", | ||
| 1656 | tp->q->ops->id, | ||
| 1657 | tp->prio & 0xffff, ntohs(tp->protocol)); | ||
| 1650 | return TC_ACT_SHOT; | 1658 | return TC_ACT_SHOT; |
| 1651 | } | 1659 | } |
| 1652 | skb->tc_verd = SET_TC_VERD(skb->tc_verd, verd); | 1660 | skb->tc_verd = SET_TC_VERD(skb->tc_verd, verd); |
| @@ -1691,7 +1699,7 @@ static int psched_show(struct seq_file *seq, void *v) | |||
| 1691 | 1699 | ||
| 1692 | static int psched_open(struct inode *inode, struct file *file) | 1700 | static int psched_open(struct inode *inode, struct file *file) |
| 1693 | { | 1701 | { |
| 1694 | return single_open(file, psched_show, PDE(inode)->data); | 1702 | return single_open(file, psched_show, NULL); |
| 1695 | } | 1703 | } |
| 1696 | 1704 | ||
| 1697 | static const struct file_operations psched_fops = { | 1705 | static const struct file_operations psched_fops = { |
| @@ -1701,14 +1709,53 @@ static const struct file_operations psched_fops = { | |||
| 1701 | .llseek = seq_lseek, | 1709 | .llseek = seq_lseek, |
| 1702 | .release = single_release, | 1710 | .release = single_release, |
| 1703 | }; | 1711 | }; |
| 1712 | |||
| 1713 | static int __net_init psched_net_init(struct net *net) | ||
| 1714 | { | ||
| 1715 | struct proc_dir_entry *e; | ||
| 1716 | |||
| 1717 | e = proc_net_fops_create(net, "psched", 0, &psched_fops); | ||
| 1718 | if (e == NULL) | ||
| 1719 | return -ENOMEM; | ||
| 1720 | |||
| 1721 | return 0; | ||
| 1722 | } | ||
| 1723 | |||
| 1724 | static void __net_exit psched_net_exit(struct net *net) | ||
| 1725 | { | ||
| 1726 | proc_net_remove(net, "psched"); | ||
| 1727 | } | ||
| 1728 | #else | ||
| 1729 | static int __net_init psched_net_init(struct net *net) | ||
| 1730 | { | ||
| 1731 | return 0; | ||
| 1732 | } | ||
| 1733 | |||
| 1734 | static void __net_exit psched_net_exit(struct net *net) | ||
| 1735 | { | ||
| 1736 | } | ||
| 1704 | #endif | 1737 | #endif |
| 1705 | 1738 | ||
| 1739 | static struct pernet_operations psched_net_ops = { | ||
| 1740 | .init = psched_net_init, | ||
| 1741 | .exit = psched_net_exit, | ||
| 1742 | }; | ||
| 1743 | |||
| 1706 | static int __init pktsched_init(void) | 1744 | static int __init pktsched_init(void) |
| 1707 | { | 1745 | { |
| 1746 | int err; | ||
| 1747 | |||
| 1748 | err = register_pernet_subsys(&psched_net_ops); | ||
| 1749 | if (err) { | ||
| 1750 | printk(KERN_ERR "pktsched_init: " | ||
| 1751 | "cannot initialize per netns operations\n"); | ||
| 1752 | return err; | ||
| 1753 | } | ||
| 1754 | |||
| 1708 | register_qdisc(&pfifo_qdisc_ops); | 1755 | register_qdisc(&pfifo_qdisc_ops); |
| 1709 | register_qdisc(&bfifo_qdisc_ops); | 1756 | register_qdisc(&bfifo_qdisc_ops); |
| 1757 | register_qdisc(&pfifo_head_drop_qdisc_ops); | ||
| 1710 | register_qdisc(&mq_qdisc_ops); | 1758 | register_qdisc(&mq_qdisc_ops); |
| 1711 | proc_net_fops_create(&init_net, "psched", 0, &psched_fops); | ||
| 1712 | 1759 | ||
| 1713 | rtnl_register(PF_UNSPEC, RTM_NEWQDISC, tc_modify_qdisc, NULL); | 1760 | rtnl_register(PF_UNSPEC, RTM_NEWQDISC, tc_modify_qdisc, NULL); |
| 1714 | rtnl_register(PF_UNSPEC, RTM_DELQDISC, tc_get_qdisc, NULL); | 1761 | rtnl_register(PF_UNSPEC, RTM_DELQDISC, tc_get_qdisc, NULL); |
