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: Victor Nogueira <victor@mojatatu.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
        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)
 {
 
        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)
 
        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()
  */
 
 
        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)) {
 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;
        }
 
        }
        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;