OSDN Git Service

devlink: push dpipe related code into separate file
authorJiri Pirko <jiri@nvidia.com>
Mon, 28 Aug 2023 06:16:47 +0000 (08:16 +0200)
committerJakub Kicinski <kuba@kernel.org>
Mon, 28 Aug 2023 15:02:22 +0000 (08:02 -0700)
Cut out another chunk from leftover.c and put dpipe related code
into a separate file.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
Link: https://lore.kernel.org/r/20230828061657.300667-6-jiri@resnulli.us
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/devlink/Makefile
net/devlink/devl_internal.h
net/devlink/dpipe.c [new file with mode: 0644]
net/devlink/leftover.c

index dcc508a..122de1d 100644 (file)
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
 
-obj-y := leftover.o core.o netlink.o netlink_gen.o dev.o port.o sb.o health.o \
+obj-y := leftover.o core.o netlink.o netlink_gen.o dev.o port.o sb.o dpipe.o \
+        health.o
index 66c9495..72653e1 100644 (file)
@@ -231,6 +231,13 @@ int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
                                        struct genl_info *info);
 int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
                                         struct genl_info *info);
+int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb, struct genl_info *info);
+int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
+                                    struct genl_info *info);
+int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb,
+                                    struct genl_info *info);
+int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb,
+                                           struct genl_info *info);
 int devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb,
                                            struct genl_info *info);
 int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb,
diff --git a/net/devlink/dpipe.c b/net/devlink/dpipe.c
new file mode 100644 (file)
index 0000000..431227c
--- /dev/null
@@ -0,0 +1,917 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
+ */
+
+#include "devl_internal.h"
+
+static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = {
+       {
+               .name = "destination mac",
+               .id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
+               .bitwidth = 48,
+       },
+};
+
+struct devlink_dpipe_header devlink_dpipe_header_ethernet = {
+       .name = "ethernet",
+       .id = DEVLINK_DPIPE_HEADER_ETHERNET,
+       .fields = devlink_dpipe_fields_ethernet,
+       .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet),
+       .global = true,
+};
+EXPORT_SYMBOL_GPL(devlink_dpipe_header_ethernet);
+
+static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = {
+       {
+               .name = "destination ip",
+               .id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP,
+               .bitwidth = 32,
+       },
+};
+
+struct devlink_dpipe_header devlink_dpipe_header_ipv4 = {
+       .name = "ipv4",
+       .id = DEVLINK_DPIPE_HEADER_IPV4,
+       .fields = devlink_dpipe_fields_ipv4,
+       .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4),
+       .global = true,
+};
+EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv4);
+
+static struct devlink_dpipe_field devlink_dpipe_fields_ipv6[] = {
+       {
+               .name = "destination ip",
+               .id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP,
+               .bitwidth = 128,
+       },
+};
+
+struct devlink_dpipe_header devlink_dpipe_header_ipv6 = {
+       .name = "ipv6",
+       .id = DEVLINK_DPIPE_HEADER_IPV6,
+       .fields = devlink_dpipe_fields_ipv6,
+       .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv6),
+       .global = true,
+};
+EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv6);
+
+int devlink_dpipe_match_put(struct sk_buff *skb,
+                           struct devlink_dpipe_match *match)
+{
+       struct devlink_dpipe_header *header = match->header;
+       struct devlink_dpipe_field *field = &header->fields[match->field_id];
+       struct nlattr *match_attr;
+
+       match_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_MATCH);
+       if (!match_attr)
+               return -EMSGSIZE;
+
+       if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) ||
+           nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) ||
+           nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
+           nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
+           nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
+               goto nla_put_failure;
+
+       nla_nest_end(skb, match_attr);
+       return 0;
+
+nla_put_failure:
+       nla_nest_cancel(skb, match_attr);
+       return -EMSGSIZE;
+}
+EXPORT_SYMBOL_GPL(devlink_dpipe_match_put);
+
+static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table,
+                                    struct sk_buff *skb)
+{
+       struct nlattr *matches_attr;
+
+       matches_attr = nla_nest_start_noflag(skb,
+                                            DEVLINK_ATTR_DPIPE_TABLE_MATCHES);
+       if (!matches_attr)
+               return -EMSGSIZE;
+
+       if (table->table_ops->matches_dump(table->priv, skb))
+               goto nla_put_failure;
+
+       nla_nest_end(skb, matches_attr);
+       return 0;
+
+nla_put_failure:
+       nla_nest_cancel(skb, matches_attr);
+       return -EMSGSIZE;
+}
+
+int devlink_dpipe_action_put(struct sk_buff *skb,
+                            struct devlink_dpipe_action *action)
+{
+       struct devlink_dpipe_header *header = action->header;
+       struct devlink_dpipe_field *field = &header->fields[action->field_id];
+       struct nlattr *action_attr;
+
+       action_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ACTION);
+       if (!action_attr)
+               return -EMSGSIZE;
+
+       if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) ||
+           nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) ||
+           nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
+           nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
+           nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
+               goto nla_put_failure;
+
+       nla_nest_end(skb, action_attr);
+       return 0;
+
+nla_put_failure:
+       nla_nest_cancel(skb, action_attr);
+       return -EMSGSIZE;
+}
+EXPORT_SYMBOL_GPL(devlink_dpipe_action_put);
+
+static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table,
+                                    struct sk_buff *skb)
+{
+       struct nlattr *actions_attr;
+
+       actions_attr = nla_nest_start_noflag(skb,
+                                            DEVLINK_ATTR_DPIPE_TABLE_ACTIONS);
+       if (!actions_attr)
+               return -EMSGSIZE;
+
+       if (table->table_ops->actions_dump(table->priv, skb))
+               goto nla_put_failure;
+
+       nla_nest_end(skb, actions_attr);
+       return 0;
+
+nla_put_failure:
+       nla_nest_cancel(skb, actions_attr);
+       return -EMSGSIZE;
+}
+
+static int devlink_dpipe_table_put(struct sk_buff *skb,
+                                  struct devlink_dpipe_table *table)
+{
+       struct nlattr *table_attr;
+       u64 table_size;
+
+       table_size = table->table_ops->size_get(table->priv);
+       table_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLE);
+       if (!table_attr)
+               return -EMSGSIZE;
+
+       if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) ||
+           nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size,
+                             DEVLINK_ATTR_PAD))
+               goto nla_put_failure;
+       if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
+                      table->counters_enabled))
+               goto nla_put_failure;
+
+       if (table->resource_valid) {
+               if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID,
+                                     table->resource_id, DEVLINK_ATTR_PAD) ||
+                   nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS,
+                                     table->resource_units, DEVLINK_ATTR_PAD))
+                       goto nla_put_failure;
+       }
+       if (devlink_dpipe_matches_put(table, skb))
+               goto nla_put_failure;
+
+       if (devlink_dpipe_actions_put(table, skb))
+               goto nla_put_failure;
+
+       nla_nest_end(skb, table_attr);
+       return 0;
+
+nla_put_failure:
+       nla_nest_cancel(skb, table_attr);
+       return -EMSGSIZE;
+}
+
+static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb,
+                                           struct genl_info *info)
+{
+       int err;
+
+       if (*pskb) {
+               err = genlmsg_reply(*pskb, info);
+               if (err)
+                       return err;
+       }
+       *pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
+       if (!*pskb)
+               return -ENOMEM;
+       return 0;
+}
+
+static int devlink_dpipe_tables_fill(struct genl_info *info,
+                                    enum devlink_command cmd, int flags,
+                                    struct list_head *dpipe_tables,
+                                    const char *table_name)
+{
+       struct devlink *devlink = info->user_ptr[0];
+       struct devlink_dpipe_table *table;
+       struct nlattr *tables_attr;
+       struct sk_buff *skb = NULL;
+       struct nlmsghdr *nlh;
+       bool incomplete;
+       void *hdr;
+       int i;
+       int err;
+
+       table = list_first_entry(dpipe_tables,
+                                struct devlink_dpipe_table, list);
+start_again:
+       err = devlink_dpipe_send_and_alloc_skb(&skb, info);
+       if (err)
+               return err;
+
+       hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
+                         &devlink_nl_family, NLM_F_MULTI, cmd);
+       if (!hdr) {
+               nlmsg_free(skb);
+               return -EMSGSIZE;
+       }
+
+       if (devlink_nl_put_handle(skb, devlink))
+               goto nla_put_failure;
+       tables_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLES);
+       if (!tables_attr)
+               goto nla_put_failure;
+
+       i = 0;
+       incomplete = false;
+       list_for_each_entry_from(table, dpipe_tables, list) {
+               if (!table_name) {
+                       err = devlink_dpipe_table_put(skb, table);
+                       if (err) {
+                               if (!i)
+                                       goto err_table_put;
+                               incomplete = true;
+                               break;
+                       }
+               } else {
+                       if (!strcmp(table->name, table_name)) {
+                               err = devlink_dpipe_table_put(skb, table);
+                               if (err)
+                                       break;
+                       }
+               }
+               i++;
+       }
+
+       nla_nest_end(skb, tables_attr);
+       genlmsg_end(skb, hdr);
+       if (incomplete)
+               goto start_again;
+
+send_done:
+       nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
+                       NLMSG_DONE, 0, flags | NLM_F_MULTI);
+       if (!nlh) {
+               err = devlink_dpipe_send_and_alloc_skb(&skb, info);
+               if (err)
+                       return err;
+               goto send_done;
+       }
+
+       return genlmsg_reply(skb, info);
+
+nla_put_failure:
+       err = -EMSGSIZE;
+err_table_put:
+       nlmsg_free(skb);
+       return err;
+}
+
+int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb, struct genl_info *info)
+{
+       struct devlink *devlink = info->user_ptr[0];
+       const char *table_name =  NULL;
+
+       if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
+               table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
+
+       return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0,
+                                        &devlink->dpipe_table_list,
+                                        table_name);
+}
+
+static int devlink_dpipe_value_put(struct sk_buff *skb,
+                                  struct devlink_dpipe_value *value)
+{
+       if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE,
+                   value->value_size, value->value))
+               return -EMSGSIZE;
+       if (value->mask)
+               if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK,
+                           value->value_size, value->mask))
+                       return -EMSGSIZE;
+       if (value->mapping_valid)
+               if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING,
+                               value->mapping_value))
+                       return -EMSGSIZE;
+       return 0;
+}
+
+static int devlink_dpipe_action_value_put(struct sk_buff *skb,
+                                         struct devlink_dpipe_value *value)
+{
+       if (!value->action)
+               return -EINVAL;
+       if (devlink_dpipe_action_put(skb, value->action))
+               return -EMSGSIZE;
+       if (devlink_dpipe_value_put(skb, value))
+               return -EMSGSIZE;
+       return 0;
+}
+
+static int devlink_dpipe_action_values_put(struct sk_buff *skb,
+                                          struct devlink_dpipe_value *values,
+                                          unsigned int values_count)
+{
+       struct nlattr *action_attr;
+       int i;
+       int err;
+
+       for (i = 0; i < values_count; i++) {
+               action_attr = nla_nest_start_noflag(skb,
+                                                   DEVLINK_ATTR_DPIPE_ACTION_VALUE);
+               if (!action_attr)
+                       return -EMSGSIZE;
+               err = devlink_dpipe_action_value_put(skb, &values[i]);
+               if (err)
+                       goto err_action_value_put;
+               nla_nest_end(skb, action_attr);
+       }
+       return 0;
+
+err_action_value_put:
+       nla_nest_cancel(skb, action_attr);
+       return err;
+}
+
+static int devlink_dpipe_match_value_put(struct sk_buff *skb,
+                                        struct devlink_dpipe_value *value)
+{
+       if (!value->match)
+               return -EINVAL;
+       if (devlink_dpipe_match_put(skb, value->match))
+               return -EMSGSIZE;
+       if (devlink_dpipe_value_put(skb, value))
+               return -EMSGSIZE;
+       return 0;
+}
+
+static int devlink_dpipe_match_values_put(struct sk_buff *skb,
+                                         struct devlink_dpipe_value *values,
+                                         unsigned int values_count)
+{
+       struct nlattr *match_attr;
+       int i;
+       int err;
+
+       for (i = 0; i < values_count; i++) {
+               match_attr = nla_nest_start_noflag(skb,
+                                                  DEVLINK_ATTR_DPIPE_MATCH_VALUE);
+               if (!match_attr)
+                       return -EMSGSIZE;
+               err = devlink_dpipe_match_value_put(skb, &values[i]);
+               if (err)
+                       goto err_match_value_put;
+               nla_nest_end(skb, match_attr);
+       }
+       return 0;
+
+err_match_value_put:
+       nla_nest_cancel(skb, match_attr);
+       return err;
+}
+
+static int devlink_dpipe_entry_put(struct sk_buff *skb,
+                                  struct devlink_dpipe_entry *entry)
+{
+       struct nlattr *entry_attr, *matches_attr, *actions_attr;
+       int err;
+
+       entry_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ENTRY);
+       if (!entry_attr)
+               return  -EMSGSIZE;
+
+       if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index,
+                             DEVLINK_ATTR_PAD))
+               goto nla_put_failure;
+       if (entry->counter_valid)
+               if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER,
+                                     entry->counter, DEVLINK_ATTR_PAD))
+                       goto nla_put_failure;
+
+       matches_attr = nla_nest_start_noflag(skb,
+                                            DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES);
+       if (!matches_attr)
+               goto nla_put_failure;
+
+       err = devlink_dpipe_match_values_put(skb, entry->match_values,
+                                            entry->match_values_count);
+       if (err) {
+               nla_nest_cancel(skb, matches_attr);
+               goto err_match_values_put;
+       }
+       nla_nest_end(skb, matches_attr);
+
+       actions_attr = nla_nest_start_noflag(skb,
+                                            DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES);
+       if (!actions_attr)
+               goto nla_put_failure;
+
+       err = devlink_dpipe_action_values_put(skb, entry->action_values,
+                                             entry->action_values_count);
+       if (err) {
+               nla_nest_cancel(skb, actions_attr);
+               goto err_action_values_put;
+       }
+       nla_nest_end(skb, actions_attr);
+
+       nla_nest_end(skb, entry_attr);
+       return 0;
+
+nla_put_failure:
+       err = -EMSGSIZE;
+err_match_values_put:
+err_action_values_put:
+       nla_nest_cancel(skb, entry_attr);
+       return err;
+}
+
+static struct devlink_dpipe_table *
+devlink_dpipe_table_find(struct list_head *dpipe_tables,
+                        const char *table_name, struct devlink *devlink)
+{
+       struct devlink_dpipe_table *table;
+
+       list_for_each_entry_rcu(table, dpipe_tables, list,
+                               lockdep_is_held(&devlink->lock)) {
+               if (!strcmp(table->name, table_name))
+                       return table;
+       }
+       return NULL;
+}
+
+int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx)
+{
+       struct devlink *devlink;
+       int err;
+
+       err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb,
+                                              dump_ctx->info);
+       if (err)
+               return err;
+
+       dump_ctx->hdr = genlmsg_put(dump_ctx->skb,
+                                   dump_ctx->info->snd_portid,
+                                   dump_ctx->info->snd_seq,
+                                   &devlink_nl_family, NLM_F_MULTI,
+                                   dump_ctx->cmd);
+       if (!dump_ctx->hdr)
+               goto nla_put_failure;
+
+       devlink = dump_ctx->info->user_ptr[0];
+       if (devlink_nl_put_handle(dump_ctx->skb, devlink))
+               goto nla_put_failure;
+       dump_ctx->nest = nla_nest_start_noflag(dump_ctx->skb,
+                                              DEVLINK_ATTR_DPIPE_ENTRIES);
+       if (!dump_ctx->nest)
+               goto nla_put_failure;
+       return 0;
+
+nla_put_failure:
+       nlmsg_free(dump_ctx->skb);
+       return -EMSGSIZE;
+}
+EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare);
+
+int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx,
+                                  struct devlink_dpipe_entry *entry)
+{
+       return devlink_dpipe_entry_put(dump_ctx->skb, entry);
+}
+EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append);
+
+int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx)
+{
+       nla_nest_end(dump_ctx->skb, dump_ctx->nest);
+       genlmsg_end(dump_ctx->skb, dump_ctx->hdr);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close);
+
+void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry)
+
+{
+       unsigned int value_count, value_index;
+       struct devlink_dpipe_value *value;
+
+       value = entry->action_values;
+       value_count = entry->action_values_count;
+       for (value_index = 0; value_index < value_count; value_index++) {
+               kfree(value[value_index].value);
+               kfree(value[value_index].mask);
+       }
+
+       value = entry->match_values;
+       value_count = entry->match_values_count;
+       for (value_index = 0; value_index < value_count; value_index++) {
+               kfree(value[value_index].value);
+               kfree(value[value_index].mask);
+       }
+}
+EXPORT_SYMBOL_GPL(devlink_dpipe_entry_clear);
+
+static int devlink_dpipe_entries_fill(struct genl_info *info,
+                                     enum devlink_command cmd, int flags,
+                                     struct devlink_dpipe_table *table)
+{
+       struct devlink_dpipe_dump_ctx dump_ctx;
+       struct nlmsghdr *nlh;
+       int err;
+
+       dump_ctx.skb = NULL;
+       dump_ctx.cmd = cmd;
+       dump_ctx.info = info;
+
+       err = table->table_ops->entries_dump(table->priv,
+                                            table->counters_enabled,
+                                            &dump_ctx);
+       if (err)
+               return err;
+
+send_done:
+       nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq,
+                       NLMSG_DONE, 0, flags | NLM_F_MULTI);
+       if (!nlh) {
+               err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info);
+               if (err)
+                       return err;
+               goto send_done;
+       }
+       return genlmsg_reply(dump_ctx.skb, info);
+}
+
+int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
+                                    struct genl_info *info)
+{
+       struct devlink *devlink = info->user_ptr[0];
+       struct devlink_dpipe_table *table;
+       const char *table_name;
+
+       if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_DPIPE_TABLE_NAME))
+               return -EINVAL;
+
+       table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
+       table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
+                                        table_name, devlink);
+       if (!table)
+               return -EINVAL;
+
+       if (!table->table_ops->entries_dump)
+               return -EINVAL;
+
+       return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET,
+                                         0, table);
+}
+
+static int devlink_dpipe_fields_put(struct sk_buff *skb,
+                                   const struct devlink_dpipe_header *header)
+{
+       struct devlink_dpipe_field *field;
+       struct nlattr *field_attr;
+       int i;
+
+       for (i = 0; i < header->fields_count; i++) {
+               field = &header->fields[i];
+               field_attr = nla_nest_start_noflag(skb,
+                                                  DEVLINK_ATTR_DPIPE_FIELD);
+               if (!field_attr)
+                       return -EMSGSIZE;
+               if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) ||
+                   nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
+                   nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) ||
+                   nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type))
+                       goto nla_put_failure;
+               nla_nest_end(skb, field_attr);
+       }
+       return 0;
+
+nla_put_failure:
+       nla_nest_cancel(skb, field_attr);
+       return -EMSGSIZE;
+}
+
+static int devlink_dpipe_header_put(struct sk_buff *skb,
+                                   struct devlink_dpipe_header *header)
+{
+       struct nlattr *fields_attr, *header_attr;
+       int err;
+
+       header_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADER);
+       if (!header_attr)
+               return -EMSGSIZE;
+
+       if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) ||
+           nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
+           nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
+               goto nla_put_failure;
+
+       fields_attr = nla_nest_start_noflag(skb,
+                                           DEVLINK_ATTR_DPIPE_HEADER_FIELDS);
+       if (!fields_attr)
+               goto nla_put_failure;
+
+       err = devlink_dpipe_fields_put(skb, header);
+       if (err) {
+               nla_nest_cancel(skb, fields_attr);
+               goto nla_put_failure;
+       }
+       nla_nest_end(skb, fields_attr);
+       nla_nest_end(skb, header_attr);
+       return 0;
+
+nla_put_failure:
+       err = -EMSGSIZE;
+       nla_nest_cancel(skb, header_attr);
+       return err;
+}
+
+static int devlink_dpipe_headers_fill(struct genl_info *info,
+                                     enum devlink_command cmd, int flags,
+                                     struct devlink_dpipe_headers *
+                                     dpipe_headers)
+{
+       struct devlink *devlink = info->user_ptr[0];
+       struct nlattr *headers_attr;
+       struct sk_buff *skb = NULL;
+       struct nlmsghdr *nlh;
+       void *hdr;
+       int i, j;
+       int err;
+
+       i = 0;
+start_again:
+       err = devlink_dpipe_send_and_alloc_skb(&skb, info);
+       if (err)
+               return err;
+
+       hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
+                         &devlink_nl_family, NLM_F_MULTI, cmd);
+       if (!hdr) {
+               nlmsg_free(skb);
+               return -EMSGSIZE;
+       }
+
+       if (devlink_nl_put_handle(skb, devlink))
+               goto nla_put_failure;
+       headers_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADERS);
+       if (!headers_attr)
+               goto nla_put_failure;
+
+       j = 0;
+       for (; i < dpipe_headers->headers_count; i++) {
+               err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]);
+               if (err) {
+                       if (!j)
+                               goto err_table_put;
+                       break;
+               }
+               j++;
+       }
+       nla_nest_end(skb, headers_attr);
+       genlmsg_end(skb, hdr);
+       if (i != dpipe_headers->headers_count)
+               goto start_again;
+
+send_done:
+       nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
+                       NLMSG_DONE, 0, flags | NLM_F_MULTI);
+       if (!nlh) {
+               err = devlink_dpipe_send_and_alloc_skb(&skb, info);
+               if (err)
+                       return err;
+               goto send_done;
+       }
+       return genlmsg_reply(skb, info);
+
+nla_put_failure:
+       err = -EMSGSIZE;
+err_table_put:
+       nlmsg_free(skb);
+       return err;
+}
+
+int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb,
+                                    struct genl_info *info)
+{
+       struct devlink *devlink = info->user_ptr[0];
+
+       if (!devlink->dpipe_headers)
+               return -EOPNOTSUPP;
+       return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET,
+                                         0, devlink->dpipe_headers);
+}
+
+static int devlink_dpipe_table_counters_set(struct devlink *devlink,
+                                           const char *table_name,
+                                           bool enable)
+{
+       struct devlink_dpipe_table *table;
+
+       table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
+                                        table_name, devlink);
+       if (!table)
+               return -EINVAL;
+
+       if (table->counter_control_extern)
+               return -EOPNOTSUPP;
+
+       if (!(table->counters_enabled ^ enable))
+               return 0;
+
+       table->counters_enabled = enable;
+       if (table->table_ops->counters_set_update)
+               table->table_ops->counters_set_update(table->priv, enable);
+       return 0;
+}
+
+int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb,
+                                           struct genl_info *info)
+{
+       struct devlink *devlink = info->user_ptr[0];
+       const char *table_name;
+       bool counters_enable;
+
+       if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_DPIPE_TABLE_NAME) ||
+           GENL_REQ_ATTR_CHECK(info,
+                               DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED))
+               return -EINVAL;
+
+       table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
+       counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]);
+
+       return devlink_dpipe_table_counters_set(devlink, table_name,
+                                               counters_enable);
+}
+
+/**
+ * devl_dpipe_headers_register - register dpipe headers
+ *
+ * @devlink: devlink
+ * @dpipe_headers: dpipe header array
+ *
+ * Register the headers supported by hardware.
+ */
+void devl_dpipe_headers_register(struct devlink *devlink,
+                                struct devlink_dpipe_headers *dpipe_headers)
+{
+       lockdep_assert_held(&devlink->lock);
+
+       devlink->dpipe_headers = dpipe_headers;
+}
+EXPORT_SYMBOL_GPL(devl_dpipe_headers_register);
+
+/**
+ * devl_dpipe_headers_unregister - unregister dpipe headers
+ *
+ * @devlink: devlink
+ *
+ * Unregister the headers supported by hardware.
+ */
+void devl_dpipe_headers_unregister(struct devlink *devlink)
+{
+       lockdep_assert_held(&devlink->lock);
+
+       devlink->dpipe_headers = NULL;
+}
+EXPORT_SYMBOL_GPL(devl_dpipe_headers_unregister);
+
+/**
+ *     devlink_dpipe_table_counter_enabled - check if counter allocation
+ *                                           required
+ *     @devlink: devlink
+ *     @table_name: tables name
+ *
+ *     Used by driver to check if counter allocation is required.
+ *     After counter allocation is turned on the table entries
+ *     are updated to include counter statistics.
+ *
+ *     After that point on the driver must respect the counter
+ *     state so that each entry added to the table is added
+ *     with a counter.
+ */
+bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
+                                        const char *table_name)
+{
+       struct devlink_dpipe_table *table;
+       bool enabled;
+
+       rcu_read_lock();
+       table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
+                                        table_name, devlink);
+       enabled = false;
+       if (table)
+               enabled = table->counters_enabled;
+       rcu_read_unlock();
+       return enabled;
+}
+EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled);
+
+/**
+ * devl_dpipe_table_register - register dpipe table
+ *
+ * @devlink: devlink
+ * @table_name: table name
+ * @table_ops: table ops
+ * @priv: priv
+ * @counter_control_extern: external control for counters
+ */
+int devl_dpipe_table_register(struct devlink *devlink,
+                             const char *table_name,
+                             struct devlink_dpipe_table_ops *table_ops,
+                             void *priv, bool counter_control_extern)
+{
+       struct devlink_dpipe_table *table;
+
+       lockdep_assert_held(&devlink->lock);
+
+       if (WARN_ON(!table_ops->size_get))
+               return -EINVAL;
+
+       if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name,
+                                    devlink))
+               return -EEXIST;
+
+       table = kzalloc(sizeof(*table), GFP_KERNEL);
+       if (!table)
+               return -ENOMEM;
+
+       table->name = table_name;
+       table->table_ops = table_ops;
+       table->priv = priv;
+       table->counter_control_extern = counter_control_extern;
+
+       list_add_tail_rcu(&table->list, &devlink->dpipe_table_list);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(devl_dpipe_table_register);
+
+/**
+ * devl_dpipe_table_unregister - unregister dpipe table
+ *
+ * @devlink: devlink
+ * @table_name: table name
+ */
+void devl_dpipe_table_unregister(struct devlink *devlink,
+                                const char *table_name)
+{
+       struct devlink_dpipe_table *table;
+
+       lockdep_assert_held(&devlink->lock);
+
+       table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
+                                        table_name, devlink);
+       if (!table)
+               return;
+       list_del_rcu(&table->list);
+       kfree_rcu(table, rcu);
+}
+EXPORT_SYMBOL_GPL(devl_dpipe_table_unregister);
+
+/**
+ * devl_dpipe_table_resource_set - set the resource id
+ *
+ * @devlink: devlink
+ * @table_name: table name
+ * @resource_id: resource id
+ * @resource_units: number of resource's units consumed per table's entry
+ */
+int devl_dpipe_table_resource_set(struct devlink *devlink,
+                                 const char *table_name, u64 resource_id,
+                                 u64 resource_units)
+{
+       struct devlink_dpipe_table *table;
+
+       table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
+                                        table_name, devlink);
+       if (!table)
+               return -EINVAL;
+
+       table->resource_id = resource_id;
+       table->resource_units = resource_units;
+       table->resource_valid = true;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(devl_dpipe_table_resource_set);
index 1bcd419..f71201e 100644 (file)
@@ -62,57 +62,6 @@ struct devlink_resource {
        void *occ_get_priv;
 };
 
-static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = {
-       {
-               .name = "destination mac",
-               .id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
-               .bitwidth = 48,
-       },
-};
-
-struct devlink_dpipe_header devlink_dpipe_header_ethernet = {
-       .name = "ethernet",
-       .id = DEVLINK_DPIPE_HEADER_ETHERNET,
-       .fields = devlink_dpipe_fields_ethernet,
-       .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet),
-       .global = true,
-};
-EXPORT_SYMBOL_GPL(devlink_dpipe_header_ethernet);
-
-static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = {
-       {
-               .name = "destination ip",
-               .id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP,
-               .bitwidth = 32,
-       },
-};
-
-struct devlink_dpipe_header devlink_dpipe_header_ipv4 = {
-       .name = "ipv4",
-       .id = DEVLINK_DPIPE_HEADER_IPV4,
-       .fields = devlink_dpipe_fields_ipv4,
-       .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4),
-       .global = true,
-};
-EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv4);
-
-static struct devlink_dpipe_field devlink_dpipe_fields_ipv6[] = {
-       {
-               .name = "destination ip",
-               .id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP,
-               .bitwidth = 128,
-       },
-};
-
-struct devlink_dpipe_header devlink_dpipe_header_ipv6 = {
-       .name = "ipv6",
-       .id = DEVLINK_DPIPE_HEADER_IPV6,
-       .fields = devlink_dpipe_fields_ipv6,
-       .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv6),
-       .global = true,
-};
-EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv6);
-
 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg);
 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwerr);
 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_trap_report);
@@ -1141,698 +1090,6 @@ int devlink_rate_nodes_check(struct devlink *devlink, u16 mode,
        return 0;
 }
 
-int devlink_dpipe_match_put(struct sk_buff *skb,
-                           struct devlink_dpipe_match *match)
-{
-       struct devlink_dpipe_header *header = match->header;
-       struct devlink_dpipe_field *field = &header->fields[match->field_id];
-       struct nlattr *match_attr;
-
-       match_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_MATCH);
-       if (!match_attr)
-               return -EMSGSIZE;
-
-       if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) ||
-           nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) ||
-           nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
-           nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
-           nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
-               goto nla_put_failure;
-
-       nla_nest_end(skb, match_attr);
-       return 0;
-
-nla_put_failure:
-       nla_nest_cancel(skb, match_attr);
-       return -EMSGSIZE;
-}
-EXPORT_SYMBOL_GPL(devlink_dpipe_match_put);
-
-static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table,
-                                    struct sk_buff *skb)
-{
-       struct nlattr *matches_attr;
-
-       matches_attr = nla_nest_start_noflag(skb,
-                                            DEVLINK_ATTR_DPIPE_TABLE_MATCHES);
-       if (!matches_attr)
-               return -EMSGSIZE;
-
-       if (table->table_ops->matches_dump(table->priv, skb))
-               goto nla_put_failure;
-
-       nla_nest_end(skb, matches_attr);
-       return 0;
-
-nla_put_failure:
-       nla_nest_cancel(skb, matches_attr);
-       return -EMSGSIZE;
-}
-
-int devlink_dpipe_action_put(struct sk_buff *skb,
-                            struct devlink_dpipe_action *action)
-{
-       struct devlink_dpipe_header *header = action->header;
-       struct devlink_dpipe_field *field = &header->fields[action->field_id];
-       struct nlattr *action_attr;
-
-       action_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ACTION);
-       if (!action_attr)
-               return -EMSGSIZE;
-
-       if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) ||
-           nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) ||
-           nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
-           nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
-           nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
-               goto nla_put_failure;
-
-       nla_nest_end(skb, action_attr);
-       return 0;
-
-nla_put_failure:
-       nla_nest_cancel(skb, action_attr);
-       return -EMSGSIZE;
-}
-EXPORT_SYMBOL_GPL(devlink_dpipe_action_put);
-
-static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table,
-                                    struct sk_buff *skb)
-{
-       struct nlattr *actions_attr;
-
-       actions_attr = nla_nest_start_noflag(skb,
-                                            DEVLINK_ATTR_DPIPE_TABLE_ACTIONS);
-       if (!actions_attr)
-               return -EMSGSIZE;
-
-       if (table->table_ops->actions_dump(table->priv, skb))
-               goto nla_put_failure;
-
-       nla_nest_end(skb, actions_attr);
-       return 0;
-
-nla_put_failure:
-       nla_nest_cancel(skb, actions_attr);
-       return -EMSGSIZE;
-}
-
-static int devlink_dpipe_table_put(struct sk_buff *skb,
-                                  struct devlink_dpipe_table *table)
-{
-       struct nlattr *table_attr;
-       u64 table_size;
-
-       table_size = table->table_ops->size_get(table->priv);
-       table_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLE);
-       if (!table_attr)
-               return -EMSGSIZE;
-
-       if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) ||
-           nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size,
-                             DEVLINK_ATTR_PAD))
-               goto nla_put_failure;
-       if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
-                      table->counters_enabled))
-               goto nla_put_failure;
-
-       if (table->resource_valid) {
-               if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID,
-                                     table->resource_id, DEVLINK_ATTR_PAD) ||
-                   nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS,
-                                     table->resource_units, DEVLINK_ATTR_PAD))
-                       goto nla_put_failure;
-       }
-       if (devlink_dpipe_matches_put(table, skb))
-               goto nla_put_failure;
-
-       if (devlink_dpipe_actions_put(table, skb))
-               goto nla_put_failure;
-
-       nla_nest_end(skb, table_attr);
-       return 0;
-
-nla_put_failure:
-       nla_nest_cancel(skb, table_attr);
-       return -EMSGSIZE;
-}
-
-static int devlink_dpipe_tables_fill(struct genl_info *info,
-                                    enum devlink_command cmd, int flags,
-                                    struct list_head *dpipe_tables,
-                                    const char *table_name)
-{
-       struct devlink *devlink = info->user_ptr[0];
-       struct devlink_dpipe_table *table;
-       struct nlattr *tables_attr;
-       struct sk_buff *skb = NULL;
-       struct nlmsghdr *nlh;
-       bool incomplete;
-       void *hdr;
-       int i;
-       int err;
-
-       table = list_first_entry(dpipe_tables,
-                                struct devlink_dpipe_table, list);
-start_again:
-       err = devlink_nl_msg_reply_and_new(&skb, info);
-       if (err)
-               return err;
-
-       hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
-                         &devlink_nl_family, NLM_F_MULTI, cmd);
-       if (!hdr) {
-               nlmsg_free(skb);
-               return -EMSGSIZE;
-       }
-
-       if (devlink_nl_put_handle(skb, devlink))
-               goto nla_put_failure;
-       tables_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLES);
-       if (!tables_attr)
-               goto nla_put_failure;
-
-       i = 0;
-       incomplete = false;
-       list_for_each_entry_from(table, dpipe_tables, list) {
-               if (!table_name) {
-                       err = devlink_dpipe_table_put(skb, table);
-                       if (err) {
-                               if (!i)
-                                       goto err_table_put;
-                               incomplete = true;
-                               break;
-                       }
-               } else {
-                       if (!strcmp(table->name, table_name)) {
-                               err = devlink_dpipe_table_put(skb, table);
-                               if (err)
-                                       break;
-                       }
-               }
-               i++;
-       }
-
-       nla_nest_end(skb, tables_attr);
-       genlmsg_end(skb, hdr);
-       if (incomplete)
-               goto start_again;
-
-send_done:
-       nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
-                       NLMSG_DONE, 0, flags | NLM_F_MULTI);
-       if (!nlh) {
-               err = devlink_nl_msg_reply_and_new(&skb, info);
-               if (err)
-                       return err;
-               goto send_done;
-       }
-
-       return genlmsg_reply(skb, info);
-
-nla_put_failure:
-       err = -EMSGSIZE;
-err_table_put:
-       nlmsg_free(skb);
-       return err;
-}
-
-static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb,
-                                         struct genl_info *info)
-{
-       struct devlink *devlink = info->user_ptr[0];
-       const char *table_name =  NULL;
-
-       if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
-               table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
-
-       return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0,
-                                        &devlink->dpipe_table_list,
-                                        table_name);
-}
-
-static int devlink_dpipe_value_put(struct sk_buff *skb,
-                                  struct devlink_dpipe_value *value)
-{
-       if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE,
-                   value->value_size, value->value))
-               return -EMSGSIZE;
-       if (value->mask)
-               if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK,
-                           value->value_size, value->mask))
-                       return -EMSGSIZE;
-       if (value->mapping_valid)
-               if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING,
-                               value->mapping_value))
-                       return -EMSGSIZE;
-       return 0;
-}
-
-static int devlink_dpipe_action_value_put(struct sk_buff *skb,
-                                         struct devlink_dpipe_value *value)
-{
-       if (!value->action)
-               return -EINVAL;
-       if (devlink_dpipe_action_put(skb, value->action))
-               return -EMSGSIZE;
-       if (devlink_dpipe_value_put(skb, value))
-               return -EMSGSIZE;
-       return 0;
-}
-
-static int devlink_dpipe_action_values_put(struct sk_buff *skb,
-                                          struct devlink_dpipe_value *values,
-                                          unsigned int values_count)
-{
-       struct nlattr *action_attr;
-       int i;
-       int err;
-
-       for (i = 0; i < values_count; i++) {
-               action_attr = nla_nest_start_noflag(skb,
-                                                   DEVLINK_ATTR_DPIPE_ACTION_VALUE);
-               if (!action_attr)
-                       return -EMSGSIZE;
-               err = devlink_dpipe_action_value_put(skb, &values[i]);
-               if (err)
-                       goto err_action_value_put;
-               nla_nest_end(skb, action_attr);
-       }
-       return 0;
-
-err_action_value_put:
-       nla_nest_cancel(skb, action_attr);
-       return err;
-}
-
-static int devlink_dpipe_match_value_put(struct sk_buff *skb,
-                                        struct devlink_dpipe_value *value)
-{
-       if (!value->match)
-               return -EINVAL;
-       if (devlink_dpipe_match_put(skb, value->match))
-               return -EMSGSIZE;
-       if (devlink_dpipe_value_put(skb, value))
-               return -EMSGSIZE;
-       return 0;
-}
-
-static int devlink_dpipe_match_values_put(struct sk_buff *skb,
-                                         struct devlink_dpipe_value *values,
-                                         unsigned int values_count)
-{
-       struct nlattr *match_attr;
-       int i;
-       int err;
-
-       for (i = 0; i < values_count; i++) {
-               match_attr = nla_nest_start_noflag(skb,
-                                                  DEVLINK_ATTR_DPIPE_MATCH_VALUE);
-               if (!match_attr)
-                       return -EMSGSIZE;
-               err = devlink_dpipe_match_value_put(skb, &values[i]);
-               if (err)
-                       goto err_match_value_put;
-               nla_nest_end(skb, match_attr);
-       }
-       return 0;
-
-err_match_value_put:
-       nla_nest_cancel(skb, match_attr);
-       return err;
-}
-
-static int devlink_dpipe_entry_put(struct sk_buff *skb,
-                                  struct devlink_dpipe_entry *entry)
-{
-       struct nlattr *entry_attr, *matches_attr, *actions_attr;
-       int err;
-
-       entry_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ENTRY);
-       if (!entry_attr)
-               return  -EMSGSIZE;
-
-       if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index,
-                             DEVLINK_ATTR_PAD))
-               goto nla_put_failure;
-       if (entry->counter_valid)
-               if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER,
-                                     entry->counter, DEVLINK_ATTR_PAD))
-                       goto nla_put_failure;
-
-       matches_attr = nla_nest_start_noflag(skb,
-                                            DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES);
-       if (!matches_attr)
-               goto nla_put_failure;
-
-       err = devlink_dpipe_match_values_put(skb, entry->match_values,
-                                            entry->match_values_count);
-       if (err) {
-               nla_nest_cancel(skb, matches_attr);
-               goto err_match_values_put;
-       }
-       nla_nest_end(skb, matches_attr);
-
-       actions_attr = nla_nest_start_noflag(skb,
-                                            DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES);
-       if (!actions_attr)
-               goto nla_put_failure;
-
-       err = devlink_dpipe_action_values_put(skb, entry->action_values,
-                                             entry->action_values_count);
-       if (err) {
-               nla_nest_cancel(skb, actions_attr);
-               goto err_action_values_put;
-       }
-       nla_nest_end(skb, actions_attr);
-
-       nla_nest_end(skb, entry_attr);
-       return 0;
-
-nla_put_failure:
-       err = -EMSGSIZE;
-err_match_values_put:
-err_action_values_put:
-       nla_nest_cancel(skb, entry_attr);
-       return err;
-}
-
-static struct devlink_dpipe_table *
-devlink_dpipe_table_find(struct list_head *dpipe_tables,
-                        const char *table_name, struct devlink *devlink)
-{
-       struct devlink_dpipe_table *table;
-       list_for_each_entry_rcu(table, dpipe_tables, list,
-                               lockdep_is_held(&devlink->lock)) {
-               if (!strcmp(table->name, table_name))
-                       return table;
-       }
-       return NULL;
-}
-
-int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx)
-{
-       struct devlink *devlink;
-       int err;
-
-       err = devlink_nl_msg_reply_and_new(&dump_ctx->skb,
-                                          dump_ctx->info);
-       if (err)
-               return err;
-
-       dump_ctx->hdr = genlmsg_put(dump_ctx->skb,
-                                   dump_ctx->info->snd_portid,
-                                   dump_ctx->info->snd_seq,
-                                   &devlink_nl_family, NLM_F_MULTI,
-                                   dump_ctx->cmd);
-       if (!dump_ctx->hdr)
-               goto nla_put_failure;
-
-       devlink = dump_ctx->info->user_ptr[0];
-       if (devlink_nl_put_handle(dump_ctx->skb, devlink))
-               goto nla_put_failure;
-       dump_ctx->nest = nla_nest_start_noflag(dump_ctx->skb,
-                                              DEVLINK_ATTR_DPIPE_ENTRIES);
-       if (!dump_ctx->nest)
-               goto nla_put_failure;
-       return 0;
-
-nla_put_failure:
-       nlmsg_free(dump_ctx->skb);
-       return -EMSGSIZE;
-}
-EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare);
-
-int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx,
-                                  struct devlink_dpipe_entry *entry)
-{
-       return devlink_dpipe_entry_put(dump_ctx->skb, entry);
-}
-EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append);
-
-int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx)
-{
-       nla_nest_end(dump_ctx->skb, dump_ctx->nest);
-       genlmsg_end(dump_ctx->skb, dump_ctx->hdr);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close);
-
-void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry)
-
-{
-       unsigned int value_count, value_index;
-       struct devlink_dpipe_value *value;
-
-       value = entry->action_values;
-       value_count = entry->action_values_count;
-       for (value_index = 0; value_index < value_count; value_index++) {
-               kfree(value[value_index].value);
-               kfree(value[value_index].mask);
-       }
-
-       value = entry->match_values;
-       value_count = entry->match_values_count;
-       for (value_index = 0; value_index < value_count; value_index++) {
-               kfree(value[value_index].value);
-               kfree(value[value_index].mask);
-       }
-}
-EXPORT_SYMBOL_GPL(devlink_dpipe_entry_clear);
-
-static int devlink_dpipe_entries_fill(struct genl_info *info,
-                                     enum devlink_command cmd, int flags,
-                                     struct devlink_dpipe_table *table)
-{
-       struct devlink_dpipe_dump_ctx dump_ctx;
-       struct nlmsghdr *nlh;
-       int err;
-
-       dump_ctx.skb = NULL;
-       dump_ctx.cmd = cmd;
-       dump_ctx.info = info;
-
-       err = table->table_ops->entries_dump(table->priv,
-                                            table->counters_enabled,
-                                            &dump_ctx);
-       if (err)
-               return err;
-
-send_done:
-       nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq,
-                       NLMSG_DONE, 0, flags | NLM_F_MULTI);
-       if (!nlh) {
-               err = devlink_nl_msg_reply_and_new(&dump_ctx.skb, info);
-               if (err)
-                       return err;
-               goto send_done;
-       }
-       return genlmsg_reply(dump_ctx.skb, info);
-}
-
-static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
-                                           struct genl_info *info)
-{
-       struct devlink *devlink = info->user_ptr[0];
-       struct devlink_dpipe_table *table;
-       const char *table_name;
-
-       if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_DPIPE_TABLE_NAME))
-               return -EINVAL;
-
-       table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
-       table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
-                                        table_name, devlink);
-       if (!table)
-               return -EINVAL;
-
-       if (!table->table_ops->entries_dump)
-               return -EINVAL;
-
-       return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET,
-                                         0, table);
-}
-
-static int devlink_dpipe_fields_put(struct sk_buff *skb,
-                                   const struct devlink_dpipe_header *header)
-{
-       struct devlink_dpipe_field *field;
-       struct nlattr *field_attr;
-       int i;
-
-       for (i = 0; i < header->fields_count; i++) {
-               field = &header->fields[i];
-               field_attr = nla_nest_start_noflag(skb,
-                                                  DEVLINK_ATTR_DPIPE_FIELD);
-               if (!field_attr)
-                       return -EMSGSIZE;
-               if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) ||
-                   nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
-                   nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) ||
-                   nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type))
-                       goto nla_put_failure;
-               nla_nest_end(skb, field_attr);
-       }
-       return 0;
-
-nla_put_failure:
-       nla_nest_cancel(skb, field_attr);
-       return -EMSGSIZE;
-}
-
-static int devlink_dpipe_header_put(struct sk_buff *skb,
-                                   struct devlink_dpipe_header *header)
-{
-       struct nlattr *fields_attr, *header_attr;
-       int err;
-
-       header_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADER);
-       if (!header_attr)
-               return -EMSGSIZE;
-
-       if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) ||
-           nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
-           nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
-               goto nla_put_failure;
-
-       fields_attr = nla_nest_start_noflag(skb,
-                                           DEVLINK_ATTR_DPIPE_HEADER_FIELDS);
-       if (!fields_attr)
-               goto nla_put_failure;
-
-       err = devlink_dpipe_fields_put(skb, header);
-       if (err) {
-               nla_nest_cancel(skb, fields_attr);
-               goto nla_put_failure;
-       }
-       nla_nest_end(skb, fields_attr);
-       nla_nest_end(skb, header_attr);
-       return 0;
-
-nla_put_failure:
-       err = -EMSGSIZE;
-       nla_nest_cancel(skb, header_attr);
-       return err;
-}
-
-static int devlink_dpipe_headers_fill(struct genl_info *info,
-                                     enum devlink_command cmd, int flags,
-                                     struct devlink_dpipe_headers *
-                                     dpipe_headers)
-{
-       struct devlink *devlink = info->user_ptr[0];
-       struct nlattr *headers_attr;
-       struct sk_buff *skb = NULL;
-       struct nlmsghdr *nlh;
-       void *hdr;
-       int i, j;
-       int err;
-
-       i = 0;
-start_again:
-       err = devlink_nl_msg_reply_and_new(&skb, info);
-       if (err)
-               return err;
-
-       hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
-                         &devlink_nl_family, NLM_F_MULTI, cmd);
-       if (!hdr) {
-               nlmsg_free(skb);
-               return -EMSGSIZE;
-       }
-
-       if (devlink_nl_put_handle(skb, devlink))
-               goto nla_put_failure;
-       headers_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADERS);
-       if (!headers_attr)
-               goto nla_put_failure;
-
-       j = 0;
-       for (; i < dpipe_headers->headers_count; i++) {
-               err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]);
-               if (err) {
-                       if (!j)
-                               goto err_table_put;
-                       break;
-               }
-               j++;
-       }
-       nla_nest_end(skb, headers_attr);
-       genlmsg_end(skb, hdr);
-       if (i != dpipe_headers->headers_count)
-               goto start_again;
-
-send_done:
-       nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
-                       NLMSG_DONE, 0, flags | NLM_F_MULTI);
-       if (!nlh) {
-               err = devlink_nl_msg_reply_and_new(&skb, info);
-               if (err)
-                       return err;
-               goto send_done;
-       }
-       return genlmsg_reply(skb, info);
-
-nla_put_failure:
-       err = -EMSGSIZE;
-err_table_put:
-       nlmsg_free(skb);
-       return err;
-}
-
-static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb,
-                                           struct genl_info *info)
-{
-       struct devlink *devlink = info->user_ptr[0];
-
-       if (!devlink->dpipe_headers)
-               return -EOPNOTSUPP;
-       return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET,
-                                         0, devlink->dpipe_headers);
-}
-
-static int devlink_dpipe_table_counters_set(struct devlink *devlink,
-                                           const char *table_name,
-                                           bool enable)
-{
-       struct devlink_dpipe_table *table;
-
-       table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
-                                        table_name, devlink);
-       if (!table)
-               return -EINVAL;
-
-       if (table->counter_control_extern)
-               return -EOPNOTSUPP;
-
-       if (!(table->counters_enabled ^ enable))
-               return 0;
-
-       table->counters_enabled = enable;
-       if (table->table_ops->counters_set_update)
-               table->table_ops->counters_set_update(table->priv, enable);
-       return 0;
-}
-
-static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb,
-                                                  struct genl_info *info)
-{
-       struct devlink *devlink = info->user_ptr[0];
-       const char *table_name;
-       bool counters_enable;
-
-       if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_DPIPE_TABLE_NAME) ||
-           GENL_REQ_ATTR_CHECK(info,
-                               DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED))
-               return -EINVAL;
-
-       table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
-       counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]);
-
-       return devlink_dpipe_table_counters_set(devlink, table_name,
-                                               counters_enable);
-}
-
 static struct devlink_resource *
 devlink_resource_find(struct devlink *devlink,
                      struct devlink_resource *resource, u64 resource_id)
@@ -5273,131 +4530,6 @@ void devlink_linecard_nested_dl_set(struct devlink_linecard *linecard,
 EXPORT_SYMBOL_GPL(devlink_linecard_nested_dl_set);
 
 /**
- * devl_dpipe_headers_register - register dpipe headers
- *
- * @devlink: devlink
- * @dpipe_headers: dpipe header array
- *
- * Register the headers supported by hardware.
- */
-void devl_dpipe_headers_register(struct devlink *devlink,
-                                struct devlink_dpipe_headers *dpipe_headers)
-{
-       lockdep_assert_held(&devlink->lock);
-
-       devlink->dpipe_headers = dpipe_headers;
-}
-EXPORT_SYMBOL_GPL(devl_dpipe_headers_register);
-
-/**
- * devl_dpipe_headers_unregister - unregister dpipe headers
- *
- * @devlink: devlink
- *
- * Unregister the headers supported by hardware.
- */
-void devl_dpipe_headers_unregister(struct devlink *devlink)
-{
-       lockdep_assert_held(&devlink->lock);
-
-       devlink->dpipe_headers = NULL;
-}
-EXPORT_SYMBOL_GPL(devl_dpipe_headers_unregister);
-
-/**
- *     devlink_dpipe_table_counter_enabled - check if counter allocation
- *                                           required
- *     @devlink: devlink
- *     @table_name: tables name
- *
- *     Used by driver to check if counter allocation is required.
- *     After counter allocation is turned on the table entries
- *     are updated to include counter statistics.
- *
- *     After that point on the driver must respect the counter
- *     state so that each entry added to the table is added
- *     with a counter.
- */
-bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
-                                        const char *table_name)
-{
-       struct devlink_dpipe_table *table;
-       bool enabled;
-
-       rcu_read_lock();
-       table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
-                                        table_name, devlink);
-       enabled = false;
-       if (table)
-               enabled = table->counters_enabled;
-       rcu_read_unlock();
-       return enabled;
-}
-EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled);
-
-/**
- * devl_dpipe_table_register - register dpipe table
- *
- * @devlink: devlink
- * @table_name: table name
- * @table_ops: table ops
- * @priv: priv
- * @counter_control_extern: external control for counters
- */
-int devl_dpipe_table_register(struct devlink *devlink,
-                             const char *table_name,
-                             struct devlink_dpipe_table_ops *table_ops,
-                             void *priv, bool counter_control_extern)
-{
-       struct devlink_dpipe_table *table;
-
-       lockdep_assert_held(&devlink->lock);
-
-       if (WARN_ON(!table_ops->size_get))
-               return -EINVAL;
-
-       if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name,
-                                    devlink))
-               return -EEXIST;
-
-       table = kzalloc(sizeof(*table), GFP_KERNEL);
-       if (!table)
-               return -ENOMEM;
-
-       table->name = table_name;
-       table->table_ops = table_ops;
-       table->priv = priv;
-       table->counter_control_extern = counter_control_extern;
-
-       list_add_tail_rcu(&table->list, &devlink->dpipe_table_list);
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(devl_dpipe_table_register);
-
-/**
- * devl_dpipe_table_unregister - unregister dpipe table
- *
- * @devlink: devlink
- * @table_name: table name
- */
-void devl_dpipe_table_unregister(struct devlink *devlink,
-                                const char *table_name)
-{
-       struct devlink_dpipe_table *table;
-
-       lockdep_assert_held(&devlink->lock);
-
-       table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
-                                        table_name, devlink);
-       if (!table)
-               return;
-       list_del_rcu(&table->list);
-       kfree_rcu(table, rcu);
-}
-EXPORT_SYMBOL_GPL(devl_dpipe_table_unregister);
-
-/**
  * devl_resource_register - devlink resource register
  *
  * @devlink: devlink
@@ -5570,32 +4702,6 @@ int devl_resource_size_get(struct devlink *devlink,
 EXPORT_SYMBOL_GPL(devl_resource_size_get);
 
 /**
- * devl_dpipe_table_resource_set - set the resource id
- *
- * @devlink: devlink
- * @table_name: table name
- * @resource_id: resource id
- * @resource_units: number of resource's units consumed per table's entry
- */
-int devl_dpipe_table_resource_set(struct devlink *devlink,
-                                 const char *table_name, u64 resource_id,
-                                 u64 resource_units)
-{
-       struct devlink_dpipe_table *table;
-
-       table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
-                                        table_name, devlink);
-       if (!table)
-               return -EINVAL;
-
-       table->resource_id = resource_id;
-       table->resource_units = resource_units;
-       table->resource_valid = true;
-       return 0;
-}
-EXPORT_SYMBOL_GPL(devl_dpipe_table_resource_set);
-
-/**
  * devl_resource_occ_get_register - register occupancy getter
  *
  * @devlink: devlink