aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYang Yingliang <yangyingliang@huawei.com>2014-02-13 21:30:41 -0500
committerDavid S. Miller <davem@davemloft.net>2014-02-14 00:15:20 -0500
commit54a4b05cd281a352d803417a98a72878fb0802cf (patch)
treef75291053c03b191ab3d8bb5ef51ca57f47e7de0
parentd4f2fa6ad61ec1db713569a179183df4d0fc6ae7 (diff)
sch_netem: return errcode before setting params
get_dist_table() and get_loss_clg() may be failed. These two functions should be called after setting the members of qdisc_priv(sch), or it will break the old settings while either of them is failed. Signed-off-by: Yang Yingliang <yangyingliang@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/sched/sch_netem.c39
1 files changed, 29 insertions, 10 deletions
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index de1059af6da1..b341943555a9 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -821,6 +821,8 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt)
821 struct netem_sched_data *q = qdisc_priv(sch); 821 struct netem_sched_data *q = qdisc_priv(sch);
822 struct nlattr *tb[TCA_NETEM_MAX + 1]; 822 struct nlattr *tb[TCA_NETEM_MAX + 1];
823 struct tc_netem_qopt *qopt; 823 struct tc_netem_qopt *qopt;
824 struct clgstate old_clg;
825 int old_loss_model = CLG_RANDOM;
824 int ret; 826 int ret;
825 827
826 if (opt == NULL) 828 if (opt == NULL)
@@ -831,6 +833,33 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt)
831 if (ret < 0) 833 if (ret < 0)
832 return ret; 834 return ret;
833 835
836 /* backup q->clg and q->loss_model */
837 old_clg = q->clg;
838 old_loss_model = q->loss_model;
839
840 if (tb[TCA_NETEM_LOSS]) {
841 ret = get_loss_clg(sch, tb[TCA_NETEM_LOSS]);
842 if (ret) {
843 q->loss_model = old_loss_model;
844 return ret;
845 }
846 } else {
847 q->loss_model = CLG_RANDOM;
848 }
849
850 if (tb[TCA_NETEM_DELAY_DIST]) {
851 ret = get_dist_table(sch, tb[TCA_NETEM_DELAY_DIST]);
852 if (ret) {
853 /* recover clg and loss_model, in case of
854 * q->clg and q->loss_model were modified
855 * in get_loss_clg()
856 */
857 q->clg = old_clg;
858 q->loss_model = old_loss_model;
859 return ret;
860 }
861 }
862
834 sch->limit = qopt->limit; 863 sch->limit = qopt->limit;
835 864
836 q->latency = qopt->latency; 865 q->latency = qopt->latency;
@@ -850,12 +879,6 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt)
850 if (tb[TCA_NETEM_CORR]) 879 if (tb[TCA_NETEM_CORR])
851 get_correlation(sch, tb[TCA_NETEM_CORR]); 880 get_correlation(sch, tb[TCA_NETEM_CORR]);
852 881
853 if (tb[TCA_NETEM_DELAY_DIST]) {
854 ret = get_dist_table(sch, tb[TCA_NETEM_DELAY_DIST]);
855 if (ret)
856 return ret;
857 }
858
859 if (tb[TCA_NETEM_REORDER]) 882 if (tb[TCA_NETEM_REORDER])
860 get_reorder(sch, tb[TCA_NETEM_REORDER]); 883 get_reorder(sch, tb[TCA_NETEM_REORDER]);
861 884
@@ -872,10 +895,6 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt)
872 if (tb[TCA_NETEM_ECN]) 895 if (tb[TCA_NETEM_ECN])
873 q->ecn = nla_get_u32(tb[TCA_NETEM_ECN]); 896 q->ecn = nla_get_u32(tb[TCA_NETEM_ECN]);
874 897
875 q->loss_model = CLG_RANDOM;
876 if (tb[TCA_NETEM_LOSS])
877 ret = get_loss_clg(sch, tb[TCA_NETEM_LOSS]);
878
879 return ret; 898 return ret;
880} 899}
881 900