summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorWANG Cong <xiyou.wangcong@gmail.com>2016-08-14 01:35:01 -0400
committerDavid S. Miller <davem@davemloft.net>2016-08-17 19:27:51 -0400
commit0852e455238f8550fa92b1e40355eb2c6805787e (patch)
tree516e10d249bd34a6eaf587ca9040ca6599a62029 /net
parent22dc13c837c33207548c8ee5116b64e2930a6e23 (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.c19
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
159override:
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;