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