Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

WANG Cong and committed by
David S. Miller
0852e455 22dc13c8

+11 -10
+11 -10
net/sched/act_police.c
··· 125 125 struct tcf_police *police; 126 126 struct qdisc_rate_table *R_tab = NULL, *P_tab = NULL; 127 127 struct tc_action_net *tn = net_generic(net, police_net_id); 128 + bool exists = false; 128 129 int size; 129 130 130 131 if (nla == NULL) ··· 140 139 size = nla_len(tb[TCA_POLICE_TBF]); 141 140 if (size != sizeof(*parm) && size != sizeof(struct tc_police_compat)) 142 141 return -EINVAL; 143 - parm = nla_data(tb[TCA_POLICE_TBF]); 144 142 145 - if (parm->index) { 146 - if (tcf_hash_check(tn, parm->index, a, bind)) { 147 - if (ovr) 148 - goto override; 149 - /* not replacing */ 150 - return -EEXIST; 151 - } 152 - } else { 143 + parm = nla_data(tb[TCA_POLICE_TBF]); 144 + exists = tcf_hash_check(tn, parm->index, a, bind); 145 + if (exists && bind) 146 + return 0; 147 + 148 + if (!exists) { 153 149 ret = tcf_hash_create(tn, parm->index, NULL, a, 154 150 &act_police_ops, bind, false); 155 151 if (ret) 156 152 return ret; 157 153 ret = ACT_P_CREATED; 154 + } else { 155 + tcf_hash_release(*a, bind); 156 + if (!ovr) 157 + return -EEXIST; 158 158 } 159 159 160 - override: 161 160 police = to_police(*a); 162 161 if (parm->rate.rate) { 163 162 err = -ENOMEM;