net: sched: Make tc-related drop reason more flexible for remaining qdiscs
authorVictor Nogueira <victor@mojatatu.com>
Sat, 16 Dec 2023 20:44:35 +0000 (17:44 -0300)
committerDavid S. Miller <davem@davemloft.net>
Wed, 20 Dec 2023 11:50:13 +0000 (11:50 +0000)
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>
include/net/pkt_cls.h
include/net/pkt_sched.h
include/net/sch_generic.h
net/core/dev.c

index 761e4500cca09ac2a5ab6a08056b9302a183741f..f308e8268651e5f00cad623301f8a95aa2a9052d 100644 (file)
@@ -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)
 {
index 9b559aa5c079be9d56f8bd9295fed81d68dce5cd..1e200d9a066df08503f34343a5482ff85a2fc602 100644 (file)
@@ -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)
index c499b56bb215ce2be999dddaf1e3c9b437a0341b..1d70c2c1572f9667aaa77e548924feeb6493adfd 100644 (file)
@@ -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()
  */
index 16af89a733e416118e3017634dcc6a5f058374f8..b875040783209e95afb92217a0a07ede42a2e425 100644 (file)
@@ -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 @@ no_lock_out:
        }
        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;