diff options
Diffstat (limited to 'net/sched/sch_api.c')
-rw-r--r-- | net/sched/sch_api.c | 44 |
1 files changed, 25 insertions, 19 deletions
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index c297e2a8e2a1..2b935e7cfe7b 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
@@ -971,13 +971,13 @@ check_loop_fn(struct Qdisc *q, unsigned long cl, struct qdisc_walker *w) | |||
971 | * Delete/get qdisc. | 971 | * Delete/get qdisc. |
972 | */ | 972 | */ |
973 | 973 | ||
974 | static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | 974 | static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n) |
975 | { | 975 | { |
976 | struct net *net = sock_net(skb->sk); | 976 | struct net *net = sock_net(skb->sk); |
977 | struct tcmsg *tcm = nlmsg_data(n); | 977 | struct tcmsg *tcm = nlmsg_data(n); |
978 | struct nlattr *tca[TCA_MAX + 1]; | 978 | struct nlattr *tca[TCA_MAX + 1]; |
979 | struct net_device *dev; | 979 | struct net_device *dev; |
980 | u32 clid = tcm->tcm_parent; | 980 | u32 clid; |
981 | struct Qdisc *q = NULL; | 981 | struct Qdisc *q = NULL; |
982 | struct Qdisc *p = NULL; | 982 | struct Qdisc *p = NULL; |
983 | int err; | 983 | int err; |
@@ -985,14 +985,15 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
985 | if ((n->nlmsg_type != RTM_GETQDISC) && !capable(CAP_NET_ADMIN)) | 985 | if ((n->nlmsg_type != RTM_GETQDISC) && !capable(CAP_NET_ADMIN)) |
986 | return -EPERM; | 986 | return -EPERM; |
987 | 987 | ||
988 | dev = __dev_get_by_index(net, tcm->tcm_ifindex); | ||
989 | if (!dev) | ||
990 | return -ENODEV; | ||
991 | |||
992 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); | 988 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); |
993 | if (err < 0) | 989 | if (err < 0) |
994 | return err; | 990 | return err; |
995 | 991 | ||
992 | dev = __dev_get_by_index(net, tcm->tcm_ifindex); | ||
993 | if (!dev) | ||
994 | return -ENODEV; | ||
995 | |||
996 | clid = tcm->tcm_parent; | ||
996 | if (clid) { | 997 | if (clid) { |
997 | if (clid != TC_H_ROOT) { | 998 | if (clid != TC_H_ROOT) { |
998 | if (TC_H_MAJ(clid) != TC_H_MAJ(TC_H_INGRESS)) { | 999 | if (TC_H_MAJ(clid) != TC_H_MAJ(TC_H_INGRESS)) { |
@@ -1038,7 +1039,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
1038 | * Create/change qdisc. | 1039 | * Create/change qdisc. |
1039 | */ | 1040 | */ |
1040 | 1041 | ||
1041 | static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | 1042 | static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n) |
1042 | { | 1043 | { |
1043 | struct net *net = sock_net(skb->sk); | 1044 | struct net *net = sock_net(skb->sk); |
1044 | struct tcmsg *tcm; | 1045 | struct tcmsg *tcm; |
@@ -1053,6 +1054,10 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
1053 | 1054 | ||
1054 | replay: | 1055 | replay: |
1055 | /* Reinit, just in case something touches this. */ | 1056 | /* Reinit, just in case something touches this. */ |
1057 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); | ||
1058 | if (err < 0) | ||
1059 | return err; | ||
1060 | |||
1056 | tcm = nlmsg_data(n); | 1061 | tcm = nlmsg_data(n); |
1057 | clid = tcm->tcm_parent; | 1062 | clid = tcm->tcm_parent; |
1058 | q = p = NULL; | 1063 | q = p = NULL; |
@@ -1061,9 +1066,6 @@ replay: | |||
1061 | if (!dev) | 1066 | if (!dev) |
1062 | return -ENODEV; | 1067 | return -ENODEV; |
1063 | 1068 | ||
1064 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); | ||
1065 | if (err < 0) | ||
1066 | return err; | ||
1067 | 1069 | ||
1068 | if (clid) { | 1070 | if (clid) { |
1069 | if (clid != TC_H_ROOT) { | 1071 | if (clid != TC_H_ROOT) { |
@@ -1372,7 +1374,7 @@ done: | |||
1372 | 1374 | ||
1373 | 1375 | ||
1374 | 1376 | ||
1375 | static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | 1377 | static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n) |
1376 | { | 1378 | { |
1377 | struct net *net = sock_net(skb->sk); | 1379 | struct net *net = sock_net(skb->sk); |
1378 | struct tcmsg *tcm = nlmsg_data(n); | 1380 | struct tcmsg *tcm = nlmsg_data(n); |
@@ -1382,22 +1384,22 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
1382 | const struct Qdisc_class_ops *cops; | 1384 | const struct Qdisc_class_ops *cops; |
1383 | unsigned long cl = 0; | 1385 | unsigned long cl = 0; |
1384 | unsigned long new_cl; | 1386 | unsigned long new_cl; |
1385 | u32 portid = tcm->tcm_parent; | 1387 | u32 portid; |
1386 | u32 clid = tcm->tcm_handle; | 1388 | u32 clid; |
1387 | u32 qid = TC_H_MAJ(clid); | 1389 | u32 qid; |
1388 | int err; | 1390 | int err; |
1389 | 1391 | ||
1390 | if ((n->nlmsg_type != RTM_GETTCLASS) && !capable(CAP_NET_ADMIN)) | 1392 | if ((n->nlmsg_type != RTM_GETTCLASS) && !capable(CAP_NET_ADMIN)) |
1391 | return -EPERM; | 1393 | return -EPERM; |
1392 | 1394 | ||
1393 | dev = __dev_get_by_index(net, tcm->tcm_ifindex); | ||
1394 | if (!dev) | ||
1395 | return -ENODEV; | ||
1396 | |||
1397 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); | 1395 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); |
1398 | if (err < 0) | 1396 | if (err < 0) |
1399 | return err; | 1397 | return err; |
1400 | 1398 | ||
1399 | dev = __dev_get_by_index(net, tcm->tcm_ifindex); | ||
1400 | if (!dev) | ||
1401 | return -ENODEV; | ||
1402 | |||
1401 | /* | 1403 | /* |
1402 | parent == TC_H_UNSPEC - unspecified parent. | 1404 | parent == TC_H_UNSPEC - unspecified parent. |
1403 | parent == TC_H_ROOT - class is root, which has no parent. | 1405 | parent == TC_H_ROOT - class is root, which has no parent. |
@@ -1413,6 +1415,10 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
1413 | 1415 | ||
1414 | /* Step 1. Determine qdisc handle X:0 */ | 1416 | /* Step 1. Determine qdisc handle X:0 */ |
1415 | 1417 | ||
1418 | portid = tcm->tcm_parent; | ||
1419 | clid = tcm->tcm_handle; | ||
1420 | qid = TC_H_MAJ(clid); | ||
1421 | |||
1416 | if (portid != TC_H_ROOT) { | 1422 | if (portid != TC_H_ROOT) { |
1417 | u32 qid1 = TC_H_MAJ(portid); | 1423 | u32 qid1 = TC_H_MAJ(portid); |
1418 | 1424 | ||
@@ -1636,7 +1642,7 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb) | |||
1636 | struct net_device *dev; | 1642 | struct net_device *dev; |
1637 | int t, s_t; | 1643 | int t, s_t; |
1638 | 1644 | ||
1639 | if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm))) | 1645 | if (nlmsg_len(cb->nlh) < sizeof(*tcm)) |
1640 | return 0; | 1646 | return 0; |
1641 | dev = dev_get_by_index(net, tcm->tcm_ifindex); | 1647 | dev = dev_get_by_index(net, tcm->tcm_ifindex); |
1642 | if (!dev) | 1648 | if (!dev) |