linux/net/core/devlink.c
<<
>>
Prefs
   1/*
   2 * net/core/devlink.c - Network physical/parent device Netlink interface
   3 *
   4 * Heavily inspired by net/wireless/
   5 * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
   6 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; either version 2 of the License, or
  11 * (at your option) any later version.
  12 */
  13
  14#include <linux/kernel.h>
  15#include <linux/module.h>
  16#include <linux/types.h>
  17#include <linux/slab.h>
  18#include <linux/gfp.h>
  19#include <linux/device.h>
  20#include <linux/list.h>
  21#include <linux/netdevice.h>
  22#include <rdma/ib_verbs.h>
  23#include <net/netlink.h>
  24#include <net/genetlink.h>
  25#include <net/rtnetlink.h>
  26#include <net/net_namespace.h>
  27#include <net/sock.h>
  28#include <net/devlink.h>
  29#define CREATE_TRACE_POINTS
  30#include <trace/events/devlink.h>
  31
  32static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = {
  33        {
  34                .name = "destination mac",
  35                .id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
  36                .bitwidth = 48,
  37        },
  38};
  39
  40struct devlink_dpipe_header devlink_dpipe_header_ethernet = {
  41        .name = "ethernet",
  42        .id = DEVLINK_DPIPE_HEADER_ETHERNET,
  43        .fields = devlink_dpipe_fields_ethernet,
  44        .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet),
  45        .global = true,
  46};
  47EXPORT_SYMBOL(devlink_dpipe_header_ethernet);
  48
  49static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = {
  50        {
  51                .name = "destination ip",
  52                .id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP,
  53                .bitwidth = 32,
  54        },
  55};
  56
  57struct devlink_dpipe_header devlink_dpipe_header_ipv4 = {
  58        .name = "ipv4",
  59        .id = DEVLINK_DPIPE_HEADER_IPV4,
  60        .fields = devlink_dpipe_fields_ipv4,
  61        .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4),
  62        .global = true,
  63};
  64EXPORT_SYMBOL(devlink_dpipe_header_ipv4);
  65
  66static struct devlink_dpipe_field devlink_dpipe_fields_ipv6[] = {
  67        {
  68                .name = "destination ip",
  69                .id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP,
  70                .bitwidth = 128,
  71        },
  72};
  73
  74struct devlink_dpipe_header devlink_dpipe_header_ipv6 = {
  75        .name = "ipv6",
  76        .id = DEVLINK_DPIPE_HEADER_IPV6,
  77        .fields = devlink_dpipe_fields_ipv6,
  78        .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv6),
  79        .global = true,
  80};
  81EXPORT_SYMBOL(devlink_dpipe_header_ipv6);
  82
  83EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg);
  84
  85static LIST_HEAD(devlink_list);
  86
  87/* devlink_mutex
  88 *
  89 * An overall lock guarding every operation coming from userspace.
  90 * It also guards devlink devices list and it is taken when
  91 * driver registers/unregisters it.
  92 */
  93static DEFINE_MUTEX(devlink_mutex);
  94
  95/* devlink_port_mutex
  96 *
  97 * Shared lock to guard lists of ports in all devlink devices.
  98 */
  99static DEFINE_MUTEX(devlink_port_mutex);
 100
 101static struct net *devlink_net(const struct devlink *devlink)
 102{
 103        return read_pnet(&devlink->_net);
 104}
 105
 106static void devlink_net_set(struct devlink *devlink, struct net *net)
 107{
 108        write_pnet(&devlink->_net, net);
 109}
 110
 111static struct devlink *devlink_get_from_attrs(struct net *net,
 112                                              struct nlattr **attrs)
 113{
 114        struct devlink *devlink;
 115        char *busname;
 116        char *devname;
 117
 118        if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME])
 119                return ERR_PTR(-EINVAL);
 120
 121        busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]);
 122        devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
 123
 124        list_for_each_entry(devlink, &devlink_list, list) {
 125                if (strcmp(devlink->dev->bus->name, busname) == 0 &&
 126                    strcmp(dev_name(devlink->dev), devname) == 0 &&
 127                    net_eq(devlink_net(devlink), net))
 128                        return devlink;
 129        }
 130
 131        return ERR_PTR(-ENODEV);
 132}
 133
 134static struct devlink *devlink_get_from_info(struct genl_info *info)
 135{
 136        return devlink_get_from_attrs(genl_info_net(info), info->attrs);
 137}
 138
 139static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
 140                                                      int port_index)
 141{
 142        struct devlink_port *devlink_port;
 143
 144        list_for_each_entry(devlink_port, &devlink->port_list, list) {
 145                if (devlink_port->index == port_index)
 146                        return devlink_port;
 147        }
 148        return NULL;
 149}
 150
 151static bool devlink_port_index_exists(struct devlink *devlink, int port_index)
 152{
 153        return devlink_port_get_by_index(devlink, port_index);
 154}
 155
 156static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
 157                                                        struct nlattr **attrs)
 158{
 159        if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
 160                u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
 161                struct devlink_port *devlink_port;
 162
 163                devlink_port = devlink_port_get_by_index(devlink, port_index);
 164                if (!devlink_port)
 165                        return ERR_PTR(-ENODEV);
 166                return devlink_port;
 167        }
 168        return ERR_PTR(-EINVAL);
 169}
 170
 171static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
 172                                                       struct genl_info *info)
 173{
 174        return devlink_port_get_from_attrs(devlink, info->attrs);
 175}
 176
 177struct devlink_sb {
 178        struct list_head list;
 179        unsigned int index;
 180        u32 size;
 181        u16 ingress_pools_count;
 182        u16 egress_pools_count;
 183        u16 ingress_tc_count;
 184        u16 egress_tc_count;
 185};
 186
 187static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb)
 188{
 189        return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count;
 190}
 191
 192static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink,
 193                                                  unsigned int sb_index)
 194{
 195        struct devlink_sb *devlink_sb;
 196
 197        list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
 198                if (devlink_sb->index == sb_index)
 199                        return devlink_sb;
 200        }
 201        return NULL;
 202}
 203
 204static bool devlink_sb_index_exists(struct devlink *devlink,
 205                                    unsigned int sb_index)
 206{
 207        return devlink_sb_get_by_index(devlink, sb_index);
 208}
 209
 210static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink,
 211                                                    struct nlattr **attrs)
 212{
 213        if (attrs[DEVLINK_ATTR_SB_INDEX]) {
 214                u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]);
 215                struct devlink_sb *devlink_sb;
 216
 217                devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
 218                if (!devlink_sb)
 219                        return ERR_PTR(-ENODEV);
 220                return devlink_sb;
 221        }
 222        return ERR_PTR(-EINVAL);
 223}
 224
 225static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink,
 226                                                   struct genl_info *info)
 227{
 228        return devlink_sb_get_from_attrs(devlink, info->attrs);
 229}
 230
 231static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb,
 232                                                struct nlattr **attrs,
 233                                                u16 *p_pool_index)
 234{
 235        u16 val;
 236
 237        if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX])
 238                return -EINVAL;
 239
 240        val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]);
 241        if (val >= devlink_sb_pool_count(devlink_sb))
 242                return -EINVAL;
 243        *p_pool_index = val;
 244        return 0;
 245}
 246
 247static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb,
 248                                               struct genl_info *info,
 249                                               u16 *p_pool_index)
 250{
 251        return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs,
 252                                                    p_pool_index);
 253}
 254
 255static int
 256devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs,
 257                                    enum devlink_sb_pool_type *p_pool_type)
 258{
 259        u8 val;
 260
 261        if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE])
 262                return -EINVAL;
 263
 264        val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]);
 265        if (val != DEVLINK_SB_POOL_TYPE_INGRESS &&
 266            val != DEVLINK_SB_POOL_TYPE_EGRESS)
 267                return -EINVAL;
 268        *p_pool_type = val;
 269        return 0;
 270}
 271
 272static int
 273devlink_sb_pool_type_get_from_info(struct genl_info *info,
 274                                   enum devlink_sb_pool_type *p_pool_type)
 275{
 276        return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type);
 277}
 278
 279static int
 280devlink_sb_th_type_get_from_attrs(struct nlattr **attrs,
 281                                  enum devlink_sb_threshold_type *p_th_type)
 282{
 283        u8 val;
 284
 285        if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])
 286                return -EINVAL;
 287
 288        val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]);
 289        if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC &&
 290            val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC)
 291                return -EINVAL;
 292        *p_th_type = val;
 293        return 0;
 294}
 295
 296static int
 297devlink_sb_th_type_get_from_info(struct genl_info *info,
 298                                 enum devlink_sb_threshold_type *p_th_type)
 299{
 300        return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type);
 301}
 302
 303static int
 304devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb,
 305                                   struct nlattr **attrs,
 306                                   enum devlink_sb_pool_type pool_type,
 307                                   u16 *p_tc_index)
 308{
 309        u16 val;
 310
 311        if (!attrs[DEVLINK_ATTR_SB_TC_INDEX])
 312                return -EINVAL;
 313
 314        val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]);
 315        if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS &&
 316            val >= devlink_sb->ingress_tc_count)
 317                return -EINVAL;
 318        if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS &&
 319            val >= devlink_sb->egress_tc_count)
 320                return -EINVAL;
 321        *p_tc_index = val;
 322        return 0;
 323}
 324
 325static int
 326devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
 327                                  struct genl_info *info,
 328                                  enum devlink_sb_pool_type pool_type,
 329                                  u16 *p_tc_index)
 330{
 331        return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs,
 332                                                  pool_type, p_tc_index);
 333}
 334
 335#define DEVLINK_NL_FLAG_NEED_DEVLINK    BIT(0)
 336#define DEVLINK_NL_FLAG_NEED_PORT       BIT(1)
 337#define DEVLINK_NL_FLAG_NEED_SB         BIT(2)
 338#define DEVLINK_NL_FLAG_LOCK_PORTS      BIT(3)
 339        /* port is not needed but we need to ensure they don't
 340         * change in the middle of command
 341         */
 342
 343static int devlink_nl_pre_doit(const struct genl_ops *ops,
 344                               struct sk_buff *skb, struct genl_info *info)
 345{
 346        struct devlink *devlink;
 347
 348        mutex_lock(&devlink_mutex);
 349        devlink = devlink_get_from_info(info);
 350        if (IS_ERR(devlink)) {
 351                mutex_unlock(&devlink_mutex);
 352                return PTR_ERR(devlink);
 353        }
 354        if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK) {
 355                info->user_ptr[0] = devlink;
 356        } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) {
 357                struct devlink_port *devlink_port;
 358
 359                mutex_lock(&devlink_port_mutex);
 360                devlink_port = devlink_port_get_from_info(devlink, info);
 361                if (IS_ERR(devlink_port)) {
 362                        mutex_unlock(&devlink_port_mutex);
 363                        mutex_unlock(&devlink_mutex);
 364                        return PTR_ERR(devlink_port);
 365                }
 366                info->user_ptr[0] = devlink_port;
 367        }
 368        if (ops->internal_flags & DEVLINK_NL_FLAG_LOCK_PORTS) {
 369                mutex_lock(&devlink_port_mutex);
 370        }
 371        if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_SB) {
 372                struct devlink_sb *devlink_sb;
 373
 374                devlink_sb = devlink_sb_get_from_info(devlink, info);
 375                if (IS_ERR(devlink_sb)) {
 376                        if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT)
 377                                mutex_unlock(&devlink_port_mutex);
 378                        mutex_unlock(&devlink_mutex);
 379                        return PTR_ERR(devlink_sb);
 380                }
 381                info->user_ptr[1] = devlink_sb;
 382        }
 383        return 0;
 384}
 385
 386static void devlink_nl_post_doit(const struct genl_ops *ops,
 387                                 struct sk_buff *skb, struct genl_info *info)
 388{
 389        if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT ||
 390            ops->internal_flags & DEVLINK_NL_FLAG_LOCK_PORTS)
 391                mutex_unlock(&devlink_port_mutex);
 392        mutex_unlock(&devlink_mutex);
 393}
 394
 395static struct genl_family devlink_nl_family;
 396
 397enum devlink_multicast_groups {
 398        DEVLINK_MCGRP_CONFIG,
 399};
 400
 401static const struct genl_multicast_group devlink_nl_mcgrps[] = {
 402        [DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME },
 403};
 404
 405static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
 406{
 407        if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name))
 408                return -EMSGSIZE;
 409        if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev)))
 410                return -EMSGSIZE;
 411        return 0;
 412}
 413
 414static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
 415                           enum devlink_command cmd, u32 portid,
 416                           u32 seq, int flags)
 417{
 418        void *hdr;
 419
 420        hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 421        if (!hdr)
 422                return -EMSGSIZE;
 423
 424        if (devlink_nl_put_handle(msg, devlink))
 425                goto nla_put_failure;
 426
 427        genlmsg_end(msg, hdr);
 428        return 0;
 429
 430nla_put_failure:
 431        genlmsg_cancel(msg, hdr);
 432        return -EMSGSIZE;
 433}
 434
 435static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
 436{
 437        struct sk_buff *msg;
 438        int err;
 439
 440        WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
 441
 442        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 443        if (!msg)
 444                return;
 445
 446        err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0);
 447        if (err) {
 448                nlmsg_free(msg);
 449                return;
 450        }
 451
 452        genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
 453                                msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
 454}
 455
 456static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
 457                                struct devlink_port *devlink_port,
 458                                enum devlink_command cmd, u32 portid,
 459                                u32 seq, int flags)
 460{
 461        void *hdr;
 462
 463        hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 464        if (!hdr)
 465                return -EMSGSIZE;
 466
 467        if (devlink_nl_put_handle(msg, devlink))
 468                goto nla_put_failure;
 469        if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
 470                goto nla_put_failure;
 471        if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
 472                goto nla_put_failure;
 473        if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
 474            nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
 475                        devlink_port->desired_type))
 476                goto nla_put_failure;
 477        if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
 478                struct net_device *netdev = devlink_port->type_dev;
 479
 480                if (netdev &&
 481                    (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
 482                                 netdev->ifindex) ||
 483                     nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
 484                                    netdev->name)))
 485                        goto nla_put_failure;
 486        }
 487        if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
 488                struct ib_device *ibdev = devlink_port->type_dev;
 489
 490                if (ibdev &&
 491                    nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
 492                                   ibdev->name))
 493                        goto nla_put_failure;
 494        }
 495        if (devlink_port->split &&
 496            nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
 497                        devlink_port->split_group))
 498                goto nla_put_failure;
 499
 500        genlmsg_end(msg, hdr);
 501        return 0;
 502
 503nla_put_failure:
 504        genlmsg_cancel(msg, hdr);
 505        return -EMSGSIZE;
 506}
 507
 508static void devlink_port_notify(struct devlink_port *devlink_port,
 509                                enum devlink_command cmd)
 510{
 511        struct devlink *devlink = devlink_port->devlink;
 512        struct sk_buff *msg;
 513        int err;
 514
 515        if (!devlink_port->registered)
 516                return;
 517
 518        WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
 519
 520        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 521        if (!msg)
 522                return;
 523
 524        err = devlink_nl_port_fill(msg, devlink, devlink_port, cmd, 0, 0, 0);
 525        if (err) {
 526                nlmsg_free(msg);
 527                return;
 528        }
 529
 530        genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
 531                                msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
 532}
 533
 534static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
 535{
 536        struct devlink *devlink = info->user_ptr[0];
 537        struct sk_buff *msg;
 538        int err;
 539
 540        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 541        if (!msg)
 542                return -ENOMEM;
 543
 544        err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
 545                              info->snd_portid, info->snd_seq, 0);
 546        if (err) {
 547                nlmsg_free(msg);
 548                return err;
 549        }
 550
 551        return genlmsg_reply(msg, info);
 552}
 553
 554static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
 555                                     struct netlink_callback *cb)
 556{
 557        struct devlink *devlink;
 558        int start = cb->args[0];
 559        int idx = 0;
 560        int err;
 561
 562        mutex_lock(&devlink_mutex);
 563        list_for_each_entry(devlink, &devlink_list, list) {
 564                if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
 565                        continue;
 566                if (idx < start) {
 567                        idx++;
 568                        continue;
 569                }
 570                err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
 571                                      NETLINK_CB(cb->skb).portid,
 572                                      cb->nlh->nlmsg_seq, NLM_F_MULTI);
 573                if (err)
 574                        goto out;
 575                idx++;
 576        }
 577out:
 578        mutex_unlock(&devlink_mutex);
 579
 580        cb->args[0] = idx;
 581        return msg->len;
 582}
 583
 584static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
 585                                        struct genl_info *info)
 586{
 587        struct devlink_port *devlink_port = info->user_ptr[0];
 588        struct devlink *devlink = devlink_port->devlink;
 589        struct sk_buff *msg;
 590        int err;
 591
 592        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 593        if (!msg)
 594                return -ENOMEM;
 595
 596        err = devlink_nl_port_fill(msg, devlink, devlink_port,
 597                                   DEVLINK_CMD_PORT_NEW,
 598                                   info->snd_portid, info->snd_seq, 0);
 599        if (err) {
 600                nlmsg_free(msg);
 601                return err;
 602        }
 603
 604        return genlmsg_reply(msg, info);
 605}
 606
 607static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
 608                                          struct netlink_callback *cb)
 609{
 610        struct devlink *devlink;
 611        struct devlink_port *devlink_port;
 612        int start = cb->args[0];
 613        int idx = 0;
 614        int err;
 615
 616        mutex_lock(&devlink_mutex);
 617        mutex_lock(&devlink_port_mutex);
 618        list_for_each_entry(devlink, &devlink_list, list) {
 619                if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
 620                        continue;
 621                list_for_each_entry(devlink_port, &devlink->port_list, list) {
 622                        if (idx < start) {
 623                                idx++;
 624                                continue;
 625                        }
 626                        err = devlink_nl_port_fill(msg, devlink, devlink_port,
 627                                                   DEVLINK_CMD_NEW,
 628                                                   NETLINK_CB(cb->skb).portid,
 629                                                   cb->nlh->nlmsg_seq,
 630                                                   NLM_F_MULTI);
 631                        if (err)
 632                                goto out;
 633                        idx++;
 634                }
 635        }
 636out:
 637        mutex_unlock(&devlink_port_mutex);
 638        mutex_unlock(&devlink_mutex);
 639
 640        cb->args[0] = idx;
 641        return msg->len;
 642}
 643
 644static int devlink_port_type_set(struct devlink *devlink,
 645                                 struct devlink_port *devlink_port,
 646                                 enum devlink_port_type port_type)
 647
 648{
 649        int err;
 650
 651        if (devlink->ops && devlink->ops->port_type_set) {
 652                if (port_type == DEVLINK_PORT_TYPE_NOTSET)
 653                        return -EINVAL;
 654                if (port_type == devlink_port->type)
 655                        return 0;
 656                err = devlink->ops->port_type_set(devlink_port, port_type);
 657                if (err)
 658                        return err;
 659                devlink_port->desired_type = port_type;
 660                devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
 661                return 0;
 662        }
 663        return -EOPNOTSUPP;
 664}
 665
 666static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
 667                                        struct genl_info *info)
 668{
 669        struct devlink_port *devlink_port = info->user_ptr[0];
 670        struct devlink *devlink = devlink_port->devlink;
 671        int err;
 672
 673        if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
 674                enum devlink_port_type port_type;
 675
 676                port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
 677                err = devlink_port_type_set(devlink, devlink_port, port_type);
 678                if (err)
 679                        return err;
 680        }
 681        return 0;
 682}
 683
 684static int devlink_port_split(struct devlink *devlink,
 685                              u32 port_index, u32 count)
 686
 687{
 688        if (devlink->ops && devlink->ops->port_split)
 689                return devlink->ops->port_split(devlink, port_index, count);
 690        return -EOPNOTSUPP;
 691}
 692
 693static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
 694                                          struct genl_info *info)
 695{
 696        struct devlink *devlink = info->user_ptr[0];
 697        u32 port_index;
 698        u32 count;
 699
 700        if (!info->attrs[DEVLINK_ATTR_PORT_INDEX] ||
 701            !info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT])
 702                return -EINVAL;
 703
 704        port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
 705        count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
 706        return devlink_port_split(devlink, port_index, count);
 707}
 708
 709static int devlink_port_unsplit(struct devlink *devlink, u32 port_index)
 710
 711{
 712        if (devlink->ops && devlink->ops->port_unsplit)
 713                return devlink->ops->port_unsplit(devlink, port_index);
 714        return -EOPNOTSUPP;
 715}
 716
 717static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
 718                                            struct genl_info *info)
 719{
 720        struct devlink *devlink = info->user_ptr[0];
 721        u32 port_index;
 722
 723        if (!info->attrs[DEVLINK_ATTR_PORT_INDEX])
 724                return -EINVAL;
 725
 726        port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
 727        return devlink_port_unsplit(devlink, port_index);
 728}
 729
 730static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
 731                              struct devlink_sb *devlink_sb,
 732                              enum devlink_command cmd, u32 portid,
 733                              u32 seq, int flags)
 734{
 735        void *hdr;
 736
 737        hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 738        if (!hdr)
 739                return -EMSGSIZE;
 740
 741        if (devlink_nl_put_handle(msg, devlink))
 742                goto nla_put_failure;
 743        if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
 744                goto nla_put_failure;
 745        if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size))
 746                goto nla_put_failure;
 747        if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT,
 748                        devlink_sb->ingress_pools_count))
 749                goto nla_put_failure;
 750        if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT,
 751                        devlink_sb->egress_pools_count))
 752                goto nla_put_failure;
 753        if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT,
 754                        devlink_sb->ingress_tc_count))
 755                goto nla_put_failure;
 756        if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT,
 757                        devlink_sb->egress_tc_count))
 758                goto nla_put_failure;
 759
 760        genlmsg_end(msg, hdr);
 761        return 0;
 762
 763nla_put_failure:
 764        genlmsg_cancel(msg, hdr);
 765        return -EMSGSIZE;
 766}
 767
 768static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb,
 769                                      struct genl_info *info)
 770{
 771        struct devlink *devlink = info->user_ptr[0];
 772        struct devlink_sb *devlink_sb = info->user_ptr[1];
 773        struct sk_buff *msg;
 774        int err;
 775
 776        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 777        if (!msg)
 778                return -ENOMEM;
 779
 780        err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
 781                                 DEVLINK_CMD_SB_NEW,
 782                                 info->snd_portid, info->snd_seq, 0);
 783        if (err) {
 784                nlmsg_free(msg);
 785                return err;
 786        }
 787
 788        return genlmsg_reply(msg, info);
 789}
 790
 791static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg,
 792                                        struct netlink_callback *cb)
 793{
 794        struct devlink *devlink;
 795        struct devlink_sb *devlink_sb;
 796        int start = cb->args[0];
 797        int idx = 0;
 798        int err;
 799
 800        mutex_lock(&devlink_mutex);
 801        list_for_each_entry(devlink, &devlink_list, list) {
 802                if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
 803                        continue;
 804                list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
 805                        if (idx < start) {
 806                                idx++;
 807                                continue;
 808                        }
 809                        err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
 810                                                 DEVLINK_CMD_SB_NEW,
 811                                                 NETLINK_CB(cb->skb).portid,
 812                                                 cb->nlh->nlmsg_seq,
 813                                                 NLM_F_MULTI);
 814                        if (err)
 815                                goto out;
 816                        idx++;
 817                }
 818        }
 819out:
 820        mutex_unlock(&devlink_mutex);
 821
 822        cb->args[0] = idx;
 823        return msg->len;
 824}
 825
 826static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink,
 827                                   struct devlink_sb *devlink_sb,
 828                                   u16 pool_index, enum devlink_command cmd,
 829                                   u32 portid, u32 seq, int flags)
 830{
 831        struct devlink_sb_pool_info pool_info;
 832        void *hdr;
 833        int err;
 834
 835        err = devlink->ops->sb_pool_get(devlink, devlink_sb->index,
 836                                        pool_index, &pool_info);
 837        if (err)
 838                return err;
 839
 840        hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 841        if (!hdr)
 842                return -EMSGSIZE;
 843
 844        if (devlink_nl_put_handle(msg, devlink))
 845                goto nla_put_failure;
 846        if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
 847                goto nla_put_failure;
 848        if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
 849                goto nla_put_failure;
 850        if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type))
 851                goto nla_put_failure;
 852        if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size))
 853                goto nla_put_failure;
 854        if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE,
 855                       pool_info.threshold_type))
 856                goto nla_put_failure;
 857
 858        genlmsg_end(msg, hdr);
 859        return 0;
 860
 861nla_put_failure:
 862        genlmsg_cancel(msg, hdr);
 863        return -EMSGSIZE;
 864}
 865
 866static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb,
 867                                           struct genl_info *info)
 868{
 869        struct devlink *devlink = info->user_ptr[0];
 870        struct devlink_sb *devlink_sb = info->user_ptr[1];
 871        struct sk_buff *msg;
 872        u16 pool_index;
 873        int err;
 874
 875        err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
 876                                                  &pool_index);
 877        if (err)
 878                return err;
 879
 880        if (!devlink->ops || !devlink->ops->sb_pool_get)
 881                return -EOPNOTSUPP;
 882
 883        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 884        if (!msg)
 885                return -ENOMEM;
 886
 887        err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index,
 888                                      DEVLINK_CMD_SB_POOL_NEW,
 889                                      info->snd_portid, info->snd_seq, 0);
 890        if (err) {
 891                nlmsg_free(msg);
 892                return err;
 893        }
 894
 895        return genlmsg_reply(msg, info);
 896}
 897
 898static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
 899                                struct devlink *devlink,
 900                                struct devlink_sb *devlink_sb,
 901                                u32 portid, u32 seq)
 902{
 903        u16 pool_count = devlink_sb_pool_count(devlink_sb);
 904        u16 pool_index;
 905        int err;
 906
 907        for (pool_index = 0; pool_index < pool_count; pool_index++) {
 908                if (*p_idx < start) {
 909                        (*p_idx)++;
 910                        continue;
 911                }
 912                err = devlink_nl_sb_pool_fill(msg, devlink,
 913                                              devlink_sb,
 914                                              pool_index,
 915                                              DEVLINK_CMD_SB_POOL_NEW,
 916                                              portid, seq, NLM_F_MULTI);
 917                if (err)
 918                        return err;
 919                (*p_idx)++;
 920        }
 921        return 0;
 922}
 923
 924static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg,
 925                                             struct netlink_callback *cb)
 926{
 927        struct devlink *devlink;
 928        struct devlink_sb *devlink_sb;
 929        int start = cb->args[0];
 930        int idx = 0;
 931        int err;
 932
 933        mutex_lock(&devlink_mutex);
 934        list_for_each_entry(devlink, &devlink_list, list) {
 935                if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
 936                    !devlink->ops || !devlink->ops->sb_pool_get)
 937                        continue;
 938                list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
 939                        err = __sb_pool_get_dumpit(msg, start, &idx, devlink,
 940                                                   devlink_sb,
 941                                                   NETLINK_CB(cb->skb).portid,
 942                                                   cb->nlh->nlmsg_seq);
 943                        if (err && err != -EOPNOTSUPP)
 944                                goto out;
 945                }
 946        }
 947out:
 948        mutex_unlock(&devlink_mutex);
 949
 950        cb->args[0] = idx;
 951        return msg->len;
 952}
 953
 954static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
 955                               u16 pool_index, u32 size,
 956                               enum devlink_sb_threshold_type threshold_type)
 957
 958{
 959        const struct devlink_ops *ops = devlink->ops;
 960
 961        if (ops && ops->sb_pool_set)
 962                return ops->sb_pool_set(devlink, sb_index, pool_index,
 963                                        size, threshold_type);
 964        return -EOPNOTSUPP;
 965}
 966
 967static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb,
 968                                           struct genl_info *info)
 969{
 970        struct devlink *devlink = info->user_ptr[0];
 971        struct devlink_sb *devlink_sb = info->user_ptr[1];
 972        enum devlink_sb_threshold_type threshold_type;
 973        u16 pool_index;
 974        u32 size;
 975        int err;
 976
 977        err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
 978                                                  &pool_index);
 979        if (err)
 980                return err;
 981
 982        err = devlink_sb_th_type_get_from_info(info, &threshold_type);
 983        if (err)
 984                return err;
 985
 986        if (!info->attrs[DEVLINK_ATTR_SB_POOL_SIZE])
 987                return -EINVAL;
 988
 989        size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]);
 990        return devlink_sb_pool_set(devlink, devlink_sb->index,
 991                                   pool_index, size, threshold_type);
 992}
 993
 994static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg,
 995                                        struct devlink *devlink,
 996                                        struct devlink_port *devlink_port,
 997                                        struct devlink_sb *devlink_sb,
 998                                        u16 pool_index,
 999                                        enum devlink_command cmd,
1000                                        u32 portid, u32 seq, int flags)
1001{
1002        const struct devlink_ops *ops = devlink->ops;
1003        u32 threshold;
1004        void *hdr;
1005        int err;
1006
1007        err = ops->sb_port_pool_get(devlink_port, devlink_sb->index,
1008                                    pool_index, &threshold);
1009        if (err)
1010                return err;
1011
1012        hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1013        if (!hdr)
1014                return -EMSGSIZE;
1015
1016        if (devlink_nl_put_handle(msg, devlink))
1017                goto nla_put_failure;
1018        if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1019                goto nla_put_failure;
1020        if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1021                goto nla_put_failure;
1022        if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
1023                goto nla_put_failure;
1024        if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
1025                goto nla_put_failure;
1026
1027        if (ops->sb_occ_port_pool_get) {
1028                u32 cur;
1029                u32 max;
1030
1031                err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index,
1032                                                pool_index, &cur, &max);
1033                if (err && err != -EOPNOTSUPP)
1034                        return err;
1035                if (!err) {
1036                        if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
1037                                goto nla_put_failure;
1038                        if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
1039                                goto nla_put_failure;
1040                }
1041        }
1042
1043        genlmsg_end(msg, hdr);
1044        return 0;
1045
1046nla_put_failure:
1047        genlmsg_cancel(msg, hdr);
1048        return -EMSGSIZE;
1049}
1050
1051static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,
1052                                                struct genl_info *info)
1053{
1054        struct devlink_port *devlink_port = info->user_ptr[0];
1055        struct devlink *devlink = devlink_port->devlink;
1056        struct devlink_sb *devlink_sb = info->user_ptr[1];
1057        struct sk_buff *msg;
1058        u16 pool_index;
1059        int err;
1060
1061        err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1062                                                  &pool_index);
1063        if (err)
1064                return err;
1065
1066        if (!devlink->ops || !devlink->ops->sb_port_pool_get)
1067                return -EOPNOTSUPP;
1068
1069        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1070        if (!msg)
1071                return -ENOMEM;
1072
1073        err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port,
1074                                           devlink_sb, pool_index,
1075                                           DEVLINK_CMD_SB_PORT_POOL_NEW,
1076                                           info->snd_portid, info->snd_seq, 0);
1077        if (err) {
1078                nlmsg_free(msg);
1079                return err;
1080        }
1081
1082        return genlmsg_reply(msg, info);
1083}
1084
1085static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
1086                                     struct devlink *devlink,
1087                                     struct devlink_sb *devlink_sb,
1088                                     u32 portid, u32 seq)
1089{
1090        struct devlink_port *devlink_port;
1091        u16 pool_count = devlink_sb_pool_count(devlink_sb);
1092        u16 pool_index;
1093        int err;
1094
1095        list_for_each_entry(devlink_port, &devlink->port_list, list) {
1096                for (pool_index = 0; pool_index < pool_count; pool_index++) {
1097                        if (*p_idx < start) {
1098                                (*p_idx)++;
1099                                continue;
1100                        }
1101                        err = devlink_nl_sb_port_pool_fill(msg, devlink,
1102                                                           devlink_port,
1103                                                           devlink_sb,
1104                                                           pool_index,
1105                                                           DEVLINK_CMD_SB_PORT_POOL_NEW,
1106                                                           portid, seq,
1107                                                           NLM_F_MULTI);
1108                        if (err)
1109                                return err;
1110                        (*p_idx)++;
1111                }
1112        }
1113        return 0;
1114}
1115
1116static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg,
1117                                                  struct netlink_callback *cb)
1118{
1119        struct devlink *devlink;
1120        struct devlink_sb *devlink_sb;
1121        int start = cb->args[0];
1122        int idx = 0;
1123        int err;
1124
1125        mutex_lock(&devlink_mutex);
1126        mutex_lock(&devlink_port_mutex);
1127        list_for_each_entry(devlink, &devlink_list, list) {
1128                if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1129                    !devlink->ops || !devlink->ops->sb_port_pool_get)
1130                        continue;
1131                list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1132                        err = __sb_port_pool_get_dumpit(msg, start, &idx,
1133                                                        devlink, devlink_sb,
1134                                                        NETLINK_CB(cb->skb).portid,
1135                                                        cb->nlh->nlmsg_seq);
1136                        if (err && err != -EOPNOTSUPP)
1137                                goto out;
1138                }
1139        }
1140out:
1141        mutex_unlock(&devlink_port_mutex);
1142        mutex_unlock(&devlink_mutex);
1143
1144        cb->args[0] = idx;
1145        return msg->len;
1146}
1147
1148static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
1149                                    unsigned int sb_index, u16 pool_index,
1150                                    u32 threshold)
1151
1152{
1153        const struct devlink_ops *ops = devlink_port->devlink->ops;
1154
1155        if (ops && ops->sb_port_pool_set)
1156                return ops->sb_port_pool_set(devlink_port, sb_index,
1157                                             pool_index, threshold);
1158        return -EOPNOTSUPP;
1159}
1160
1161static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb,
1162                                                struct genl_info *info)
1163{
1164        struct devlink_port *devlink_port = info->user_ptr[0];
1165        struct devlink_sb *devlink_sb = info->user_ptr[1];
1166        u16 pool_index;
1167        u32 threshold;
1168        int err;
1169
1170        err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1171                                                  &pool_index);
1172        if (err)
1173                return err;
1174
1175        if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1176                return -EINVAL;
1177
1178        threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1179        return devlink_sb_port_pool_set(devlink_port, devlink_sb->index,
1180                                        pool_index, threshold);
1181}
1182
1183static int
1184devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink,
1185                                struct devlink_port *devlink_port,
1186                                struct devlink_sb *devlink_sb, u16 tc_index,
1187                                enum devlink_sb_pool_type pool_type,
1188                                enum devlink_command cmd,
1189                                u32 portid, u32 seq, int flags)
1190{
1191        const struct devlink_ops *ops = devlink->ops;
1192        u16 pool_index;
1193        u32 threshold;
1194        void *hdr;
1195        int err;
1196
1197        err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index,
1198                                       tc_index, pool_type,
1199                                       &pool_index, &threshold);
1200        if (err)
1201                return err;
1202
1203        hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1204        if (!hdr)
1205                return -EMSGSIZE;
1206
1207        if (devlink_nl_put_handle(msg, devlink))
1208                goto nla_put_failure;
1209        if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1210                goto nla_put_failure;
1211        if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1212                goto nla_put_failure;
1213        if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index))
1214                goto nla_put_failure;
1215        if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type))
1216                goto nla_put_failure;
1217        if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
1218                goto nla_put_failure;
1219        if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
1220                goto nla_put_failure;
1221
1222        if (ops->sb_occ_tc_port_bind_get) {
1223                u32 cur;
1224                u32 max;
1225
1226                err = ops->sb_occ_tc_port_bind_get(devlink_port,
1227                                                   devlink_sb->index,
1228                                                   tc_index, pool_type,
1229                                                   &cur, &max);
1230                if (err && err != -EOPNOTSUPP)
1231                        return err;
1232                if (!err) {
1233                        if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
1234                                goto nla_put_failure;
1235                        if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
1236                                goto nla_put_failure;
1237                }
1238        }
1239
1240        genlmsg_end(msg, hdr);
1241        return 0;
1242
1243nla_put_failure:
1244        genlmsg_cancel(msg, hdr);
1245        return -EMSGSIZE;
1246}
1247
1248static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,
1249                                                   struct genl_info *info)
1250{
1251        struct devlink_port *devlink_port = info->user_ptr[0];
1252        struct devlink *devlink = devlink_port->devlink;
1253        struct devlink_sb *devlink_sb = info->user_ptr[1];
1254        struct sk_buff *msg;
1255        enum devlink_sb_pool_type pool_type;
1256        u16 tc_index;
1257        int err;
1258
1259        err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1260        if (err)
1261                return err;
1262
1263        err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1264                                                pool_type, &tc_index);
1265        if (err)
1266                return err;
1267
1268        if (!devlink->ops || !devlink->ops->sb_tc_pool_bind_get)
1269                return -EOPNOTSUPP;
1270
1271        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1272        if (!msg)
1273                return -ENOMEM;
1274
1275        err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port,
1276                                              devlink_sb, tc_index, pool_type,
1277                                              DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1278                                              info->snd_portid,
1279                                              info->snd_seq, 0);
1280        if (err) {
1281                nlmsg_free(msg);
1282                return err;
1283        }
1284
1285        return genlmsg_reply(msg, info);
1286}
1287
1288static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1289                                        int start, int *p_idx,
1290                                        struct devlink *devlink,
1291                                        struct devlink_sb *devlink_sb,
1292                                        u32 portid, u32 seq)
1293{
1294        struct devlink_port *devlink_port;
1295        u16 tc_index;
1296        int err;
1297
1298        list_for_each_entry(devlink_port, &devlink->port_list, list) {
1299                for (tc_index = 0;
1300                     tc_index < devlink_sb->ingress_tc_count; tc_index++) {
1301                        if (*p_idx < start) {
1302                                (*p_idx)++;
1303                                continue;
1304                        }
1305                        err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1306                                                              devlink_port,
1307                                                              devlink_sb,
1308                                                              tc_index,
1309                                                              DEVLINK_SB_POOL_TYPE_INGRESS,
1310                                                              DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1311                                                              portid, seq,
1312                                                              NLM_F_MULTI);
1313                        if (err)
1314                                return err;
1315                        (*p_idx)++;
1316                }
1317                for (tc_index = 0;
1318                     tc_index < devlink_sb->egress_tc_count; tc_index++) {
1319                        if (*p_idx < start) {
1320                                (*p_idx)++;
1321                                continue;
1322                        }
1323                        err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1324                                                              devlink_port,
1325                                                              devlink_sb,
1326                                                              tc_index,
1327                                                              DEVLINK_SB_POOL_TYPE_EGRESS,
1328                                                              DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1329                                                              portid, seq,
1330                                                              NLM_F_MULTI);
1331                        if (err)
1332                                return err;
1333                        (*p_idx)++;
1334                }
1335        }
1336        return 0;
1337}
1338
1339static int
1340devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1341                                          struct netlink_callback *cb)
1342{
1343        struct devlink *devlink;
1344        struct devlink_sb *devlink_sb;
1345        int start = cb->args[0];
1346        int idx = 0;
1347        int err;
1348
1349        mutex_lock(&devlink_mutex);
1350        mutex_lock(&devlink_port_mutex);
1351        list_for_each_entry(devlink, &devlink_list, list) {
1352                if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1353                    !devlink->ops || !devlink->ops->sb_tc_pool_bind_get)
1354                        continue;
1355                list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1356                        err = __sb_tc_pool_bind_get_dumpit(msg, start, &idx,
1357                                                           devlink,
1358                                                           devlink_sb,
1359                                                           NETLINK_CB(cb->skb).portid,
1360                                                           cb->nlh->nlmsg_seq);
1361                        if (err && err != -EOPNOTSUPP)
1362                                goto out;
1363                }
1364        }
1365out:
1366        mutex_unlock(&devlink_port_mutex);
1367        mutex_unlock(&devlink_mutex);
1368
1369        cb->args[0] = idx;
1370        return msg->len;
1371}
1372
1373static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port,
1374                                       unsigned int sb_index, u16 tc_index,
1375                                       enum devlink_sb_pool_type pool_type,
1376                                       u16 pool_index, u32 threshold)
1377
1378{
1379        const struct devlink_ops *ops = devlink_port->devlink->ops;
1380
1381        if (ops && ops->sb_tc_pool_bind_set)
1382                return ops->sb_tc_pool_bind_set(devlink_port, sb_index,
1383                                                tc_index, pool_type,
1384                                                pool_index, threshold);
1385        return -EOPNOTSUPP;
1386}
1387
1388static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb,
1389                                                   struct genl_info *info)
1390{
1391        struct devlink_port *devlink_port = info->user_ptr[0];
1392        struct devlink_sb *devlink_sb = info->user_ptr[1];
1393        enum devlink_sb_pool_type pool_type;
1394        u16 tc_index;
1395        u16 pool_index;
1396        u32 threshold;
1397        int err;
1398
1399        err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1400        if (err)
1401                return err;
1402
1403        err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1404                                                pool_type, &tc_index);
1405        if (err)
1406                return err;
1407
1408        err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1409                                                  &pool_index);
1410        if (err)
1411                return err;
1412
1413        if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1414                return -EINVAL;
1415
1416        threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1417        return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index,
1418                                           tc_index, pool_type,
1419                                           pool_index, threshold);
1420}
1421
1422static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
1423                                               struct genl_info *info)
1424{
1425        struct devlink *devlink = info->user_ptr[0];
1426        struct devlink_sb *devlink_sb = info->user_ptr[1];
1427        const struct devlink_ops *ops = devlink->ops;
1428
1429        if (ops && ops->sb_occ_snapshot)
1430                return ops->sb_occ_snapshot(devlink, devlink_sb->index);
1431        return -EOPNOTSUPP;
1432}
1433
1434static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
1435                                                struct genl_info *info)
1436{
1437        struct devlink *devlink = info->user_ptr[0];
1438        struct devlink_sb *devlink_sb = info->user_ptr[1];
1439        const struct devlink_ops *ops = devlink->ops;
1440
1441        if (ops && ops->sb_occ_max_clear)
1442                return ops->sb_occ_max_clear(devlink, devlink_sb->index);
1443        return -EOPNOTSUPP;
1444}
1445
1446static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
1447                                   enum devlink_command cmd, u32 portid,
1448                                   u32 seq, int flags)
1449{
1450        const struct devlink_ops *ops = devlink->ops;
1451        u8 inline_mode, encap_mode;
1452        void *hdr;
1453        int err = 0;
1454        u16 mode;
1455
1456        hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1457        if (!hdr)
1458                return -EMSGSIZE;
1459
1460        err = devlink_nl_put_handle(msg, devlink);
1461        if (err)
1462                goto nla_put_failure;
1463
1464        if (ops->eswitch_mode_get) {
1465                err = ops->eswitch_mode_get(devlink, &mode);
1466                if (err)
1467                        goto nla_put_failure;
1468                err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode);
1469                if (err)
1470                        goto nla_put_failure;
1471        }
1472
1473        if (ops->eswitch_inline_mode_get) {
1474                err = ops->eswitch_inline_mode_get(devlink, &inline_mode);
1475                if (err)
1476                        goto nla_put_failure;
1477                err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE,
1478                                 inline_mode);
1479                if (err)
1480                        goto nla_put_failure;
1481        }
1482
1483        if (ops->eswitch_encap_mode_get) {
1484                err = ops->eswitch_encap_mode_get(devlink, &encap_mode);
1485                if (err)
1486                        goto nla_put_failure;
1487                err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode);
1488                if (err)
1489                        goto nla_put_failure;
1490        }
1491
1492        genlmsg_end(msg, hdr);
1493        return 0;
1494
1495nla_put_failure:
1496        genlmsg_cancel(msg, hdr);
1497        return err;
1498}
1499
1500static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb,
1501                                           struct genl_info *info)
1502{
1503        struct devlink *devlink = info->user_ptr[0];
1504        const struct devlink_ops *ops = devlink->ops;
1505        struct sk_buff *msg;
1506        int err;
1507
1508        if (!ops)
1509                return -EOPNOTSUPP;
1510
1511        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1512        if (!msg)
1513                return -ENOMEM;
1514
1515        err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET,
1516                                      info->snd_portid, info->snd_seq, 0);
1517
1518        if (err) {
1519                nlmsg_free(msg);
1520                return err;
1521        }
1522
1523        return genlmsg_reply(msg, info);
1524}
1525
1526static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb,
1527                                           struct genl_info *info)
1528{
1529        struct devlink *devlink = info->user_ptr[0];
1530        const struct devlink_ops *ops = devlink->ops;
1531        u8 inline_mode, encap_mode;
1532        int err = 0;
1533        u16 mode;
1534
1535        if (!ops)
1536                return -EOPNOTSUPP;
1537
1538        if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) {
1539                if (!ops->eswitch_mode_set)
1540                        return -EOPNOTSUPP;
1541                mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
1542                err = ops->eswitch_mode_set(devlink, mode);
1543                if (err)
1544                        return err;
1545        }
1546
1547        if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) {
1548                if (!ops->eswitch_inline_mode_set)
1549                        return -EOPNOTSUPP;
1550                inline_mode = nla_get_u8(
1551                                info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]);
1552                err = ops->eswitch_inline_mode_set(devlink, inline_mode);
1553                if (err)
1554                        return err;
1555        }
1556
1557        if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) {
1558                if (!ops->eswitch_encap_mode_set)
1559                        return -EOPNOTSUPP;
1560                encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]);
1561                err = ops->eswitch_encap_mode_set(devlink, encap_mode);
1562                if (err)
1563                        return err;
1564        }
1565
1566        return 0;
1567}
1568
1569int devlink_dpipe_match_put(struct sk_buff *skb,
1570                            struct devlink_dpipe_match *match)
1571{
1572        struct devlink_dpipe_header *header = match->header;
1573        struct devlink_dpipe_field *field = &header->fields[match->field_id];
1574        struct nlattr *match_attr;
1575
1576        match_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_MATCH);
1577        if (!match_attr)
1578                return -EMSGSIZE;
1579
1580        if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) ||
1581            nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) ||
1582            nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
1583            nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
1584            nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
1585                goto nla_put_failure;
1586
1587        nla_nest_end(skb, match_attr);
1588        return 0;
1589
1590nla_put_failure:
1591        nla_nest_cancel(skb, match_attr);
1592        return -EMSGSIZE;
1593}
1594EXPORT_SYMBOL_GPL(devlink_dpipe_match_put);
1595
1596static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table,
1597                                     struct sk_buff *skb)
1598{
1599        struct nlattr *matches_attr;
1600
1601        matches_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLE_MATCHES);
1602        if (!matches_attr)
1603                return -EMSGSIZE;
1604
1605        if (table->table_ops->matches_dump(table->priv, skb))
1606                goto nla_put_failure;
1607
1608        nla_nest_end(skb, matches_attr);
1609        return 0;
1610
1611nla_put_failure:
1612        nla_nest_cancel(skb, matches_attr);
1613        return -EMSGSIZE;
1614}
1615
1616int devlink_dpipe_action_put(struct sk_buff *skb,
1617                             struct devlink_dpipe_action *action)
1618{
1619        struct devlink_dpipe_header *header = action->header;
1620        struct devlink_dpipe_field *field = &header->fields[action->field_id];
1621        struct nlattr *action_attr;
1622
1623        action_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_ACTION);
1624        if (!action_attr)
1625                return -EMSGSIZE;
1626
1627        if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) ||
1628            nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) ||
1629            nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
1630            nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
1631            nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
1632                goto nla_put_failure;
1633
1634        nla_nest_end(skb, action_attr);
1635        return 0;
1636
1637nla_put_failure:
1638        nla_nest_cancel(skb, action_attr);
1639        return -EMSGSIZE;
1640}
1641EXPORT_SYMBOL_GPL(devlink_dpipe_action_put);
1642
1643static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table,
1644                                     struct sk_buff *skb)
1645{
1646        struct nlattr *actions_attr;
1647
1648        actions_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLE_ACTIONS);
1649        if (!actions_attr)
1650                return -EMSGSIZE;
1651
1652        if (table->table_ops->actions_dump(table->priv, skb))
1653                goto nla_put_failure;
1654
1655        nla_nest_end(skb, actions_attr);
1656        return 0;
1657
1658nla_put_failure:
1659        nla_nest_cancel(skb, actions_attr);
1660        return -EMSGSIZE;
1661}
1662
1663static int devlink_dpipe_table_put(struct sk_buff *skb,
1664                                   struct devlink_dpipe_table *table)
1665{
1666        struct nlattr *table_attr;
1667        u64 table_size;
1668
1669        table_size = table->table_ops->size_get(table->priv);
1670        table_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLE);
1671        if (!table_attr)
1672                return -EMSGSIZE;
1673
1674        if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) ||
1675            nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size,
1676                              DEVLINK_ATTR_PAD))
1677                goto nla_put_failure;
1678        if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
1679                       table->counters_enabled))
1680                goto nla_put_failure;
1681
1682        if (devlink_dpipe_matches_put(table, skb))
1683                goto nla_put_failure;
1684
1685        if (devlink_dpipe_actions_put(table, skb))
1686                goto nla_put_failure;
1687
1688        nla_nest_end(skb, table_attr);
1689        return 0;
1690
1691nla_put_failure:
1692        nla_nest_cancel(skb, table_attr);
1693        return -EMSGSIZE;
1694}
1695
1696static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb,
1697                                            struct genl_info *info)
1698{
1699        int err;
1700
1701        if (*pskb) {
1702                err = genlmsg_reply(*pskb, info);
1703                if (err)
1704                        return err;
1705        }
1706        *pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
1707        if (!*pskb)
1708                return -ENOMEM;
1709        return 0;
1710}
1711
1712static int devlink_dpipe_tables_fill(struct genl_info *info,
1713                                     enum devlink_command cmd, int flags,
1714                                     struct list_head *dpipe_tables,
1715                                     const char *table_name)
1716{
1717        struct devlink *devlink = info->user_ptr[0];
1718        struct devlink_dpipe_table *table;
1719        struct nlattr *tables_attr;
1720        struct sk_buff *skb = NULL;
1721        struct nlmsghdr *nlh;
1722        bool incomplete;
1723        void *hdr;
1724        int i;
1725        int err;
1726
1727        table = list_first_entry(dpipe_tables,
1728                                 struct devlink_dpipe_table, list);
1729start_again:
1730        err = devlink_dpipe_send_and_alloc_skb(&skb, info);
1731        if (err)
1732                return err;
1733
1734        hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
1735                          &devlink_nl_family, NLM_F_MULTI, cmd);
1736        if (!hdr) {
1737                nlmsg_free(skb);
1738                return -EMSGSIZE;
1739        }
1740
1741        if (devlink_nl_put_handle(skb, devlink))
1742                goto nla_put_failure;
1743        tables_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLES);
1744        if (!tables_attr)
1745                goto nla_put_failure;
1746
1747        i = 0;
1748        incomplete = false;
1749        list_for_each_entry_from(table, dpipe_tables, list) {
1750                if (!table_name) {
1751                        err = devlink_dpipe_table_put(skb, table);
1752                        if (err) {
1753                                if (!i)
1754                                        goto err_table_put;
1755                                incomplete = true;
1756                                break;
1757                        }
1758                } else {
1759                        if (!strcmp(table->name, table_name)) {
1760                                err = devlink_dpipe_table_put(skb, table);
1761                                if (err)
1762                                        break;
1763                        }
1764                }
1765                i++;
1766        }
1767
1768        nla_nest_end(skb, tables_attr);
1769        genlmsg_end(skb, hdr);
1770        if (incomplete)
1771                goto start_again;
1772
1773send_done:
1774        nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
1775                        NLMSG_DONE, 0, flags | NLM_F_MULTI);
1776        if (!nlh) {
1777                err = devlink_dpipe_send_and_alloc_skb(&skb, info);
1778                if (err)
1779                        goto err_skb_send_alloc;
1780                goto send_done;
1781        }
1782
1783        return genlmsg_reply(skb, info);
1784
1785nla_put_failure:
1786        err = -EMSGSIZE;
1787err_table_put:
1788err_skb_send_alloc:
1789        genlmsg_cancel(skb, hdr);
1790        nlmsg_free(skb);
1791        return err;
1792}
1793
1794static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb,
1795                                          struct genl_info *info)
1796{
1797        struct devlink *devlink = info->user_ptr[0];
1798        const char *table_name =  NULL;
1799
1800        if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
1801                table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
1802
1803        return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0,
1804                                         &devlink->dpipe_table_list,
1805                                         table_name);
1806}
1807
1808static int devlink_dpipe_value_put(struct sk_buff *skb,
1809                                   struct devlink_dpipe_value *value)
1810{
1811        if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE,
1812                    value->value_size, value->value))
1813                return -EMSGSIZE;
1814        if (value->mask)
1815                if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK,
1816                            value->value_size, value->mask))
1817                        return -EMSGSIZE;
1818        if (value->mapping_valid)
1819                if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING,
1820                                value->mapping_value))
1821                        return -EMSGSIZE;
1822        return 0;
1823}
1824
1825static int devlink_dpipe_action_value_put(struct sk_buff *skb,
1826                                          struct devlink_dpipe_value *value)
1827{
1828        if (!value->action)
1829                return -EINVAL;
1830        if (devlink_dpipe_action_put(skb, value->action))
1831                return -EMSGSIZE;
1832        if (devlink_dpipe_value_put(skb, value))
1833                return -EMSGSIZE;
1834        return 0;
1835}
1836
1837static int devlink_dpipe_action_values_put(struct sk_buff *skb,
1838                                           struct devlink_dpipe_value *values,
1839                                           unsigned int values_count)
1840{
1841        struct nlattr *action_attr;
1842        int i;
1843        int err;
1844
1845        for (i = 0; i < values_count; i++) {
1846                action_attr = nla_nest_start(skb,
1847                                             DEVLINK_ATTR_DPIPE_ACTION_VALUE);
1848                if (!action_attr)
1849                        return -EMSGSIZE;
1850                err = devlink_dpipe_action_value_put(skb, &values[i]);
1851                if (err)
1852                        goto err_action_value_put;
1853                nla_nest_end(skb, action_attr);
1854        }
1855        return 0;
1856
1857err_action_value_put:
1858        nla_nest_cancel(skb, action_attr);
1859        return err;
1860}
1861
1862static int devlink_dpipe_match_value_put(struct sk_buff *skb,
1863                                         struct devlink_dpipe_value *value)
1864{
1865        if (!value->match)
1866                return -EINVAL;
1867        if (devlink_dpipe_match_put(skb, value->match))
1868                return -EMSGSIZE;
1869        if (devlink_dpipe_value_put(skb, value))
1870                return -EMSGSIZE;
1871        return 0;
1872}
1873
1874static int devlink_dpipe_match_values_put(struct sk_buff *skb,
1875                                          struct devlink_dpipe_value *values,
1876                                          unsigned int values_count)
1877{
1878        struct nlattr *match_attr;
1879        int i;
1880        int err;
1881
1882        for (i = 0; i < values_count; i++) {
1883                match_attr = nla_nest_start(skb,
1884                                            DEVLINK_ATTR_DPIPE_MATCH_VALUE);
1885                if (!match_attr)
1886                        return -EMSGSIZE;
1887                err = devlink_dpipe_match_value_put(skb, &values[i]);
1888                if (err)
1889                        goto err_match_value_put;
1890                nla_nest_end(skb, match_attr);
1891        }
1892        return 0;
1893
1894err_match_value_put:
1895        nla_nest_cancel(skb, match_attr);
1896        return err;
1897}
1898
1899static int devlink_dpipe_entry_put(struct sk_buff *skb,
1900                                   struct devlink_dpipe_entry *entry)
1901{
1902        struct nlattr *entry_attr, *matches_attr, *actions_attr;
1903        int err;
1904
1905        entry_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_ENTRY);
1906        if (!entry_attr)
1907                return  -EMSGSIZE;
1908
1909        if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index,
1910                              DEVLINK_ATTR_PAD))
1911                goto nla_put_failure;
1912        if (entry->counter_valid)
1913                if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER,
1914                                      entry->counter, DEVLINK_ATTR_PAD))
1915                        goto nla_put_failure;
1916
1917        matches_attr = nla_nest_start(skb,
1918                                      DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES);
1919        if (!matches_attr)
1920                goto nla_put_failure;
1921
1922        err = devlink_dpipe_match_values_put(skb, entry->match_values,
1923                                             entry->match_values_count);
1924        if (err) {
1925                nla_nest_cancel(skb, matches_attr);
1926                goto err_match_values_put;
1927        }
1928        nla_nest_end(skb, matches_attr);
1929
1930        actions_attr = nla_nest_start(skb,
1931                                      DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES);
1932        if (!actions_attr)
1933                goto nla_put_failure;
1934
1935        err = devlink_dpipe_action_values_put(skb, entry->action_values,
1936                                              entry->action_values_count);
1937        if (err) {
1938                nla_nest_cancel(skb, actions_attr);
1939                goto err_action_values_put;
1940        }
1941        nla_nest_end(skb, actions_attr);
1942
1943        nla_nest_end(skb, entry_attr);
1944        return 0;
1945
1946nla_put_failure:
1947        err = -EMSGSIZE;
1948err_match_values_put:
1949err_action_values_put:
1950        nla_nest_cancel(skb, entry_attr);
1951        return err;
1952}
1953
1954static struct devlink_dpipe_table *
1955devlink_dpipe_table_find(struct list_head *dpipe_tables,
1956                         const char *table_name)
1957{
1958        struct devlink_dpipe_table *table;
1959
1960        list_for_each_entry_rcu(table, dpipe_tables, list) {
1961                if (!strcmp(table->name, table_name))
1962                        return table;
1963        }
1964        return NULL;
1965}
1966
1967int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx)
1968{
1969        struct devlink *devlink;
1970        int err;
1971
1972        err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb,
1973                                               dump_ctx->info);
1974        if (err)
1975                return err;
1976
1977        dump_ctx->hdr = genlmsg_put(dump_ctx->skb,
1978                                    dump_ctx->info->snd_portid,
1979                                    dump_ctx->info->snd_seq,
1980                                    &devlink_nl_family, NLM_F_MULTI,
1981                                    dump_ctx->cmd);
1982        if (!dump_ctx->hdr)
1983                goto nla_put_failure;
1984
1985        devlink = dump_ctx->info->user_ptr[0];
1986        if (devlink_nl_put_handle(dump_ctx->skb, devlink))
1987                goto nla_put_failure;
1988        dump_ctx->nest = nla_nest_start(dump_ctx->skb,
1989                                        DEVLINK_ATTR_DPIPE_ENTRIES);
1990        if (!dump_ctx->nest)
1991                goto nla_put_failure;
1992        return 0;
1993
1994nla_put_failure:
1995        genlmsg_cancel(dump_ctx->skb, dump_ctx->hdr);
1996        nlmsg_free(dump_ctx->skb);
1997        return -EMSGSIZE;
1998}
1999EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare);
2000
2001int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx,
2002                                   struct devlink_dpipe_entry *entry)
2003{
2004        return devlink_dpipe_entry_put(dump_ctx->skb, entry);
2005}
2006EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append);
2007
2008int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx)
2009{
2010        nla_nest_end(dump_ctx->skb, dump_ctx->nest);
2011        genlmsg_end(dump_ctx->skb, dump_ctx->hdr);
2012        return 0;
2013}
2014EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close);
2015
2016void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry)
2017
2018{
2019        unsigned int value_count, value_index;
2020        struct devlink_dpipe_value *value;
2021
2022        value = entry->action_values;
2023        value_count = entry->action_values_count;
2024        for (value_index = 0; value_index < value_count; value_index++) {
2025                kfree(value[value_index].value);
2026                kfree(value[value_index].mask);
2027        }
2028
2029        value = entry->match_values;
2030        value_count = entry->match_values_count;
2031        for (value_index = 0; value_index < value_count; value_index++) {
2032                kfree(value[value_index].value);
2033                kfree(value[value_index].mask);
2034        }
2035}
2036EXPORT_SYMBOL(devlink_dpipe_entry_clear);
2037
2038static int devlink_dpipe_entries_fill(struct genl_info *info,
2039                                      enum devlink_command cmd, int flags,
2040                                      struct devlink_dpipe_table *table)
2041{
2042        struct devlink_dpipe_dump_ctx dump_ctx;
2043        struct nlmsghdr *nlh;
2044        int err;
2045
2046        dump_ctx.skb = NULL;
2047        dump_ctx.cmd = cmd;
2048        dump_ctx.info = info;
2049
2050        err = table->table_ops->entries_dump(table->priv,
2051                                             table->counters_enabled,
2052                                             &dump_ctx);
2053        if (err)
2054                goto err_entries_dump;
2055
2056send_done:
2057        nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq,
2058                        NLMSG_DONE, 0, flags | NLM_F_MULTI);
2059        if (!nlh) {
2060                err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info);
2061                if (err)
2062                        goto err_skb_send_alloc;
2063                goto send_done;
2064        }
2065        return genlmsg_reply(dump_ctx.skb, info);
2066
2067err_entries_dump:
2068err_skb_send_alloc:
2069        genlmsg_cancel(dump_ctx.skb, dump_ctx.hdr);
2070        nlmsg_free(dump_ctx.skb);
2071        return err;
2072}
2073
2074static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
2075                                            struct genl_info *info)
2076{
2077        struct devlink *devlink = info->user_ptr[0];
2078        struct devlink_dpipe_table *table;
2079        const char *table_name;
2080
2081        if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
2082                return -EINVAL;
2083
2084        table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
2085        table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2086                                         table_name);
2087        if (!table)
2088                return -EINVAL;
2089
2090        if (!table->table_ops->entries_dump)
2091                return -EINVAL;
2092
2093        return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET,
2094                                          0, table);
2095}
2096
2097static int devlink_dpipe_fields_put(struct sk_buff *skb,
2098                                    const struct devlink_dpipe_header *header)
2099{
2100        struct devlink_dpipe_field *field;
2101        struct nlattr *field_attr;
2102        int i;
2103
2104        for (i = 0; i < header->fields_count; i++) {
2105                field = &header->fields[i];
2106                field_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_FIELD);
2107                if (!field_attr)
2108                        return -EMSGSIZE;
2109                if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) ||
2110                    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
2111                    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) ||
2112                    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type))
2113                        goto nla_put_failure;
2114                nla_nest_end(skb, field_attr);
2115        }
2116        return 0;
2117
2118nla_put_failure:
2119        nla_nest_cancel(skb, field_attr);
2120        return -EMSGSIZE;
2121}
2122
2123static int devlink_dpipe_header_put(struct sk_buff *skb,
2124                                    struct devlink_dpipe_header *header)
2125{
2126        struct nlattr *fields_attr, *header_attr;
2127        int err;
2128
2129        header_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_HEADER);
2130        if (!header_attr)
2131                return -EMSGSIZE;
2132
2133        if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) ||
2134            nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
2135            nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
2136                goto nla_put_failure;
2137
2138        fields_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_HEADER_FIELDS);
2139        if (!fields_attr)
2140                goto nla_put_failure;
2141
2142        err = devlink_dpipe_fields_put(skb, header);
2143        if (err) {
2144                nla_nest_cancel(skb, fields_attr);
2145                goto nla_put_failure;
2146        }
2147        nla_nest_end(skb, fields_attr);
2148        nla_nest_end(skb, header_attr);
2149        return 0;
2150
2151nla_put_failure:
2152        err = -EMSGSIZE;
2153        nla_nest_cancel(skb, header_attr);
2154        return err;
2155}
2156
2157static int devlink_dpipe_headers_fill(struct genl_info *info,
2158                                      enum devlink_command cmd, int flags,
2159                                      struct devlink_dpipe_headers *
2160                                      dpipe_headers)
2161{
2162        struct devlink *devlink = info->user_ptr[0];
2163        struct nlattr *headers_attr;
2164        struct sk_buff *skb = NULL;
2165        struct nlmsghdr *nlh;
2166        void *hdr;
2167        int i, j;
2168        int err;
2169
2170        i = 0;
2171start_again:
2172        err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2173        if (err)
2174                return err;
2175
2176        hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
2177                          &devlink_nl_family, NLM_F_MULTI, cmd);
2178        if (!hdr) {
2179                nlmsg_free(skb);
2180                return -EMSGSIZE;
2181        }
2182
2183        if (devlink_nl_put_handle(skb, devlink))
2184                goto nla_put_failure;
2185        headers_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_HEADERS);
2186        if (!headers_attr)
2187                goto nla_put_failure;
2188
2189        j = 0;
2190        for (; i < dpipe_headers->headers_count; i++) {
2191                err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]);
2192                if (err) {
2193                        if (!j)
2194                                goto err_table_put;
2195                        break;
2196                }
2197                j++;
2198        }
2199        nla_nest_end(skb, headers_attr);
2200        genlmsg_end(skb, hdr);
2201        if (i != dpipe_headers->headers_count)
2202                goto start_again;
2203
2204send_done:
2205        nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
2206                        NLMSG_DONE, 0, flags | NLM_F_MULTI);
2207        if (!nlh) {
2208                err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2209                if (err)
2210                        goto err_skb_send_alloc;
2211                goto send_done;
2212        }
2213        return genlmsg_reply(skb, info);
2214
2215nla_put_failure:
2216        err = -EMSGSIZE;
2217err_table_put:
2218err_skb_send_alloc:
2219        genlmsg_cancel(skb, hdr);
2220        nlmsg_free(skb);
2221        return err;
2222}
2223
2224static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb,
2225                                            struct genl_info *info)
2226{
2227        struct devlink *devlink = info->user_ptr[0];
2228
2229        if (!devlink->dpipe_headers)
2230                return -EOPNOTSUPP;
2231        return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET,
2232                                          0, devlink->dpipe_headers);
2233}
2234
2235static int devlink_dpipe_table_counters_set(struct devlink *devlink,
2236                                            const char *table_name,
2237                                            bool enable)
2238{
2239        struct devlink_dpipe_table *table;
2240
2241        table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2242                                         table_name);
2243        if (!table)
2244                return -EINVAL;
2245
2246        if (table->counter_control_extern)
2247                return -EOPNOTSUPP;
2248
2249        if (!(table->counters_enabled ^ enable))
2250                return 0;
2251
2252        table->counters_enabled = enable;
2253        if (table->table_ops->counters_set_update)
2254                table->table_ops->counters_set_update(table->priv, enable);
2255        return 0;
2256}
2257
2258static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb,
2259                                                   struct genl_info *info)
2260{
2261        struct devlink *devlink = info->user_ptr[0];
2262        const char *table_name;
2263        bool counters_enable;
2264
2265        if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME] ||
2266            !info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED])
2267                return -EINVAL;
2268
2269        table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
2270        counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]);
2271
2272        return devlink_dpipe_table_counters_set(devlink, table_name,
2273                                                counters_enable);
2274}
2275
2276static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
2277        [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
2278        [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
2279        [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 },
2280        [DEVLINK_ATTR_PORT_TYPE] = { .type = NLA_U16 },
2281        [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 },
2282        [DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 },
2283        [DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 },
2284        [DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 },
2285        [DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 },
2286        [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 },
2287        [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
2288        [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
2289        [DEVLINK_ATTR_ESWITCH_MODE] = { .type = NLA_U16 },
2290        [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 },
2291        [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 },
2292        [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING },
2293        [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 },
2294};
2295
2296static const struct genl_ops devlink_nl_ops[] = {
2297        {
2298                .cmd = DEVLINK_CMD_GET,
2299                .doit = devlink_nl_cmd_get_doit,
2300                .dumpit = devlink_nl_cmd_get_dumpit,
2301                .policy = devlink_nl_policy,
2302                .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2303                /* can be retrieved by unprivileged users */
2304        },
2305        {
2306                .cmd = DEVLINK_CMD_PORT_GET,
2307                .doit = devlink_nl_cmd_port_get_doit,
2308                .dumpit = devlink_nl_cmd_port_get_dumpit,
2309                .policy = devlink_nl_policy,
2310                .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
2311                /* can be retrieved by unprivileged users */
2312        },
2313        {
2314                .cmd = DEVLINK_CMD_PORT_SET,
2315                .doit = devlink_nl_cmd_port_set_doit,
2316                .policy = devlink_nl_policy,
2317                .flags = GENL_ADMIN_PERM,
2318                .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
2319        },
2320        {
2321                .cmd = DEVLINK_CMD_PORT_SPLIT,
2322                .doit = devlink_nl_cmd_port_split_doit,
2323                .policy = devlink_nl_policy,
2324                .flags = GENL_ADMIN_PERM,
2325                .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2326        },
2327        {
2328                .cmd = DEVLINK_CMD_PORT_UNSPLIT,
2329                .doit = devlink_nl_cmd_port_unsplit_doit,
2330                .policy = devlink_nl_policy,
2331                .flags = GENL_ADMIN_PERM,
2332                .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2333        },
2334        {
2335                .cmd = DEVLINK_CMD_SB_GET,
2336                .doit = devlink_nl_cmd_sb_get_doit,
2337                .dumpit = devlink_nl_cmd_sb_get_dumpit,
2338                .policy = devlink_nl_policy,
2339                .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2340                                  DEVLINK_NL_FLAG_NEED_SB,
2341                /* can be retrieved by unprivileged users */
2342        },
2343        {
2344                .cmd = DEVLINK_CMD_SB_POOL_GET,
2345                .doit = devlink_nl_cmd_sb_pool_get_doit,
2346                .dumpit = devlink_nl_cmd_sb_pool_get_dumpit,
2347                .policy = devlink_nl_policy,
2348                .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2349                                  DEVLINK_NL_FLAG_NEED_SB,
2350                /* can be retrieved by unprivileged users */
2351        },
2352        {
2353                .cmd = DEVLINK_CMD_SB_POOL_SET,
2354                .doit = devlink_nl_cmd_sb_pool_set_doit,
2355                .policy = devlink_nl_policy,
2356                .flags = GENL_ADMIN_PERM,
2357                .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2358                                  DEVLINK_NL_FLAG_NEED_SB,
2359        },
2360        {
2361                .cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
2362                .doit = devlink_nl_cmd_sb_port_pool_get_doit,
2363                .dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit,
2364                .policy = devlink_nl_policy,
2365                .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
2366                                  DEVLINK_NL_FLAG_NEED_SB,
2367                /* can be retrieved by unprivileged users */
2368        },
2369        {
2370                .cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
2371                .doit = devlink_nl_cmd_sb_port_pool_set_doit,
2372                .policy = devlink_nl_policy,
2373                .flags = GENL_ADMIN_PERM,
2374                .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
2375                                  DEVLINK_NL_FLAG_NEED_SB,
2376        },
2377        {
2378                .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
2379                .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
2380                .dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit,
2381                .policy = devlink_nl_policy,
2382                .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
2383                                  DEVLINK_NL_FLAG_NEED_SB,
2384                /* can be retrieved by unprivileged users */
2385        },
2386        {
2387                .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
2388                .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
2389                .policy = devlink_nl_policy,
2390                .flags = GENL_ADMIN_PERM,
2391                .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
2392                                  DEVLINK_NL_FLAG_NEED_SB,
2393        },
2394        {
2395                .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
2396                .doit = devlink_nl_cmd_sb_occ_snapshot_doit,
2397                .policy = devlink_nl_policy,
2398                .flags = GENL_ADMIN_PERM,
2399                .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2400                                  DEVLINK_NL_FLAG_NEED_SB |
2401                                  DEVLINK_NL_FLAG_LOCK_PORTS,
2402        },
2403        {
2404                .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
2405                .doit = devlink_nl_cmd_sb_occ_max_clear_doit,
2406                .policy = devlink_nl_policy,
2407                .flags = GENL_ADMIN_PERM,
2408                .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2409                                  DEVLINK_NL_FLAG_NEED_SB |
2410                                  DEVLINK_NL_FLAG_LOCK_PORTS,
2411        },
2412        {
2413                .cmd = DEVLINK_CMD_ESWITCH_GET,
2414                .doit = devlink_nl_cmd_eswitch_get_doit,
2415                .policy = devlink_nl_policy,
2416                .flags = GENL_ADMIN_PERM,
2417                .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2418        },
2419        {
2420                .cmd = DEVLINK_CMD_ESWITCH_SET,
2421                .doit = devlink_nl_cmd_eswitch_set_doit,
2422                .policy = devlink_nl_policy,
2423                .flags = GENL_ADMIN_PERM,
2424                .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2425        },
2426        {
2427                .cmd = DEVLINK_CMD_DPIPE_TABLE_GET,
2428                .doit = devlink_nl_cmd_dpipe_table_get,
2429                .policy = devlink_nl_policy,
2430                .flags = GENL_ADMIN_PERM,
2431                .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2432        },
2433        {
2434                .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET,
2435                .doit = devlink_nl_cmd_dpipe_entries_get,
2436                .policy = devlink_nl_policy,
2437                .flags = GENL_ADMIN_PERM,
2438                .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2439        },
2440        {
2441                .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET,
2442                .doit = devlink_nl_cmd_dpipe_headers_get,
2443                .policy = devlink_nl_policy,
2444                .flags = GENL_ADMIN_PERM,
2445                .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2446        },
2447        {
2448                .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
2449                .doit = devlink_nl_cmd_dpipe_table_counters_set,
2450                .policy = devlink_nl_policy,
2451                .flags = GENL_ADMIN_PERM,
2452                .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2453        },
2454};
2455
2456static struct genl_family devlink_nl_family __ro_after_init = {
2457        .name           = DEVLINK_GENL_NAME,
2458        .version        = DEVLINK_GENL_VERSION,
2459        .maxattr        = DEVLINK_ATTR_MAX,
2460        .netnsok        = true,
2461        .pre_doit       = devlink_nl_pre_doit,
2462        .post_doit      = devlink_nl_post_doit,
2463        .module         = THIS_MODULE,
2464        .ops            = devlink_nl_ops,
2465        .n_ops          = ARRAY_SIZE(devlink_nl_ops),
2466        .mcgrps         = devlink_nl_mcgrps,
2467        .n_mcgrps       = ARRAY_SIZE(devlink_nl_mcgrps),
2468};
2469
2470/**
2471 *      devlink_alloc - Allocate new devlink instance resources
2472 *
2473 *      @ops: ops
2474 *      @priv_size: size of user private data
2475 *
2476 *      Allocate new devlink instance resources, including devlink index
2477 *      and name.
2478 */
2479struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
2480{
2481        struct devlink *devlink;
2482
2483        devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
2484        if (!devlink)
2485                return NULL;
2486        devlink->ops = ops;
2487        devlink_net_set(devlink, &init_net);
2488        INIT_LIST_HEAD(&devlink->port_list);
2489        INIT_LIST_HEAD(&devlink->sb_list);
2490        INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list);
2491        return devlink;
2492}
2493EXPORT_SYMBOL_GPL(devlink_alloc);
2494
2495/**
2496 *      devlink_register - Register devlink instance
2497 *
2498 *      @devlink: devlink
2499 */
2500int devlink_register(struct devlink *devlink, struct device *dev)
2501{
2502        mutex_lock(&devlink_mutex);
2503        devlink->dev = dev;
2504        list_add_tail(&devlink->list, &devlink_list);
2505        devlink_notify(devlink, DEVLINK_CMD_NEW);
2506        mutex_unlock(&devlink_mutex);
2507        return 0;
2508}
2509EXPORT_SYMBOL_GPL(devlink_register);
2510
2511/**
2512 *      devlink_unregister - Unregister devlink instance
2513 *
2514 *      @devlink: devlink
2515 */
2516void devlink_unregister(struct devlink *devlink)
2517{
2518        mutex_lock(&devlink_mutex);
2519        devlink_notify(devlink, DEVLINK_CMD_DEL);
2520        list_del(&devlink->list);
2521        mutex_unlock(&devlink_mutex);
2522}
2523EXPORT_SYMBOL_GPL(devlink_unregister);
2524
2525/**
2526 *      devlink_free - Free devlink instance resources
2527 *
2528 *      @devlink: devlink
2529 */
2530void devlink_free(struct devlink *devlink)
2531{
2532        kfree(devlink);
2533}
2534EXPORT_SYMBOL_GPL(devlink_free);
2535
2536/**
2537 *      devlink_port_register - Register devlink port
2538 *
2539 *      @devlink: devlink
2540 *      @devlink_port: devlink port
2541 *      @port_index
2542 *
2543 *      Register devlink port with provided port index. User can use
2544 *      any indexing, even hw-related one. devlink_port structure
2545 *      is convenient to be embedded inside user driver private structure.
2546 *      Note that the caller should take care of zeroing the devlink_port
2547 *      structure.
2548 */
2549int devlink_port_register(struct devlink *devlink,
2550                          struct devlink_port *devlink_port,
2551                          unsigned int port_index)
2552{
2553        mutex_lock(&devlink_port_mutex);
2554        if (devlink_port_index_exists(devlink, port_index)) {
2555                mutex_unlock(&devlink_port_mutex);
2556                return -EEXIST;
2557        }
2558        devlink_port->devlink = devlink;
2559        devlink_port->index = port_index;
2560        devlink_port->registered = true;
2561        list_add_tail(&devlink_port->list, &devlink->port_list);
2562        mutex_unlock(&devlink_port_mutex);
2563        devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
2564        return 0;
2565}
2566EXPORT_SYMBOL_GPL(devlink_port_register);
2567
2568/**
2569 *      devlink_port_unregister - Unregister devlink port
2570 *
2571 *      @devlink_port: devlink port
2572 */
2573void devlink_port_unregister(struct devlink_port *devlink_port)
2574{
2575        devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
2576        mutex_lock(&devlink_port_mutex);
2577        list_del(&devlink_port->list);
2578        mutex_unlock(&devlink_port_mutex);
2579}
2580EXPORT_SYMBOL_GPL(devlink_port_unregister);
2581
2582static void __devlink_port_type_set(struct devlink_port *devlink_port,
2583                                    enum devlink_port_type type,
2584                                    void *type_dev)
2585{
2586        devlink_port->type = type;
2587        devlink_port->type_dev = type_dev;
2588        devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
2589}
2590
2591/**
2592 *      devlink_port_type_eth_set - Set port type to Ethernet
2593 *
2594 *      @devlink_port: devlink port
2595 *      @netdev: related netdevice
2596 */
2597void devlink_port_type_eth_set(struct devlink_port *devlink_port,
2598                               struct net_device *netdev)
2599{
2600        return __devlink_port_type_set(devlink_port,
2601                                       DEVLINK_PORT_TYPE_ETH, netdev);
2602}
2603EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
2604
2605/**
2606 *      devlink_port_type_ib_set - Set port type to InfiniBand
2607 *
2608 *      @devlink_port: devlink port
2609 *      @ibdev: related IB device
2610 */
2611void devlink_port_type_ib_set(struct devlink_port *devlink_port,
2612                              struct ib_device *ibdev)
2613{
2614        return __devlink_port_type_set(devlink_port,
2615                                       DEVLINK_PORT_TYPE_IB, ibdev);
2616}
2617EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
2618
2619/**
2620 *      devlink_port_type_clear - Clear port type
2621 *
2622 *      @devlink_port: devlink port
2623 */
2624void devlink_port_type_clear(struct devlink_port *devlink_port)
2625{
2626        return __devlink_port_type_set(devlink_port,
2627                                       DEVLINK_PORT_TYPE_NOTSET, NULL);
2628}
2629EXPORT_SYMBOL_GPL(devlink_port_type_clear);
2630
2631/**
2632 *      devlink_port_split_set - Set port is split
2633 *
2634 *      @devlink_port: devlink port
2635 *      @split_group: split group - identifies group split port is part of
2636 */
2637void devlink_port_split_set(struct devlink_port *devlink_port,
2638                            u32 split_group)
2639{
2640        devlink_port->split = true;
2641        devlink_port->split_group = split_group;
2642        devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
2643}
2644EXPORT_SYMBOL_GPL(devlink_port_split_set);
2645
2646int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
2647                        u32 size, u16 ingress_pools_count,
2648                        u16 egress_pools_count, u16 ingress_tc_count,
2649                        u16 egress_tc_count)
2650{
2651        struct devlink_sb *devlink_sb;
2652        int err = 0;
2653
2654        mutex_lock(&devlink_mutex);
2655        if (devlink_sb_index_exists(devlink, sb_index)) {
2656                err = -EEXIST;
2657                goto unlock;
2658        }
2659
2660        devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
2661        if (!devlink_sb) {
2662                err = -ENOMEM;
2663                goto unlock;
2664        }
2665        devlink_sb->index = sb_index;
2666        devlink_sb->size = size;
2667        devlink_sb->ingress_pools_count = ingress_pools_count;
2668        devlink_sb->egress_pools_count = egress_pools_count;
2669        devlink_sb->ingress_tc_count = ingress_tc_count;
2670        devlink_sb->egress_tc_count = egress_tc_count;
2671        list_add_tail(&devlink_sb->list, &devlink->sb_list);
2672unlock:
2673        mutex_unlock(&devlink_mutex);
2674        return err;
2675}
2676EXPORT_SYMBOL_GPL(devlink_sb_register);
2677
2678void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
2679{
2680        struct devlink_sb *devlink_sb;
2681
2682        mutex_lock(&devlink_mutex);
2683        devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
2684        WARN_ON(!devlink_sb);
2685        list_del(&devlink_sb->list);
2686        mutex_unlock(&devlink_mutex);
2687        kfree(devlink_sb);
2688}
2689EXPORT_SYMBOL_GPL(devlink_sb_unregister);
2690
2691/**
2692 *      devlink_dpipe_headers_register - register dpipe headers
2693 *
2694 *      @devlink: devlink
2695 *      @dpipe_headers: dpipe header array
2696 *
2697 *      Register the headers supported by hardware.
2698 */
2699int devlink_dpipe_headers_register(struct devlink *devlink,
2700                                   struct devlink_dpipe_headers *dpipe_headers)
2701{
2702        mutex_lock(&devlink_mutex);
2703        devlink->dpipe_headers = dpipe_headers;
2704        mutex_unlock(&devlink_mutex);
2705        return 0;
2706}
2707EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register);
2708
2709/**
2710 *      devlink_dpipe_headers_unregister - unregister dpipe headers
2711 *
2712 *      @devlink: devlink
2713 *
2714 *      Unregister the headers supported by hardware.
2715 */
2716void devlink_dpipe_headers_unregister(struct devlink *devlink)
2717{
2718        mutex_lock(&devlink_mutex);
2719        devlink->dpipe_headers = NULL;
2720        mutex_unlock(&devlink_mutex);
2721}
2722EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister);
2723
2724/**
2725 *      devlink_dpipe_table_counter_enabled - check if counter allocation
2726 *                                            required
2727 *      @devlink: devlink
2728 *      @table_name: tables name
2729 *
2730 *      Used by driver to check if counter allocation is required.
2731 *      After counter allocation is turned on the table entries
2732 *      are updated to include counter statistics.
2733 *
2734 *      After that point on the driver must respect the counter
2735 *      state so that each entry added to the table is added
2736 *      with a counter.
2737 */
2738bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
2739                                         const char *table_name)
2740{
2741        struct devlink_dpipe_table *table;
2742        bool enabled;
2743
2744        rcu_read_lock();
2745        table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2746                                         table_name);
2747        enabled = false;
2748        if (table)
2749                enabled = table->counters_enabled;
2750        rcu_read_unlock();
2751        return enabled;
2752}
2753EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled);
2754
2755/**
2756 *      devlink_dpipe_table_register - register dpipe table
2757 *
2758 *      @devlink: devlink
2759 *      @table_name: table name
2760 *      @table_ops: table ops
2761 *      @priv: priv
2762 *      @counter_control_extern: external control for counters
2763 */
2764int devlink_dpipe_table_register(struct devlink *devlink,
2765                                 const char *table_name,
2766                                 struct devlink_dpipe_table_ops *table_ops,
2767                                 void *priv, bool counter_control_extern)
2768{
2769        struct devlink_dpipe_table *table;
2770
2771        if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name))
2772                return -EEXIST;
2773
2774        if (WARN_ON(!table_ops->size_get))
2775                return -EINVAL;
2776
2777        table = kzalloc(sizeof(*table), GFP_KERNEL);
2778        if (!table)
2779                return -ENOMEM;
2780
2781        table->name = table_name;
2782        table->table_ops = table_ops;
2783        table->priv = priv;
2784        table->counter_control_extern = counter_control_extern;
2785
2786        mutex_lock(&devlink_mutex);
2787        list_add_tail_rcu(&table->list, &devlink->dpipe_table_list);
2788        mutex_unlock(&devlink_mutex);
2789        return 0;
2790}
2791EXPORT_SYMBOL_GPL(devlink_dpipe_table_register);
2792
2793/**
2794 *      devlink_dpipe_table_unregister - unregister dpipe table
2795 *
2796 *      @devlink: devlink
2797 *      @table_name: table name
2798 */
2799void devlink_dpipe_table_unregister(struct devlink *devlink,
2800                                    const char *table_name)
2801{
2802        struct devlink_dpipe_table *table;
2803
2804        mutex_lock(&devlink_mutex);
2805        table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2806                                         table_name);
2807        if (!table)
2808                goto unlock;
2809        list_del_rcu(&table->list);
2810        mutex_unlock(&devlink_mutex);
2811        kfree_rcu(table, rcu);
2812        return;
2813unlock:
2814        mutex_unlock(&devlink_mutex);
2815}
2816EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister);
2817
2818static int __init devlink_module_init(void)
2819{
2820        return genl_register_family(&devlink_nl_family);
2821}
2822
2823static void __exit devlink_module_exit(void)
2824{
2825        genl_unregister_family(&devlink_nl_family);
2826}
2827
2828module_init(devlink_module_init);
2829module_exit(devlink_module_exit);
2830
2831MODULE_LICENSE("GPL v2");
2832MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
2833MODULE_DESCRIPTION("Network physical device Netlink interface");
2834MODULE_ALIAS_GENL_FAMILY(DEVLINK_GENL_NAME);
2835