net: sch_tbf: Add a graft command
authorPetr Machata <petrm@nvidia.com>
Tue, 19 Oct 2021 08:07:04 +0000 (11:07 +0300)
committerDavid S. Miller <davem@davemloft.net>
Tue, 19 Oct 2021 11:24:51 +0000 (12:24 +0100)
As another qdisc is linked to the TBF, the latter should issue an event to
give drivers a chance to react to the grafting. In other qdiscs, this event
is called GRAFT, so follow suit with TBF as well.

Signed-off-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/pkt_cls.h
net/sched/sch_tbf.c

index 4a58331..193f88e 100644 (file)
@@ -977,6 +977,7 @@ enum tc_tbf_command {
        TC_TBF_REPLACE,
        TC_TBF_DESTROY,
        TC_TBF_STATS,
+       TC_TBF_GRAFT,
 };
 
 struct tc_tbf_qopt_offload_replace_params {
@@ -992,6 +993,7 @@ struct tc_tbf_qopt_offload {
        union {
                struct tc_tbf_qopt_offload_replace_params replace_params;
                struct tc_qopt_offload_stats stats;
+               u32 child_handle;
        };
 };
 
index 78e7902..7210227 100644 (file)
@@ -184,6 +184,20 @@ static int tbf_offload_dump(struct Qdisc *sch)
        return qdisc_offload_dump_helper(sch, TC_SETUP_QDISC_TBF, &qopt);
 }
 
+static void tbf_offload_graft(struct Qdisc *sch, struct Qdisc *new,
+                             struct Qdisc *old, struct netlink_ext_ack *extack)
+{
+       struct tc_tbf_qopt_offload graft_offload = {
+               .handle         = sch->handle,
+               .parent         = sch->parent,
+               .child_handle   = new->handle,
+               .command        = TC_TBF_GRAFT,
+       };
+
+       qdisc_offload_graft_helper(qdisc_dev(sch), sch, new, old,
+                                  TC_SETUP_QDISC_TBF, &graft_offload, extack);
+}
+
 /* GSO packet is too big, segment it so that tbf can transmit
  * each segment in time
  */
@@ -547,6 +561,8 @@ static int tbf_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
                new = &noop_qdisc;
 
        *old = qdisc_replace(sch, new, &q->qdisc);
+
+       tbf_offload_graft(sch, new, *old, extack);
        return 0;
 }