Commit b6a3c606 authored by Victor Nogueira's avatar Victor Nogueira Committed by David S. Miller
Browse files

net: sched: Make tc-related drop reason more flexible for remaining qdiscs

Incrementing on Daniel's patch[1], make tc-related drop reason more
flexible for remaining qdiscs - that is, all qdiscs aside from clsact.
In essence, the drop reason will be set by cls_api and act_api in case
any error occurred in the data path. With that, we can give the user more
detailed information so that they can distinguish between a policy drop
or an error drop.

[1] https://lore.kernel.org/all/20231009092655.22025-1-daniel@iogearbox.net



Signed-off-by: default avatarVictor Nogueira <victor@mojatatu.com>
Acked-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent fb278072
Loading
Loading
Loading
Loading
+0 −16
Original line number Diff line number Diff line
@@ -154,22 +154,6 @@ __cls_set_class(unsigned long *clp, unsigned long cl)
	return xchg(clp, cl);
}

struct tc_skb_cb;

static inline struct tc_skb_cb *tc_skb_cb(const struct sk_buff *skb);

static inline enum skb_drop_reason
tcf_get_drop_reason(const struct sk_buff *skb)
{
	return tc_skb_cb(skb)->drop_reason;
}

static inline void tcf_set_drop_reason(const struct sk_buff *skb,
				       enum skb_drop_reason reason)
{
	tc_skb_cb(skb)->drop_reason = reason;
}

static inline void
__tcf_bind_filter(struct Qdisc *q, struct tcf_result *r, unsigned long base)
{
+0 −19
Original line number Diff line number Diff line
@@ -275,25 +275,6 @@ static inline void skb_txtime_consumed(struct sk_buff *skb)
	skb->tstamp = ktime_set(0, 0);
}

struct tc_skb_cb {
	struct qdisc_skb_cb qdisc_cb;
	u32 drop_reason;

	u16 zone; /* Only valid if post_ct = true */
	u16 mru;
	u8 post_ct:1;
	u8 post_ct_snat:1;
	u8 post_ct_dnat:1;
};

static inline struct tc_skb_cb *tc_skb_cb(const struct sk_buff *skb)
{
	struct tc_skb_cb *cb = (struct tc_skb_cb *)skb->cb;

	BUILD_BUG_ON(sizeof(*cb) > sizeof_field(struct sk_buff, cb));
	return cb;
}

static inline bool tc_qdisc_stats_dump(struct Qdisc *sch,
				       unsigned long cl,
				       struct qdisc_walker *arg)
+31 −0
Original line number Diff line number Diff line
@@ -1036,6 +1036,37 @@ static inline struct sk_buff *qdisc_dequeue_head(struct Qdisc *sch)
	return skb;
}

struct tc_skb_cb {
	struct qdisc_skb_cb qdisc_cb;
	u32 drop_reason;

	u16 zone; /* Only valid if post_ct = true */
	u16 mru;
	u8 post_ct:1;
	u8 post_ct_snat:1;
	u8 post_ct_dnat:1;
};

static inline struct tc_skb_cb *tc_skb_cb(const struct sk_buff *skb)
{
	struct tc_skb_cb *cb = (struct tc_skb_cb *)skb->cb;

	BUILD_BUG_ON(sizeof(*cb) > sizeof_field(struct sk_buff, cb));
	return cb;
}

static inline enum skb_drop_reason
tcf_get_drop_reason(const struct sk_buff *skb)
{
	return tc_skb_cb(skb)->drop_reason;
}

static inline void tcf_set_drop_reason(const struct sk_buff *skb,
				       enum skb_drop_reason reason)
{
	tc_skb_cb(skb)->drop_reason = reason;
}

/* Instead of calling kfree_skb() while root qdisc lock is held,
 * queue the skb for future freeing at end of __dev_xmit_skb()
 */
+5 −2
Original line number Diff line number Diff line
@@ -3753,6 +3753,8 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,

	qdisc_calculate_pkt_len(skb, q);

	tcf_set_drop_reason(skb, SKB_DROP_REASON_QDISC_DROP);

	if (q->flags & TCQ_F_NOLOCK) {
		if (q->flags & TCQ_F_CAN_BYPASS && nolock_qdisc_is_empty(q) &&
		    qdisc_run_begin(q)) {
@@ -3782,7 +3784,7 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
no_lock_out:
		if (unlikely(to_free))
			kfree_skb_list_reason(to_free,
					      SKB_DROP_REASON_QDISC_DROP);
					      tcf_get_drop_reason(to_free));
		return rc;
	}

@@ -3837,7 +3839,8 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
	}
	spin_unlock(root_lock);
	if (unlikely(to_free))
		kfree_skb_list_reason(to_free, SKB_DROP_REASON_QDISC_DROP);
		kfree_skb_list_reason(to_free,
				      tcf_get_drop_reason(to_free));
	if (unlikely(contended))
		spin_unlock(&q->busylock);
	return rc;