Skip to content

Commit bee9705

Browse files
committed
Merge branch 'net-sched-tc-drop-reason'
Victor Nogueira says: ==================== net: sched: Make tc-related drop reason more flexible for remaining qdiscs This patch builds on Daniel's patch[1] to add initial support of tc drop reason. The main goal is to distinguish between policy and error drops for the remainder of the egress qdiscs (other than clsact). The drop reason is set by cls_api and act_api in the tc skb cb in case any error occurred in the data path. Also add new skb drop reasons that are idiosyncratic to TC. [1] https://lore.kernel.org/all/[email protected] Changes in V5: - Drop "EXT_" from cookie error's drop reason name in doc Changes in V4: - Condense all the cookie drop reasons into one Changes in V3: - Removed duplicate assignment - Rename function tc_skb_cb_drop_reason to tcf_get_drop_reason - Move zone field upwards in struct tc_skb_cb to move hole to the end of the struct Changes in V2: - Dropped RFC tag - Removed check for drop reason being overwritten by filter in cls_api.c - Simplified logic and removed function tcf_init_drop_reason ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 18764b8 + 4cf24dc commit bee9705

File tree

7 files changed

+70
-49
lines changed

7 files changed

+70
-49
lines changed

include/net/dropreason-core.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,10 @@
8585
FN(IPV6_NDISC_BAD_OPTIONS) \
8686
FN(IPV6_NDISC_NS_OTHERHOST) \
8787
FN(QUEUE_PURGE) \
88-
FN(TC_ERROR) \
88+
FN(TC_COOKIE_ERROR) \
8989
FN(PACKET_SOCK_ERROR) \
90+
FN(TC_CHAIN_NOTFOUND) \
91+
FN(TC_RECLASSIFY_LOOP) \
9092
FNe(MAX)
9193

9294
/**
@@ -377,13 +379,23 @@ enum skb_drop_reason {
377379
SKB_DROP_REASON_IPV6_NDISC_NS_OTHERHOST,
378380
/** @SKB_DROP_REASON_QUEUE_PURGE: bulk free. */
379381
SKB_DROP_REASON_QUEUE_PURGE,
380-
/** @SKB_DROP_REASON_TC_ERROR: generic internal tc error. */
381-
SKB_DROP_REASON_TC_ERROR,
382+
/**
383+
* @SKB_DROP_REASON_TC_COOKIE_ERROR: An error occurred whilst
384+
* processing a tc ext cookie.
385+
*/
386+
SKB_DROP_REASON_TC_COOKIE_ERROR,
382387
/**
383388
* @SKB_DROP_REASON_PACKET_SOCK_ERROR: generic packet socket errors
384389
* after its filter matches an incoming packet.
385390
*/
386391
SKB_DROP_REASON_PACKET_SOCK_ERROR,
392+
/** @SKB_DROP_REASON_TC_CHAIN_NOTFOUND: tc chain lookup failed. */
393+
SKB_DROP_REASON_TC_CHAIN_NOTFOUND,
394+
/**
395+
* @SKB_DROP_REASON_TC_RECLASSIFY_LOOP: tc exceeded max reclassify loop
396+
* iterations.
397+
*/
398+
SKB_DROP_REASON_TC_RECLASSIFY_LOOP,
387399
/**
388400
* @SKB_DROP_REASON_MAX: the maximum of core drop reasons, which
389401
* shouldn't be used as a real 'reason' - only for tracing code gen

include/net/pkt_cls.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -154,12 +154,6 @@ __cls_set_class(unsigned long *clp, unsigned long cl)
154154
return xchg(clp, cl);
155155
}
156156

157-
static inline void tcf_set_drop_reason(struct tcf_result *res,
158-
enum skb_drop_reason reason)
159-
{
160-
res->drop_reason = reason;
161-
}
162-
163157
static inline void
164158
__tcf_bind_filter(struct Qdisc *q, struct tcf_result *r, unsigned long base)
165159
{

include/net/pkt_sched.h

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -275,24 +275,6 @@ static inline void skb_txtime_consumed(struct sk_buff *skb)
275275
skb->tstamp = ktime_set(0, 0);
276276
}
277277

278-
struct tc_skb_cb {
279-
struct qdisc_skb_cb qdisc_cb;
280-
281-
u16 mru;
282-
u8 post_ct:1;
283-
u8 post_ct_snat:1;
284-
u8 post_ct_dnat:1;
285-
u16 zone; /* Only valid if post_ct = true */
286-
};
287-
288-
static inline struct tc_skb_cb *tc_skb_cb(const struct sk_buff *skb)
289-
{
290-
struct tc_skb_cb *cb = (struct tc_skb_cb *)skb->cb;
291-
292-
BUILD_BUG_ON(sizeof(*cb) > sizeof_field(struct sk_buff, cb));
293-
return cb;
294-
}
295-
296278
static inline bool tc_qdisc_stats_dump(struct Qdisc *sch,
297279
unsigned long cl,
298280
struct qdisc_walker *arg)

include/net/sch_generic.h

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,6 @@ struct tcf_result {
332332
};
333333
const struct tcf_proto *goto_tp;
334334
};
335-
enum skb_drop_reason drop_reason;
336335
};
337336

338337
struct tcf_chain;
@@ -1037,6 +1036,37 @@ static inline struct sk_buff *qdisc_dequeue_head(struct Qdisc *sch)
10371036
return skb;
10381037
}
10391038

1039+
struct tc_skb_cb {
1040+
struct qdisc_skb_cb qdisc_cb;
1041+
u32 drop_reason;
1042+
1043+
u16 zone; /* Only valid if post_ct = true */
1044+
u16 mru;
1045+
u8 post_ct:1;
1046+
u8 post_ct_snat:1;
1047+
u8 post_ct_dnat:1;
1048+
};
1049+
1050+
static inline struct tc_skb_cb *tc_skb_cb(const struct sk_buff *skb)
1051+
{
1052+
struct tc_skb_cb *cb = (struct tc_skb_cb *)skb->cb;
1053+
1054+
BUILD_BUG_ON(sizeof(*cb) > sizeof_field(struct sk_buff, cb));
1055+
return cb;
1056+
}
1057+
1058+
static inline enum skb_drop_reason
1059+
tcf_get_drop_reason(const struct sk_buff *skb)
1060+
{
1061+
return tc_skb_cb(skb)->drop_reason;
1062+
}
1063+
1064+
static inline void tcf_set_drop_reason(const struct sk_buff *skb,
1065+
enum skb_drop_reason reason)
1066+
{
1067+
tc_skb_cb(skb)->drop_reason = reason;
1068+
}
1069+
10401070
/* Instead of calling kfree_skb() while root qdisc lock is held,
10411071
* queue the skb for future freeing at end of __dev_xmit_skb()
10421072
*/

net/core/dev.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3753,6 +3753,8 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
37533753

37543754
qdisc_calculate_pkt_len(skb, q);
37553755

3756+
tcf_set_drop_reason(skb, SKB_DROP_REASON_QDISC_DROP);
3757+
37563758
if (q->flags & TCQ_F_NOLOCK) {
37573759
if (q->flags & TCQ_F_CAN_BYPASS && nolock_qdisc_is_empty(q) &&
37583760
qdisc_run_begin(q)) {
@@ -3782,7 +3784,7 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
37823784
no_lock_out:
37833785
if (unlikely(to_free))
37843786
kfree_skb_list_reason(to_free,
3785-
SKB_DROP_REASON_QDISC_DROP);
3787+
tcf_get_drop_reason(to_free));
37863788
return rc;
37873789
}
37883790

@@ -3837,7 +3839,8 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
38373839
}
38383840
spin_unlock(root_lock);
38393841
if (unlikely(to_free))
3840-
kfree_skb_list_reason(to_free, SKB_DROP_REASON_QDISC_DROP);
3842+
kfree_skb_list_reason(to_free,
3843+
tcf_get_drop_reason(to_free));
38413844
if (unlikely(contended))
38423845
spin_unlock(&q->busylock);
38433846
return rc;
@@ -3923,14 +3926,14 @@ static int tc_run(struct tcx_entry *entry, struct sk_buff *skb,
39233926

39243927
tc_skb_cb(skb)->mru = 0;
39253928
tc_skb_cb(skb)->post_ct = false;
3926-
res.drop_reason = *drop_reason;
3929+
tcf_set_drop_reason(skb, *drop_reason);
39273930

39283931
mini_qdisc_bstats_cpu_update(miniq, skb);
39293932
ret = tcf_classify(skb, miniq->block, miniq->filter_list, &res, false);
39303933
/* Only tcf related quirks below. */
39313934
switch (ret) {
39323935
case TC_ACT_SHOT:
3933-
*drop_reason = res.drop_reason;
3936+
*drop_reason = tcf_get_drop_reason(skb);
39343937
mini_qdisc_qstats_cpu_drop(miniq);
39353938
break;
39363939
case TC_ACT_OK:

net/sched/act_api.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1119,7 +1119,8 @@ int tcf_action_exec(struct sk_buff *skb, struct tc_action **actions,
11191119
}
11201120
} else if (TC_ACT_EXT_CMP(ret, TC_ACT_GOTO_CHAIN)) {
11211121
if (unlikely(!rcu_access_pointer(a->goto_chain))) {
1122-
tcf_set_drop_reason(res, SKB_DROP_REASON_TC_ERROR);
1122+
tcf_set_drop_reason(skb,
1123+
SKB_DROP_REASON_TC_CHAIN_NOTFOUND);
11231124
return TC_ACT_SHOT;
11241125
}
11251126
tcf_action_goto_chain_exec(a, res);

net/sched/cls_api.c

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1657,7 +1657,6 @@ static inline int __tcf_classify(struct sk_buff *skb,
16571657
int act_index,
16581658
u32 *last_executed_chain)
16591659
{
1660-
u32 orig_reason = res->drop_reason;
16611660
#ifdef CONFIG_NET_CLS_ACT
16621661
const int max_reclassify_loop = 16;
16631662
const struct tcf_proto *first_tp;
@@ -1682,13 +1681,15 @@ static inline int __tcf_classify(struct sk_buff *skb,
16821681
*/
16831682
if (unlikely(n->tp != tp || n->tp->chain != n->chain ||
16841683
!tp->ops->get_exts)) {
1685-
tcf_set_drop_reason(res, SKB_DROP_REASON_TC_ERROR);
1684+
tcf_set_drop_reason(skb,
1685+
SKB_DROP_REASON_TC_COOKIE_ERROR);
16861686
return TC_ACT_SHOT;
16871687
}
16881688

16891689
exts = tp->ops->get_exts(tp, n->handle);
16901690
if (unlikely(!exts || n->exts != exts)) {
1691-
tcf_set_drop_reason(res, SKB_DROP_REASON_TC_ERROR);
1691+
tcf_set_drop_reason(skb,
1692+
SKB_DROP_REASON_TC_COOKIE_ERROR);
16921693
return TC_ACT_SHOT;
16931694
}
16941695

@@ -1712,18 +1713,13 @@ static inline int __tcf_classify(struct sk_buff *skb,
17121713
goto reset;
17131714
}
17141715
#endif
1715-
if (err >= 0) {
1716-
/* Policy drop or drop reason is over-written by
1717-
* classifiers with a bogus value(0) */
1718-
if (err == TC_ACT_SHOT &&
1719-
res->drop_reason == SKB_NOT_DROPPED_YET)
1720-
tcf_set_drop_reason(res, orig_reason);
1716+
if (err >= 0)
17211717
return err;
1722-
}
17231718
}
17241719

17251720
if (unlikely(n)) {
1726-
tcf_set_drop_reason(res, SKB_DROP_REASON_TC_ERROR);
1721+
tcf_set_drop_reason(skb,
1722+
SKB_DROP_REASON_TC_COOKIE_ERROR);
17271723
return TC_ACT_SHOT;
17281724
}
17291725

@@ -1735,7 +1731,8 @@ static inline int __tcf_classify(struct sk_buff *skb,
17351731
tp->chain->block->index,
17361732
tp->prio & 0xffff,
17371733
ntohs(tp->protocol));
1738-
tcf_set_drop_reason(res, SKB_DROP_REASON_TC_ERROR);
1734+
tcf_set_drop_reason(skb,
1735+
SKB_DROP_REASON_TC_RECLASSIFY_LOOP);
17391736
return TC_ACT_SHOT;
17401737
}
17411738

@@ -1773,7 +1770,8 @@ int tcf_classify(struct sk_buff *skb,
17731770
n = tcf_exts_miss_cookie_lookup(ext->act_miss_cookie,
17741771
&act_index);
17751772
if (!n) {
1776-
tcf_set_drop_reason(res, SKB_DROP_REASON_TC_ERROR);
1773+
tcf_set_drop_reason(skb,
1774+
SKB_DROP_REASON_TC_COOKIE_ERROR);
17771775
return TC_ACT_SHOT;
17781776
}
17791777

@@ -1784,7 +1782,9 @@ int tcf_classify(struct sk_buff *skb,
17841782

17851783
fchain = tcf_chain_lookup_rcu(block, chain);
17861784
if (!fchain) {
1787-
tcf_set_drop_reason(res, SKB_DROP_REASON_TC_ERROR);
1785+
tcf_set_drop_reason(skb,
1786+
SKB_DROP_REASON_TC_CHAIN_NOTFOUND);
1787+
17881788
return TC_ACT_SHOT;
17891789
}
17901790

@@ -1806,10 +1806,9 @@ int tcf_classify(struct sk_buff *skb,
18061806

18071807
ext = tc_skb_ext_alloc(skb);
18081808
if (WARN_ON_ONCE(!ext)) {
1809-
tcf_set_drop_reason(res, SKB_DROP_REASON_TC_ERROR);
1809+
tcf_set_drop_reason(skb, SKB_DROP_REASON_NOMEM);
18101810
return TC_ACT_SHOT;
18111811
}
1812-
18131812
ext->chain = last_executed_chain;
18141813
ext->mru = cb->mru;
18151814
ext->post_ct = cb->post_ct;

0 commit comments

Comments
 (0)