diff options
author | Jakub Kicinski <jakub.kicinski@netronome.com> | 2018-11-07 17:33:37 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-11-08 16:19:48 -0800 |
commit | bfaee9113f30abfa1f77ecb5e4a6f53a9d4c690c (patch) | |
tree | b395ad6193d47fcd3f868607d48eece07a6d4ef6 /net/sched/sch_api.c | |
parent | 58f8927399eac8f2ac3c7289a2856b8b5516ba30 (diff) |
net: sched: add an offload graft helper
Qdisc graft operation of offload-capable qdiscs performs a few
extra steps which are identical among all the qdiscs. Add
a helper to share this code.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: John Hurley <john.hurley@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched/sch_api.c')
-rw-r--r-- | net/sched/sch_api.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index e534825d3d3a..4b3af41cc1d7 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -831,6 +831,35 @@ int qdisc_offload_dump_helper(struct Qdisc *sch, enum tc_setup_type type, } EXPORT_SYMBOL(qdisc_offload_dump_helper); +void qdisc_offload_graft_helper(struct net_device *dev, struct Qdisc *sch, + struct Qdisc *new, struct Qdisc *old, + enum tc_setup_type type, void *type_data, + struct netlink_ext_ack *extack) +{ + bool any_qdisc_is_offloaded; + int err; + + if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc) + return; + + err = dev->netdev_ops->ndo_setup_tc(dev, type, type_data); + + /* Don't report error if the graft is part of destroy operation. */ + if (!err || !new || new == &noop_qdisc) + return; + + /* Don't report error if the parent, the old child and the new + * one are not offloaded. + */ + any_qdisc_is_offloaded = new->flags & TCQ_F_OFFLOADED; + any_qdisc_is_offloaded |= sch && sch->flags & TCQ_F_OFFLOADED; + any_qdisc_is_offloaded |= old && old->flags & TCQ_F_OFFLOADED; + + if (any_qdisc_is_offloaded) + NL_SET_ERR_MSG(extack, "Offloading graft operation failed."); +} +EXPORT_SYMBOL(qdisc_offload_graft_helper); + static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid, u32 portid, u32 seq, u16 flags, int event) { |