diff options
author | WANG Cong <xiyou.wangcong@gmail.com> | 2016-08-14 01:35:01 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-08-17 19:27:51 -0400 |
commit | 0852e455238f8550fa92b1e40355eb2c6805787e (patch) | |
tree | 516e10d249bd34a6eaf587ca9040ca6599a62029 /net | |
parent | 22dc13c837c33207548c8ee5116b64e2930a6e23 (diff) |
net_sched: unify the init logic for act_police
Jamal reported a crash when we create a police action
with a specific index, this is because the init logic
is not correct, we should always create one for this
case. Just unify the logic with other tc actions.
Fixes: a03e6fe56971 ("act_police: fix a crash during removal")
Reported-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/sched/act_police.c | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/net/sched/act_police.c b/net/sched/act_police.c index b3c7e975fc9e..259352d978df 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c | |||
@@ -125,6 +125,7 @@ static int tcf_act_police_init(struct net *net, struct nlattr *nla, | |||
125 | struct tcf_police *police; | 125 | struct tcf_police *police; |
126 | struct qdisc_rate_table *R_tab = NULL, *P_tab = NULL; | 126 | struct qdisc_rate_table *R_tab = NULL, *P_tab = NULL; |
127 | struct tc_action_net *tn = net_generic(net, police_net_id); | 127 | struct tc_action_net *tn = net_generic(net, police_net_id); |
128 | bool exists = false; | ||
128 | int size; | 129 | int size; |
129 | 130 | ||
130 | if (nla == NULL) | 131 | if (nla == NULL) |
@@ -139,24 +140,24 @@ static int tcf_act_police_init(struct net *net, struct nlattr *nla, | |||
139 | size = nla_len(tb[TCA_POLICE_TBF]); | 140 | size = nla_len(tb[TCA_POLICE_TBF]); |
140 | if (size != sizeof(*parm) && size != sizeof(struct tc_police_compat)) | 141 | if (size != sizeof(*parm) && size != sizeof(struct tc_police_compat)) |
141 | return -EINVAL; | 142 | return -EINVAL; |
143 | |||
142 | parm = nla_data(tb[TCA_POLICE_TBF]); | 144 | parm = nla_data(tb[TCA_POLICE_TBF]); |
145 | exists = tcf_hash_check(tn, parm->index, a, bind); | ||
146 | if (exists && bind) | ||
147 | return 0; | ||
143 | 148 | ||
144 | if (parm->index) { | 149 | if (!exists) { |
145 | if (tcf_hash_check(tn, parm->index, a, bind)) { | ||
146 | if (ovr) | ||
147 | goto override; | ||
148 | /* not replacing */ | ||
149 | return -EEXIST; | ||
150 | } | ||
151 | } else { | ||
152 | ret = tcf_hash_create(tn, parm->index, NULL, a, | 150 | ret = tcf_hash_create(tn, parm->index, NULL, a, |
153 | &act_police_ops, bind, false); | 151 | &act_police_ops, bind, false); |
154 | if (ret) | 152 | if (ret) |
155 | return ret; | 153 | return ret; |
156 | ret = ACT_P_CREATED; | 154 | ret = ACT_P_CREATED; |
155 | } else { | ||
156 | tcf_hash_release(*a, bind); | ||
157 | if (!ovr) | ||
158 | return -EEXIST; | ||
157 | } | 159 | } |
158 | 160 | ||
159 | override: | ||
160 | police = to_police(*a); | 161 | police = to_police(*a); |
161 | if (parm->rate.rate) { | 162 | if (parm->rate.rate) { |
162 | err = -ENOMEM; | 163 | err = -ENOMEM; |