net: sched: use counter to break reclassify loops
Seems all we want here is to avoid endless 'goto reclassify' loop. tc_classify_compat even resets this counter when something other than TC_ACT_RECLASSIFY is returned, so this skb-counter doesn't break hypothetical loops induced by something other than perpetual TC_ACT_RECLASSIFY return values. skb_act_clone is now identical to skb_clone, so just use that. Tested with following (bogus) filter: tc filter add dev eth0 parent ffff: \ protocol ip u32 match u32 0 0 police rate 10Kbit burst \ 64000 mtu 1500 action reclassify Acked-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: Florian Westphal <fw@strlen.de> Acked-by: Alexei Starovoitov <ast@plumgrid.com> Acked-by: Jamal Hadi Salim <jhs@mojatatu.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
b04096ff33
commit
e578d9c025
@@ -1816,13 +1816,8 @@ int tc_classify_compat(struct sk_buff *skb, const struct tcf_proto *tp,
|
||||
continue;
|
||||
err = tp->classify(skb, tp, res);
|
||||
|
||||
if (err >= 0) {
|
||||
#ifdef CONFIG_NET_CLS_ACT
|
||||
if (err != TC_ACT_RECLASSIFY && skb->tc_verd)
|
||||
skb->tc_verd = SET_TC_VERD(skb->tc_verd, 0);
|
||||
#endif
|
||||
if (err >= 0)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -1834,23 +1829,22 @@ int tc_classify(struct sk_buff *skb, const struct tcf_proto *tp,
|
||||
int err = 0;
|
||||
#ifdef CONFIG_NET_CLS_ACT
|
||||
const struct tcf_proto *otp = tp;
|
||||
int limit = 0;
|
||||
reclassify:
|
||||
#endif
|
||||
|
||||
err = tc_classify_compat(skb, tp, res);
|
||||
#ifdef CONFIG_NET_CLS_ACT
|
||||
if (err == TC_ACT_RECLASSIFY) {
|
||||
u32 verd = G_TC_VERD(skb->tc_verd);
|
||||
tp = otp;
|
||||
|
||||
if (verd++ >= MAX_REC_LOOP) {
|
||||
if (unlikely(limit++ >= MAX_REC_LOOP)) {
|
||||
net_notice_ratelimited("%s: packet reclassify loop rule prio %u protocol %02x\n",
|
||||
tp->q->ops->id,
|
||||
tp->prio & 0xffff,
|
||||
ntohs(tp->protocol));
|
||||
return TC_ACT_SHOT;
|
||||
}
|
||||
skb->tc_verd = SET_TC_VERD(skb->tc_verd, verd);
|
||||
goto reclassify;
|
||||
}
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user