Linux Audio

Check our new training course

Loading...
v4.6
  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
 30static LIST_HEAD(devlink_list);
 31
 32/* devlink_mutex
 33 *
 34 * An overall lock guarding every operation coming from userspace.
 35 * It also guards devlink devices list and it is taken when
 36 * driver registers/unregisters it.
 37 */
 38static DEFINE_MUTEX(devlink_mutex);
 39
 40/* devlink_port_mutex
 41 *
 42 * Shared lock to guard lists of ports in all devlink devices.
 43 */
 44static DEFINE_MUTEX(devlink_port_mutex);
 45
 46static struct net *devlink_net(const struct devlink *devlink)
 47{
 48	return read_pnet(&devlink->_net);
 49}
 50
 51static void devlink_net_set(struct devlink *devlink, struct net *net)
 52{
 53	write_pnet(&devlink->_net, net);
 54}
 55
 56static struct devlink *devlink_get_from_attrs(struct net *net,
 57					      struct nlattr **attrs)
 58{
 59	struct devlink *devlink;
 60	char *busname;
 61	char *devname;
 62
 63	if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME])
 64		return ERR_PTR(-EINVAL);
 65
 66	busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]);
 67	devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
 68
 69	list_for_each_entry(devlink, &devlink_list, list) {
 70		if (strcmp(devlink->dev->bus->name, busname) == 0 &&
 71		    strcmp(dev_name(devlink->dev), devname) == 0 &&
 72		    net_eq(devlink_net(devlink), net))
 73			return devlink;
 74	}
 75
 76	return ERR_PTR(-ENODEV);
 77}
 78
 79static struct devlink *devlink_get_from_info(struct genl_info *info)
 80{
 81	return devlink_get_from_attrs(genl_info_net(info), info->attrs);
 82}
 83
 84static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
 85						      int port_index)
 86{
 87	struct devlink_port *devlink_port;
 88
 89	list_for_each_entry(devlink_port, &devlink->port_list, list) {
 90		if (devlink_port->index == port_index)
 91			return devlink_port;
 92	}
 93	return NULL;
 94}
 95
 96static bool devlink_port_index_exists(struct devlink *devlink, int port_index)
 97{
 98	return devlink_port_get_by_index(devlink, port_index);
 99}
100
101static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
102							struct nlattr **attrs)
103{
104	if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
105		u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
106		struct devlink_port *devlink_port;
107
108		devlink_port = devlink_port_get_by_index(devlink, port_index);
109		if (!devlink_port)
110			return ERR_PTR(-ENODEV);
111		return devlink_port;
112	}
113	return ERR_PTR(-EINVAL);
114}
115
116static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
117						       struct genl_info *info)
118{
119	return devlink_port_get_from_attrs(devlink, info->attrs);
120}
121
122#define DEVLINK_NL_FLAG_NEED_PORT	BIT(0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
124static int devlink_nl_pre_doit(const struct genl_ops *ops,
125			       struct sk_buff *skb, struct genl_info *info)
126{
127	struct devlink *devlink;
128
129	mutex_lock(&devlink_mutex);
130	devlink = devlink_get_from_info(info);
131	if (IS_ERR(devlink)) {
132		mutex_unlock(&devlink_mutex);
133		return PTR_ERR(devlink);
134	}
135	info->user_ptr[0] = devlink;
136	if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) {
 
137		struct devlink_port *devlink_port;
138
139		mutex_lock(&devlink_port_mutex);
140		devlink_port = devlink_port_get_from_info(devlink, info);
141		if (IS_ERR(devlink_port)) {
142			mutex_unlock(&devlink_port_mutex);
143			mutex_unlock(&devlink_mutex);
144			return PTR_ERR(devlink_port);
145		}
146		info->user_ptr[1] = devlink_port;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147	}
148	return 0;
149}
150
151static void devlink_nl_post_doit(const struct genl_ops *ops,
152				 struct sk_buff *skb, struct genl_info *info)
153{
154	if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT)
 
155		mutex_unlock(&devlink_port_mutex);
156	mutex_unlock(&devlink_mutex);
157}
158
159static struct genl_family devlink_nl_family = {
160	.id		= GENL_ID_GENERATE,
161	.name		= DEVLINK_GENL_NAME,
162	.version	= DEVLINK_GENL_VERSION,
163	.maxattr	= DEVLINK_ATTR_MAX,
164	.netnsok	= true,
165	.pre_doit	= devlink_nl_pre_doit,
166	.post_doit	= devlink_nl_post_doit,
167};
168
169enum devlink_multicast_groups {
170	DEVLINK_MCGRP_CONFIG,
171};
172
173static const struct genl_multicast_group devlink_nl_mcgrps[] = {
174	[DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME },
175};
176
177static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
178{
179	if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name))
180		return -EMSGSIZE;
181	if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev)))
182		return -EMSGSIZE;
183	return 0;
184}
185
186static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
187			   enum devlink_command cmd, u32 portid,
188			   u32 seq, int flags)
189{
190	void *hdr;
191
192	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
193	if (!hdr)
194		return -EMSGSIZE;
195
196	if (devlink_nl_put_handle(msg, devlink))
197		goto nla_put_failure;
198
199	genlmsg_end(msg, hdr);
200	return 0;
201
202nla_put_failure:
203	genlmsg_cancel(msg, hdr);
204	return -EMSGSIZE;
205}
206
207static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
208{
209	struct sk_buff *msg;
210	int err;
211
212	WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
213
214	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
215	if (!msg)
216		return;
217
218	err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0);
219	if (err) {
220		nlmsg_free(msg);
221		return;
222	}
223
224	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
225				msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
226}
227
228static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
229				struct devlink_port *devlink_port,
230				enum devlink_command cmd, u32 portid,
231				u32 seq, int flags)
232{
233	void *hdr;
234
235	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
236	if (!hdr)
237		return -EMSGSIZE;
238
239	if (devlink_nl_put_handle(msg, devlink))
240		goto nla_put_failure;
241	if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
242		goto nla_put_failure;
243	if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
244		goto nla_put_failure;
245	if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
246	    nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
247			devlink_port->desired_type))
248		goto nla_put_failure;
249	if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
250		struct net_device *netdev = devlink_port->type_dev;
251
252		if (netdev &&
253		    (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
254				 netdev->ifindex) ||
255		     nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
256				    netdev->name)))
257			goto nla_put_failure;
258	}
259	if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
260		struct ib_device *ibdev = devlink_port->type_dev;
261
262		if (ibdev &&
263		    nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
264				   ibdev->name))
265			goto nla_put_failure;
266	}
267	if (devlink_port->split &&
268	    nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
269			devlink_port->split_group))
270		goto nla_put_failure;
271
272	genlmsg_end(msg, hdr);
273	return 0;
274
275nla_put_failure:
276	genlmsg_cancel(msg, hdr);
277	return -EMSGSIZE;
278}
279
280static void devlink_port_notify(struct devlink_port *devlink_port,
281				enum devlink_command cmd)
282{
283	struct devlink *devlink = devlink_port->devlink;
284	struct sk_buff *msg;
285	int err;
286
287	if (!devlink_port->registered)
288		return;
289
290	WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
291
292	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
293	if (!msg)
294		return;
295
296	err = devlink_nl_port_fill(msg, devlink, devlink_port, cmd, 0, 0, 0);
297	if (err) {
298		nlmsg_free(msg);
299		return;
300	}
301
302	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
303				msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
304}
305
306static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
307{
308	struct devlink *devlink = info->user_ptr[0];
309	struct sk_buff *msg;
310	int err;
311
312	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
313	if (!msg)
314		return -ENOMEM;
315
316	err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
317			      info->snd_portid, info->snd_seq, 0);
318	if (err) {
319		nlmsg_free(msg);
320		return err;
321	}
322
323	return genlmsg_reply(msg, info);
324}
325
326static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
327				     struct netlink_callback *cb)
328{
329	struct devlink *devlink;
330	int start = cb->args[0];
331	int idx = 0;
332	int err;
333
334	mutex_lock(&devlink_mutex);
335	list_for_each_entry(devlink, &devlink_list, list) {
336		if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
337			continue;
338		if (idx < start) {
339			idx++;
340			continue;
341		}
342		err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
343				      NETLINK_CB(cb->skb).portid,
344				      cb->nlh->nlmsg_seq, NLM_F_MULTI);
345		if (err)
346			goto out;
347		idx++;
348	}
349out:
350	mutex_unlock(&devlink_mutex);
351
352	cb->args[0] = idx;
353	return msg->len;
354}
355
356static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
357					struct genl_info *info)
358{
359	struct devlink *devlink = info->user_ptr[0];
360	struct devlink_port *devlink_port = info->user_ptr[1];
361	struct sk_buff *msg;
362	int err;
363
364	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
365	if (!msg)
366		return -ENOMEM;
367
368	err = devlink_nl_port_fill(msg, devlink, devlink_port,
369				   DEVLINK_CMD_PORT_NEW,
370				   info->snd_portid, info->snd_seq, 0);
371	if (err) {
372		nlmsg_free(msg);
373		return err;
374	}
375
376	return genlmsg_reply(msg, info);
377}
378
379static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
380					  struct netlink_callback *cb)
381{
382	struct devlink *devlink;
383	struct devlink_port *devlink_port;
384	int start = cb->args[0];
385	int idx = 0;
386	int err;
387
388	mutex_lock(&devlink_mutex);
389	mutex_lock(&devlink_port_mutex);
390	list_for_each_entry(devlink, &devlink_list, list) {
391		if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
392			continue;
393		list_for_each_entry(devlink_port, &devlink->port_list, list) {
394			if (idx < start) {
395				idx++;
396				continue;
397			}
398			err = devlink_nl_port_fill(msg, devlink, devlink_port,
399						   DEVLINK_CMD_NEW,
400						   NETLINK_CB(cb->skb).portid,
401						   cb->nlh->nlmsg_seq,
402						   NLM_F_MULTI);
403			if (err)
404				goto out;
405			idx++;
406		}
407	}
408out:
409	mutex_unlock(&devlink_port_mutex);
410	mutex_unlock(&devlink_mutex);
411
412	cb->args[0] = idx;
413	return msg->len;
414}
415
416static int devlink_port_type_set(struct devlink *devlink,
417				 struct devlink_port *devlink_port,
418				 enum devlink_port_type port_type)
419
420{
421	int err;
422
423	if (devlink->ops && devlink->ops->port_type_set) {
424		if (port_type == DEVLINK_PORT_TYPE_NOTSET)
425			return -EINVAL;
 
 
426		err = devlink->ops->port_type_set(devlink_port, port_type);
427		if (err)
428			return err;
429		devlink_port->desired_type = port_type;
430		devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
431		return 0;
432	}
433	return -EOPNOTSUPP;
434}
435
436static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
437					struct genl_info *info)
438{
439	struct devlink *devlink = info->user_ptr[0];
440	struct devlink_port *devlink_port = info->user_ptr[1];
441	int err;
442
443	if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
444		enum devlink_port_type port_type;
445
446		port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
447		err = devlink_port_type_set(devlink, devlink_port, port_type);
448		if (err)
449			return err;
450	}
451	return 0;
452}
453
454static int devlink_port_split(struct devlink *devlink,
455			      u32 port_index, u32 count)
456
457{
458	if (devlink->ops && devlink->ops->port_split)
459		return devlink->ops->port_split(devlink, port_index, count);
460	return -EOPNOTSUPP;
461}
462
463static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
464					  struct genl_info *info)
465{
466	struct devlink *devlink = info->user_ptr[0];
467	u32 port_index;
468	u32 count;
469
470	if (!info->attrs[DEVLINK_ATTR_PORT_INDEX] ||
471	    !info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT])
472		return -EINVAL;
473
474	port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
475	count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
476	return devlink_port_split(devlink, port_index, count);
477}
478
479static int devlink_port_unsplit(struct devlink *devlink, u32 port_index)
480
481{
482	if (devlink->ops && devlink->ops->port_unsplit)
483		return devlink->ops->port_unsplit(devlink, port_index);
484	return -EOPNOTSUPP;
485}
486
487static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
488					    struct genl_info *info)
489{
490	struct devlink *devlink = info->user_ptr[0];
491	u32 port_index;
492
493	if (!info->attrs[DEVLINK_ATTR_PORT_INDEX])
494		return -EINVAL;
495
496	port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
497	return devlink_port_unsplit(devlink, port_index);
498}
499
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
500static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
501	[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
502	[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
503	[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 },
504	[DEVLINK_ATTR_PORT_TYPE] = { .type = NLA_U16 },
505	[DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 },
 
 
 
 
 
 
 
 
 
506};
507
508static const struct genl_ops devlink_nl_ops[] = {
509	{
510		.cmd = DEVLINK_CMD_GET,
511		.doit = devlink_nl_cmd_get_doit,
512		.dumpit = devlink_nl_cmd_get_dumpit,
513		.policy = devlink_nl_policy,
 
514		/* can be retrieved by unprivileged users */
515	},
516	{
517		.cmd = DEVLINK_CMD_PORT_GET,
518		.doit = devlink_nl_cmd_port_get_doit,
519		.dumpit = devlink_nl_cmd_port_get_dumpit,
520		.policy = devlink_nl_policy,
521		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
522		/* can be retrieved by unprivileged users */
523	},
524	{
525		.cmd = DEVLINK_CMD_PORT_SET,
526		.doit = devlink_nl_cmd_port_set_doit,
527		.policy = devlink_nl_policy,
528		.flags = GENL_ADMIN_PERM,
529		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
530	},
531	{
532		.cmd = DEVLINK_CMD_PORT_SPLIT,
533		.doit = devlink_nl_cmd_port_split_doit,
534		.policy = devlink_nl_policy,
535		.flags = GENL_ADMIN_PERM,
 
536	},
537	{
538		.cmd = DEVLINK_CMD_PORT_UNSPLIT,
539		.doit = devlink_nl_cmd_port_unsplit_doit,
540		.policy = devlink_nl_policy,
541		.flags = GENL_ADMIN_PERM,
 
 
 
 
 
 
 
 
 
 
542	},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
543};
544
545/**
546 *	devlink_alloc - Allocate new devlink instance resources
547 *
548 *	@ops: ops
549 *	@priv_size: size of user private data
550 *
551 *	Allocate new devlink instance resources, including devlink index
552 *	and name.
553 */
554struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
555{
556	struct devlink *devlink;
557
558	devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
559	if (!devlink)
560		return NULL;
561	devlink->ops = ops;
562	devlink_net_set(devlink, &init_net);
563	INIT_LIST_HEAD(&devlink->port_list);
 
564	return devlink;
565}
566EXPORT_SYMBOL_GPL(devlink_alloc);
567
568/**
569 *	devlink_register - Register devlink instance
570 *
571 *	@devlink: devlink
572 */
573int devlink_register(struct devlink *devlink, struct device *dev)
574{
575	mutex_lock(&devlink_mutex);
576	devlink->dev = dev;
577	list_add_tail(&devlink->list, &devlink_list);
578	devlink_notify(devlink, DEVLINK_CMD_NEW);
579	mutex_unlock(&devlink_mutex);
580	return 0;
581}
582EXPORT_SYMBOL_GPL(devlink_register);
583
584/**
585 *	devlink_unregister - Unregister devlink instance
586 *
587 *	@devlink: devlink
588 */
589void devlink_unregister(struct devlink *devlink)
590{
591	mutex_lock(&devlink_mutex);
592	devlink_notify(devlink, DEVLINK_CMD_DEL);
593	list_del(&devlink->list);
594	mutex_unlock(&devlink_mutex);
595}
596EXPORT_SYMBOL_GPL(devlink_unregister);
597
598/**
599 *	devlink_free - Free devlink instance resources
600 *
601 *	@devlink: devlink
602 */
603void devlink_free(struct devlink *devlink)
604{
605	kfree(devlink);
606}
607EXPORT_SYMBOL_GPL(devlink_free);
608
609/**
610 *	devlink_port_register - Register devlink port
611 *
612 *	@devlink: devlink
613 *	@devlink_port: devlink port
614 *	@port_index
615 *
616 *	Register devlink port with provided port index. User can use
617 *	any indexing, even hw-related one. devlink_port structure
618 *	is convenient to be embedded inside user driver private structure.
619 *	Note that the caller should take care of zeroing the devlink_port
620 *	structure.
621 */
622int devlink_port_register(struct devlink *devlink,
623			  struct devlink_port *devlink_port,
624			  unsigned int port_index)
625{
626	mutex_lock(&devlink_port_mutex);
627	if (devlink_port_index_exists(devlink, port_index)) {
628		mutex_unlock(&devlink_port_mutex);
629		return -EEXIST;
630	}
631	devlink_port->devlink = devlink;
632	devlink_port->index = port_index;
633	devlink_port->type = DEVLINK_PORT_TYPE_NOTSET;
634	devlink_port->registered = true;
635	list_add_tail(&devlink_port->list, &devlink->port_list);
636	mutex_unlock(&devlink_port_mutex);
637	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
638	return 0;
639}
640EXPORT_SYMBOL_GPL(devlink_port_register);
641
642/**
643 *	devlink_port_unregister - Unregister devlink port
644 *
645 *	@devlink_port: devlink port
646 */
647void devlink_port_unregister(struct devlink_port *devlink_port)
648{
649	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
650	mutex_lock(&devlink_port_mutex);
651	list_del(&devlink_port->list);
652	mutex_unlock(&devlink_port_mutex);
653}
654EXPORT_SYMBOL_GPL(devlink_port_unregister);
655
656static void __devlink_port_type_set(struct devlink_port *devlink_port,
657				    enum devlink_port_type type,
658				    void *type_dev)
659{
660	devlink_port->type = type;
661	devlink_port->type_dev = type_dev;
662	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
663}
664
665/**
666 *	devlink_port_type_eth_set - Set port type to Ethernet
667 *
668 *	@devlink_port: devlink port
669 *	@netdev: related netdevice
670 */
671void devlink_port_type_eth_set(struct devlink_port *devlink_port,
672			       struct net_device *netdev)
673{
674	return __devlink_port_type_set(devlink_port,
675				       DEVLINK_PORT_TYPE_ETH, netdev);
676}
677EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
678
679/**
680 *	devlink_port_type_ib_set - Set port type to InfiniBand
681 *
682 *	@devlink_port: devlink port
683 *	@ibdev: related IB device
684 */
685void devlink_port_type_ib_set(struct devlink_port *devlink_port,
686			      struct ib_device *ibdev)
687{
688	return __devlink_port_type_set(devlink_port,
689				       DEVLINK_PORT_TYPE_IB, ibdev);
690}
691EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
692
693/**
694 *	devlink_port_type_clear - Clear port type
695 *
696 *	@devlink_port: devlink port
697 */
698void devlink_port_type_clear(struct devlink_port *devlink_port)
699{
700	return __devlink_port_type_set(devlink_port,
701				       DEVLINK_PORT_TYPE_NOTSET, NULL);
702}
703EXPORT_SYMBOL_GPL(devlink_port_type_clear);
704
705/**
706 *	devlink_port_split_set - Set port is split
707 *
708 *	@devlink_port: devlink port
709 *	@split_group: split group - identifies group split port is part of
710 */
711void devlink_port_split_set(struct devlink_port *devlink_port,
712			    u32 split_group)
713{
714	devlink_port->split = true;
715	devlink_port->split_group = split_group;
716	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
717}
718EXPORT_SYMBOL_GPL(devlink_port_split_set);
719
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
720static int __init devlink_module_init(void)
721{
722	return genl_register_family_with_ops_groups(&devlink_nl_family,
723						    devlink_nl_ops,
724						    devlink_nl_mcgrps);
725}
726
727static void __exit devlink_module_exit(void)
728{
729	genl_unregister_family(&devlink_nl_family);
730}
731
732module_init(devlink_module_init);
733module_exit(devlink_module_exit);
734
735MODULE_LICENSE("GPL v2");
736MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
737MODULE_DESCRIPTION("Network physical device Netlink interface");
738MODULE_ALIAS_GENL_FAMILY(DEVLINK_GENL_NAME);
v4.10.11
   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
  32EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg);
  33
  34static LIST_HEAD(devlink_list);
  35
  36/* devlink_mutex
  37 *
  38 * An overall lock guarding every operation coming from userspace.
  39 * It also guards devlink devices list and it is taken when
  40 * driver registers/unregisters it.
  41 */
  42static DEFINE_MUTEX(devlink_mutex);
  43
  44/* devlink_port_mutex
  45 *
  46 * Shared lock to guard lists of ports in all devlink devices.
  47 */
  48static DEFINE_MUTEX(devlink_port_mutex);
  49
  50static struct net *devlink_net(const struct devlink *devlink)
  51{
  52	return read_pnet(&devlink->_net);
  53}
  54
  55static void devlink_net_set(struct devlink *devlink, struct net *net)
  56{
  57	write_pnet(&devlink->_net, net);
  58}
  59
  60static struct devlink *devlink_get_from_attrs(struct net *net,
  61					      struct nlattr **attrs)
  62{
  63	struct devlink *devlink;
  64	char *busname;
  65	char *devname;
  66
  67	if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME])
  68		return ERR_PTR(-EINVAL);
  69
  70	busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]);
  71	devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
  72
  73	list_for_each_entry(devlink, &devlink_list, list) {
  74		if (strcmp(devlink->dev->bus->name, busname) == 0 &&
  75		    strcmp(dev_name(devlink->dev), devname) == 0 &&
  76		    net_eq(devlink_net(devlink), net))
  77			return devlink;
  78	}
  79
  80	return ERR_PTR(-ENODEV);
  81}
  82
  83static struct devlink *devlink_get_from_info(struct genl_info *info)
  84{
  85	return devlink_get_from_attrs(genl_info_net(info), info->attrs);
  86}
  87
  88static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
  89						      int port_index)
  90{
  91	struct devlink_port *devlink_port;
  92
  93	list_for_each_entry(devlink_port, &devlink->port_list, list) {
  94		if (devlink_port->index == port_index)
  95			return devlink_port;
  96	}
  97	return NULL;
  98}
  99
 100static bool devlink_port_index_exists(struct devlink *devlink, int port_index)
 101{
 102	return devlink_port_get_by_index(devlink, port_index);
 103}
 104
 105static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
 106							struct nlattr **attrs)
 107{
 108	if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
 109		u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
 110		struct devlink_port *devlink_port;
 111
 112		devlink_port = devlink_port_get_by_index(devlink, port_index);
 113		if (!devlink_port)
 114			return ERR_PTR(-ENODEV);
 115		return devlink_port;
 116	}
 117	return ERR_PTR(-EINVAL);
 118}
 119
 120static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
 121						       struct genl_info *info)
 122{
 123	return devlink_port_get_from_attrs(devlink, info->attrs);
 124}
 125
 126struct devlink_sb {
 127	struct list_head list;
 128	unsigned int index;
 129	u32 size;
 130	u16 ingress_pools_count;
 131	u16 egress_pools_count;
 132	u16 ingress_tc_count;
 133	u16 egress_tc_count;
 134};
 135
 136static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb)
 137{
 138	return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count;
 139}
 140
 141static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink,
 142						  unsigned int sb_index)
 143{
 144	struct devlink_sb *devlink_sb;
 145
 146	list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
 147		if (devlink_sb->index == sb_index)
 148			return devlink_sb;
 149	}
 150	return NULL;
 151}
 152
 153static bool devlink_sb_index_exists(struct devlink *devlink,
 154				    unsigned int sb_index)
 155{
 156	return devlink_sb_get_by_index(devlink, sb_index);
 157}
 158
 159static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink,
 160						    struct nlattr **attrs)
 161{
 162	if (attrs[DEVLINK_ATTR_SB_INDEX]) {
 163		u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]);
 164		struct devlink_sb *devlink_sb;
 165
 166		devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
 167		if (!devlink_sb)
 168			return ERR_PTR(-ENODEV);
 169		return devlink_sb;
 170	}
 171	return ERR_PTR(-EINVAL);
 172}
 173
 174static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink,
 175						   struct genl_info *info)
 176{
 177	return devlink_sb_get_from_attrs(devlink, info->attrs);
 178}
 179
 180static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb,
 181						struct nlattr **attrs,
 182						u16 *p_pool_index)
 183{
 184	u16 val;
 185
 186	if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX])
 187		return -EINVAL;
 188
 189	val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]);
 190	if (val >= devlink_sb_pool_count(devlink_sb))
 191		return -EINVAL;
 192	*p_pool_index = val;
 193	return 0;
 194}
 195
 196static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb,
 197					       struct genl_info *info,
 198					       u16 *p_pool_index)
 199{
 200	return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs,
 201						    p_pool_index);
 202}
 203
 204static int
 205devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs,
 206				    enum devlink_sb_pool_type *p_pool_type)
 207{
 208	u8 val;
 209
 210	if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE])
 211		return -EINVAL;
 212
 213	val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]);
 214	if (val != DEVLINK_SB_POOL_TYPE_INGRESS &&
 215	    val != DEVLINK_SB_POOL_TYPE_EGRESS)
 216		return -EINVAL;
 217	*p_pool_type = val;
 218	return 0;
 219}
 220
 221static int
 222devlink_sb_pool_type_get_from_info(struct genl_info *info,
 223				   enum devlink_sb_pool_type *p_pool_type)
 224{
 225	return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type);
 226}
 227
 228static int
 229devlink_sb_th_type_get_from_attrs(struct nlattr **attrs,
 230				  enum devlink_sb_threshold_type *p_th_type)
 231{
 232	u8 val;
 233
 234	if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])
 235		return -EINVAL;
 236
 237	val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]);
 238	if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC &&
 239	    val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC)
 240		return -EINVAL;
 241	*p_th_type = val;
 242	return 0;
 243}
 244
 245static int
 246devlink_sb_th_type_get_from_info(struct genl_info *info,
 247				 enum devlink_sb_threshold_type *p_th_type)
 248{
 249	return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type);
 250}
 251
 252static int
 253devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb,
 254				   struct nlattr **attrs,
 255				   enum devlink_sb_pool_type pool_type,
 256				   u16 *p_tc_index)
 257{
 258	u16 val;
 259
 260	if (!attrs[DEVLINK_ATTR_SB_TC_INDEX])
 261		return -EINVAL;
 262
 263	val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]);
 264	if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS &&
 265	    val >= devlink_sb->ingress_tc_count)
 266		return -EINVAL;
 267	if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS &&
 268	    val >= devlink_sb->egress_tc_count)
 269		return -EINVAL;
 270	*p_tc_index = val;
 271	return 0;
 272}
 273
 274static int
 275devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
 276				  struct genl_info *info,
 277				  enum devlink_sb_pool_type pool_type,
 278				  u16 *p_tc_index)
 279{
 280	return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs,
 281						  pool_type, p_tc_index);
 282}
 283
 284#define DEVLINK_NL_FLAG_NEED_DEVLINK	BIT(0)
 285#define DEVLINK_NL_FLAG_NEED_PORT	BIT(1)
 286#define DEVLINK_NL_FLAG_NEED_SB		BIT(2)
 287#define DEVLINK_NL_FLAG_LOCK_PORTS	BIT(3)
 288	/* port is not needed but we need to ensure they don't
 289	 * change in the middle of command
 290	 */
 291
 292static int devlink_nl_pre_doit(const struct genl_ops *ops,
 293			       struct sk_buff *skb, struct genl_info *info)
 294{
 295	struct devlink *devlink;
 296
 297	mutex_lock(&devlink_mutex);
 298	devlink = devlink_get_from_info(info);
 299	if (IS_ERR(devlink)) {
 300		mutex_unlock(&devlink_mutex);
 301		return PTR_ERR(devlink);
 302	}
 303	if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK) {
 304		info->user_ptr[0] = devlink;
 305	} else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) {
 306		struct devlink_port *devlink_port;
 307
 308		mutex_lock(&devlink_port_mutex);
 309		devlink_port = devlink_port_get_from_info(devlink, info);
 310		if (IS_ERR(devlink_port)) {
 311			mutex_unlock(&devlink_port_mutex);
 312			mutex_unlock(&devlink_mutex);
 313			return PTR_ERR(devlink_port);
 314		}
 315		info->user_ptr[0] = devlink_port;
 316	}
 317	if (ops->internal_flags & DEVLINK_NL_FLAG_LOCK_PORTS) {
 318		mutex_lock(&devlink_port_mutex);
 319	}
 320	if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_SB) {
 321		struct devlink_sb *devlink_sb;
 322
 323		devlink_sb = devlink_sb_get_from_info(devlink, info);
 324		if (IS_ERR(devlink_sb)) {
 325			if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT)
 326				mutex_unlock(&devlink_port_mutex);
 327			mutex_unlock(&devlink_mutex);
 328			return PTR_ERR(devlink_sb);
 329		}
 330		info->user_ptr[1] = devlink_sb;
 331	}
 332	return 0;
 333}
 334
 335static void devlink_nl_post_doit(const struct genl_ops *ops,
 336				 struct sk_buff *skb, struct genl_info *info)
 337{
 338	if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT ||
 339	    ops->internal_flags & DEVLINK_NL_FLAG_LOCK_PORTS)
 340		mutex_unlock(&devlink_port_mutex);
 341	mutex_unlock(&devlink_mutex);
 342}
 343
 344static struct genl_family devlink_nl_family;
 
 
 
 
 
 
 
 
 345
 346enum devlink_multicast_groups {
 347	DEVLINK_MCGRP_CONFIG,
 348};
 349
 350static const struct genl_multicast_group devlink_nl_mcgrps[] = {
 351	[DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME },
 352};
 353
 354static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
 355{
 356	if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name))
 357		return -EMSGSIZE;
 358	if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev)))
 359		return -EMSGSIZE;
 360	return 0;
 361}
 362
 363static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
 364			   enum devlink_command cmd, u32 portid,
 365			   u32 seq, int flags)
 366{
 367	void *hdr;
 368
 369	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 370	if (!hdr)
 371		return -EMSGSIZE;
 372
 373	if (devlink_nl_put_handle(msg, devlink))
 374		goto nla_put_failure;
 375
 376	genlmsg_end(msg, hdr);
 377	return 0;
 378
 379nla_put_failure:
 380	genlmsg_cancel(msg, hdr);
 381	return -EMSGSIZE;
 382}
 383
 384static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
 385{
 386	struct sk_buff *msg;
 387	int err;
 388
 389	WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
 390
 391	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 392	if (!msg)
 393		return;
 394
 395	err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0);
 396	if (err) {
 397		nlmsg_free(msg);
 398		return;
 399	}
 400
 401	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
 402				msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
 403}
 404
 405static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
 406				struct devlink_port *devlink_port,
 407				enum devlink_command cmd, u32 portid,
 408				u32 seq, int flags)
 409{
 410	void *hdr;
 411
 412	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 413	if (!hdr)
 414		return -EMSGSIZE;
 415
 416	if (devlink_nl_put_handle(msg, devlink))
 417		goto nla_put_failure;
 418	if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
 419		goto nla_put_failure;
 420	if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
 421		goto nla_put_failure;
 422	if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
 423	    nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
 424			devlink_port->desired_type))
 425		goto nla_put_failure;
 426	if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
 427		struct net_device *netdev = devlink_port->type_dev;
 428
 429		if (netdev &&
 430		    (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
 431				 netdev->ifindex) ||
 432		     nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
 433				    netdev->name)))
 434			goto nla_put_failure;
 435	}
 436	if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
 437		struct ib_device *ibdev = devlink_port->type_dev;
 438
 439		if (ibdev &&
 440		    nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
 441				   ibdev->name))
 442			goto nla_put_failure;
 443	}
 444	if (devlink_port->split &&
 445	    nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
 446			devlink_port->split_group))
 447		goto nla_put_failure;
 448
 449	genlmsg_end(msg, hdr);
 450	return 0;
 451
 452nla_put_failure:
 453	genlmsg_cancel(msg, hdr);
 454	return -EMSGSIZE;
 455}
 456
 457static void devlink_port_notify(struct devlink_port *devlink_port,
 458				enum devlink_command cmd)
 459{
 460	struct devlink *devlink = devlink_port->devlink;
 461	struct sk_buff *msg;
 462	int err;
 463
 464	if (!devlink_port->registered)
 465		return;
 466
 467	WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
 468
 469	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 470	if (!msg)
 471		return;
 472
 473	err = devlink_nl_port_fill(msg, devlink, devlink_port, cmd, 0, 0, 0);
 474	if (err) {
 475		nlmsg_free(msg);
 476		return;
 477	}
 478
 479	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
 480				msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
 481}
 482
 483static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
 484{
 485	struct devlink *devlink = info->user_ptr[0];
 486	struct sk_buff *msg;
 487	int err;
 488
 489	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 490	if (!msg)
 491		return -ENOMEM;
 492
 493	err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
 494			      info->snd_portid, info->snd_seq, 0);
 495	if (err) {
 496		nlmsg_free(msg);
 497		return err;
 498	}
 499
 500	return genlmsg_reply(msg, info);
 501}
 502
 503static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
 504				     struct netlink_callback *cb)
 505{
 506	struct devlink *devlink;
 507	int start = cb->args[0];
 508	int idx = 0;
 509	int err;
 510
 511	mutex_lock(&devlink_mutex);
 512	list_for_each_entry(devlink, &devlink_list, list) {
 513		if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
 514			continue;
 515		if (idx < start) {
 516			idx++;
 517			continue;
 518		}
 519		err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
 520				      NETLINK_CB(cb->skb).portid,
 521				      cb->nlh->nlmsg_seq, NLM_F_MULTI);
 522		if (err)
 523			goto out;
 524		idx++;
 525	}
 526out:
 527	mutex_unlock(&devlink_mutex);
 528
 529	cb->args[0] = idx;
 530	return msg->len;
 531}
 532
 533static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
 534					struct genl_info *info)
 535{
 536	struct devlink_port *devlink_port = info->user_ptr[0];
 537	struct devlink *devlink = devlink_port->devlink;
 538	struct sk_buff *msg;
 539	int err;
 540
 541	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 542	if (!msg)
 543		return -ENOMEM;
 544
 545	err = devlink_nl_port_fill(msg, devlink, devlink_port,
 546				   DEVLINK_CMD_PORT_NEW,
 547				   info->snd_portid, info->snd_seq, 0);
 548	if (err) {
 549		nlmsg_free(msg);
 550		return err;
 551	}
 552
 553	return genlmsg_reply(msg, info);
 554}
 555
 556static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
 557					  struct netlink_callback *cb)
 558{
 559	struct devlink *devlink;
 560	struct devlink_port *devlink_port;
 561	int start = cb->args[0];
 562	int idx = 0;
 563	int err;
 564
 565	mutex_lock(&devlink_mutex);
 566	mutex_lock(&devlink_port_mutex);
 567	list_for_each_entry(devlink, &devlink_list, list) {
 568		if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
 569			continue;
 570		list_for_each_entry(devlink_port, &devlink->port_list, list) {
 571			if (idx < start) {
 572				idx++;
 573				continue;
 574			}
 575			err = devlink_nl_port_fill(msg, devlink, devlink_port,
 576						   DEVLINK_CMD_NEW,
 577						   NETLINK_CB(cb->skb).portid,
 578						   cb->nlh->nlmsg_seq,
 579						   NLM_F_MULTI);
 580			if (err)
 581				goto out;
 582			idx++;
 583		}
 584	}
 585out:
 586	mutex_unlock(&devlink_port_mutex);
 587	mutex_unlock(&devlink_mutex);
 588
 589	cb->args[0] = idx;
 590	return msg->len;
 591}
 592
 593static int devlink_port_type_set(struct devlink *devlink,
 594				 struct devlink_port *devlink_port,
 595				 enum devlink_port_type port_type)
 596
 597{
 598	int err;
 599
 600	if (devlink->ops && devlink->ops->port_type_set) {
 601		if (port_type == DEVLINK_PORT_TYPE_NOTSET)
 602			return -EINVAL;
 603		if (port_type == devlink_port->type)
 604			return 0;
 605		err = devlink->ops->port_type_set(devlink_port, port_type);
 606		if (err)
 607			return err;
 608		devlink_port->desired_type = port_type;
 609		devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
 610		return 0;
 611	}
 612	return -EOPNOTSUPP;
 613}
 614
 615static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
 616					struct genl_info *info)
 617{
 618	struct devlink_port *devlink_port = info->user_ptr[0];
 619	struct devlink *devlink = devlink_port->devlink;
 620	int err;
 621
 622	if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
 623		enum devlink_port_type port_type;
 624
 625		port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
 626		err = devlink_port_type_set(devlink, devlink_port, port_type);
 627		if (err)
 628			return err;
 629	}
 630	return 0;
 631}
 632
 633static int devlink_port_split(struct devlink *devlink,
 634			      u32 port_index, u32 count)
 635
 636{
 637	if (devlink->ops && devlink->ops->port_split)
 638		return devlink->ops->port_split(devlink, port_index, count);
 639	return -EOPNOTSUPP;
 640}
 641
 642static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
 643					  struct genl_info *info)
 644{
 645	struct devlink *devlink = info->user_ptr[0];
 646	u32 port_index;
 647	u32 count;
 648
 649	if (!info->attrs[DEVLINK_ATTR_PORT_INDEX] ||
 650	    !info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT])
 651		return -EINVAL;
 652
 653	port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
 654	count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
 655	return devlink_port_split(devlink, port_index, count);
 656}
 657
 658static int devlink_port_unsplit(struct devlink *devlink, u32 port_index)
 659
 660{
 661	if (devlink->ops && devlink->ops->port_unsplit)
 662		return devlink->ops->port_unsplit(devlink, port_index);
 663	return -EOPNOTSUPP;
 664}
 665
 666static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
 667					    struct genl_info *info)
 668{
 669	struct devlink *devlink = info->user_ptr[0];
 670	u32 port_index;
 671
 672	if (!info->attrs[DEVLINK_ATTR_PORT_INDEX])
 673		return -EINVAL;
 674
 675	port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
 676	return devlink_port_unsplit(devlink, port_index);
 677}
 678
 679static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
 680			      struct devlink_sb *devlink_sb,
 681			      enum devlink_command cmd, u32 portid,
 682			      u32 seq, int flags)
 683{
 684	void *hdr;
 685
 686	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 687	if (!hdr)
 688		return -EMSGSIZE;
 689
 690	if (devlink_nl_put_handle(msg, devlink))
 691		goto nla_put_failure;
 692	if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
 693		goto nla_put_failure;
 694	if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size))
 695		goto nla_put_failure;
 696	if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT,
 697			devlink_sb->ingress_pools_count))
 698		goto nla_put_failure;
 699	if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT,
 700			devlink_sb->egress_pools_count))
 701		goto nla_put_failure;
 702	if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT,
 703			devlink_sb->ingress_tc_count))
 704		goto nla_put_failure;
 705	if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT,
 706			devlink_sb->egress_tc_count))
 707		goto nla_put_failure;
 708
 709	genlmsg_end(msg, hdr);
 710	return 0;
 711
 712nla_put_failure:
 713	genlmsg_cancel(msg, hdr);
 714	return -EMSGSIZE;
 715}
 716
 717static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb,
 718				      struct genl_info *info)
 719{
 720	struct devlink *devlink = info->user_ptr[0];
 721	struct devlink_sb *devlink_sb = info->user_ptr[1];
 722	struct sk_buff *msg;
 723	int err;
 724
 725	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 726	if (!msg)
 727		return -ENOMEM;
 728
 729	err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
 730				 DEVLINK_CMD_SB_NEW,
 731				 info->snd_portid, info->snd_seq, 0);
 732	if (err) {
 733		nlmsg_free(msg);
 734		return err;
 735	}
 736
 737	return genlmsg_reply(msg, info);
 738}
 739
 740static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg,
 741					struct netlink_callback *cb)
 742{
 743	struct devlink *devlink;
 744	struct devlink_sb *devlink_sb;
 745	int start = cb->args[0];
 746	int idx = 0;
 747	int err;
 748
 749	mutex_lock(&devlink_mutex);
 750	list_for_each_entry(devlink, &devlink_list, list) {
 751		if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
 752			continue;
 753		list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
 754			if (idx < start) {
 755				idx++;
 756				continue;
 757			}
 758			err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
 759						 DEVLINK_CMD_SB_NEW,
 760						 NETLINK_CB(cb->skb).portid,
 761						 cb->nlh->nlmsg_seq,
 762						 NLM_F_MULTI);
 763			if (err)
 764				goto out;
 765			idx++;
 766		}
 767	}
 768out:
 769	mutex_unlock(&devlink_mutex);
 770
 771	cb->args[0] = idx;
 772	return msg->len;
 773}
 774
 775static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink,
 776				   struct devlink_sb *devlink_sb,
 777				   u16 pool_index, enum devlink_command cmd,
 778				   u32 portid, u32 seq, int flags)
 779{
 780	struct devlink_sb_pool_info pool_info;
 781	void *hdr;
 782	int err;
 783
 784	err = devlink->ops->sb_pool_get(devlink, devlink_sb->index,
 785					pool_index, &pool_info);
 786	if (err)
 787		return err;
 788
 789	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 790	if (!hdr)
 791		return -EMSGSIZE;
 792
 793	if (devlink_nl_put_handle(msg, devlink))
 794		goto nla_put_failure;
 795	if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
 796		goto nla_put_failure;
 797	if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
 798		goto nla_put_failure;
 799	if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type))
 800		goto nla_put_failure;
 801	if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size))
 802		goto nla_put_failure;
 803	if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE,
 804		       pool_info.threshold_type))
 805		goto nla_put_failure;
 806
 807	genlmsg_end(msg, hdr);
 808	return 0;
 809
 810nla_put_failure:
 811	genlmsg_cancel(msg, hdr);
 812	return -EMSGSIZE;
 813}
 814
 815static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb,
 816					   struct genl_info *info)
 817{
 818	struct devlink *devlink = info->user_ptr[0];
 819	struct devlink_sb *devlink_sb = info->user_ptr[1];
 820	struct sk_buff *msg;
 821	u16 pool_index;
 822	int err;
 823
 824	err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
 825						  &pool_index);
 826	if (err)
 827		return err;
 828
 829	if (!devlink->ops || !devlink->ops->sb_pool_get)
 830		return -EOPNOTSUPP;
 831
 832	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 833	if (!msg)
 834		return -ENOMEM;
 835
 836	err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index,
 837				      DEVLINK_CMD_SB_POOL_NEW,
 838				      info->snd_portid, info->snd_seq, 0);
 839	if (err) {
 840		nlmsg_free(msg);
 841		return err;
 842	}
 843
 844	return genlmsg_reply(msg, info);
 845}
 846
 847static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
 848				struct devlink *devlink,
 849				struct devlink_sb *devlink_sb,
 850				u32 portid, u32 seq)
 851{
 852	u16 pool_count = devlink_sb_pool_count(devlink_sb);
 853	u16 pool_index;
 854	int err;
 855
 856	for (pool_index = 0; pool_index < pool_count; pool_index++) {
 857		if (*p_idx < start) {
 858			(*p_idx)++;
 859			continue;
 860		}
 861		err = devlink_nl_sb_pool_fill(msg, devlink,
 862					      devlink_sb,
 863					      pool_index,
 864					      DEVLINK_CMD_SB_POOL_NEW,
 865					      portid, seq, NLM_F_MULTI);
 866		if (err)
 867			return err;
 868		(*p_idx)++;
 869	}
 870	return 0;
 871}
 872
 873static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg,
 874					     struct netlink_callback *cb)
 875{
 876	struct devlink *devlink;
 877	struct devlink_sb *devlink_sb;
 878	int start = cb->args[0];
 879	int idx = 0;
 880	int err;
 881
 882	mutex_lock(&devlink_mutex);
 883	list_for_each_entry(devlink, &devlink_list, list) {
 884		if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
 885		    !devlink->ops || !devlink->ops->sb_pool_get)
 886			continue;
 887		list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
 888			err = __sb_pool_get_dumpit(msg, start, &idx, devlink,
 889						   devlink_sb,
 890						   NETLINK_CB(cb->skb).portid,
 891						   cb->nlh->nlmsg_seq);
 892			if (err && err != -EOPNOTSUPP)
 893				goto out;
 894		}
 895	}
 896out:
 897	mutex_unlock(&devlink_mutex);
 898
 899	cb->args[0] = idx;
 900	return msg->len;
 901}
 902
 903static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
 904			       u16 pool_index, u32 size,
 905			       enum devlink_sb_threshold_type threshold_type)
 906
 907{
 908	const struct devlink_ops *ops = devlink->ops;
 909
 910	if (ops && ops->sb_pool_set)
 911		return ops->sb_pool_set(devlink, sb_index, pool_index,
 912					size, threshold_type);
 913	return -EOPNOTSUPP;
 914}
 915
 916static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb,
 917					   struct genl_info *info)
 918{
 919	struct devlink *devlink = info->user_ptr[0];
 920	struct devlink_sb *devlink_sb = info->user_ptr[1];
 921	enum devlink_sb_threshold_type threshold_type;
 922	u16 pool_index;
 923	u32 size;
 924	int err;
 925
 926	err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
 927						  &pool_index);
 928	if (err)
 929		return err;
 930
 931	err = devlink_sb_th_type_get_from_info(info, &threshold_type);
 932	if (err)
 933		return err;
 934
 935	if (!info->attrs[DEVLINK_ATTR_SB_POOL_SIZE])
 936		return -EINVAL;
 937
 938	size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]);
 939	return devlink_sb_pool_set(devlink, devlink_sb->index,
 940				   pool_index, size, threshold_type);
 941}
 942
 943static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg,
 944					struct devlink *devlink,
 945					struct devlink_port *devlink_port,
 946					struct devlink_sb *devlink_sb,
 947					u16 pool_index,
 948					enum devlink_command cmd,
 949					u32 portid, u32 seq, int flags)
 950{
 951	const struct devlink_ops *ops = devlink->ops;
 952	u32 threshold;
 953	void *hdr;
 954	int err;
 955
 956	err = ops->sb_port_pool_get(devlink_port, devlink_sb->index,
 957				    pool_index, &threshold);
 958	if (err)
 959		return err;
 960
 961	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 962	if (!hdr)
 963		return -EMSGSIZE;
 964
 965	if (devlink_nl_put_handle(msg, devlink))
 966		goto nla_put_failure;
 967	if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
 968		goto nla_put_failure;
 969	if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
 970		goto nla_put_failure;
 971	if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
 972		goto nla_put_failure;
 973	if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
 974		goto nla_put_failure;
 975
 976	if (ops->sb_occ_port_pool_get) {
 977		u32 cur;
 978		u32 max;
 979
 980		err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index,
 981						pool_index, &cur, &max);
 982		if (err && err != -EOPNOTSUPP)
 983			return err;
 984		if (!err) {
 985			if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
 986				goto nla_put_failure;
 987			if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
 988				goto nla_put_failure;
 989		}
 990	}
 991
 992	genlmsg_end(msg, hdr);
 993	return 0;
 994
 995nla_put_failure:
 996	genlmsg_cancel(msg, hdr);
 997	return -EMSGSIZE;
 998}
 999
1000static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,
1001						struct genl_info *info)
1002{
1003	struct devlink_port *devlink_port = info->user_ptr[0];
1004	struct devlink *devlink = devlink_port->devlink;
1005	struct devlink_sb *devlink_sb = info->user_ptr[1];
1006	struct sk_buff *msg;
1007	u16 pool_index;
1008	int err;
1009
1010	err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1011						  &pool_index);
1012	if (err)
1013		return err;
1014
1015	if (!devlink->ops || !devlink->ops->sb_port_pool_get)
1016		return -EOPNOTSUPP;
1017
1018	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1019	if (!msg)
1020		return -ENOMEM;
1021
1022	err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port,
1023					   devlink_sb, pool_index,
1024					   DEVLINK_CMD_SB_PORT_POOL_NEW,
1025					   info->snd_portid, info->snd_seq, 0);
1026	if (err) {
1027		nlmsg_free(msg);
1028		return err;
1029	}
1030
1031	return genlmsg_reply(msg, info);
1032}
1033
1034static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
1035				     struct devlink *devlink,
1036				     struct devlink_sb *devlink_sb,
1037				     u32 portid, u32 seq)
1038{
1039	struct devlink_port *devlink_port;
1040	u16 pool_count = devlink_sb_pool_count(devlink_sb);
1041	u16 pool_index;
1042	int err;
1043
1044	list_for_each_entry(devlink_port, &devlink->port_list, list) {
1045		for (pool_index = 0; pool_index < pool_count; pool_index++) {
1046			if (*p_idx < start) {
1047				(*p_idx)++;
1048				continue;
1049			}
1050			err = devlink_nl_sb_port_pool_fill(msg, devlink,
1051							   devlink_port,
1052							   devlink_sb,
1053							   pool_index,
1054							   DEVLINK_CMD_SB_PORT_POOL_NEW,
1055							   portid, seq,
1056							   NLM_F_MULTI);
1057			if (err)
1058				return err;
1059			(*p_idx)++;
1060		}
1061	}
1062	return 0;
1063}
1064
1065static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg,
1066						  struct netlink_callback *cb)
1067{
1068	struct devlink *devlink;
1069	struct devlink_sb *devlink_sb;
1070	int start = cb->args[0];
1071	int idx = 0;
1072	int err;
1073
1074	mutex_lock(&devlink_mutex);
1075	mutex_lock(&devlink_port_mutex);
1076	list_for_each_entry(devlink, &devlink_list, list) {
1077		if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1078		    !devlink->ops || !devlink->ops->sb_port_pool_get)
1079			continue;
1080		list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1081			err = __sb_port_pool_get_dumpit(msg, start, &idx,
1082							devlink, devlink_sb,
1083							NETLINK_CB(cb->skb).portid,
1084							cb->nlh->nlmsg_seq);
1085			if (err && err != -EOPNOTSUPP)
1086				goto out;
1087		}
1088	}
1089out:
1090	mutex_unlock(&devlink_port_mutex);
1091	mutex_unlock(&devlink_mutex);
1092
1093	cb->args[0] = idx;
1094	return msg->len;
1095}
1096
1097static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
1098				    unsigned int sb_index, u16 pool_index,
1099				    u32 threshold)
1100
1101{
1102	const struct devlink_ops *ops = devlink_port->devlink->ops;
1103
1104	if (ops && ops->sb_port_pool_set)
1105		return ops->sb_port_pool_set(devlink_port, sb_index,
1106					     pool_index, threshold);
1107	return -EOPNOTSUPP;
1108}
1109
1110static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb,
1111						struct genl_info *info)
1112{
1113	struct devlink_port *devlink_port = info->user_ptr[0];
1114	struct devlink_sb *devlink_sb = info->user_ptr[1];
1115	u16 pool_index;
1116	u32 threshold;
1117	int err;
1118
1119	err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1120						  &pool_index);
1121	if (err)
1122		return err;
1123
1124	if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1125		return -EINVAL;
1126
1127	threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1128	return devlink_sb_port_pool_set(devlink_port, devlink_sb->index,
1129					pool_index, threshold);
1130}
1131
1132static int
1133devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink,
1134				struct devlink_port *devlink_port,
1135				struct devlink_sb *devlink_sb, u16 tc_index,
1136				enum devlink_sb_pool_type pool_type,
1137				enum devlink_command cmd,
1138				u32 portid, u32 seq, int flags)
1139{
1140	const struct devlink_ops *ops = devlink->ops;
1141	u16 pool_index;
1142	u32 threshold;
1143	void *hdr;
1144	int err;
1145
1146	err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index,
1147				       tc_index, pool_type,
1148				       &pool_index, &threshold);
1149	if (err)
1150		return err;
1151
1152	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1153	if (!hdr)
1154		return -EMSGSIZE;
1155
1156	if (devlink_nl_put_handle(msg, devlink))
1157		goto nla_put_failure;
1158	if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1159		goto nla_put_failure;
1160	if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1161		goto nla_put_failure;
1162	if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index))
1163		goto nla_put_failure;
1164	if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type))
1165		goto nla_put_failure;
1166	if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
1167		goto nla_put_failure;
1168	if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
1169		goto nla_put_failure;
1170
1171	if (ops->sb_occ_tc_port_bind_get) {
1172		u32 cur;
1173		u32 max;
1174
1175		err = ops->sb_occ_tc_port_bind_get(devlink_port,
1176						   devlink_sb->index,
1177						   tc_index, pool_type,
1178						   &cur, &max);
1179		if (err && err != -EOPNOTSUPP)
1180			return err;
1181		if (!err) {
1182			if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
1183				goto nla_put_failure;
1184			if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
1185				goto nla_put_failure;
1186		}
1187	}
1188
1189	genlmsg_end(msg, hdr);
1190	return 0;
1191
1192nla_put_failure:
1193	genlmsg_cancel(msg, hdr);
1194	return -EMSGSIZE;
1195}
1196
1197static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,
1198						   struct genl_info *info)
1199{
1200	struct devlink_port *devlink_port = info->user_ptr[0];
1201	struct devlink *devlink = devlink_port->devlink;
1202	struct devlink_sb *devlink_sb = info->user_ptr[1];
1203	struct sk_buff *msg;
1204	enum devlink_sb_pool_type pool_type;
1205	u16 tc_index;
1206	int err;
1207
1208	err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1209	if (err)
1210		return err;
1211
1212	err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1213						pool_type, &tc_index);
1214	if (err)
1215		return err;
1216
1217	if (!devlink->ops || !devlink->ops->sb_tc_pool_bind_get)
1218		return -EOPNOTSUPP;
1219
1220	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1221	if (!msg)
1222		return -ENOMEM;
1223
1224	err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port,
1225					      devlink_sb, tc_index, pool_type,
1226					      DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1227					      info->snd_portid,
1228					      info->snd_seq, 0);
1229	if (err) {
1230		nlmsg_free(msg);
1231		return err;
1232	}
1233
1234	return genlmsg_reply(msg, info);
1235}
1236
1237static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1238					int start, int *p_idx,
1239					struct devlink *devlink,
1240					struct devlink_sb *devlink_sb,
1241					u32 portid, u32 seq)
1242{
1243	struct devlink_port *devlink_port;
1244	u16 tc_index;
1245	int err;
1246
1247	list_for_each_entry(devlink_port, &devlink->port_list, list) {
1248		for (tc_index = 0;
1249		     tc_index < devlink_sb->ingress_tc_count; tc_index++) {
1250			if (*p_idx < start) {
1251				(*p_idx)++;
1252				continue;
1253			}
1254			err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1255							      devlink_port,
1256							      devlink_sb,
1257							      tc_index,
1258							      DEVLINK_SB_POOL_TYPE_INGRESS,
1259							      DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1260							      portid, seq,
1261							      NLM_F_MULTI);
1262			if (err)
1263				return err;
1264			(*p_idx)++;
1265		}
1266		for (tc_index = 0;
1267		     tc_index < devlink_sb->egress_tc_count; tc_index++) {
1268			if (*p_idx < start) {
1269				(*p_idx)++;
1270				continue;
1271			}
1272			err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1273							      devlink_port,
1274							      devlink_sb,
1275							      tc_index,
1276							      DEVLINK_SB_POOL_TYPE_EGRESS,
1277							      DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1278							      portid, seq,
1279							      NLM_F_MULTI);
1280			if (err)
1281				return err;
1282			(*p_idx)++;
1283		}
1284	}
1285	return 0;
1286}
1287
1288static int
1289devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1290					  struct netlink_callback *cb)
1291{
1292	struct devlink *devlink;
1293	struct devlink_sb *devlink_sb;
1294	int start = cb->args[0];
1295	int idx = 0;
1296	int err;
1297
1298	mutex_lock(&devlink_mutex);
1299	mutex_lock(&devlink_port_mutex);
1300	list_for_each_entry(devlink, &devlink_list, list) {
1301		if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1302		    !devlink->ops || !devlink->ops->sb_tc_pool_bind_get)
1303			continue;
1304		list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1305			err = __sb_tc_pool_bind_get_dumpit(msg, start, &idx,
1306							   devlink,
1307							   devlink_sb,
1308							   NETLINK_CB(cb->skb).portid,
1309							   cb->nlh->nlmsg_seq);
1310			if (err && err != -EOPNOTSUPP)
1311				goto out;
1312		}
1313	}
1314out:
1315	mutex_unlock(&devlink_port_mutex);
1316	mutex_unlock(&devlink_mutex);
1317
1318	cb->args[0] = idx;
1319	return msg->len;
1320}
1321
1322static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port,
1323				       unsigned int sb_index, u16 tc_index,
1324				       enum devlink_sb_pool_type pool_type,
1325				       u16 pool_index, u32 threshold)
1326
1327{
1328	const struct devlink_ops *ops = devlink_port->devlink->ops;
1329
1330	if (ops && ops->sb_tc_pool_bind_set)
1331		return ops->sb_tc_pool_bind_set(devlink_port, sb_index,
1332						tc_index, pool_type,
1333						pool_index, threshold);
1334	return -EOPNOTSUPP;
1335}
1336
1337static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb,
1338						   struct genl_info *info)
1339{
1340	struct devlink_port *devlink_port = info->user_ptr[0];
1341	struct devlink_sb *devlink_sb = info->user_ptr[1];
1342	enum devlink_sb_pool_type pool_type;
1343	u16 tc_index;
1344	u16 pool_index;
1345	u32 threshold;
1346	int err;
1347
1348	err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1349	if (err)
1350		return err;
1351
1352	err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1353						pool_type, &tc_index);
1354	if (err)
1355		return err;
1356
1357	err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1358						  &pool_index);
1359	if (err)
1360		return err;
1361
1362	if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1363		return -EINVAL;
1364
1365	threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1366	return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index,
1367					   tc_index, pool_type,
1368					   pool_index, threshold);
1369}
1370
1371static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
1372					       struct genl_info *info)
1373{
1374	struct devlink *devlink = info->user_ptr[0];
1375	struct devlink_sb *devlink_sb = info->user_ptr[1];
1376	const struct devlink_ops *ops = devlink->ops;
1377
1378	if (ops && ops->sb_occ_snapshot)
1379		return ops->sb_occ_snapshot(devlink, devlink_sb->index);
1380	return -EOPNOTSUPP;
1381}
1382
1383static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
1384						struct genl_info *info)
1385{
1386	struct devlink *devlink = info->user_ptr[0];
1387	struct devlink_sb *devlink_sb = info->user_ptr[1];
1388	const struct devlink_ops *ops = devlink->ops;
1389
1390	if (ops && ops->sb_occ_max_clear)
1391		return ops->sb_occ_max_clear(devlink, devlink_sb->index);
1392	return -EOPNOTSUPP;
1393}
1394
1395static int devlink_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
1396				enum devlink_command cmd, u32 portid,
1397				u32 seq, int flags)
1398{
1399	const struct devlink_ops *ops = devlink->ops;
1400	void *hdr;
1401	int err = 0;
1402	u16 mode;
1403	u8 inline_mode;
1404
1405	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1406	if (!hdr)
1407		return -EMSGSIZE;
1408
1409	err = devlink_nl_put_handle(msg, devlink);
1410	if (err)
1411		goto out;
1412
1413	err = ops->eswitch_mode_get(devlink, &mode);
1414	if (err)
1415		goto out;
1416	err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode);
1417	if (err)
1418		goto out;
1419
1420	if (ops->eswitch_inline_mode_get) {
1421		err = ops->eswitch_inline_mode_get(devlink, &inline_mode);
1422		if (err)
1423			goto out;
1424		err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE,
1425				 inline_mode);
1426		if (err)
1427			goto out;
1428	}
1429
1430	genlmsg_end(msg, hdr);
1431	return 0;
1432
1433out:
1434	genlmsg_cancel(msg, hdr);
1435	return err;
1436}
1437
1438static int devlink_nl_cmd_eswitch_mode_get_doit(struct sk_buff *skb,
1439						struct genl_info *info)
1440{
1441	struct devlink *devlink = info->user_ptr[0];
1442	const struct devlink_ops *ops = devlink->ops;
1443	struct sk_buff *msg;
1444	int err;
1445
1446	if (!ops || !ops->eswitch_mode_get)
1447		return -EOPNOTSUPP;
1448
1449	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1450	if (!msg)
1451		return -ENOMEM;
1452
1453	err = devlink_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_MODE_GET,
1454				   info->snd_portid, info->snd_seq, 0);
1455
1456	if (err) {
1457		nlmsg_free(msg);
1458		return err;
1459	}
1460
1461	return genlmsg_reply(msg, info);
1462}
1463
1464static int devlink_nl_cmd_eswitch_mode_set_doit(struct sk_buff *skb,
1465						struct genl_info *info)
1466{
1467	struct devlink *devlink = info->user_ptr[0];
1468	const struct devlink_ops *ops = devlink->ops;
1469	u16 mode;
1470	u8 inline_mode;
1471	int err = 0;
1472
1473	if (!ops)
1474		return -EOPNOTSUPP;
1475
1476	if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) {
1477		if (!ops->eswitch_mode_set)
1478			return -EOPNOTSUPP;
1479		mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
1480		err = ops->eswitch_mode_set(devlink, mode);
1481		if (err)
1482			return err;
1483	}
1484
1485	if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) {
1486		if (!ops->eswitch_inline_mode_set)
1487			return -EOPNOTSUPP;
1488		inline_mode = nla_get_u8(
1489				info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]);
1490		err = ops->eswitch_inline_mode_set(devlink, inline_mode);
1491		if (err)
1492			return err;
1493	}
1494
1495	return 0;
1496}
1497
1498static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
1499	[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
1500	[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
1501	[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 },
1502	[DEVLINK_ATTR_PORT_TYPE] = { .type = NLA_U16 },
1503	[DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 },
1504	[DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 },
1505	[DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 },
1506	[DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 },
1507	[DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 },
1508	[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 },
1509	[DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
1510	[DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
1511	[DEVLINK_ATTR_ESWITCH_MODE] = { .type = NLA_U16 },
1512	[DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 },
1513};
1514
1515static const struct genl_ops devlink_nl_ops[] = {
1516	{
1517		.cmd = DEVLINK_CMD_GET,
1518		.doit = devlink_nl_cmd_get_doit,
1519		.dumpit = devlink_nl_cmd_get_dumpit,
1520		.policy = devlink_nl_policy,
1521		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
1522		/* can be retrieved by unprivileged users */
1523	},
1524	{
1525		.cmd = DEVLINK_CMD_PORT_GET,
1526		.doit = devlink_nl_cmd_port_get_doit,
1527		.dumpit = devlink_nl_cmd_port_get_dumpit,
1528		.policy = devlink_nl_policy,
1529		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
1530		/* can be retrieved by unprivileged users */
1531	},
1532	{
1533		.cmd = DEVLINK_CMD_PORT_SET,
1534		.doit = devlink_nl_cmd_port_set_doit,
1535		.policy = devlink_nl_policy,
1536		.flags = GENL_ADMIN_PERM,
1537		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
1538	},
1539	{
1540		.cmd = DEVLINK_CMD_PORT_SPLIT,
1541		.doit = devlink_nl_cmd_port_split_doit,
1542		.policy = devlink_nl_policy,
1543		.flags = GENL_ADMIN_PERM,
1544		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
1545	},
1546	{
1547		.cmd = DEVLINK_CMD_PORT_UNSPLIT,
1548		.doit = devlink_nl_cmd_port_unsplit_doit,
1549		.policy = devlink_nl_policy,
1550		.flags = GENL_ADMIN_PERM,
1551		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
1552	},
1553	{
1554		.cmd = DEVLINK_CMD_SB_GET,
1555		.doit = devlink_nl_cmd_sb_get_doit,
1556		.dumpit = devlink_nl_cmd_sb_get_dumpit,
1557		.policy = devlink_nl_policy,
1558		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
1559				  DEVLINK_NL_FLAG_NEED_SB,
1560		/* can be retrieved by unprivileged users */
1561	},
1562	{
1563		.cmd = DEVLINK_CMD_SB_POOL_GET,
1564		.doit = devlink_nl_cmd_sb_pool_get_doit,
1565		.dumpit = devlink_nl_cmd_sb_pool_get_dumpit,
1566		.policy = devlink_nl_policy,
1567		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
1568				  DEVLINK_NL_FLAG_NEED_SB,
1569		/* can be retrieved by unprivileged users */
1570	},
1571	{
1572		.cmd = DEVLINK_CMD_SB_POOL_SET,
1573		.doit = devlink_nl_cmd_sb_pool_set_doit,
1574		.policy = devlink_nl_policy,
1575		.flags = GENL_ADMIN_PERM,
1576		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
1577				  DEVLINK_NL_FLAG_NEED_SB,
1578	},
1579	{
1580		.cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
1581		.doit = devlink_nl_cmd_sb_port_pool_get_doit,
1582		.dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit,
1583		.policy = devlink_nl_policy,
1584		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
1585				  DEVLINK_NL_FLAG_NEED_SB,
1586		/* can be retrieved by unprivileged users */
1587	},
1588	{
1589		.cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
1590		.doit = devlink_nl_cmd_sb_port_pool_set_doit,
1591		.policy = devlink_nl_policy,
1592		.flags = GENL_ADMIN_PERM,
1593		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
1594				  DEVLINK_NL_FLAG_NEED_SB,
1595	},
1596	{
1597		.cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
1598		.doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
1599		.dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit,
1600		.policy = devlink_nl_policy,
1601		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
1602				  DEVLINK_NL_FLAG_NEED_SB,
1603		/* can be retrieved by unprivileged users */
1604	},
1605	{
1606		.cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
1607		.doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
1608		.policy = devlink_nl_policy,
1609		.flags = GENL_ADMIN_PERM,
1610		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
1611				  DEVLINK_NL_FLAG_NEED_SB,
1612	},
1613	{
1614		.cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
1615		.doit = devlink_nl_cmd_sb_occ_snapshot_doit,
1616		.policy = devlink_nl_policy,
1617		.flags = GENL_ADMIN_PERM,
1618		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
1619				  DEVLINK_NL_FLAG_NEED_SB |
1620				  DEVLINK_NL_FLAG_LOCK_PORTS,
1621	},
1622	{
1623		.cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
1624		.doit = devlink_nl_cmd_sb_occ_max_clear_doit,
1625		.policy = devlink_nl_policy,
1626		.flags = GENL_ADMIN_PERM,
1627		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
1628				  DEVLINK_NL_FLAG_NEED_SB |
1629				  DEVLINK_NL_FLAG_LOCK_PORTS,
1630	},
1631	{
1632		.cmd = DEVLINK_CMD_ESWITCH_MODE_GET,
1633		.doit = devlink_nl_cmd_eswitch_mode_get_doit,
1634		.policy = devlink_nl_policy,
1635		.flags = GENL_ADMIN_PERM,
1636		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
1637	},
1638	{
1639		.cmd = DEVLINK_CMD_ESWITCH_MODE_SET,
1640		.doit = devlink_nl_cmd_eswitch_mode_set_doit,
1641		.policy = devlink_nl_policy,
1642		.flags = GENL_ADMIN_PERM,
1643		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
1644	},
1645};
1646
1647static struct genl_family devlink_nl_family __ro_after_init = {
1648	.name		= DEVLINK_GENL_NAME,
1649	.version	= DEVLINK_GENL_VERSION,
1650	.maxattr	= DEVLINK_ATTR_MAX,
1651	.netnsok	= true,
1652	.pre_doit	= devlink_nl_pre_doit,
1653	.post_doit	= devlink_nl_post_doit,
1654	.module		= THIS_MODULE,
1655	.ops		= devlink_nl_ops,
1656	.n_ops		= ARRAY_SIZE(devlink_nl_ops),
1657	.mcgrps		= devlink_nl_mcgrps,
1658	.n_mcgrps	= ARRAY_SIZE(devlink_nl_mcgrps),
1659};
1660
1661/**
1662 *	devlink_alloc - Allocate new devlink instance resources
1663 *
1664 *	@ops: ops
1665 *	@priv_size: size of user private data
1666 *
1667 *	Allocate new devlink instance resources, including devlink index
1668 *	and name.
1669 */
1670struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
1671{
1672	struct devlink *devlink;
1673
1674	devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
1675	if (!devlink)
1676		return NULL;
1677	devlink->ops = ops;
1678	devlink_net_set(devlink, &init_net);
1679	INIT_LIST_HEAD(&devlink->port_list);
1680	INIT_LIST_HEAD(&devlink->sb_list);
1681	return devlink;
1682}
1683EXPORT_SYMBOL_GPL(devlink_alloc);
1684
1685/**
1686 *	devlink_register - Register devlink instance
1687 *
1688 *	@devlink: devlink
1689 */
1690int devlink_register(struct devlink *devlink, struct device *dev)
1691{
1692	mutex_lock(&devlink_mutex);
1693	devlink->dev = dev;
1694	list_add_tail(&devlink->list, &devlink_list);
1695	devlink_notify(devlink, DEVLINK_CMD_NEW);
1696	mutex_unlock(&devlink_mutex);
1697	return 0;
1698}
1699EXPORT_SYMBOL_GPL(devlink_register);
1700
1701/**
1702 *	devlink_unregister - Unregister devlink instance
1703 *
1704 *	@devlink: devlink
1705 */
1706void devlink_unregister(struct devlink *devlink)
1707{
1708	mutex_lock(&devlink_mutex);
1709	devlink_notify(devlink, DEVLINK_CMD_DEL);
1710	list_del(&devlink->list);
1711	mutex_unlock(&devlink_mutex);
1712}
1713EXPORT_SYMBOL_GPL(devlink_unregister);
1714
1715/**
1716 *	devlink_free - Free devlink instance resources
1717 *
1718 *	@devlink: devlink
1719 */
1720void devlink_free(struct devlink *devlink)
1721{
1722	kfree(devlink);
1723}
1724EXPORT_SYMBOL_GPL(devlink_free);
1725
1726/**
1727 *	devlink_port_register - Register devlink port
1728 *
1729 *	@devlink: devlink
1730 *	@devlink_port: devlink port
1731 *	@port_index
1732 *
1733 *	Register devlink port with provided port index. User can use
1734 *	any indexing, even hw-related one. devlink_port structure
1735 *	is convenient to be embedded inside user driver private structure.
1736 *	Note that the caller should take care of zeroing the devlink_port
1737 *	structure.
1738 */
1739int devlink_port_register(struct devlink *devlink,
1740			  struct devlink_port *devlink_port,
1741			  unsigned int port_index)
1742{
1743	mutex_lock(&devlink_port_mutex);
1744	if (devlink_port_index_exists(devlink, port_index)) {
1745		mutex_unlock(&devlink_port_mutex);
1746		return -EEXIST;
1747	}
1748	devlink_port->devlink = devlink;
1749	devlink_port->index = port_index;
 
1750	devlink_port->registered = true;
1751	list_add_tail(&devlink_port->list, &devlink->port_list);
1752	mutex_unlock(&devlink_port_mutex);
1753	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
1754	return 0;
1755}
1756EXPORT_SYMBOL_GPL(devlink_port_register);
1757
1758/**
1759 *	devlink_port_unregister - Unregister devlink port
1760 *
1761 *	@devlink_port: devlink port
1762 */
1763void devlink_port_unregister(struct devlink_port *devlink_port)
1764{
1765	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
1766	mutex_lock(&devlink_port_mutex);
1767	list_del(&devlink_port->list);
1768	mutex_unlock(&devlink_port_mutex);
1769}
1770EXPORT_SYMBOL_GPL(devlink_port_unregister);
1771
1772static void __devlink_port_type_set(struct devlink_port *devlink_port,
1773				    enum devlink_port_type type,
1774				    void *type_dev)
1775{
1776	devlink_port->type = type;
1777	devlink_port->type_dev = type_dev;
1778	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
1779}
1780
1781/**
1782 *	devlink_port_type_eth_set - Set port type to Ethernet
1783 *
1784 *	@devlink_port: devlink port
1785 *	@netdev: related netdevice
1786 */
1787void devlink_port_type_eth_set(struct devlink_port *devlink_port,
1788			       struct net_device *netdev)
1789{
1790	return __devlink_port_type_set(devlink_port,
1791				       DEVLINK_PORT_TYPE_ETH, netdev);
1792}
1793EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
1794
1795/**
1796 *	devlink_port_type_ib_set - Set port type to InfiniBand
1797 *
1798 *	@devlink_port: devlink port
1799 *	@ibdev: related IB device
1800 */
1801void devlink_port_type_ib_set(struct devlink_port *devlink_port,
1802			      struct ib_device *ibdev)
1803{
1804	return __devlink_port_type_set(devlink_port,
1805				       DEVLINK_PORT_TYPE_IB, ibdev);
1806}
1807EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
1808
1809/**
1810 *	devlink_port_type_clear - Clear port type
1811 *
1812 *	@devlink_port: devlink port
1813 */
1814void devlink_port_type_clear(struct devlink_port *devlink_port)
1815{
1816	return __devlink_port_type_set(devlink_port,
1817				       DEVLINK_PORT_TYPE_NOTSET, NULL);
1818}
1819EXPORT_SYMBOL_GPL(devlink_port_type_clear);
1820
1821/**
1822 *	devlink_port_split_set - Set port is split
1823 *
1824 *	@devlink_port: devlink port
1825 *	@split_group: split group - identifies group split port is part of
1826 */
1827void devlink_port_split_set(struct devlink_port *devlink_port,
1828			    u32 split_group)
1829{
1830	devlink_port->split = true;
1831	devlink_port->split_group = split_group;
1832	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
1833}
1834EXPORT_SYMBOL_GPL(devlink_port_split_set);
1835
1836int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
1837			u32 size, u16 ingress_pools_count,
1838			u16 egress_pools_count, u16 ingress_tc_count,
1839			u16 egress_tc_count)
1840{
1841	struct devlink_sb *devlink_sb;
1842	int err = 0;
1843
1844	mutex_lock(&devlink_mutex);
1845	if (devlink_sb_index_exists(devlink, sb_index)) {
1846		err = -EEXIST;
1847		goto unlock;
1848	}
1849
1850	devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
1851	if (!devlink_sb) {
1852		err = -ENOMEM;
1853		goto unlock;
1854	}
1855	devlink_sb->index = sb_index;
1856	devlink_sb->size = size;
1857	devlink_sb->ingress_pools_count = ingress_pools_count;
1858	devlink_sb->egress_pools_count = egress_pools_count;
1859	devlink_sb->ingress_tc_count = ingress_tc_count;
1860	devlink_sb->egress_tc_count = egress_tc_count;
1861	list_add_tail(&devlink_sb->list, &devlink->sb_list);
1862unlock:
1863	mutex_unlock(&devlink_mutex);
1864	return err;
1865}
1866EXPORT_SYMBOL_GPL(devlink_sb_register);
1867
1868void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
1869{
1870	struct devlink_sb *devlink_sb;
1871
1872	mutex_lock(&devlink_mutex);
1873	devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
1874	WARN_ON(!devlink_sb);
1875	list_del(&devlink_sb->list);
1876	mutex_unlock(&devlink_mutex);
1877	kfree(devlink_sb);
1878}
1879EXPORT_SYMBOL_GPL(devlink_sb_unregister);
1880
1881static int __init devlink_module_init(void)
1882{
1883	return genl_register_family(&devlink_nl_family);
 
 
1884}
1885
1886static void __exit devlink_module_exit(void)
1887{
1888	genl_unregister_family(&devlink_nl_family);
1889}
1890
1891module_init(devlink_module_init);
1892module_exit(devlink_module_exit);
1893
1894MODULE_LICENSE("GPL v2");
1895MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
1896MODULE_DESCRIPTION("Network physical device Netlink interface");
1897MODULE_ALIAS_GENL_FAMILY(DEVLINK_GENL_NAME);