From: Jiri Pirko <j...@mellanox.com>

Benefit from the previously introduced shared filter blocks
infrastructure and allow ingress and clsact qdisc instances to share
filter blocks. The block index is coming from userspace as qdisc option.

Signed-off-by: Jiri Pirko <j...@mellanox.com>
---
v6->v7:
- adjust to the core changes and check block index attributes for being 0
v3->v4:
- rebased on top of the current net-next
v2->v3:
- removed "p_" prefix from block index function args
---
 include/uapi/linux/pkt_sched.h |  11 +++++
 net/sched/sch_ingress.c        | 101 ++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 111 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/pkt_sched.h b/include/uapi/linux/pkt_sched.h
index 37b5096..8cc554a 100644
--- a/include/uapi/linux/pkt_sched.h
+++ b/include/uapi/linux/pkt_sched.h
@@ -934,4 +934,15 @@ enum {
 
 #define TCA_CBS_MAX (__TCA_CBS_MAX - 1)
 
+/* Ingress/clsact */
+
+enum {
+       TCA_CLSACT_UNSPEC,
+       TCA_CLSACT_INGRESS_BLOCK,
+       TCA_CLSACT_EGRESS_BLOCK,
+       __TCA_CLSACT_MAX
+};
+
+#define TCA_CLSACT_MAX (__TCA_CLSACT_MAX - 1)
+
 #endif
diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c
index 7ca2be2..1bef8d4 100644
--- a/net/sched/sch_ingress.c
+++ b/net/sched/sch_ingress.c
@@ -61,6 +61,32 @@ static void clsact_chain_head_change(struct tcf_proto 
*tp_head, void *priv)
        struct mini_Qdisc_pair *miniqp = priv;
 
        mini_qdisc_pair_swap(miniqp, tp_head);
+};
+
+static const struct nla_policy ingress_policy[TCA_CLSACT_MAX + 1] = {
+       [TCA_CLSACT_INGRESS_BLOCK]      = { .type = NLA_U32 },
+};
+
+static int ingress_parse_opt(struct nlattr *opt, struct tcf_block_ext_info *ei,
+                            struct netlink_ext_ack *extack)
+{
+       struct nlattr *tb[TCA_CLSACT_MAX + 1];
+       int err;
+
+       if (!opt)
+               return 0;
+       err = nla_parse_nested(tb, TCA_CLSACT_MAX, opt, ingress_policy, NULL);
+       if (err)
+               return err;
+
+       if (tb[TCA_CLSACT_INGRESS_BLOCK]) {
+               ei->block_index = nla_get_u32(tb[TCA_CLSACT_INGRESS_BLOCK]);
+               if (!ei->block_index) {
+                       NL_SET_ERR_MSG(extack, "Block index cannot be 0");
+                       return -EINVAL;
+               }
+       }
+       return 0;
 }
 
 static int ingress_init(struct Qdisc *sch, struct nlattr *opt,
@@ -74,6 +100,10 @@ static int ingress_init(struct Qdisc *sch, struct nlattr 
*opt,
 
        mini_qdisc_pair_init(&q->miniqp, sch, &dev->miniq_ingress);
 
+       err = ingress_parse_opt(opt, &q->block_info, extack);
+       if (err)
+               return err;
+
        q->block_info.binder_type = TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS;
        q->block_info.chain_head_change = clsact_chain_head_change;
        q->block_info.chain_head_change_priv = &q->miniqp;
@@ -97,11 +127,15 @@ static void ingress_destroy(struct Qdisc *sch)
 
 static int ingress_dump(struct Qdisc *sch, struct sk_buff *skb)
 {
+       struct ingress_sched_data *q = qdisc_priv(sch);
        struct nlattr *nest;
 
        nest = nla_nest_start(skb, TCA_OPTIONS);
        if (nest == NULL)
                goto nla_put_failure;
+       if (q->block->index &&
+           nla_put_u32(skb, TCA_CLSACT_INGRESS_BLOCK, q->block->index))
+               goto nla_put_failure;
 
        return nla_nest_end(skb, nest);
 
@@ -170,6 +204,44 @@ static struct tcf_block *clsact_tcf_block(struct Qdisc 
*sch, unsigned long cl,
        }
 }
 
+static const struct nla_policy clsact_policy[TCA_CLSACT_MAX + 1] = {
+       [TCA_CLSACT_INGRESS_BLOCK]      = { .type = NLA_U32 },
+       [TCA_CLSACT_EGRESS_BLOCK]       = { .type = NLA_U32 },
+};
+
+static int clsact_parse_opt(struct nlattr *opt,
+                           struct tcf_block_ext_info *ei_ingress,
+                           struct tcf_block_ext_info *ei_egress,
+                           struct netlink_ext_ack *extack)
+{
+       struct nlattr *tb[TCA_CLSACT_MAX + 1];
+       int err;
+
+       if (!opt)
+               return 0;
+       err = nla_parse_nested(tb, TCA_CLSACT_MAX, opt, clsact_policy, NULL);
+       if (err)
+               return err;
+
+       if (tb[TCA_CLSACT_INGRESS_BLOCK]) {
+               ei_ingress->block_index =
+                       nla_get_u32(tb[TCA_CLSACT_INGRESS_BLOCK]);
+               if (!ei_ingress->block_index) {
+                       NL_SET_ERR_MSG(extack, "Block index cannot be 0");
+                       return -EINVAL;
+               }
+       }
+       if (tb[TCA_CLSACT_EGRESS_BLOCK]) {
+               ei_egress->block_index =
+                       nla_get_u32(tb[TCA_CLSACT_EGRESS_BLOCK]);
+               if (!ei_egress->block_index) {
+                       NL_SET_ERR_MSG(extack, "Block index cannot be 0");
+                       return -EINVAL;
+               }
+       }
+       return 0;
+}
+
 static int clsact_init(struct Qdisc *sch, struct nlattr *opt,
                       struct netlink_ext_ack *extack)
 {
@@ -182,6 +254,11 @@ static int clsact_init(struct Qdisc *sch, struct nlattr 
*opt,
 
        mini_qdisc_pair_init(&q->miniqp_ingress, sch, &dev->miniq_ingress);
 
+       err = clsact_parse_opt(opt, &q->ingress_block_info,
+                              &q->egress_block_info, extack);
+       if (err)
+               return err;
+
        q->ingress_block_info.binder_type = 
TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS;
        q->ingress_block_info.chain_head_change = clsact_chain_head_change;
        q->ingress_block_info.chain_head_change_priv = &q->miniqp_ingress;
@@ -218,6 +295,28 @@ static void clsact_destroy(struct Qdisc *sch)
        net_dec_egress_queue();
 }
 
+static int clsact_dump(struct Qdisc *sch, struct sk_buff *skb)
+{
+       struct clsact_sched_data *q = qdisc_priv(sch);
+       struct nlattr *nest;
+
+       nest = nla_nest_start(skb, TCA_OPTIONS);
+       if (!nest)
+               goto nla_put_failure;
+       if (q->ingress_block->index &&
+           nla_put_u32(skb, TCA_CLSACT_INGRESS_BLOCK, q->ingress_block->index))
+               goto nla_put_failure;
+       if (q->egress_block->index &&
+           nla_put_u32(skb, TCA_CLSACT_EGRESS_BLOCK, q->egress_block->index))
+               goto nla_put_failure;
+
+       return nla_nest_end(skb, nest);
+
+nla_put_failure:
+       nla_nest_cancel(skb, nest);
+       return -1;
+}
+
 static const struct Qdisc_class_ops clsact_class_ops = {
        .leaf           =       ingress_leaf,
        .find           =       clsact_find,
@@ -233,7 +332,7 @@ static struct Qdisc_ops clsact_qdisc_ops __read_mostly = {
        .priv_size      =       sizeof(struct clsact_sched_data),
        .init           =       clsact_init,
        .destroy        =       clsact_destroy,
-       .dump           =       ingress_dump,
+       .dump           =       clsact_dump,
        .owner          =       THIS_MODULE,
 };
 
-- 
2.9.5

Reply via email to