Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
   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
  95static struct net *devlink_net(const struct devlink *devlink)
  96{
  97	return read_pnet(&devlink->_net);
  98}
  99
 100static void devlink_net_set(struct devlink *devlink, struct net *net)
 101{
 102	write_pnet(&devlink->_net, net);
 103}
 104
 105static struct devlink *devlink_get_from_attrs(struct net *net,
 106					      struct nlattr **attrs)
 107{
 108	struct devlink *devlink;
 109	char *busname;
 110	char *devname;
 111
 112	if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME])
 113		return ERR_PTR(-EINVAL);
 114
 115	busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]);
 116	devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
 117
 118	list_for_each_entry(devlink, &devlink_list, list) {
 119		if (strcmp(devlink->dev->bus->name, busname) == 0 &&
 120		    strcmp(dev_name(devlink->dev), devname) == 0 &&
 121		    net_eq(devlink_net(devlink), net))
 122			return devlink;
 123	}
 124
 125	return ERR_PTR(-ENODEV);
 126}
 127
 128static struct devlink *devlink_get_from_info(struct genl_info *info)
 129{
 130	return devlink_get_from_attrs(genl_info_net(info), info->attrs);
 131}
 132
 133static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
 134						      int port_index)
 135{
 136	struct devlink_port *devlink_port;
 137
 138	list_for_each_entry(devlink_port, &devlink->port_list, list) {
 139		if (devlink_port->index == port_index)
 140			return devlink_port;
 141	}
 142	return NULL;
 143}
 144
 145static bool devlink_port_index_exists(struct devlink *devlink, int port_index)
 146{
 147	return devlink_port_get_by_index(devlink, port_index);
 148}
 149
 150static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
 151							struct nlattr **attrs)
 152{
 153	if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
 154		u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
 155		struct devlink_port *devlink_port;
 156
 157		devlink_port = devlink_port_get_by_index(devlink, port_index);
 158		if (!devlink_port)
 159			return ERR_PTR(-ENODEV);
 160		return devlink_port;
 161	}
 162	return ERR_PTR(-EINVAL);
 163}
 164
 165static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
 166						       struct genl_info *info)
 167{
 168	return devlink_port_get_from_attrs(devlink, info->attrs);
 169}
 170
 171struct devlink_sb {
 172	struct list_head list;
 173	unsigned int index;
 174	u32 size;
 175	u16 ingress_pools_count;
 176	u16 egress_pools_count;
 177	u16 ingress_tc_count;
 178	u16 egress_tc_count;
 179};
 180
 181static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb)
 182{
 183	return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count;
 184}
 185
 186static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink,
 187						  unsigned int sb_index)
 188{
 189	struct devlink_sb *devlink_sb;
 190
 191	list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
 192		if (devlink_sb->index == sb_index)
 193			return devlink_sb;
 194	}
 195	return NULL;
 196}
 197
 198static bool devlink_sb_index_exists(struct devlink *devlink,
 199				    unsigned int sb_index)
 200{
 201	return devlink_sb_get_by_index(devlink, sb_index);
 202}
 203
 204static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink,
 205						    struct nlattr **attrs)
 206{
 207	if (attrs[DEVLINK_ATTR_SB_INDEX]) {
 208		u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]);
 209		struct devlink_sb *devlink_sb;
 210
 211		devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
 212		if (!devlink_sb)
 213			return ERR_PTR(-ENODEV);
 214		return devlink_sb;
 215	}
 216	return ERR_PTR(-EINVAL);
 217}
 218
 219static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink,
 220						   struct genl_info *info)
 221{
 222	return devlink_sb_get_from_attrs(devlink, info->attrs);
 223}
 224
 225static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb,
 226						struct nlattr **attrs,
 227						u16 *p_pool_index)
 228{
 229	u16 val;
 230
 231	if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX])
 232		return -EINVAL;
 233
 234	val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]);
 235	if (val >= devlink_sb_pool_count(devlink_sb))
 236		return -EINVAL;
 237	*p_pool_index = val;
 238	return 0;
 239}
 240
 241static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb,
 242					       struct genl_info *info,
 243					       u16 *p_pool_index)
 244{
 245	return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs,
 246						    p_pool_index);
 247}
 248
 249static int
 250devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs,
 251				    enum devlink_sb_pool_type *p_pool_type)
 252{
 253	u8 val;
 254
 255	if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE])
 256		return -EINVAL;
 257
 258	val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]);
 259	if (val != DEVLINK_SB_POOL_TYPE_INGRESS &&
 260	    val != DEVLINK_SB_POOL_TYPE_EGRESS)
 261		return -EINVAL;
 262	*p_pool_type = val;
 263	return 0;
 264}
 265
 266static int
 267devlink_sb_pool_type_get_from_info(struct genl_info *info,
 268				   enum devlink_sb_pool_type *p_pool_type)
 269{
 270	return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type);
 271}
 272
 273static int
 274devlink_sb_th_type_get_from_attrs(struct nlattr **attrs,
 275				  enum devlink_sb_threshold_type *p_th_type)
 276{
 277	u8 val;
 278
 279	if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])
 280		return -EINVAL;
 281
 282	val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]);
 283	if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC &&
 284	    val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC)
 285		return -EINVAL;
 286	*p_th_type = val;
 287	return 0;
 288}
 289
 290static int
 291devlink_sb_th_type_get_from_info(struct genl_info *info,
 292				 enum devlink_sb_threshold_type *p_th_type)
 293{
 294	return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type);
 295}
 296
 297static int
 298devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb,
 299				   struct nlattr **attrs,
 300				   enum devlink_sb_pool_type pool_type,
 301				   u16 *p_tc_index)
 302{
 303	u16 val;
 304
 305	if (!attrs[DEVLINK_ATTR_SB_TC_INDEX])
 306		return -EINVAL;
 307
 308	val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]);
 309	if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS &&
 310	    val >= devlink_sb->ingress_tc_count)
 311		return -EINVAL;
 312	if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS &&
 313	    val >= devlink_sb->egress_tc_count)
 314		return -EINVAL;
 315	*p_tc_index = val;
 316	return 0;
 317}
 318
 319static int
 320devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
 321				  struct genl_info *info,
 322				  enum devlink_sb_pool_type pool_type,
 323				  u16 *p_tc_index)
 324{
 325	return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs,
 326						  pool_type, p_tc_index);
 327}
 328
 329#define DEVLINK_NL_FLAG_NEED_DEVLINK	BIT(0)
 330#define DEVLINK_NL_FLAG_NEED_PORT	BIT(1)
 331#define DEVLINK_NL_FLAG_NEED_SB		BIT(2)
 332
 333/* The per devlink instance lock is taken by default in the pre-doit
 334 * operation, yet several commands do not require this. The global
 335 * devlink lock is taken and protects from disruption by user-calls.
 336 */
 337#define DEVLINK_NL_FLAG_NO_LOCK		BIT(3)
 338
 339static int devlink_nl_pre_doit(const struct genl_ops *ops,
 340			       struct sk_buff *skb, struct genl_info *info)
 341{
 342	struct devlink *devlink;
 343	int err;
 344
 345	mutex_lock(&devlink_mutex);
 346	devlink = devlink_get_from_info(info);
 347	if (IS_ERR(devlink)) {
 348		mutex_unlock(&devlink_mutex);
 349		return PTR_ERR(devlink);
 350	}
 351	if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
 352		mutex_lock(&devlink->lock);
 353	if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK) {
 354		info->user_ptr[0] = devlink;
 355	} else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) {
 356		struct devlink_port *devlink_port;
 357
 358		devlink_port = devlink_port_get_from_info(devlink, info);
 359		if (IS_ERR(devlink_port)) {
 360			err = PTR_ERR(devlink_port);
 361			goto unlock;
 362		}
 363		info->user_ptr[0] = devlink_port;
 364	}
 365	if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_SB) {
 366		struct devlink_sb *devlink_sb;
 367
 368		devlink_sb = devlink_sb_get_from_info(devlink, info);
 369		if (IS_ERR(devlink_sb)) {
 370			err = PTR_ERR(devlink_sb);
 371			goto unlock;
 372		}
 373		info->user_ptr[1] = devlink_sb;
 374	}
 375	return 0;
 376
 377unlock:
 378	if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
 379		mutex_unlock(&devlink->lock);
 380	mutex_unlock(&devlink_mutex);
 381	return err;
 382}
 383
 384static void devlink_nl_post_doit(const struct genl_ops *ops,
 385				 struct sk_buff *skb, struct genl_info *info)
 386{
 387	struct devlink *devlink;
 388
 389	devlink = devlink_get_from_info(info);
 390	if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
 391		mutex_unlock(&devlink->lock);
 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	list_for_each_entry(devlink, &devlink_list, list) {
 618		if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
 619			continue;
 620		mutex_lock(&devlink->lock);
 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				mutex_unlock(&devlink->lock);
 633				goto out;
 634			}
 635			idx++;
 636		}
 637		mutex_unlock(&devlink->lock);
 638	}
 639out:
 640	mutex_unlock(&devlink_mutex);
 641
 642	cb->args[0] = idx;
 643	return msg->len;
 644}
 645
 646static int devlink_port_type_set(struct devlink *devlink,
 647				 struct devlink_port *devlink_port,
 648				 enum devlink_port_type port_type)
 649
 650{
 651	int err;
 652
 653	if (devlink->ops && devlink->ops->port_type_set) {
 654		if (port_type == DEVLINK_PORT_TYPE_NOTSET)
 655			return -EINVAL;
 656		if (port_type == devlink_port->type)
 657			return 0;
 658		err = devlink->ops->port_type_set(devlink_port, port_type);
 659		if (err)
 660			return err;
 661		devlink_port->desired_type = port_type;
 662		devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
 663		return 0;
 664	}
 665	return -EOPNOTSUPP;
 666}
 667
 668static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
 669					struct genl_info *info)
 670{
 671	struct devlink_port *devlink_port = info->user_ptr[0];
 672	struct devlink *devlink = devlink_port->devlink;
 673	int err;
 674
 675	if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
 676		enum devlink_port_type port_type;
 677
 678		port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
 679		err = devlink_port_type_set(devlink, devlink_port, port_type);
 680		if (err)
 681			return err;
 682	}
 683	return 0;
 684}
 685
 686static int devlink_port_split(struct devlink *devlink,
 687			      u32 port_index, u32 count)
 688
 689{
 690	if (devlink->ops && devlink->ops->port_split)
 691		return devlink->ops->port_split(devlink, port_index, count);
 692	return -EOPNOTSUPP;
 693}
 694
 695static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
 696					  struct genl_info *info)
 697{
 698	struct devlink *devlink = info->user_ptr[0];
 699	u32 port_index;
 700	u32 count;
 701
 702	if (!info->attrs[DEVLINK_ATTR_PORT_INDEX] ||
 703	    !info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT])
 704		return -EINVAL;
 705
 706	port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
 707	count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
 708	return devlink_port_split(devlink, port_index, count);
 709}
 710
 711static int devlink_port_unsplit(struct devlink *devlink, u32 port_index)
 712
 713{
 714	if (devlink->ops && devlink->ops->port_unsplit)
 715		return devlink->ops->port_unsplit(devlink, port_index);
 716	return -EOPNOTSUPP;
 717}
 718
 719static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
 720					    struct genl_info *info)
 721{
 722	struct devlink *devlink = info->user_ptr[0];
 723	u32 port_index;
 724
 725	if (!info->attrs[DEVLINK_ATTR_PORT_INDEX])
 726		return -EINVAL;
 727
 728	port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
 729	return devlink_port_unsplit(devlink, port_index);
 730}
 731
 732static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
 733			      struct devlink_sb *devlink_sb,
 734			      enum devlink_command cmd, u32 portid,
 735			      u32 seq, int flags)
 736{
 737	void *hdr;
 738
 739	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 740	if (!hdr)
 741		return -EMSGSIZE;
 742
 743	if (devlink_nl_put_handle(msg, devlink))
 744		goto nla_put_failure;
 745	if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
 746		goto nla_put_failure;
 747	if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size))
 748		goto nla_put_failure;
 749	if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT,
 750			devlink_sb->ingress_pools_count))
 751		goto nla_put_failure;
 752	if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT,
 753			devlink_sb->egress_pools_count))
 754		goto nla_put_failure;
 755	if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT,
 756			devlink_sb->ingress_tc_count))
 757		goto nla_put_failure;
 758	if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT,
 759			devlink_sb->egress_tc_count))
 760		goto nla_put_failure;
 761
 762	genlmsg_end(msg, hdr);
 763	return 0;
 764
 765nla_put_failure:
 766	genlmsg_cancel(msg, hdr);
 767	return -EMSGSIZE;
 768}
 769
 770static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb,
 771				      struct genl_info *info)
 772{
 773	struct devlink *devlink = info->user_ptr[0];
 774	struct devlink_sb *devlink_sb = info->user_ptr[1];
 775	struct sk_buff *msg;
 776	int err;
 777
 778	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 779	if (!msg)
 780		return -ENOMEM;
 781
 782	err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
 783				 DEVLINK_CMD_SB_NEW,
 784				 info->snd_portid, info->snd_seq, 0);
 785	if (err) {
 786		nlmsg_free(msg);
 787		return err;
 788	}
 789
 790	return genlmsg_reply(msg, info);
 791}
 792
 793static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg,
 794					struct netlink_callback *cb)
 795{
 796	struct devlink *devlink;
 797	struct devlink_sb *devlink_sb;
 798	int start = cb->args[0];
 799	int idx = 0;
 800	int err;
 801
 802	mutex_lock(&devlink_mutex);
 803	list_for_each_entry(devlink, &devlink_list, list) {
 804		if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
 805			continue;
 806		mutex_lock(&devlink->lock);
 807		list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
 808			if (idx < start) {
 809				idx++;
 810				continue;
 811			}
 812			err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
 813						 DEVLINK_CMD_SB_NEW,
 814						 NETLINK_CB(cb->skb).portid,
 815						 cb->nlh->nlmsg_seq,
 816						 NLM_F_MULTI);
 817			if (err) {
 818				mutex_unlock(&devlink->lock);
 819				goto out;
 820			}
 821			idx++;
 822		}
 823		mutex_unlock(&devlink->lock);
 824	}
 825out:
 826	mutex_unlock(&devlink_mutex);
 827
 828	cb->args[0] = idx;
 829	return msg->len;
 830}
 831
 832static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink,
 833				   struct devlink_sb *devlink_sb,
 834				   u16 pool_index, enum devlink_command cmd,
 835				   u32 portid, u32 seq, int flags)
 836{
 837	struct devlink_sb_pool_info pool_info;
 838	void *hdr;
 839	int err;
 840
 841	err = devlink->ops->sb_pool_get(devlink, devlink_sb->index,
 842					pool_index, &pool_info);
 843	if (err)
 844		return err;
 845
 846	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 847	if (!hdr)
 848		return -EMSGSIZE;
 849
 850	if (devlink_nl_put_handle(msg, devlink))
 851		goto nla_put_failure;
 852	if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
 853		goto nla_put_failure;
 854	if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
 855		goto nla_put_failure;
 856	if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type))
 857		goto nla_put_failure;
 858	if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size))
 859		goto nla_put_failure;
 860	if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE,
 861		       pool_info.threshold_type))
 862		goto nla_put_failure;
 863
 864	genlmsg_end(msg, hdr);
 865	return 0;
 866
 867nla_put_failure:
 868	genlmsg_cancel(msg, hdr);
 869	return -EMSGSIZE;
 870}
 871
 872static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb,
 873					   struct genl_info *info)
 874{
 875	struct devlink *devlink = info->user_ptr[0];
 876	struct devlink_sb *devlink_sb = info->user_ptr[1];
 877	struct sk_buff *msg;
 878	u16 pool_index;
 879	int err;
 880
 881	err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
 882						  &pool_index);
 883	if (err)
 884		return err;
 885
 886	if (!devlink->ops || !devlink->ops->sb_pool_get)
 887		return -EOPNOTSUPP;
 888
 889	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 890	if (!msg)
 891		return -ENOMEM;
 892
 893	err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index,
 894				      DEVLINK_CMD_SB_POOL_NEW,
 895				      info->snd_portid, info->snd_seq, 0);
 896	if (err) {
 897		nlmsg_free(msg);
 898		return err;
 899	}
 900
 901	return genlmsg_reply(msg, info);
 902}
 903
 904static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
 905				struct devlink *devlink,
 906				struct devlink_sb *devlink_sb,
 907				u32 portid, u32 seq)
 908{
 909	u16 pool_count = devlink_sb_pool_count(devlink_sb);
 910	u16 pool_index;
 911	int err;
 912
 913	for (pool_index = 0; pool_index < pool_count; pool_index++) {
 914		if (*p_idx < start) {
 915			(*p_idx)++;
 916			continue;
 917		}
 918		err = devlink_nl_sb_pool_fill(msg, devlink,
 919					      devlink_sb,
 920					      pool_index,
 921					      DEVLINK_CMD_SB_POOL_NEW,
 922					      portid, seq, NLM_F_MULTI);
 923		if (err)
 924			return err;
 925		(*p_idx)++;
 926	}
 927	return 0;
 928}
 929
 930static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg,
 931					     struct netlink_callback *cb)
 932{
 933	struct devlink *devlink;
 934	struct devlink_sb *devlink_sb;
 935	int start = cb->args[0];
 936	int idx = 0;
 937	int err;
 938
 939	mutex_lock(&devlink_mutex);
 940	list_for_each_entry(devlink, &devlink_list, list) {
 941		if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
 942		    !devlink->ops || !devlink->ops->sb_pool_get)
 943			continue;
 944		mutex_lock(&devlink->lock);
 945		list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
 946			err = __sb_pool_get_dumpit(msg, start, &idx, devlink,
 947						   devlink_sb,
 948						   NETLINK_CB(cb->skb).portid,
 949						   cb->nlh->nlmsg_seq);
 950			if (err && err != -EOPNOTSUPP) {
 951				mutex_unlock(&devlink->lock);
 952				goto out;
 953			}
 954		}
 955		mutex_unlock(&devlink->lock);
 956	}
 957out:
 958	mutex_unlock(&devlink_mutex);
 959
 960	cb->args[0] = idx;
 961	return msg->len;
 962}
 963
 964static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
 965			       u16 pool_index, u32 size,
 966			       enum devlink_sb_threshold_type threshold_type)
 967
 968{
 969	const struct devlink_ops *ops = devlink->ops;
 970
 971	if (ops && ops->sb_pool_set)
 972		return ops->sb_pool_set(devlink, sb_index, pool_index,
 973					size, threshold_type);
 974	return -EOPNOTSUPP;
 975}
 976
 977static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb,
 978					   struct genl_info *info)
 979{
 980	struct devlink *devlink = info->user_ptr[0];
 981	struct devlink_sb *devlink_sb = info->user_ptr[1];
 982	enum devlink_sb_threshold_type threshold_type;
 983	u16 pool_index;
 984	u32 size;
 985	int err;
 986
 987	err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
 988						  &pool_index);
 989	if (err)
 990		return err;
 991
 992	err = devlink_sb_th_type_get_from_info(info, &threshold_type);
 993	if (err)
 994		return err;
 995
 996	if (!info->attrs[DEVLINK_ATTR_SB_POOL_SIZE])
 997		return -EINVAL;
 998
 999	size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]);
1000	return devlink_sb_pool_set(devlink, devlink_sb->index,
1001				   pool_index, size, threshold_type);
1002}
1003
1004static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg,
1005					struct devlink *devlink,
1006					struct devlink_port *devlink_port,
1007					struct devlink_sb *devlink_sb,
1008					u16 pool_index,
1009					enum devlink_command cmd,
1010					u32 portid, u32 seq, int flags)
1011{
1012	const struct devlink_ops *ops = devlink->ops;
1013	u32 threshold;
1014	void *hdr;
1015	int err;
1016
1017	err = ops->sb_port_pool_get(devlink_port, devlink_sb->index,
1018				    pool_index, &threshold);
1019	if (err)
1020		return err;
1021
1022	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1023	if (!hdr)
1024		return -EMSGSIZE;
1025
1026	if (devlink_nl_put_handle(msg, devlink))
1027		goto nla_put_failure;
1028	if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1029		goto nla_put_failure;
1030	if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1031		goto nla_put_failure;
1032	if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
1033		goto nla_put_failure;
1034	if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
1035		goto nla_put_failure;
1036
1037	if (ops->sb_occ_port_pool_get) {
1038		u32 cur;
1039		u32 max;
1040
1041		err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index,
1042						pool_index, &cur, &max);
1043		if (err && err != -EOPNOTSUPP)
1044			return err;
1045		if (!err) {
1046			if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
1047				goto nla_put_failure;
1048			if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
1049				goto nla_put_failure;
1050		}
1051	}
1052
1053	genlmsg_end(msg, hdr);
1054	return 0;
1055
1056nla_put_failure:
1057	genlmsg_cancel(msg, hdr);
1058	return -EMSGSIZE;
1059}
1060
1061static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,
1062						struct genl_info *info)
1063{
1064	struct devlink_port *devlink_port = info->user_ptr[0];
1065	struct devlink *devlink = devlink_port->devlink;
1066	struct devlink_sb *devlink_sb = info->user_ptr[1];
1067	struct sk_buff *msg;
1068	u16 pool_index;
1069	int err;
1070
1071	err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1072						  &pool_index);
1073	if (err)
1074		return err;
1075
1076	if (!devlink->ops || !devlink->ops->sb_port_pool_get)
1077		return -EOPNOTSUPP;
1078
1079	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1080	if (!msg)
1081		return -ENOMEM;
1082
1083	err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port,
1084					   devlink_sb, pool_index,
1085					   DEVLINK_CMD_SB_PORT_POOL_NEW,
1086					   info->snd_portid, info->snd_seq, 0);
1087	if (err) {
1088		nlmsg_free(msg);
1089		return err;
1090	}
1091
1092	return genlmsg_reply(msg, info);
1093}
1094
1095static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
1096				     struct devlink *devlink,
1097				     struct devlink_sb *devlink_sb,
1098				     u32 portid, u32 seq)
1099{
1100	struct devlink_port *devlink_port;
1101	u16 pool_count = devlink_sb_pool_count(devlink_sb);
1102	u16 pool_index;
1103	int err;
1104
1105	list_for_each_entry(devlink_port, &devlink->port_list, list) {
1106		for (pool_index = 0; pool_index < pool_count; pool_index++) {
1107			if (*p_idx < start) {
1108				(*p_idx)++;
1109				continue;
1110			}
1111			err = devlink_nl_sb_port_pool_fill(msg, devlink,
1112							   devlink_port,
1113							   devlink_sb,
1114							   pool_index,
1115							   DEVLINK_CMD_SB_PORT_POOL_NEW,
1116							   portid, seq,
1117							   NLM_F_MULTI);
1118			if (err)
1119				return err;
1120			(*p_idx)++;
1121		}
1122	}
1123	return 0;
1124}
1125
1126static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg,
1127						  struct netlink_callback *cb)
1128{
1129	struct devlink *devlink;
1130	struct devlink_sb *devlink_sb;
1131	int start = cb->args[0];
1132	int idx = 0;
1133	int err;
1134
1135	mutex_lock(&devlink_mutex);
1136	list_for_each_entry(devlink, &devlink_list, list) {
1137		if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1138		    !devlink->ops || !devlink->ops->sb_port_pool_get)
1139			continue;
1140		mutex_lock(&devlink->lock);
1141		list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1142			err = __sb_port_pool_get_dumpit(msg, start, &idx,
1143							devlink, devlink_sb,
1144							NETLINK_CB(cb->skb).portid,
1145							cb->nlh->nlmsg_seq);
1146			if (err && err != -EOPNOTSUPP) {
1147				mutex_unlock(&devlink->lock);
1148				goto out;
1149			}
1150		}
1151		mutex_unlock(&devlink->lock);
1152	}
1153out:
1154	mutex_unlock(&devlink_mutex);
1155
1156	cb->args[0] = idx;
1157	return msg->len;
1158}
1159
1160static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
1161				    unsigned int sb_index, u16 pool_index,
1162				    u32 threshold)
1163
1164{
1165	const struct devlink_ops *ops = devlink_port->devlink->ops;
1166
1167	if (ops && ops->sb_port_pool_set)
1168		return ops->sb_port_pool_set(devlink_port, sb_index,
1169					     pool_index, threshold);
1170	return -EOPNOTSUPP;
1171}
1172
1173static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb,
1174						struct genl_info *info)
1175{
1176	struct devlink_port *devlink_port = info->user_ptr[0];
1177	struct devlink_sb *devlink_sb = info->user_ptr[1];
1178	u16 pool_index;
1179	u32 threshold;
1180	int err;
1181
1182	err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1183						  &pool_index);
1184	if (err)
1185		return err;
1186
1187	if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1188		return -EINVAL;
1189
1190	threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1191	return devlink_sb_port_pool_set(devlink_port, devlink_sb->index,
1192					pool_index, threshold);
1193}
1194
1195static int
1196devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink,
1197				struct devlink_port *devlink_port,
1198				struct devlink_sb *devlink_sb, u16 tc_index,
1199				enum devlink_sb_pool_type pool_type,
1200				enum devlink_command cmd,
1201				u32 portid, u32 seq, int flags)
1202{
1203	const struct devlink_ops *ops = devlink->ops;
1204	u16 pool_index;
1205	u32 threshold;
1206	void *hdr;
1207	int err;
1208
1209	err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index,
1210				       tc_index, pool_type,
1211				       &pool_index, &threshold);
1212	if (err)
1213		return err;
1214
1215	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1216	if (!hdr)
1217		return -EMSGSIZE;
1218
1219	if (devlink_nl_put_handle(msg, devlink))
1220		goto nla_put_failure;
1221	if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1222		goto nla_put_failure;
1223	if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1224		goto nla_put_failure;
1225	if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index))
1226		goto nla_put_failure;
1227	if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type))
1228		goto nla_put_failure;
1229	if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
1230		goto nla_put_failure;
1231	if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
1232		goto nla_put_failure;
1233
1234	if (ops->sb_occ_tc_port_bind_get) {
1235		u32 cur;
1236		u32 max;
1237
1238		err = ops->sb_occ_tc_port_bind_get(devlink_port,
1239						   devlink_sb->index,
1240						   tc_index, pool_type,
1241						   &cur, &max);
1242		if (err && err != -EOPNOTSUPP)
1243			return err;
1244		if (!err) {
1245			if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
1246				goto nla_put_failure;
1247			if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
1248				goto nla_put_failure;
1249		}
1250	}
1251
1252	genlmsg_end(msg, hdr);
1253	return 0;
1254
1255nla_put_failure:
1256	genlmsg_cancel(msg, hdr);
1257	return -EMSGSIZE;
1258}
1259
1260static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,
1261						   struct genl_info *info)
1262{
1263	struct devlink_port *devlink_port = info->user_ptr[0];
1264	struct devlink *devlink = devlink_port->devlink;
1265	struct devlink_sb *devlink_sb = info->user_ptr[1];
1266	struct sk_buff *msg;
1267	enum devlink_sb_pool_type pool_type;
1268	u16 tc_index;
1269	int err;
1270
1271	err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1272	if (err)
1273		return err;
1274
1275	err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1276						pool_type, &tc_index);
1277	if (err)
1278		return err;
1279
1280	if (!devlink->ops || !devlink->ops->sb_tc_pool_bind_get)
1281		return -EOPNOTSUPP;
1282
1283	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1284	if (!msg)
1285		return -ENOMEM;
1286
1287	err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port,
1288					      devlink_sb, tc_index, pool_type,
1289					      DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1290					      info->snd_portid,
1291					      info->snd_seq, 0);
1292	if (err) {
1293		nlmsg_free(msg);
1294		return err;
1295	}
1296
1297	return genlmsg_reply(msg, info);
1298}
1299
1300static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1301					int start, int *p_idx,
1302					struct devlink *devlink,
1303					struct devlink_sb *devlink_sb,
1304					u32 portid, u32 seq)
1305{
1306	struct devlink_port *devlink_port;
1307	u16 tc_index;
1308	int err;
1309
1310	list_for_each_entry(devlink_port, &devlink->port_list, list) {
1311		for (tc_index = 0;
1312		     tc_index < devlink_sb->ingress_tc_count; tc_index++) {
1313			if (*p_idx < start) {
1314				(*p_idx)++;
1315				continue;
1316			}
1317			err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1318							      devlink_port,
1319							      devlink_sb,
1320							      tc_index,
1321							      DEVLINK_SB_POOL_TYPE_INGRESS,
1322							      DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1323							      portid, seq,
1324							      NLM_F_MULTI);
1325			if (err)
1326				return err;
1327			(*p_idx)++;
1328		}
1329		for (tc_index = 0;
1330		     tc_index < devlink_sb->egress_tc_count; tc_index++) {
1331			if (*p_idx < start) {
1332				(*p_idx)++;
1333				continue;
1334			}
1335			err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1336							      devlink_port,
1337							      devlink_sb,
1338							      tc_index,
1339							      DEVLINK_SB_POOL_TYPE_EGRESS,
1340							      DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1341							      portid, seq,
1342							      NLM_F_MULTI);
1343			if (err)
1344				return err;
1345			(*p_idx)++;
1346		}
1347	}
1348	return 0;
1349}
1350
1351static int
1352devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1353					  struct netlink_callback *cb)
1354{
1355	struct devlink *devlink;
1356	struct devlink_sb *devlink_sb;
1357	int start = cb->args[0];
1358	int idx = 0;
1359	int err;
1360
1361	mutex_lock(&devlink_mutex);
1362	list_for_each_entry(devlink, &devlink_list, list) {
1363		if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1364		    !devlink->ops || !devlink->ops->sb_tc_pool_bind_get)
1365			continue;
1366
1367		mutex_lock(&devlink->lock);
1368		list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1369			err = __sb_tc_pool_bind_get_dumpit(msg, start, &idx,
1370							   devlink,
1371							   devlink_sb,
1372							   NETLINK_CB(cb->skb).portid,
1373							   cb->nlh->nlmsg_seq);
1374			if (err && err != -EOPNOTSUPP) {
1375				mutex_unlock(&devlink->lock);
1376				goto out;
1377			}
1378		}
1379		mutex_unlock(&devlink->lock);
1380	}
1381out:
1382	mutex_unlock(&devlink_mutex);
1383
1384	cb->args[0] = idx;
1385	return msg->len;
1386}
1387
1388static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port,
1389				       unsigned int sb_index, u16 tc_index,
1390				       enum devlink_sb_pool_type pool_type,
1391				       u16 pool_index, u32 threshold)
1392
1393{
1394	const struct devlink_ops *ops = devlink_port->devlink->ops;
1395
1396	if (ops && ops->sb_tc_pool_bind_set)
1397		return ops->sb_tc_pool_bind_set(devlink_port, sb_index,
1398						tc_index, pool_type,
1399						pool_index, threshold);
1400	return -EOPNOTSUPP;
1401}
1402
1403static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb,
1404						   struct genl_info *info)
1405{
1406	struct devlink_port *devlink_port = info->user_ptr[0];
1407	struct devlink_sb *devlink_sb = info->user_ptr[1];
1408	enum devlink_sb_pool_type pool_type;
1409	u16 tc_index;
1410	u16 pool_index;
1411	u32 threshold;
1412	int err;
1413
1414	err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1415	if (err)
1416		return err;
1417
1418	err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1419						pool_type, &tc_index);
1420	if (err)
1421		return err;
1422
1423	err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1424						  &pool_index);
1425	if (err)
1426		return err;
1427
1428	if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1429		return -EINVAL;
1430
1431	threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1432	return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index,
1433					   tc_index, pool_type,
1434					   pool_index, threshold);
1435}
1436
1437static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
1438					       struct genl_info *info)
1439{
1440	struct devlink *devlink = info->user_ptr[0];
1441	struct devlink_sb *devlink_sb = info->user_ptr[1];
1442	const struct devlink_ops *ops = devlink->ops;
1443
1444	if (ops && ops->sb_occ_snapshot)
1445		return ops->sb_occ_snapshot(devlink, devlink_sb->index);
1446	return -EOPNOTSUPP;
1447}
1448
1449static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
1450						struct genl_info *info)
1451{
1452	struct devlink *devlink = info->user_ptr[0];
1453	struct devlink_sb *devlink_sb = info->user_ptr[1];
1454	const struct devlink_ops *ops = devlink->ops;
1455
1456	if (ops && ops->sb_occ_max_clear)
1457		return ops->sb_occ_max_clear(devlink, devlink_sb->index);
1458	return -EOPNOTSUPP;
1459}
1460
1461static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
1462				   enum devlink_command cmd, u32 portid,
1463				   u32 seq, int flags)
1464{
1465	const struct devlink_ops *ops = devlink->ops;
1466	u8 inline_mode, encap_mode;
1467	void *hdr;
1468	int err = 0;
1469	u16 mode;
1470
1471	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1472	if (!hdr)
1473		return -EMSGSIZE;
1474
1475	err = devlink_nl_put_handle(msg, devlink);
1476	if (err)
1477		goto nla_put_failure;
1478
1479	if (ops->eswitch_mode_get) {
1480		err = ops->eswitch_mode_get(devlink, &mode);
1481		if (err)
1482			goto nla_put_failure;
1483		err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode);
1484		if (err)
1485			goto nla_put_failure;
1486	}
1487
1488	if (ops->eswitch_inline_mode_get) {
1489		err = ops->eswitch_inline_mode_get(devlink, &inline_mode);
1490		if (err)
1491			goto nla_put_failure;
1492		err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE,
1493				 inline_mode);
1494		if (err)
1495			goto nla_put_failure;
1496	}
1497
1498	if (ops->eswitch_encap_mode_get) {
1499		err = ops->eswitch_encap_mode_get(devlink, &encap_mode);
1500		if (err)
1501			goto nla_put_failure;
1502		err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode);
1503		if (err)
1504			goto nla_put_failure;
1505	}
1506
1507	genlmsg_end(msg, hdr);
1508	return 0;
1509
1510nla_put_failure:
1511	genlmsg_cancel(msg, hdr);
1512	return err;
1513}
1514
1515static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb,
1516					   struct genl_info *info)
1517{
1518	struct devlink *devlink = info->user_ptr[0];
1519	const struct devlink_ops *ops = devlink->ops;
1520	struct sk_buff *msg;
1521	int err;
1522
1523	if (!ops)
1524		return -EOPNOTSUPP;
1525
1526	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1527	if (!msg)
1528		return -ENOMEM;
1529
1530	err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET,
1531				      info->snd_portid, info->snd_seq, 0);
1532
1533	if (err) {
1534		nlmsg_free(msg);
1535		return err;
1536	}
1537
1538	return genlmsg_reply(msg, info);
1539}
1540
1541static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb,
1542					   struct genl_info *info)
1543{
1544	struct devlink *devlink = info->user_ptr[0];
1545	const struct devlink_ops *ops = devlink->ops;
1546	u8 inline_mode, encap_mode;
1547	int err = 0;
1548	u16 mode;
1549
1550	if (!ops)
1551		return -EOPNOTSUPP;
1552
1553	if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) {
1554		if (!ops->eswitch_mode_set)
1555			return -EOPNOTSUPP;
1556		mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
1557		err = ops->eswitch_mode_set(devlink, mode);
1558		if (err)
1559			return err;
1560	}
1561
1562	if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) {
1563		if (!ops->eswitch_inline_mode_set)
1564			return -EOPNOTSUPP;
1565		inline_mode = nla_get_u8(
1566				info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]);
1567		err = ops->eswitch_inline_mode_set(devlink, inline_mode);
1568		if (err)
1569			return err;
1570	}
1571
1572	if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) {
1573		if (!ops->eswitch_encap_mode_set)
1574			return -EOPNOTSUPP;
1575		encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]);
1576		err = ops->eswitch_encap_mode_set(devlink, encap_mode);
1577		if (err)
1578			return err;
1579	}
1580
1581	return 0;
1582}
1583
1584int devlink_dpipe_match_put(struct sk_buff *skb,
1585			    struct devlink_dpipe_match *match)
1586{
1587	struct devlink_dpipe_header *header = match->header;
1588	struct devlink_dpipe_field *field = &header->fields[match->field_id];
1589	struct nlattr *match_attr;
1590
1591	match_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_MATCH);
1592	if (!match_attr)
1593		return -EMSGSIZE;
1594
1595	if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) ||
1596	    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) ||
1597	    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
1598	    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
1599	    nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
1600		goto nla_put_failure;
1601
1602	nla_nest_end(skb, match_attr);
1603	return 0;
1604
1605nla_put_failure:
1606	nla_nest_cancel(skb, match_attr);
1607	return -EMSGSIZE;
1608}
1609EXPORT_SYMBOL_GPL(devlink_dpipe_match_put);
1610
1611static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table,
1612				     struct sk_buff *skb)
1613{
1614	struct nlattr *matches_attr;
1615
1616	matches_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLE_MATCHES);
1617	if (!matches_attr)
1618		return -EMSGSIZE;
1619
1620	if (table->table_ops->matches_dump(table->priv, skb))
1621		goto nla_put_failure;
1622
1623	nla_nest_end(skb, matches_attr);
1624	return 0;
1625
1626nla_put_failure:
1627	nla_nest_cancel(skb, matches_attr);
1628	return -EMSGSIZE;
1629}
1630
1631int devlink_dpipe_action_put(struct sk_buff *skb,
1632			     struct devlink_dpipe_action *action)
1633{
1634	struct devlink_dpipe_header *header = action->header;
1635	struct devlink_dpipe_field *field = &header->fields[action->field_id];
1636	struct nlattr *action_attr;
1637
1638	action_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_ACTION);
1639	if (!action_attr)
1640		return -EMSGSIZE;
1641
1642	if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) ||
1643	    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) ||
1644	    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
1645	    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
1646	    nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
1647		goto nla_put_failure;
1648
1649	nla_nest_end(skb, action_attr);
1650	return 0;
1651
1652nla_put_failure:
1653	nla_nest_cancel(skb, action_attr);
1654	return -EMSGSIZE;
1655}
1656EXPORT_SYMBOL_GPL(devlink_dpipe_action_put);
1657
1658static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table,
1659				     struct sk_buff *skb)
1660{
1661	struct nlattr *actions_attr;
1662
1663	actions_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLE_ACTIONS);
1664	if (!actions_attr)
1665		return -EMSGSIZE;
1666
1667	if (table->table_ops->actions_dump(table->priv, skb))
1668		goto nla_put_failure;
1669
1670	nla_nest_end(skb, actions_attr);
1671	return 0;
1672
1673nla_put_failure:
1674	nla_nest_cancel(skb, actions_attr);
1675	return -EMSGSIZE;
1676}
1677
1678static int devlink_dpipe_table_put(struct sk_buff *skb,
1679				   struct devlink_dpipe_table *table)
1680{
1681	struct nlattr *table_attr;
1682	u64 table_size;
1683
1684	table_size = table->table_ops->size_get(table->priv);
1685	table_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLE);
1686	if (!table_attr)
1687		return -EMSGSIZE;
1688
1689	if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) ||
1690	    nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size,
1691			      DEVLINK_ATTR_PAD))
1692		goto nla_put_failure;
1693	if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
1694		       table->counters_enabled))
1695		goto nla_put_failure;
1696
1697	if (table->resource_valid) {
1698		if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID,
1699				      table->resource_id, DEVLINK_ATTR_PAD) ||
1700		    nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS,
1701				      table->resource_units, DEVLINK_ATTR_PAD))
1702			goto nla_put_failure;
1703	}
1704	if (devlink_dpipe_matches_put(table, skb))
1705		goto nla_put_failure;
1706
1707	if (devlink_dpipe_actions_put(table, skb))
1708		goto nla_put_failure;
1709
1710	nla_nest_end(skb, table_attr);
1711	return 0;
1712
1713nla_put_failure:
1714	nla_nest_cancel(skb, table_attr);
1715	return -EMSGSIZE;
1716}
1717
1718static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb,
1719					    struct genl_info *info)
1720{
1721	int err;
1722
1723	if (*pskb) {
1724		err = genlmsg_reply(*pskb, info);
1725		if (err)
1726			return err;
1727	}
1728	*pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
1729	if (!*pskb)
1730		return -ENOMEM;
1731	return 0;
1732}
1733
1734static int devlink_dpipe_tables_fill(struct genl_info *info,
1735				     enum devlink_command cmd, int flags,
1736				     struct list_head *dpipe_tables,
1737				     const char *table_name)
1738{
1739	struct devlink *devlink = info->user_ptr[0];
1740	struct devlink_dpipe_table *table;
1741	struct nlattr *tables_attr;
1742	struct sk_buff *skb = NULL;
1743	struct nlmsghdr *nlh;
1744	bool incomplete;
1745	void *hdr;
1746	int i;
1747	int err;
1748
1749	table = list_first_entry(dpipe_tables,
1750				 struct devlink_dpipe_table, list);
1751start_again:
1752	err = devlink_dpipe_send_and_alloc_skb(&skb, info);
1753	if (err)
1754		return err;
1755
1756	hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
1757			  &devlink_nl_family, NLM_F_MULTI, cmd);
1758	if (!hdr) {
1759		nlmsg_free(skb);
1760		return -EMSGSIZE;
1761	}
1762
1763	if (devlink_nl_put_handle(skb, devlink))
1764		goto nla_put_failure;
1765	tables_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLES);
1766	if (!tables_attr)
1767		goto nla_put_failure;
1768
1769	i = 0;
1770	incomplete = false;
1771	list_for_each_entry_from(table, dpipe_tables, list) {
1772		if (!table_name) {
1773			err = devlink_dpipe_table_put(skb, table);
1774			if (err) {
1775				if (!i)
1776					goto err_table_put;
1777				incomplete = true;
1778				break;
1779			}
1780		} else {
1781			if (!strcmp(table->name, table_name)) {
1782				err = devlink_dpipe_table_put(skb, table);
1783				if (err)
1784					break;
1785			}
1786		}
1787		i++;
1788	}
1789
1790	nla_nest_end(skb, tables_attr);
1791	genlmsg_end(skb, hdr);
1792	if (incomplete)
1793		goto start_again;
1794
1795send_done:
1796	nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
1797			NLMSG_DONE, 0, flags | NLM_F_MULTI);
1798	if (!nlh) {
1799		err = devlink_dpipe_send_and_alloc_skb(&skb, info);
1800		if (err)
1801			return err;
1802		goto send_done;
1803	}
1804
1805	return genlmsg_reply(skb, info);
1806
1807nla_put_failure:
1808	err = -EMSGSIZE;
1809err_table_put:
1810	genlmsg_cancel(skb, hdr);
1811	nlmsg_free(skb);
1812	return err;
1813}
1814
1815static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb,
1816					  struct genl_info *info)
1817{
1818	struct devlink *devlink = info->user_ptr[0];
1819	const char *table_name =  NULL;
1820
1821	if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
1822		table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
1823
1824	return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0,
1825					 &devlink->dpipe_table_list,
1826					 table_name);
1827}
1828
1829static int devlink_dpipe_value_put(struct sk_buff *skb,
1830				   struct devlink_dpipe_value *value)
1831{
1832	if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE,
1833		    value->value_size, value->value))
1834		return -EMSGSIZE;
1835	if (value->mask)
1836		if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK,
1837			    value->value_size, value->mask))
1838			return -EMSGSIZE;
1839	if (value->mapping_valid)
1840		if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING,
1841				value->mapping_value))
1842			return -EMSGSIZE;
1843	return 0;
1844}
1845
1846static int devlink_dpipe_action_value_put(struct sk_buff *skb,
1847					  struct devlink_dpipe_value *value)
1848{
1849	if (!value->action)
1850		return -EINVAL;
1851	if (devlink_dpipe_action_put(skb, value->action))
1852		return -EMSGSIZE;
1853	if (devlink_dpipe_value_put(skb, value))
1854		return -EMSGSIZE;
1855	return 0;
1856}
1857
1858static int devlink_dpipe_action_values_put(struct sk_buff *skb,
1859					   struct devlink_dpipe_value *values,
1860					   unsigned int values_count)
1861{
1862	struct nlattr *action_attr;
1863	int i;
1864	int err;
1865
1866	for (i = 0; i < values_count; i++) {
1867		action_attr = nla_nest_start(skb,
1868					     DEVLINK_ATTR_DPIPE_ACTION_VALUE);
1869		if (!action_attr)
1870			return -EMSGSIZE;
1871		err = devlink_dpipe_action_value_put(skb, &values[i]);
1872		if (err)
1873			goto err_action_value_put;
1874		nla_nest_end(skb, action_attr);
1875	}
1876	return 0;
1877
1878err_action_value_put:
1879	nla_nest_cancel(skb, action_attr);
1880	return err;
1881}
1882
1883static int devlink_dpipe_match_value_put(struct sk_buff *skb,
1884					 struct devlink_dpipe_value *value)
1885{
1886	if (!value->match)
1887		return -EINVAL;
1888	if (devlink_dpipe_match_put(skb, value->match))
1889		return -EMSGSIZE;
1890	if (devlink_dpipe_value_put(skb, value))
1891		return -EMSGSIZE;
1892	return 0;
1893}
1894
1895static int devlink_dpipe_match_values_put(struct sk_buff *skb,
1896					  struct devlink_dpipe_value *values,
1897					  unsigned int values_count)
1898{
1899	struct nlattr *match_attr;
1900	int i;
1901	int err;
1902
1903	for (i = 0; i < values_count; i++) {
1904		match_attr = nla_nest_start(skb,
1905					    DEVLINK_ATTR_DPIPE_MATCH_VALUE);
1906		if (!match_attr)
1907			return -EMSGSIZE;
1908		err = devlink_dpipe_match_value_put(skb, &values[i]);
1909		if (err)
1910			goto err_match_value_put;
1911		nla_nest_end(skb, match_attr);
1912	}
1913	return 0;
1914
1915err_match_value_put:
1916	nla_nest_cancel(skb, match_attr);
1917	return err;
1918}
1919
1920static int devlink_dpipe_entry_put(struct sk_buff *skb,
1921				   struct devlink_dpipe_entry *entry)
1922{
1923	struct nlattr *entry_attr, *matches_attr, *actions_attr;
1924	int err;
1925
1926	entry_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_ENTRY);
1927	if (!entry_attr)
1928		return  -EMSGSIZE;
1929
1930	if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index,
1931			      DEVLINK_ATTR_PAD))
1932		goto nla_put_failure;
1933	if (entry->counter_valid)
1934		if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER,
1935				      entry->counter, DEVLINK_ATTR_PAD))
1936			goto nla_put_failure;
1937
1938	matches_attr = nla_nest_start(skb,
1939				      DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES);
1940	if (!matches_attr)
1941		goto nla_put_failure;
1942
1943	err = devlink_dpipe_match_values_put(skb, entry->match_values,
1944					     entry->match_values_count);
1945	if (err) {
1946		nla_nest_cancel(skb, matches_attr);
1947		goto err_match_values_put;
1948	}
1949	nla_nest_end(skb, matches_attr);
1950
1951	actions_attr = nla_nest_start(skb,
1952				      DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES);
1953	if (!actions_attr)
1954		goto nla_put_failure;
1955
1956	err = devlink_dpipe_action_values_put(skb, entry->action_values,
1957					      entry->action_values_count);
1958	if (err) {
1959		nla_nest_cancel(skb, actions_attr);
1960		goto err_action_values_put;
1961	}
1962	nla_nest_end(skb, actions_attr);
1963
1964	nla_nest_end(skb, entry_attr);
1965	return 0;
1966
1967nla_put_failure:
1968	err = -EMSGSIZE;
1969err_match_values_put:
1970err_action_values_put:
1971	nla_nest_cancel(skb, entry_attr);
1972	return err;
1973}
1974
1975static struct devlink_dpipe_table *
1976devlink_dpipe_table_find(struct list_head *dpipe_tables,
1977			 const char *table_name)
1978{
1979	struct devlink_dpipe_table *table;
1980
1981	list_for_each_entry_rcu(table, dpipe_tables, list) {
1982		if (!strcmp(table->name, table_name))
1983			return table;
1984	}
1985	return NULL;
1986}
1987
1988int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx)
1989{
1990	struct devlink *devlink;
1991	int err;
1992
1993	err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb,
1994					       dump_ctx->info);
1995	if (err)
1996		return err;
1997
1998	dump_ctx->hdr = genlmsg_put(dump_ctx->skb,
1999				    dump_ctx->info->snd_portid,
2000				    dump_ctx->info->snd_seq,
2001				    &devlink_nl_family, NLM_F_MULTI,
2002				    dump_ctx->cmd);
2003	if (!dump_ctx->hdr)
2004		goto nla_put_failure;
2005
2006	devlink = dump_ctx->info->user_ptr[0];
2007	if (devlink_nl_put_handle(dump_ctx->skb, devlink))
2008		goto nla_put_failure;
2009	dump_ctx->nest = nla_nest_start(dump_ctx->skb,
2010					DEVLINK_ATTR_DPIPE_ENTRIES);
2011	if (!dump_ctx->nest)
2012		goto nla_put_failure;
2013	return 0;
2014
2015nla_put_failure:
2016	genlmsg_cancel(dump_ctx->skb, dump_ctx->hdr);
2017	nlmsg_free(dump_ctx->skb);
2018	return -EMSGSIZE;
2019}
2020EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare);
2021
2022int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx,
2023				   struct devlink_dpipe_entry *entry)
2024{
2025	return devlink_dpipe_entry_put(dump_ctx->skb, entry);
2026}
2027EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append);
2028
2029int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx)
2030{
2031	nla_nest_end(dump_ctx->skb, dump_ctx->nest);
2032	genlmsg_end(dump_ctx->skb, dump_ctx->hdr);
2033	return 0;
2034}
2035EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close);
2036
2037void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry)
2038
2039{
2040	unsigned int value_count, value_index;
2041	struct devlink_dpipe_value *value;
2042
2043	value = entry->action_values;
2044	value_count = entry->action_values_count;
2045	for (value_index = 0; value_index < value_count; value_index++) {
2046		kfree(value[value_index].value);
2047		kfree(value[value_index].mask);
2048	}
2049
2050	value = entry->match_values;
2051	value_count = entry->match_values_count;
2052	for (value_index = 0; value_index < value_count; value_index++) {
2053		kfree(value[value_index].value);
2054		kfree(value[value_index].mask);
2055	}
2056}
2057EXPORT_SYMBOL(devlink_dpipe_entry_clear);
2058
2059static int devlink_dpipe_entries_fill(struct genl_info *info,
2060				      enum devlink_command cmd, int flags,
2061				      struct devlink_dpipe_table *table)
2062{
2063	struct devlink_dpipe_dump_ctx dump_ctx;
2064	struct nlmsghdr *nlh;
2065	int err;
2066
2067	dump_ctx.skb = NULL;
2068	dump_ctx.cmd = cmd;
2069	dump_ctx.info = info;
2070
2071	err = table->table_ops->entries_dump(table->priv,
2072					     table->counters_enabled,
2073					     &dump_ctx);
2074	if (err)
2075		return err;
2076
2077send_done:
2078	nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq,
2079			NLMSG_DONE, 0, flags | NLM_F_MULTI);
2080	if (!nlh) {
2081		err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info);
2082		if (err)
2083			return err;
2084		goto send_done;
2085	}
2086	return genlmsg_reply(dump_ctx.skb, info);
2087}
2088
2089static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
2090					    struct genl_info *info)
2091{
2092	struct devlink *devlink = info->user_ptr[0];
2093	struct devlink_dpipe_table *table;
2094	const char *table_name;
2095
2096	if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
2097		return -EINVAL;
2098
2099	table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
2100	table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2101					 table_name);
2102	if (!table)
2103		return -EINVAL;
2104
2105	if (!table->table_ops->entries_dump)
2106		return -EINVAL;
2107
2108	return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET,
2109					  0, table);
2110}
2111
2112static int devlink_dpipe_fields_put(struct sk_buff *skb,
2113				    const struct devlink_dpipe_header *header)
2114{
2115	struct devlink_dpipe_field *field;
2116	struct nlattr *field_attr;
2117	int i;
2118
2119	for (i = 0; i < header->fields_count; i++) {
2120		field = &header->fields[i];
2121		field_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_FIELD);
2122		if (!field_attr)
2123			return -EMSGSIZE;
2124		if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) ||
2125		    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
2126		    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) ||
2127		    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type))
2128			goto nla_put_failure;
2129		nla_nest_end(skb, field_attr);
2130	}
2131	return 0;
2132
2133nla_put_failure:
2134	nla_nest_cancel(skb, field_attr);
2135	return -EMSGSIZE;
2136}
2137
2138static int devlink_dpipe_header_put(struct sk_buff *skb,
2139				    struct devlink_dpipe_header *header)
2140{
2141	struct nlattr *fields_attr, *header_attr;
2142	int err;
2143
2144	header_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_HEADER);
2145	if (!header_attr)
2146		return -EMSGSIZE;
2147
2148	if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) ||
2149	    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
2150	    nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
2151		goto nla_put_failure;
2152
2153	fields_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_HEADER_FIELDS);
2154	if (!fields_attr)
2155		goto nla_put_failure;
2156
2157	err = devlink_dpipe_fields_put(skb, header);
2158	if (err) {
2159		nla_nest_cancel(skb, fields_attr);
2160		goto nla_put_failure;
2161	}
2162	nla_nest_end(skb, fields_attr);
2163	nla_nest_end(skb, header_attr);
2164	return 0;
2165
2166nla_put_failure:
2167	err = -EMSGSIZE;
2168	nla_nest_cancel(skb, header_attr);
2169	return err;
2170}
2171
2172static int devlink_dpipe_headers_fill(struct genl_info *info,
2173				      enum devlink_command cmd, int flags,
2174				      struct devlink_dpipe_headers *
2175				      dpipe_headers)
2176{
2177	struct devlink *devlink = info->user_ptr[0];
2178	struct nlattr *headers_attr;
2179	struct sk_buff *skb = NULL;
2180	struct nlmsghdr *nlh;
2181	void *hdr;
2182	int i, j;
2183	int err;
2184
2185	i = 0;
2186start_again:
2187	err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2188	if (err)
2189		return err;
2190
2191	hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
2192			  &devlink_nl_family, NLM_F_MULTI, cmd);
2193	if (!hdr) {
2194		nlmsg_free(skb);
2195		return -EMSGSIZE;
2196	}
2197
2198	if (devlink_nl_put_handle(skb, devlink))
2199		goto nla_put_failure;
2200	headers_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_HEADERS);
2201	if (!headers_attr)
2202		goto nla_put_failure;
2203
2204	j = 0;
2205	for (; i < dpipe_headers->headers_count; i++) {
2206		err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]);
2207		if (err) {
2208			if (!j)
2209				goto err_table_put;
2210			break;
2211		}
2212		j++;
2213	}
2214	nla_nest_end(skb, headers_attr);
2215	genlmsg_end(skb, hdr);
2216	if (i != dpipe_headers->headers_count)
2217		goto start_again;
2218
2219send_done:
2220	nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
2221			NLMSG_DONE, 0, flags | NLM_F_MULTI);
2222	if (!nlh) {
2223		err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2224		if (err)
2225			return err;
2226		goto send_done;
2227	}
2228	return genlmsg_reply(skb, info);
2229
2230nla_put_failure:
2231	err = -EMSGSIZE;
2232err_table_put:
2233	genlmsg_cancel(skb, hdr);
2234	nlmsg_free(skb);
2235	return err;
2236}
2237
2238static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb,
2239					    struct genl_info *info)
2240{
2241	struct devlink *devlink = info->user_ptr[0];
2242
2243	if (!devlink->dpipe_headers)
2244		return -EOPNOTSUPP;
2245	return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET,
2246					  0, devlink->dpipe_headers);
2247}
2248
2249static int devlink_dpipe_table_counters_set(struct devlink *devlink,
2250					    const char *table_name,
2251					    bool enable)
2252{
2253	struct devlink_dpipe_table *table;
2254
2255	table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2256					 table_name);
2257	if (!table)
2258		return -EINVAL;
2259
2260	if (table->counter_control_extern)
2261		return -EOPNOTSUPP;
2262
2263	if (!(table->counters_enabled ^ enable))
2264		return 0;
2265
2266	table->counters_enabled = enable;
2267	if (table->table_ops->counters_set_update)
2268		table->table_ops->counters_set_update(table->priv, enable);
2269	return 0;
2270}
2271
2272static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb,
2273						   struct genl_info *info)
2274{
2275	struct devlink *devlink = info->user_ptr[0];
2276	const char *table_name;
2277	bool counters_enable;
2278
2279	if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME] ||
2280	    !info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED])
2281		return -EINVAL;
2282
2283	table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
2284	counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]);
2285
2286	return devlink_dpipe_table_counters_set(devlink, table_name,
2287						counters_enable);
2288}
2289
2290static struct devlink_resource *
2291devlink_resource_find(struct devlink *devlink,
2292		      struct devlink_resource *resource, u64 resource_id)
2293{
2294	struct list_head *resource_list;
2295
2296	if (resource)
2297		resource_list = &resource->resource_list;
2298	else
2299		resource_list = &devlink->resource_list;
2300
2301	list_for_each_entry(resource, resource_list, list) {
2302		struct devlink_resource *child_resource;
2303
2304		if (resource->id == resource_id)
2305			return resource;
2306
2307		child_resource = devlink_resource_find(devlink, resource,
2308						       resource_id);
2309		if (child_resource)
2310			return child_resource;
2311	}
2312	return NULL;
2313}
2314
2315static void
2316devlink_resource_validate_children(struct devlink_resource *resource)
2317{
2318	struct devlink_resource *child_resource;
2319	bool size_valid = true;
2320	u64 parts_size = 0;
2321
2322	if (list_empty(&resource->resource_list))
2323		goto out;
2324
2325	list_for_each_entry(child_resource, &resource->resource_list, list)
2326		parts_size += child_resource->size_new;
2327
2328	if (parts_size > resource->size_new)
2329		size_valid = false;
2330out:
2331	resource->size_valid = size_valid;
2332}
2333
2334static int
2335devlink_resource_validate_size(struct devlink_resource *resource, u64 size,
2336			       struct netlink_ext_ack *extack)
2337{
2338	u64 reminder;
2339	int err = 0;
2340
2341	if (size > resource->size_params.size_max) {
2342		NL_SET_ERR_MSG_MOD(extack, "Size larger than maximum");
2343		err = -EINVAL;
2344	}
2345
2346	if (size < resource->size_params.size_min) {
2347		NL_SET_ERR_MSG_MOD(extack, "Size smaller than minimum");
2348		err = -EINVAL;
2349	}
2350
2351	div64_u64_rem(size, resource->size_params.size_granularity, &reminder);
2352	if (reminder) {
2353		NL_SET_ERR_MSG_MOD(extack, "Wrong granularity");
2354		err = -EINVAL;
2355	}
2356
2357	return err;
2358}
2359
2360static int devlink_nl_cmd_resource_set(struct sk_buff *skb,
2361				       struct genl_info *info)
2362{
2363	struct devlink *devlink = info->user_ptr[0];
2364	struct devlink_resource *resource;
2365	u64 resource_id;
2366	u64 size;
2367	int err;
2368
2369	if (!info->attrs[DEVLINK_ATTR_RESOURCE_ID] ||
2370	    !info->attrs[DEVLINK_ATTR_RESOURCE_SIZE])
2371		return -EINVAL;
2372	resource_id = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_ID]);
2373
2374	resource = devlink_resource_find(devlink, NULL, resource_id);
2375	if (!resource)
2376		return -EINVAL;
2377
2378	size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]);
2379	err = devlink_resource_validate_size(resource, size, info->extack);
2380	if (err)
2381		return err;
2382
2383	resource->size_new = size;
2384	devlink_resource_validate_children(resource);
2385	if (resource->parent)
2386		devlink_resource_validate_children(resource->parent);
2387	return 0;
2388}
2389
2390static int
2391devlink_resource_size_params_put(struct devlink_resource *resource,
2392				 struct sk_buff *skb)
2393{
2394	struct devlink_resource_size_params *size_params;
2395
2396	size_params = &resource->size_params;
2397	if (nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_GRAN,
2398			      size_params->size_granularity, DEVLINK_ATTR_PAD) ||
2399	    nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MAX,
2400			      size_params->size_max, DEVLINK_ATTR_PAD) ||
2401	    nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MIN,
2402			      size_params->size_min, DEVLINK_ATTR_PAD) ||
2403	    nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_UNIT, size_params->unit))
2404		return -EMSGSIZE;
2405	return 0;
2406}
2407
2408static int devlink_resource_occ_put(struct devlink_resource *resource,
2409				    struct sk_buff *skb)
2410{
2411	if (!resource->occ_get)
2412		return 0;
2413	return nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_OCC,
2414				 resource->occ_get(resource->occ_get_priv),
2415				 DEVLINK_ATTR_PAD);
2416}
2417
2418static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb,
2419				struct devlink_resource *resource)
2420{
2421	struct devlink_resource *child_resource;
2422	struct nlattr *child_resource_attr;
2423	struct nlattr *resource_attr;
2424
2425	resource_attr = nla_nest_start(skb, DEVLINK_ATTR_RESOURCE);
2426	if (!resource_attr)
2427		return -EMSGSIZE;
2428
2429	if (nla_put_string(skb, DEVLINK_ATTR_RESOURCE_NAME, resource->name) ||
2430	    nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE, resource->size,
2431			      DEVLINK_ATTR_PAD) ||
2432	    nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_ID, resource->id,
2433			      DEVLINK_ATTR_PAD))
2434		goto nla_put_failure;
2435	if (resource->size != resource->size_new)
2436		nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_NEW,
2437				  resource->size_new, DEVLINK_ATTR_PAD);
2438	if (devlink_resource_occ_put(resource, skb))
2439		goto nla_put_failure;
2440	if (devlink_resource_size_params_put(resource, skb))
2441		goto nla_put_failure;
2442	if (list_empty(&resource->resource_list))
2443		goto out;
2444
2445	if (nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_SIZE_VALID,
2446		       resource->size_valid))
2447		goto nla_put_failure;
2448
2449	child_resource_attr = nla_nest_start(skb, DEVLINK_ATTR_RESOURCE_LIST);
2450	if (!child_resource_attr)
2451		goto nla_put_failure;
2452
2453	list_for_each_entry(child_resource, &resource->resource_list, list) {
2454		if (devlink_resource_put(devlink, skb, child_resource))
2455			goto resource_put_failure;
2456	}
2457
2458	nla_nest_end(skb, child_resource_attr);
2459out:
2460	nla_nest_end(skb, resource_attr);
2461	return 0;
2462
2463resource_put_failure:
2464	nla_nest_cancel(skb, child_resource_attr);
2465nla_put_failure:
2466	nla_nest_cancel(skb, resource_attr);
2467	return -EMSGSIZE;
2468}
2469
2470static int devlink_resource_fill(struct genl_info *info,
2471				 enum devlink_command cmd, int flags)
2472{
2473	struct devlink *devlink = info->user_ptr[0];
2474	struct devlink_resource *resource;
2475	struct nlattr *resources_attr;
2476	struct sk_buff *skb = NULL;
2477	struct nlmsghdr *nlh;
2478	bool incomplete;
2479	void *hdr;
2480	int i;
2481	int err;
2482
2483	resource = list_first_entry(&devlink->resource_list,
2484				    struct devlink_resource, list);
2485start_again:
2486	err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2487	if (err)
2488		return err;
2489
2490	hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
2491			  &devlink_nl_family, NLM_F_MULTI, cmd);
2492	if (!hdr) {
2493		nlmsg_free(skb);
2494		return -EMSGSIZE;
2495	}
2496
2497	if (devlink_nl_put_handle(skb, devlink))
2498		goto nla_put_failure;
2499
2500	resources_attr = nla_nest_start(skb, DEVLINK_ATTR_RESOURCE_LIST);
2501	if (!resources_attr)
2502		goto nla_put_failure;
2503
2504	incomplete = false;
2505	i = 0;
2506	list_for_each_entry_from(resource, &devlink->resource_list, list) {
2507		err = devlink_resource_put(devlink, skb, resource);
2508		if (err) {
2509			if (!i)
2510				goto err_resource_put;
2511			incomplete = true;
2512			break;
2513		}
2514		i++;
2515	}
2516	nla_nest_end(skb, resources_attr);
2517	genlmsg_end(skb, hdr);
2518	if (incomplete)
2519		goto start_again;
2520send_done:
2521	nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
2522			NLMSG_DONE, 0, flags | NLM_F_MULTI);
2523	if (!nlh) {
2524		err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2525		if (err)
2526			goto err_skb_send_alloc;
2527		goto send_done;
2528	}
2529	return genlmsg_reply(skb, info);
2530
2531nla_put_failure:
2532	err = -EMSGSIZE;
2533err_resource_put:
2534err_skb_send_alloc:
2535	genlmsg_cancel(skb, hdr);
2536	nlmsg_free(skb);
2537	return err;
2538}
2539
2540static int devlink_nl_cmd_resource_dump(struct sk_buff *skb,
2541					struct genl_info *info)
2542{
2543	struct devlink *devlink = info->user_ptr[0];
2544
2545	if (list_empty(&devlink->resource_list))
2546		return -EOPNOTSUPP;
2547
2548	return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0);
2549}
2550
2551static int
2552devlink_resources_validate(struct devlink *devlink,
2553			   struct devlink_resource *resource,
2554			   struct genl_info *info)
2555{
2556	struct list_head *resource_list;
2557	int err = 0;
2558
2559	if (resource)
2560		resource_list = &resource->resource_list;
2561	else
2562		resource_list = &devlink->resource_list;
2563
2564	list_for_each_entry(resource, resource_list, list) {
2565		if (!resource->size_valid)
2566			return -EINVAL;
2567		err = devlink_resources_validate(devlink, resource, info);
2568		if (err)
2569			return err;
2570	}
2571	return err;
2572}
2573
2574static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
2575{
2576	struct devlink *devlink = info->user_ptr[0];
2577	int err;
2578
2579	if (!devlink->ops->reload)
2580		return -EOPNOTSUPP;
2581
2582	err = devlink_resources_validate(devlink, NULL, info);
2583	if (err) {
2584		NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed");
2585		return err;
2586	}
2587	return devlink->ops->reload(devlink);
2588}
2589
2590static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
2591	[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
2592	[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
2593	[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 },
2594	[DEVLINK_ATTR_PORT_TYPE] = { .type = NLA_U16 },
2595	[DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 },
2596	[DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 },
2597	[DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 },
2598	[DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 },
2599	[DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 },
2600	[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 },
2601	[DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
2602	[DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
2603	[DEVLINK_ATTR_ESWITCH_MODE] = { .type = NLA_U16 },
2604	[DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 },
2605	[DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 },
2606	[DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING },
2607	[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 },
2608	[DEVLINK_ATTR_RESOURCE_ID] = { .type = NLA_U64},
2609	[DEVLINK_ATTR_RESOURCE_SIZE] = { .type = NLA_U64},
2610};
2611
2612static const struct genl_ops devlink_nl_ops[] = {
2613	{
2614		.cmd = DEVLINK_CMD_GET,
2615		.doit = devlink_nl_cmd_get_doit,
2616		.dumpit = devlink_nl_cmd_get_dumpit,
2617		.policy = devlink_nl_policy,
2618		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2619		/* can be retrieved by unprivileged users */
2620	},
2621	{
2622		.cmd = DEVLINK_CMD_PORT_GET,
2623		.doit = devlink_nl_cmd_port_get_doit,
2624		.dumpit = devlink_nl_cmd_port_get_dumpit,
2625		.policy = devlink_nl_policy,
2626		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
2627		/* can be retrieved by unprivileged users */
2628	},
2629	{
2630		.cmd = DEVLINK_CMD_PORT_SET,
2631		.doit = devlink_nl_cmd_port_set_doit,
2632		.policy = devlink_nl_policy,
2633		.flags = GENL_ADMIN_PERM,
2634		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
2635	},
2636	{
2637		.cmd = DEVLINK_CMD_PORT_SPLIT,
2638		.doit = devlink_nl_cmd_port_split_doit,
2639		.policy = devlink_nl_policy,
2640		.flags = GENL_ADMIN_PERM,
2641		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2642				  DEVLINK_NL_FLAG_NO_LOCK,
2643	},
2644	{
2645		.cmd = DEVLINK_CMD_PORT_UNSPLIT,
2646		.doit = devlink_nl_cmd_port_unsplit_doit,
2647		.policy = devlink_nl_policy,
2648		.flags = GENL_ADMIN_PERM,
2649		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2650				  DEVLINK_NL_FLAG_NO_LOCK,
2651	},
2652	{
2653		.cmd = DEVLINK_CMD_SB_GET,
2654		.doit = devlink_nl_cmd_sb_get_doit,
2655		.dumpit = devlink_nl_cmd_sb_get_dumpit,
2656		.policy = devlink_nl_policy,
2657		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2658				  DEVLINK_NL_FLAG_NEED_SB,
2659		/* can be retrieved by unprivileged users */
2660	},
2661	{
2662		.cmd = DEVLINK_CMD_SB_POOL_GET,
2663		.doit = devlink_nl_cmd_sb_pool_get_doit,
2664		.dumpit = devlink_nl_cmd_sb_pool_get_dumpit,
2665		.policy = devlink_nl_policy,
2666		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2667				  DEVLINK_NL_FLAG_NEED_SB,
2668		/* can be retrieved by unprivileged users */
2669	},
2670	{
2671		.cmd = DEVLINK_CMD_SB_POOL_SET,
2672		.doit = devlink_nl_cmd_sb_pool_set_doit,
2673		.policy = devlink_nl_policy,
2674		.flags = GENL_ADMIN_PERM,
2675		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2676				  DEVLINK_NL_FLAG_NEED_SB,
2677	},
2678	{
2679		.cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
2680		.doit = devlink_nl_cmd_sb_port_pool_get_doit,
2681		.dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit,
2682		.policy = devlink_nl_policy,
2683		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
2684				  DEVLINK_NL_FLAG_NEED_SB,
2685		/* can be retrieved by unprivileged users */
2686	},
2687	{
2688		.cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
2689		.doit = devlink_nl_cmd_sb_port_pool_set_doit,
2690		.policy = devlink_nl_policy,
2691		.flags = GENL_ADMIN_PERM,
2692		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
2693				  DEVLINK_NL_FLAG_NEED_SB,
2694	},
2695	{
2696		.cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
2697		.doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
2698		.dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit,
2699		.policy = devlink_nl_policy,
2700		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
2701				  DEVLINK_NL_FLAG_NEED_SB,
2702		/* can be retrieved by unprivileged users */
2703	},
2704	{
2705		.cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
2706		.doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
2707		.policy = devlink_nl_policy,
2708		.flags = GENL_ADMIN_PERM,
2709		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
2710				  DEVLINK_NL_FLAG_NEED_SB,
2711	},
2712	{
2713		.cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
2714		.doit = devlink_nl_cmd_sb_occ_snapshot_doit,
2715		.policy = devlink_nl_policy,
2716		.flags = GENL_ADMIN_PERM,
2717		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2718				  DEVLINK_NL_FLAG_NEED_SB,
2719	},
2720	{
2721		.cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
2722		.doit = devlink_nl_cmd_sb_occ_max_clear_doit,
2723		.policy = devlink_nl_policy,
2724		.flags = GENL_ADMIN_PERM,
2725		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2726				  DEVLINK_NL_FLAG_NEED_SB,
2727	},
2728	{
2729		.cmd = DEVLINK_CMD_ESWITCH_GET,
2730		.doit = devlink_nl_cmd_eswitch_get_doit,
2731		.policy = devlink_nl_policy,
2732		.flags = GENL_ADMIN_PERM,
2733		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2734	},
2735	{
2736		.cmd = DEVLINK_CMD_ESWITCH_SET,
2737		.doit = devlink_nl_cmd_eswitch_set_doit,
2738		.policy = devlink_nl_policy,
2739		.flags = GENL_ADMIN_PERM,
2740		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2741	},
2742	{
2743		.cmd = DEVLINK_CMD_DPIPE_TABLE_GET,
2744		.doit = devlink_nl_cmd_dpipe_table_get,
2745		.policy = devlink_nl_policy,
2746		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2747		/* can be retrieved by unprivileged users */
2748	},
2749	{
2750		.cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET,
2751		.doit = devlink_nl_cmd_dpipe_entries_get,
2752		.policy = devlink_nl_policy,
2753		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2754		/* can be retrieved by unprivileged users */
2755	},
2756	{
2757		.cmd = DEVLINK_CMD_DPIPE_HEADERS_GET,
2758		.doit = devlink_nl_cmd_dpipe_headers_get,
2759		.policy = devlink_nl_policy,
2760		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2761		/* can be retrieved by unprivileged users */
2762	},
2763	{
2764		.cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
2765		.doit = devlink_nl_cmd_dpipe_table_counters_set,
2766		.policy = devlink_nl_policy,
2767		.flags = GENL_ADMIN_PERM,
2768		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2769	},
2770	{
2771		.cmd = DEVLINK_CMD_RESOURCE_SET,
2772		.doit = devlink_nl_cmd_resource_set,
2773		.policy = devlink_nl_policy,
2774		.flags = GENL_ADMIN_PERM,
2775		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2776	},
2777	{
2778		.cmd = DEVLINK_CMD_RESOURCE_DUMP,
2779		.doit = devlink_nl_cmd_resource_dump,
2780		.policy = devlink_nl_policy,
2781		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2782		/* can be retrieved by unprivileged users */
2783	},
2784	{
2785		.cmd = DEVLINK_CMD_RELOAD,
2786		.doit = devlink_nl_cmd_reload,
2787		.policy = devlink_nl_policy,
2788		.flags = GENL_ADMIN_PERM,
2789		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2790				  DEVLINK_NL_FLAG_NO_LOCK,
2791	},
2792};
2793
2794static struct genl_family devlink_nl_family __ro_after_init = {
2795	.name		= DEVLINK_GENL_NAME,
2796	.version	= DEVLINK_GENL_VERSION,
2797	.maxattr	= DEVLINK_ATTR_MAX,
2798	.netnsok	= true,
2799	.pre_doit	= devlink_nl_pre_doit,
2800	.post_doit	= devlink_nl_post_doit,
2801	.module		= THIS_MODULE,
2802	.ops		= devlink_nl_ops,
2803	.n_ops		= ARRAY_SIZE(devlink_nl_ops),
2804	.mcgrps		= devlink_nl_mcgrps,
2805	.n_mcgrps	= ARRAY_SIZE(devlink_nl_mcgrps),
2806};
2807
2808/**
2809 *	devlink_alloc - Allocate new devlink instance resources
2810 *
2811 *	@ops: ops
2812 *	@priv_size: size of user private data
2813 *
2814 *	Allocate new devlink instance resources, including devlink index
2815 *	and name.
2816 */
2817struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
2818{
2819	struct devlink *devlink;
2820
2821	devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
2822	if (!devlink)
2823		return NULL;
2824	devlink->ops = ops;
2825	devlink_net_set(devlink, &init_net);
2826	INIT_LIST_HEAD(&devlink->port_list);
2827	INIT_LIST_HEAD(&devlink->sb_list);
2828	INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list);
2829	INIT_LIST_HEAD(&devlink->resource_list);
2830	mutex_init(&devlink->lock);
2831	return devlink;
2832}
2833EXPORT_SYMBOL_GPL(devlink_alloc);
2834
2835/**
2836 *	devlink_register - Register devlink instance
2837 *
2838 *	@devlink: devlink
2839 */
2840int devlink_register(struct devlink *devlink, struct device *dev)
2841{
2842	mutex_lock(&devlink_mutex);
2843	devlink->dev = dev;
2844	list_add_tail(&devlink->list, &devlink_list);
2845	devlink_notify(devlink, DEVLINK_CMD_NEW);
2846	mutex_unlock(&devlink_mutex);
2847	return 0;
2848}
2849EXPORT_SYMBOL_GPL(devlink_register);
2850
2851/**
2852 *	devlink_unregister - Unregister devlink instance
2853 *
2854 *	@devlink: devlink
2855 */
2856void devlink_unregister(struct devlink *devlink)
2857{
2858	mutex_lock(&devlink_mutex);
2859	devlink_notify(devlink, DEVLINK_CMD_DEL);
2860	list_del(&devlink->list);
2861	mutex_unlock(&devlink_mutex);
2862}
2863EXPORT_SYMBOL_GPL(devlink_unregister);
2864
2865/**
2866 *	devlink_free - Free devlink instance resources
2867 *
2868 *	@devlink: devlink
2869 */
2870void devlink_free(struct devlink *devlink)
2871{
2872	kfree(devlink);
2873}
2874EXPORT_SYMBOL_GPL(devlink_free);
2875
2876/**
2877 *	devlink_port_register - Register devlink port
2878 *
2879 *	@devlink: devlink
2880 *	@devlink_port: devlink port
2881 *	@port_index
2882 *
2883 *	Register devlink port with provided port index. User can use
2884 *	any indexing, even hw-related one. devlink_port structure
2885 *	is convenient to be embedded inside user driver private structure.
2886 *	Note that the caller should take care of zeroing the devlink_port
2887 *	structure.
2888 */
2889int devlink_port_register(struct devlink *devlink,
2890			  struct devlink_port *devlink_port,
2891			  unsigned int port_index)
2892{
2893	mutex_lock(&devlink->lock);
2894	if (devlink_port_index_exists(devlink, port_index)) {
2895		mutex_unlock(&devlink->lock);
2896		return -EEXIST;
2897	}
2898	devlink_port->devlink = devlink;
2899	devlink_port->index = port_index;
2900	devlink_port->registered = true;
2901	list_add_tail(&devlink_port->list, &devlink->port_list);
2902	mutex_unlock(&devlink->lock);
2903	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
2904	return 0;
2905}
2906EXPORT_SYMBOL_GPL(devlink_port_register);
2907
2908/**
2909 *	devlink_port_unregister - Unregister devlink port
2910 *
2911 *	@devlink_port: devlink port
2912 */
2913void devlink_port_unregister(struct devlink_port *devlink_port)
2914{
2915	struct devlink *devlink = devlink_port->devlink;
2916
2917	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
2918	mutex_lock(&devlink->lock);
2919	list_del(&devlink_port->list);
2920	mutex_unlock(&devlink->lock);
2921}
2922EXPORT_SYMBOL_GPL(devlink_port_unregister);
2923
2924static void __devlink_port_type_set(struct devlink_port *devlink_port,
2925				    enum devlink_port_type type,
2926				    void *type_dev)
2927{
2928	devlink_port->type = type;
2929	devlink_port->type_dev = type_dev;
2930	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
2931}
2932
2933/**
2934 *	devlink_port_type_eth_set - Set port type to Ethernet
2935 *
2936 *	@devlink_port: devlink port
2937 *	@netdev: related netdevice
2938 */
2939void devlink_port_type_eth_set(struct devlink_port *devlink_port,
2940			       struct net_device *netdev)
2941{
2942	return __devlink_port_type_set(devlink_port,
2943				       DEVLINK_PORT_TYPE_ETH, netdev);
2944}
2945EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
2946
2947/**
2948 *	devlink_port_type_ib_set - Set port type to InfiniBand
2949 *
2950 *	@devlink_port: devlink port
2951 *	@ibdev: related IB device
2952 */
2953void devlink_port_type_ib_set(struct devlink_port *devlink_port,
2954			      struct ib_device *ibdev)
2955{
2956	return __devlink_port_type_set(devlink_port,
2957				       DEVLINK_PORT_TYPE_IB, ibdev);
2958}
2959EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
2960
2961/**
2962 *	devlink_port_type_clear - Clear port type
2963 *
2964 *	@devlink_port: devlink port
2965 */
2966void devlink_port_type_clear(struct devlink_port *devlink_port)
2967{
2968	return __devlink_port_type_set(devlink_port,
2969				       DEVLINK_PORT_TYPE_NOTSET, NULL);
2970}
2971EXPORT_SYMBOL_GPL(devlink_port_type_clear);
2972
2973/**
2974 *	devlink_port_split_set - Set port is split
2975 *
2976 *	@devlink_port: devlink port
2977 *	@split_group: split group - identifies group split port is part of
2978 */
2979void devlink_port_split_set(struct devlink_port *devlink_port,
2980			    u32 split_group)
2981{
2982	devlink_port->split = true;
2983	devlink_port->split_group = split_group;
2984	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
2985}
2986EXPORT_SYMBOL_GPL(devlink_port_split_set);
2987
2988int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
2989			u32 size, u16 ingress_pools_count,
2990			u16 egress_pools_count, u16 ingress_tc_count,
2991			u16 egress_tc_count)
2992{
2993	struct devlink_sb *devlink_sb;
2994	int err = 0;
2995
2996	mutex_lock(&devlink->lock);
2997	if (devlink_sb_index_exists(devlink, sb_index)) {
2998		err = -EEXIST;
2999		goto unlock;
3000	}
3001
3002	devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
3003	if (!devlink_sb) {
3004		err = -ENOMEM;
3005		goto unlock;
3006	}
3007	devlink_sb->index = sb_index;
3008	devlink_sb->size = size;
3009	devlink_sb->ingress_pools_count = ingress_pools_count;
3010	devlink_sb->egress_pools_count = egress_pools_count;
3011	devlink_sb->ingress_tc_count = ingress_tc_count;
3012	devlink_sb->egress_tc_count = egress_tc_count;
3013	list_add_tail(&devlink_sb->list, &devlink->sb_list);
3014unlock:
3015	mutex_unlock(&devlink->lock);
3016	return err;
3017}
3018EXPORT_SYMBOL_GPL(devlink_sb_register);
3019
3020void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
3021{
3022	struct devlink_sb *devlink_sb;
3023
3024	mutex_lock(&devlink->lock);
3025	devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
3026	WARN_ON(!devlink_sb);
3027	list_del(&devlink_sb->list);
3028	mutex_unlock(&devlink->lock);
3029	kfree(devlink_sb);
3030}
3031EXPORT_SYMBOL_GPL(devlink_sb_unregister);
3032
3033/**
3034 *	devlink_dpipe_headers_register - register dpipe headers
3035 *
3036 *	@devlink: devlink
3037 *	@dpipe_headers: dpipe header array
3038 *
3039 *	Register the headers supported by hardware.
3040 */
3041int devlink_dpipe_headers_register(struct devlink *devlink,
3042				   struct devlink_dpipe_headers *dpipe_headers)
3043{
3044	mutex_lock(&devlink->lock);
3045	devlink->dpipe_headers = dpipe_headers;
3046	mutex_unlock(&devlink->lock);
3047	return 0;
3048}
3049EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register);
3050
3051/**
3052 *	devlink_dpipe_headers_unregister - unregister dpipe headers
3053 *
3054 *	@devlink: devlink
3055 *
3056 *	Unregister the headers supported by hardware.
3057 */
3058void devlink_dpipe_headers_unregister(struct devlink *devlink)
3059{
3060	mutex_lock(&devlink->lock);
3061	devlink->dpipe_headers = NULL;
3062	mutex_unlock(&devlink->lock);
3063}
3064EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister);
3065
3066/**
3067 *	devlink_dpipe_table_counter_enabled - check if counter allocation
3068 *					      required
3069 *	@devlink: devlink
3070 *	@table_name: tables name
3071 *
3072 *	Used by driver to check if counter allocation is required.
3073 *	After counter allocation is turned on the table entries
3074 *	are updated to include counter statistics.
3075 *
3076 *	After that point on the driver must respect the counter
3077 *	state so that each entry added to the table is added
3078 *	with a counter.
3079 */
3080bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
3081					 const char *table_name)
3082{
3083	struct devlink_dpipe_table *table;
3084	bool enabled;
3085
3086	rcu_read_lock();
3087	table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
3088					 table_name);
3089	enabled = false;
3090	if (table)
3091		enabled = table->counters_enabled;
3092	rcu_read_unlock();
3093	return enabled;
3094}
3095EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled);
3096
3097/**
3098 *	devlink_dpipe_table_register - register dpipe table
3099 *
3100 *	@devlink: devlink
3101 *	@table_name: table name
3102 *	@table_ops: table ops
3103 *	@priv: priv
3104 *	@counter_control_extern: external control for counters
3105 */
3106int devlink_dpipe_table_register(struct devlink *devlink,
3107				 const char *table_name,
3108				 struct devlink_dpipe_table_ops *table_ops,
3109				 void *priv, bool counter_control_extern)
3110{
3111	struct devlink_dpipe_table *table;
3112
3113	if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name))
3114		return -EEXIST;
3115
3116	if (WARN_ON(!table_ops->size_get))
3117		return -EINVAL;
3118
3119	table = kzalloc(sizeof(*table), GFP_KERNEL);
3120	if (!table)
3121		return -ENOMEM;
3122
3123	table->name = table_name;
3124	table->table_ops = table_ops;
3125	table->priv = priv;
3126	table->counter_control_extern = counter_control_extern;
3127
3128	mutex_lock(&devlink->lock);
3129	list_add_tail_rcu(&table->list, &devlink->dpipe_table_list);
3130	mutex_unlock(&devlink->lock);
3131	return 0;
3132}
3133EXPORT_SYMBOL_GPL(devlink_dpipe_table_register);
3134
3135/**
3136 *	devlink_dpipe_table_unregister - unregister dpipe table
3137 *
3138 *	@devlink: devlink
3139 *	@table_name: table name
3140 */
3141void devlink_dpipe_table_unregister(struct devlink *devlink,
3142				    const char *table_name)
3143{
3144	struct devlink_dpipe_table *table;
3145
3146	mutex_lock(&devlink->lock);
3147	table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
3148					 table_name);
3149	if (!table)
3150		goto unlock;
3151	list_del_rcu(&table->list);
3152	mutex_unlock(&devlink->lock);
3153	kfree_rcu(table, rcu);
3154	return;
3155unlock:
3156	mutex_unlock(&devlink->lock);
3157}
3158EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister);
3159
3160/**
3161 *	devlink_resource_register - devlink resource register
3162 *
3163 *	@devlink: devlink
3164 *	@resource_name: resource's name
3165 *	@top_hierarchy: top hierarchy
3166 *	@reload_required: reload is required for new configuration to
3167 *			  apply
3168 *	@resource_size: resource's size
3169 *	@resource_id: resource's id
3170 *	@parent_reosurce_id: resource's parent id
3171 *	@size params: size parameters
3172 */
3173int devlink_resource_register(struct devlink *devlink,
3174			      const char *resource_name,
3175			      u64 resource_size,
3176			      u64 resource_id,
3177			      u64 parent_resource_id,
3178			      const struct devlink_resource_size_params *size_params)
3179{
3180	struct devlink_resource *resource;
3181	struct list_head *resource_list;
3182	bool top_hierarchy;
3183	int err = 0;
3184
3185	top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
3186
3187	mutex_lock(&devlink->lock);
3188	resource = devlink_resource_find(devlink, NULL, resource_id);
3189	if (resource) {
3190		err = -EINVAL;
3191		goto out;
3192	}
3193
3194	resource = kzalloc(sizeof(*resource), GFP_KERNEL);
3195	if (!resource) {
3196		err = -ENOMEM;
3197		goto out;
3198	}
3199
3200	if (top_hierarchy) {
3201		resource_list = &devlink->resource_list;
3202	} else {
3203		struct devlink_resource *parent_resource;
3204
3205		parent_resource = devlink_resource_find(devlink, NULL,
3206							parent_resource_id);
3207		if (parent_resource) {
3208			resource_list = &parent_resource->resource_list;
3209			resource->parent = parent_resource;
3210		} else {
3211			kfree(resource);
3212			err = -EINVAL;
3213			goto out;
3214		}
3215	}
3216
3217	resource->name = resource_name;
3218	resource->size = resource_size;
3219	resource->size_new = resource_size;
3220	resource->id = resource_id;
3221	resource->size_valid = true;
3222	memcpy(&resource->size_params, size_params,
3223	       sizeof(resource->size_params));
3224	INIT_LIST_HEAD(&resource->resource_list);
3225	list_add_tail(&resource->list, resource_list);
3226out:
3227	mutex_unlock(&devlink->lock);
3228	return err;
3229}
3230EXPORT_SYMBOL_GPL(devlink_resource_register);
3231
3232/**
3233 *	devlink_resources_unregister - free all resources
3234 *
3235 *	@devlink: devlink
3236 *	@resource: resource
3237 */
3238void devlink_resources_unregister(struct devlink *devlink,
3239				  struct devlink_resource *resource)
3240{
3241	struct devlink_resource *tmp, *child_resource;
3242	struct list_head *resource_list;
3243
3244	if (resource)
3245		resource_list = &resource->resource_list;
3246	else
3247		resource_list = &devlink->resource_list;
3248
3249	if (!resource)
3250		mutex_lock(&devlink->lock);
3251
3252	list_for_each_entry_safe(child_resource, tmp, resource_list, list) {
3253		devlink_resources_unregister(devlink, child_resource);
3254		list_del(&child_resource->list);
3255		kfree(child_resource);
3256	}
3257
3258	if (!resource)
3259		mutex_unlock(&devlink->lock);
3260}
3261EXPORT_SYMBOL_GPL(devlink_resources_unregister);
3262
3263/**
3264 *	devlink_resource_size_get - get and update size
3265 *
3266 *	@devlink: devlink
3267 *	@resource_id: the requested resource id
3268 *	@p_resource_size: ptr to update
3269 */
3270int devlink_resource_size_get(struct devlink *devlink,
3271			      u64 resource_id,
3272			      u64 *p_resource_size)
3273{
3274	struct devlink_resource *resource;
3275	int err = 0;
3276
3277	mutex_lock(&devlink->lock);
3278	resource = devlink_resource_find(devlink, NULL, resource_id);
3279	if (!resource) {
3280		err = -EINVAL;
3281		goto out;
3282	}
3283	*p_resource_size = resource->size_new;
3284	resource->size = resource->size_new;
3285out:
3286	mutex_unlock(&devlink->lock);
3287	return err;
3288}
3289EXPORT_SYMBOL_GPL(devlink_resource_size_get);
3290
3291/**
3292 *	devlink_dpipe_table_resource_set - set the resource id
3293 *
3294 *	@devlink: devlink
3295 *	@table_name: table name
3296 *	@resource_id: resource id
3297 *	@resource_units: number of resource's units consumed per table's entry
3298 */
3299int devlink_dpipe_table_resource_set(struct devlink *devlink,
3300				     const char *table_name, u64 resource_id,
3301				     u64 resource_units)
3302{
3303	struct devlink_dpipe_table *table;
3304	int err = 0;
3305
3306	mutex_lock(&devlink->lock);
3307	table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
3308					 table_name);
3309	if (!table) {
3310		err = -EINVAL;
3311		goto out;
3312	}
3313	table->resource_id = resource_id;
3314	table->resource_units = resource_units;
3315	table->resource_valid = true;
3316out:
3317	mutex_unlock(&devlink->lock);
3318	return err;
3319}
3320EXPORT_SYMBOL_GPL(devlink_dpipe_table_resource_set);
3321
3322/**
3323 *	devlink_resource_occ_get_register - register occupancy getter
3324 *
3325 *	@devlink: devlink
3326 *	@resource_id: resource id
3327 *	@occ_get: occupancy getter callback
3328 *	@occ_get_priv: occupancy getter callback priv
3329 */
3330void devlink_resource_occ_get_register(struct devlink *devlink,
3331				       u64 resource_id,
3332				       devlink_resource_occ_get_t *occ_get,
3333				       void *occ_get_priv)
3334{
3335	struct devlink_resource *resource;
3336
3337	mutex_lock(&devlink->lock);
3338	resource = devlink_resource_find(devlink, NULL, resource_id);
3339	if (WARN_ON(!resource))
3340		goto out;
3341	WARN_ON(resource->occ_get);
3342
3343	resource->occ_get = occ_get;
3344	resource->occ_get_priv = occ_get_priv;
3345out:
3346	mutex_unlock(&devlink->lock);
3347}
3348EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register);
3349
3350/**
3351 *	devlink_resource_occ_get_unregister - unregister occupancy getter
3352 *
3353 *	@devlink: devlink
3354 *	@resource_id: resource id
3355 */
3356void devlink_resource_occ_get_unregister(struct devlink *devlink,
3357					 u64 resource_id)
3358{
3359	struct devlink_resource *resource;
3360
3361	mutex_lock(&devlink->lock);
3362	resource = devlink_resource_find(devlink, NULL, resource_id);
3363	if (WARN_ON(!resource))
3364		goto out;
3365	WARN_ON(!resource->occ_get);
3366
3367	resource->occ_get = NULL;
3368	resource->occ_get_priv = NULL;
3369out:
3370	mutex_unlock(&devlink->lock);
3371}
3372EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister);
3373
3374static int __init devlink_module_init(void)
3375{
3376	return genl_register_family(&devlink_nl_family);
3377}
3378
3379static void __exit devlink_module_exit(void)
3380{
3381	genl_unregister_family(&devlink_nl_family);
3382}
3383
3384module_init(devlink_module_init);
3385module_exit(devlink_module_exit);
3386
3387MODULE_LICENSE("GPL v2");
3388MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
3389MODULE_DESCRIPTION("Network physical device Netlink interface");
3390MODULE_ALIAS_GENL_FAMILY(DEVLINK_GENL_NAME);