• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * net/core/devlink.c - Network physical/parent device Netlink interface
4  *
5  * Heavily inspired by net/wireless/
6  * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
7  * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
8  */
9 
10 #include <linux/etherdevice.h>
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/types.h>
14 #include <linux/slab.h>
15 #include <linux/gfp.h>
16 #include <linux/device.h>
17 #include <linux/list.h>
18 #include <linux/netdevice.h>
19 #include <linux/spinlock.h>
20 #include <linux/refcount.h>
21 #include <linux/workqueue.h>
22 #include <linux/u64_stats_sync.h>
23 #include <linux/timekeeping.h>
24 #include <rdma/ib_verbs.h>
25 #include <net/netlink.h>
26 #include <net/genetlink.h>
27 #include <net/rtnetlink.h>
28 #include <net/net_namespace.h>
29 #include <net/sock.h>
30 #include <net/devlink.h>
31 #define CREATE_TRACE_POINTS
32 #include <trace/events/devlink.h>
33 
34 #define DEVLINK_RELOAD_STATS_ARRAY_SIZE \
35 	(__DEVLINK_RELOAD_LIMIT_MAX * __DEVLINK_RELOAD_ACTION_MAX)
36 
37 struct devlink_dev_stats {
38 	u32 reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE];
39 	u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE];
40 };
41 
42 struct devlink {
43 	u32 index;
44 	struct list_head port_list;
45 	struct list_head rate_list;
46 	struct list_head sb_list;
47 	struct list_head dpipe_table_list;
48 	struct list_head resource_list;
49 	struct list_head param_list;
50 	struct list_head region_list;
51 	struct list_head reporter_list;
52 	struct mutex reporters_lock; /* protects reporter_list */
53 	struct devlink_dpipe_headers *dpipe_headers;
54 	struct list_head trap_list;
55 	struct list_head trap_group_list;
56 	struct list_head trap_policer_list;
57 	struct list_head linecard_list;
58 	struct mutex linecards_lock; /* protects linecard_list */
59 	const struct devlink_ops *ops;
60 	u64 features;
61 	struct xarray snapshot_ids;
62 	struct devlink_dev_stats stats;
63 	struct device *dev;
64 	possible_net_t _net;
65 	/* Serializes access to devlink instance specific objects such as
66 	 * port, sb, dpipe, resource, params, region, traps and more.
67 	 */
68 	struct mutex lock;
69 	struct lock_class_key lock_key;
70 	u8 reload_failed:1;
71 	refcount_t refcount;
72 	struct completion comp;
73 	struct rcu_head rcu;
74 	char priv[] __aligned(NETDEV_ALIGN);
75 };
76 
77 struct devlink_linecard_ops;
78 struct devlink_linecard_type;
79 
80 struct devlink_linecard {
81 	struct list_head list;
82 	struct devlink *devlink;
83 	unsigned int index;
84 	refcount_t refcount;
85 	const struct devlink_linecard_ops *ops;
86 	void *priv;
87 	enum devlink_linecard_state state;
88 	struct mutex state_lock; /* Protects state */
89 	const char *type;
90 	struct devlink_linecard_type *types;
91 	unsigned int types_count;
92 	struct devlink *nested_devlink;
93 };
94 
95 /**
96  * struct devlink_resource - devlink resource
97  * @name: name of the resource
98  * @id: id, per devlink instance
99  * @size: size of the resource
100  * @size_new: updated size of the resource, reload is needed
101  * @size_valid: valid in case the total size of the resource is valid
102  *              including its children
103  * @parent: parent resource
104  * @size_params: size parameters
105  * @list: parent list
106  * @resource_list: list of child resources
107  * @occ_get: occupancy getter callback
108  * @occ_get_priv: occupancy getter callback priv
109  */
110 struct devlink_resource {
111 	const char *name;
112 	u64 id;
113 	u64 size;
114 	u64 size_new;
115 	bool size_valid;
116 	struct devlink_resource *parent;
117 	struct devlink_resource_size_params size_params;
118 	struct list_head list;
119 	struct list_head resource_list;
120 	devlink_resource_occ_get_t *occ_get;
121 	void *occ_get_priv;
122 };
123 
devlink_priv(struct devlink * devlink)124 void *devlink_priv(struct devlink *devlink)
125 {
126 	return &devlink->priv;
127 }
128 EXPORT_SYMBOL_GPL(devlink_priv);
129 
priv_to_devlink(void * priv)130 struct devlink *priv_to_devlink(void *priv)
131 {
132 	return container_of(priv, struct devlink, priv);
133 }
134 EXPORT_SYMBOL_GPL(priv_to_devlink);
135 
devlink_to_dev(const struct devlink * devlink)136 struct device *devlink_to_dev(const struct devlink *devlink)
137 {
138 	return devlink->dev;
139 }
140 EXPORT_SYMBOL_GPL(devlink_to_dev);
141 
142 static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = {
143 	{
144 		.name = "destination mac",
145 		.id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
146 		.bitwidth = 48,
147 	},
148 };
149 
150 struct devlink_dpipe_header devlink_dpipe_header_ethernet = {
151 	.name = "ethernet",
152 	.id = DEVLINK_DPIPE_HEADER_ETHERNET,
153 	.fields = devlink_dpipe_fields_ethernet,
154 	.fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet),
155 	.global = true,
156 };
157 EXPORT_SYMBOL_GPL(devlink_dpipe_header_ethernet);
158 
159 static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = {
160 	{
161 		.name = "destination ip",
162 		.id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP,
163 		.bitwidth = 32,
164 	},
165 };
166 
167 struct devlink_dpipe_header devlink_dpipe_header_ipv4 = {
168 	.name = "ipv4",
169 	.id = DEVLINK_DPIPE_HEADER_IPV4,
170 	.fields = devlink_dpipe_fields_ipv4,
171 	.fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4),
172 	.global = true,
173 };
174 EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv4);
175 
176 static struct devlink_dpipe_field devlink_dpipe_fields_ipv6[] = {
177 	{
178 		.name = "destination ip",
179 		.id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP,
180 		.bitwidth = 128,
181 	},
182 };
183 
184 struct devlink_dpipe_header devlink_dpipe_header_ipv6 = {
185 	.name = "ipv6",
186 	.id = DEVLINK_DPIPE_HEADER_IPV6,
187 	.fields = devlink_dpipe_fields_ipv6,
188 	.fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv6),
189 	.global = true,
190 };
191 EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv6);
192 
193 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg);
194 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwerr);
195 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_trap_report);
196 
197 static const struct nla_policy devlink_function_nl_policy[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1] = {
198 	[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] = { .type = NLA_BINARY },
199 	[DEVLINK_PORT_FN_ATTR_STATE] =
200 		NLA_POLICY_RANGE(NLA_U8, DEVLINK_PORT_FN_STATE_INACTIVE,
201 				 DEVLINK_PORT_FN_STATE_ACTIVE),
202 };
203 
204 static const struct nla_policy devlink_selftest_nl_policy[DEVLINK_ATTR_SELFTEST_ID_MAX + 1] = {
205 	[DEVLINK_ATTR_SELFTEST_ID_FLASH] = { .type = NLA_FLAG },
206 };
207 
208 static DEFINE_XARRAY_FLAGS(devlinks, XA_FLAGS_ALLOC);
209 #define DEVLINK_REGISTERED XA_MARK_1
210 #define DEVLINK_UNREGISTERING XA_MARK_2
211 
212 /* devlink instances are open to the access from the user space after
213  * devlink_register() call. Such logical barrier allows us to have certain
214  * expectations related to locking.
215  *
216  * Before *_register() - we are in initialization stage and no parallel
217  * access possible to the devlink instance. All drivers perform that phase
218  * by implicitly holding device_lock.
219  *
220  * After *_register() - users and driver can access devlink instance at
221  * the same time.
222  */
223 #define ASSERT_DEVLINK_REGISTERED(d)                                           \
224 	WARN_ON_ONCE(!xa_get_mark(&devlinks, (d)->index, DEVLINK_REGISTERED))
225 #define ASSERT_DEVLINK_NOT_REGISTERED(d)                                       \
226 	WARN_ON_ONCE(xa_get_mark(&devlinks, (d)->index, DEVLINK_REGISTERED))
227 
devlink_net(const struct devlink * devlink)228 struct net *devlink_net(const struct devlink *devlink)
229 {
230 	return read_pnet(&devlink->_net);
231 }
232 EXPORT_SYMBOL_GPL(devlink_net);
233 
__devlink_put_rcu(struct rcu_head * head)234 static void __devlink_put_rcu(struct rcu_head *head)
235 {
236 	struct devlink *devlink = container_of(head, struct devlink, rcu);
237 
238 	complete(&devlink->comp);
239 }
240 
devlink_put(struct devlink * devlink)241 void devlink_put(struct devlink *devlink)
242 {
243 	if (refcount_dec_and_test(&devlink->refcount))
244 		/* Make sure unregister operation that may await the completion
245 		 * is unblocked only after all users are after the end of
246 		 * RCU grace period.
247 		 */
248 		call_rcu(&devlink->rcu, __devlink_put_rcu);
249 }
250 
devlink_try_get(struct devlink * devlink)251 struct devlink *__must_check devlink_try_get(struct devlink *devlink)
252 {
253 	if (refcount_inc_not_zero(&devlink->refcount))
254 		return devlink;
255 	return NULL;
256 }
257 
devl_assert_locked(struct devlink * devlink)258 void devl_assert_locked(struct devlink *devlink)
259 {
260 	lockdep_assert_held(&devlink->lock);
261 }
262 EXPORT_SYMBOL_GPL(devl_assert_locked);
263 
264 #ifdef CONFIG_LOCKDEP
265 /* For use in conjunction with LOCKDEP only e.g. rcu_dereference_protected() */
devl_lock_is_held(struct devlink * devlink)266 bool devl_lock_is_held(struct devlink *devlink)
267 {
268 	return lockdep_is_held(&devlink->lock);
269 }
270 EXPORT_SYMBOL_GPL(devl_lock_is_held);
271 #endif
272 
devl_lock(struct devlink * devlink)273 void devl_lock(struct devlink *devlink)
274 {
275 	mutex_lock(&devlink->lock);
276 }
277 EXPORT_SYMBOL_GPL(devl_lock);
278 
devl_trylock(struct devlink * devlink)279 int devl_trylock(struct devlink *devlink)
280 {
281 	return mutex_trylock(&devlink->lock);
282 }
283 EXPORT_SYMBOL_GPL(devl_trylock);
284 
devl_unlock(struct devlink * devlink)285 void devl_unlock(struct devlink *devlink)
286 {
287 	mutex_unlock(&devlink->lock);
288 }
289 EXPORT_SYMBOL_GPL(devl_unlock);
290 
291 static struct devlink *
devlinks_xa_find_get(struct net * net,unsigned long * indexp,xa_mark_t filter,void * (* xa_find_fn)(struct xarray *,unsigned long *,unsigned long,xa_mark_t))292 devlinks_xa_find_get(struct net *net, unsigned long *indexp, xa_mark_t filter,
293 		     void * (*xa_find_fn)(struct xarray *, unsigned long *,
294 					  unsigned long, xa_mark_t))
295 {
296 	struct devlink *devlink;
297 
298 	rcu_read_lock();
299 retry:
300 	devlink = xa_find_fn(&devlinks, indexp, ULONG_MAX, DEVLINK_REGISTERED);
301 	if (!devlink)
302 		goto unlock;
303 
304 	/* In case devlink_unregister() was already called and "unregistering"
305 	 * mark was set, do not allow to get a devlink reference here.
306 	 * This prevents live-lock of devlink_unregister() wait for completion.
307 	 */
308 	if (xa_get_mark(&devlinks, *indexp, DEVLINK_UNREGISTERING))
309 		goto retry;
310 
311 	/* For a possible retry, the xa_find_after() should be always used */
312 	xa_find_fn = xa_find_after;
313 	if (!devlink_try_get(devlink))
314 		goto retry;
315 	if (!net_eq(devlink_net(devlink), net)) {
316 		devlink_put(devlink);
317 		goto retry;
318 	}
319 unlock:
320 	rcu_read_unlock();
321 	return devlink;
322 }
323 
devlinks_xa_find_get_first(struct net * net,unsigned long * indexp,xa_mark_t filter)324 static struct devlink *devlinks_xa_find_get_first(struct net *net,
325 						  unsigned long *indexp,
326 						  xa_mark_t filter)
327 {
328 	return devlinks_xa_find_get(net, indexp, filter, xa_find);
329 }
330 
devlinks_xa_find_get_next(struct net * net,unsigned long * indexp,xa_mark_t filter)331 static struct devlink *devlinks_xa_find_get_next(struct net *net,
332 						 unsigned long *indexp,
333 						 xa_mark_t filter)
334 {
335 	return devlinks_xa_find_get(net, indexp, filter, xa_find_after);
336 }
337 
338 /* Iterate over devlink pointers which were possible to get reference to.
339  * devlink_put() needs to be called for each iterated devlink pointer
340  * in loop body in order to release the reference.
341  */
342 #define devlinks_xa_for_each_get(net, index, devlink, filter)			\
343 	for (index = 0,								\
344 	     devlink = devlinks_xa_find_get_first(net, &index, filter);		\
345 	     devlink; devlink = devlinks_xa_find_get_next(net, &index, filter))
346 
347 #define devlinks_xa_for_each_registered_get(net, index, devlink)		\
348 	devlinks_xa_for_each_get(net, index, devlink, DEVLINK_REGISTERED)
349 
devlink_get_from_attrs(struct net * net,struct nlattr ** attrs)350 static struct devlink *devlink_get_from_attrs(struct net *net,
351 					      struct nlattr **attrs)
352 {
353 	struct devlink *devlink;
354 	unsigned long index;
355 	char *busname;
356 	char *devname;
357 
358 	if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME])
359 		return ERR_PTR(-EINVAL);
360 
361 	busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]);
362 	devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
363 
364 	devlinks_xa_for_each_registered_get(net, index, devlink) {
365 		if (strcmp(devlink->dev->bus->name, busname) == 0 &&
366 		    strcmp(dev_name(devlink->dev), devname) == 0)
367 			return devlink;
368 		devlink_put(devlink);
369 	}
370 
371 	return ERR_PTR(-ENODEV);
372 }
373 
374 #define ASSERT_DEVLINK_PORT_REGISTERED(devlink_port)				\
375 	WARN_ON_ONCE(!(devlink_port)->registered)
376 #define ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port)			\
377 	WARN_ON_ONCE((devlink_port)->registered)
378 #define ASSERT_DEVLINK_PORT_INITIALIZED(devlink_port)				\
379 	WARN_ON_ONCE(!(devlink_port)->initialized)
380 
devlink_port_get_by_index(struct devlink * devlink,unsigned int port_index)381 static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
382 						      unsigned int port_index)
383 {
384 	struct devlink_port *devlink_port;
385 
386 	list_for_each_entry(devlink_port, &devlink->port_list, list) {
387 		if (devlink_port->index == port_index)
388 			return devlink_port;
389 	}
390 	return NULL;
391 }
392 
devlink_port_index_exists(struct devlink * devlink,unsigned int port_index)393 static bool devlink_port_index_exists(struct devlink *devlink,
394 				      unsigned int port_index)
395 {
396 	return devlink_port_get_by_index(devlink, port_index);
397 }
398 
devlink_port_get_from_attrs(struct devlink * devlink,struct nlattr ** attrs)399 static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
400 							struct nlattr **attrs)
401 {
402 	if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
403 		u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
404 		struct devlink_port *devlink_port;
405 
406 		devlink_port = devlink_port_get_by_index(devlink, port_index);
407 		if (!devlink_port)
408 			return ERR_PTR(-ENODEV);
409 		return devlink_port;
410 	}
411 	return ERR_PTR(-EINVAL);
412 }
413 
devlink_port_get_from_info(struct devlink * devlink,struct genl_info * info)414 static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
415 						       struct genl_info *info)
416 {
417 	return devlink_port_get_from_attrs(devlink, info->attrs);
418 }
419 
420 static inline bool
devlink_rate_is_leaf(struct devlink_rate * devlink_rate)421 devlink_rate_is_leaf(struct devlink_rate *devlink_rate)
422 {
423 	return devlink_rate->type == DEVLINK_RATE_TYPE_LEAF;
424 }
425 
426 static inline bool
devlink_rate_is_node(struct devlink_rate * devlink_rate)427 devlink_rate_is_node(struct devlink_rate *devlink_rate)
428 {
429 	return devlink_rate->type == DEVLINK_RATE_TYPE_NODE;
430 }
431 
432 static struct devlink_rate *
devlink_rate_leaf_get_from_info(struct devlink * devlink,struct genl_info * info)433 devlink_rate_leaf_get_from_info(struct devlink *devlink, struct genl_info *info)
434 {
435 	struct devlink_rate *devlink_rate;
436 	struct devlink_port *devlink_port;
437 
438 	devlink_port = devlink_port_get_from_attrs(devlink, info->attrs);
439 	if (IS_ERR(devlink_port))
440 		return ERR_CAST(devlink_port);
441 	devlink_rate = devlink_port->devlink_rate;
442 	return devlink_rate ?: ERR_PTR(-ENODEV);
443 }
444 
445 static struct devlink_rate *
devlink_rate_node_get_by_name(struct devlink * devlink,const char * node_name)446 devlink_rate_node_get_by_name(struct devlink *devlink, const char *node_name)
447 {
448 	static struct devlink_rate *devlink_rate;
449 
450 	list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
451 		if (devlink_rate_is_node(devlink_rate) &&
452 		    !strcmp(node_name, devlink_rate->name))
453 			return devlink_rate;
454 	}
455 	return ERR_PTR(-ENODEV);
456 }
457 
458 static struct devlink_rate *
devlink_rate_node_get_from_attrs(struct devlink * devlink,struct nlattr ** attrs)459 devlink_rate_node_get_from_attrs(struct devlink *devlink, struct nlattr **attrs)
460 {
461 	const char *rate_node_name;
462 	size_t len;
463 
464 	if (!attrs[DEVLINK_ATTR_RATE_NODE_NAME])
465 		return ERR_PTR(-EINVAL);
466 	rate_node_name = nla_data(attrs[DEVLINK_ATTR_RATE_NODE_NAME]);
467 	len = strlen(rate_node_name);
468 	/* Name cannot be empty or decimal number */
469 	if (!len || strspn(rate_node_name, "0123456789") == len)
470 		return ERR_PTR(-EINVAL);
471 
472 	return devlink_rate_node_get_by_name(devlink, rate_node_name);
473 }
474 
475 static struct devlink_rate *
devlink_rate_node_get_from_info(struct devlink * devlink,struct genl_info * info)476 devlink_rate_node_get_from_info(struct devlink *devlink, struct genl_info *info)
477 {
478 	return devlink_rate_node_get_from_attrs(devlink, info->attrs);
479 }
480 
481 static struct devlink_rate *
devlink_rate_get_from_info(struct devlink * devlink,struct genl_info * info)482 devlink_rate_get_from_info(struct devlink *devlink, struct genl_info *info)
483 {
484 	struct nlattr **attrs = info->attrs;
485 
486 	if (attrs[DEVLINK_ATTR_PORT_INDEX])
487 		return devlink_rate_leaf_get_from_info(devlink, info);
488 	else if (attrs[DEVLINK_ATTR_RATE_NODE_NAME])
489 		return devlink_rate_node_get_from_info(devlink, info);
490 	else
491 		return ERR_PTR(-EINVAL);
492 }
493 
494 static struct devlink_linecard *
devlink_linecard_get_by_index(struct devlink * devlink,unsigned int linecard_index)495 devlink_linecard_get_by_index(struct devlink *devlink,
496 			      unsigned int linecard_index)
497 {
498 	struct devlink_linecard *devlink_linecard;
499 
500 	list_for_each_entry(devlink_linecard, &devlink->linecard_list, list) {
501 		if (devlink_linecard->index == linecard_index)
502 			return devlink_linecard;
503 	}
504 	return NULL;
505 }
506 
devlink_linecard_index_exists(struct devlink * devlink,unsigned int linecard_index)507 static bool devlink_linecard_index_exists(struct devlink *devlink,
508 					  unsigned int linecard_index)
509 {
510 	return devlink_linecard_get_by_index(devlink, linecard_index);
511 }
512 
513 static struct devlink_linecard *
devlink_linecard_get_from_attrs(struct devlink * devlink,struct nlattr ** attrs)514 devlink_linecard_get_from_attrs(struct devlink *devlink, struct nlattr **attrs)
515 {
516 	if (attrs[DEVLINK_ATTR_LINECARD_INDEX]) {
517 		u32 linecard_index = nla_get_u32(attrs[DEVLINK_ATTR_LINECARD_INDEX]);
518 		struct devlink_linecard *linecard;
519 
520 		mutex_lock(&devlink->linecards_lock);
521 		linecard = devlink_linecard_get_by_index(devlink, linecard_index);
522 		if (linecard)
523 			refcount_inc(&linecard->refcount);
524 		mutex_unlock(&devlink->linecards_lock);
525 		if (!linecard)
526 			return ERR_PTR(-ENODEV);
527 		return linecard;
528 	}
529 	return ERR_PTR(-EINVAL);
530 }
531 
532 static struct devlink_linecard *
devlink_linecard_get_from_info(struct devlink * devlink,struct genl_info * info)533 devlink_linecard_get_from_info(struct devlink *devlink, struct genl_info *info)
534 {
535 	return devlink_linecard_get_from_attrs(devlink, info->attrs);
536 }
537 
devlink_linecard_put(struct devlink_linecard * linecard)538 static void devlink_linecard_put(struct devlink_linecard *linecard)
539 {
540 	if (refcount_dec_and_test(&linecard->refcount)) {
541 		mutex_destroy(&linecard->state_lock);
542 		kfree(linecard);
543 	}
544 }
545 
546 struct devlink_sb {
547 	struct list_head list;
548 	unsigned int index;
549 	u32 size;
550 	u16 ingress_pools_count;
551 	u16 egress_pools_count;
552 	u16 ingress_tc_count;
553 	u16 egress_tc_count;
554 };
555 
devlink_sb_pool_count(struct devlink_sb * devlink_sb)556 static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb)
557 {
558 	return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count;
559 }
560 
devlink_sb_get_by_index(struct devlink * devlink,unsigned int sb_index)561 static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink,
562 						  unsigned int sb_index)
563 {
564 	struct devlink_sb *devlink_sb;
565 
566 	list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
567 		if (devlink_sb->index == sb_index)
568 			return devlink_sb;
569 	}
570 	return NULL;
571 }
572 
devlink_sb_index_exists(struct devlink * devlink,unsigned int sb_index)573 static bool devlink_sb_index_exists(struct devlink *devlink,
574 				    unsigned int sb_index)
575 {
576 	return devlink_sb_get_by_index(devlink, sb_index);
577 }
578 
devlink_sb_get_from_attrs(struct devlink * devlink,struct nlattr ** attrs)579 static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink,
580 						    struct nlattr **attrs)
581 {
582 	if (attrs[DEVLINK_ATTR_SB_INDEX]) {
583 		u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]);
584 		struct devlink_sb *devlink_sb;
585 
586 		devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
587 		if (!devlink_sb)
588 			return ERR_PTR(-ENODEV);
589 		return devlink_sb;
590 	}
591 	return ERR_PTR(-EINVAL);
592 }
593 
devlink_sb_get_from_info(struct devlink * devlink,struct genl_info * info)594 static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink,
595 						   struct genl_info *info)
596 {
597 	return devlink_sb_get_from_attrs(devlink, info->attrs);
598 }
599 
devlink_sb_pool_index_get_from_attrs(struct devlink_sb * devlink_sb,struct nlattr ** attrs,u16 * p_pool_index)600 static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb,
601 						struct nlattr **attrs,
602 						u16 *p_pool_index)
603 {
604 	u16 val;
605 
606 	if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX])
607 		return -EINVAL;
608 
609 	val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]);
610 	if (val >= devlink_sb_pool_count(devlink_sb))
611 		return -EINVAL;
612 	*p_pool_index = val;
613 	return 0;
614 }
615 
devlink_sb_pool_index_get_from_info(struct devlink_sb * devlink_sb,struct genl_info * info,u16 * p_pool_index)616 static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb,
617 					       struct genl_info *info,
618 					       u16 *p_pool_index)
619 {
620 	return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs,
621 						    p_pool_index);
622 }
623 
624 static int
devlink_sb_pool_type_get_from_attrs(struct nlattr ** attrs,enum devlink_sb_pool_type * p_pool_type)625 devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs,
626 				    enum devlink_sb_pool_type *p_pool_type)
627 {
628 	u8 val;
629 
630 	if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE])
631 		return -EINVAL;
632 
633 	val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]);
634 	if (val != DEVLINK_SB_POOL_TYPE_INGRESS &&
635 	    val != DEVLINK_SB_POOL_TYPE_EGRESS)
636 		return -EINVAL;
637 	*p_pool_type = val;
638 	return 0;
639 }
640 
641 static int
devlink_sb_pool_type_get_from_info(struct genl_info * info,enum devlink_sb_pool_type * p_pool_type)642 devlink_sb_pool_type_get_from_info(struct genl_info *info,
643 				   enum devlink_sb_pool_type *p_pool_type)
644 {
645 	return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type);
646 }
647 
648 static int
devlink_sb_th_type_get_from_attrs(struct nlattr ** attrs,enum devlink_sb_threshold_type * p_th_type)649 devlink_sb_th_type_get_from_attrs(struct nlattr **attrs,
650 				  enum devlink_sb_threshold_type *p_th_type)
651 {
652 	u8 val;
653 
654 	if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])
655 		return -EINVAL;
656 
657 	val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]);
658 	if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC &&
659 	    val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC)
660 		return -EINVAL;
661 	*p_th_type = val;
662 	return 0;
663 }
664 
665 static int
devlink_sb_th_type_get_from_info(struct genl_info * info,enum devlink_sb_threshold_type * p_th_type)666 devlink_sb_th_type_get_from_info(struct genl_info *info,
667 				 enum devlink_sb_threshold_type *p_th_type)
668 {
669 	return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type);
670 }
671 
672 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)673 devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb,
674 				   struct nlattr **attrs,
675 				   enum devlink_sb_pool_type pool_type,
676 				   u16 *p_tc_index)
677 {
678 	u16 val;
679 
680 	if (!attrs[DEVLINK_ATTR_SB_TC_INDEX])
681 		return -EINVAL;
682 
683 	val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]);
684 	if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS &&
685 	    val >= devlink_sb->ingress_tc_count)
686 		return -EINVAL;
687 	if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS &&
688 	    val >= devlink_sb->egress_tc_count)
689 		return -EINVAL;
690 	*p_tc_index = val;
691 	return 0;
692 }
693 
694 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)695 devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
696 				  struct genl_info *info,
697 				  enum devlink_sb_pool_type pool_type,
698 				  u16 *p_tc_index)
699 {
700 	return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs,
701 						  pool_type, p_tc_index);
702 }
703 
704 struct devlink_region {
705 	struct devlink *devlink;
706 	struct devlink_port *port;
707 	struct list_head list;
708 	union {
709 		const struct devlink_region_ops *ops;
710 		const struct devlink_port_region_ops *port_ops;
711 	};
712 	struct mutex snapshot_lock; /* protects snapshot_list,
713 				     * max_snapshots and cur_snapshots
714 				     * consistency.
715 				     */
716 	struct list_head snapshot_list;
717 	u32 max_snapshots;
718 	u32 cur_snapshots;
719 	u64 size;
720 };
721 
722 struct devlink_snapshot {
723 	struct list_head list;
724 	struct devlink_region *region;
725 	u8 *data;
726 	u32 id;
727 };
728 
729 static struct devlink_region *
devlink_region_get_by_name(struct devlink * devlink,const char * region_name)730 devlink_region_get_by_name(struct devlink *devlink, const char *region_name)
731 {
732 	struct devlink_region *region;
733 
734 	list_for_each_entry(region, &devlink->region_list, list)
735 		if (!strcmp(region->ops->name, region_name))
736 			return region;
737 
738 	return NULL;
739 }
740 
741 static struct devlink_region *
devlink_port_region_get_by_name(struct devlink_port * port,const char * region_name)742 devlink_port_region_get_by_name(struct devlink_port *port,
743 				const char *region_name)
744 {
745 	struct devlink_region *region;
746 
747 	list_for_each_entry(region, &port->region_list, list)
748 		if (!strcmp(region->ops->name, region_name))
749 			return region;
750 
751 	return NULL;
752 }
753 
754 static struct devlink_snapshot *
devlink_region_snapshot_get_by_id(struct devlink_region * region,u32 id)755 devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id)
756 {
757 	struct devlink_snapshot *snapshot;
758 
759 	list_for_each_entry(snapshot, &region->snapshot_list, list)
760 		if (snapshot->id == id)
761 			return snapshot;
762 
763 	return NULL;
764 }
765 
766 #define DEVLINK_NL_FLAG_NEED_PORT		BIT(0)
767 #define DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT	BIT(1)
768 #define DEVLINK_NL_FLAG_NEED_RATE		BIT(2)
769 #define DEVLINK_NL_FLAG_NEED_RATE_NODE		BIT(3)
770 #define DEVLINK_NL_FLAG_NEED_LINECARD		BIT(4)
771 
devlink_nl_pre_doit(const struct genl_ops * ops,struct sk_buff * skb,struct genl_info * info)772 static int devlink_nl_pre_doit(const struct genl_ops *ops,
773 			       struct sk_buff *skb, struct genl_info *info)
774 {
775 	struct devlink_linecard *linecard;
776 	struct devlink_port *devlink_port;
777 	struct devlink *devlink;
778 	int err;
779 
780 	devlink = devlink_get_from_attrs(genl_info_net(info), info->attrs);
781 	if (IS_ERR(devlink))
782 		return PTR_ERR(devlink);
783 	devl_lock(devlink);
784 	info->user_ptr[0] = devlink;
785 	if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) {
786 		devlink_port = devlink_port_get_from_info(devlink, info);
787 		if (IS_ERR(devlink_port)) {
788 			err = PTR_ERR(devlink_port);
789 			goto unlock;
790 		}
791 		info->user_ptr[1] = devlink_port;
792 	} else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT) {
793 		devlink_port = devlink_port_get_from_info(devlink, info);
794 		if (!IS_ERR(devlink_port))
795 			info->user_ptr[1] = devlink_port;
796 	} else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_RATE) {
797 		struct devlink_rate *devlink_rate;
798 
799 		devlink_rate = devlink_rate_get_from_info(devlink, info);
800 		if (IS_ERR(devlink_rate)) {
801 			err = PTR_ERR(devlink_rate);
802 			goto unlock;
803 		}
804 		info->user_ptr[1] = devlink_rate;
805 	} else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_RATE_NODE) {
806 		struct devlink_rate *rate_node;
807 
808 		rate_node = devlink_rate_node_get_from_info(devlink, info);
809 		if (IS_ERR(rate_node)) {
810 			err = PTR_ERR(rate_node);
811 			goto unlock;
812 		}
813 		info->user_ptr[1] = rate_node;
814 	} else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_LINECARD) {
815 		linecard = devlink_linecard_get_from_info(devlink, info);
816 		if (IS_ERR(linecard)) {
817 			err = PTR_ERR(linecard);
818 			goto unlock;
819 		}
820 		info->user_ptr[1] = linecard;
821 	}
822 	return 0;
823 
824 unlock:
825 	devl_unlock(devlink);
826 	devlink_put(devlink);
827 	return err;
828 }
829 
devlink_nl_post_doit(const struct genl_ops * ops,struct sk_buff * skb,struct genl_info * info)830 static void devlink_nl_post_doit(const struct genl_ops *ops,
831 				 struct sk_buff *skb, struct genl_info *info)
832 {
833 	struct devlink_linecard *linecard;
834 	struct devlink *devlink;
835 
836 	devlink = info->user_ptr[0];
837 	if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_LINECARD) {
838 		linecard = info->user_ptr[1];
839 		devlink_linecard_put(linecard);
840 	}
841 	devl_unlock(devlink);
842 	devlink_put(devlink);
843 }
844 
845 static struct genl_family devlink_nl_family;
846 
847 enum devlink_multicast_groups {
848 	DEVLINK_MCGRP_CONFIG,
849 };
850 
851 static const struct genl_multicast_group devlink_nl_mcgrps[] = {
852 	[DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME },
853 };
854 
devlink_nl_put_handle(struct sk_buff * msg,struct devlink * devlink)855 static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
856 {
857 	if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name))
858 		return -EMSGSIZE;
859 	if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev)))
860 		return -EMSGSIZE;
861 	return 0;
862 }
863 
devlink_nl_put_nested_handle(struct sk_buff * msg,struct devlink * devlink)864 static int devlink_nl_put_nested_handle(struct sk_buff *msg, struct devlink *devlink)
865 {
866 	struct nlattr *nested_attr;
867 
868 	nested_attr = nla_nest_start(msg, DEVLINK_ATTR_NESTED_DEVLINK);
869 	if (!nested_attr)
870 		return -EMSGSIZE;
871 	if (devlink_nl_put_handle(msg, devlink))
872 		goto nla_put_failure;
873 
874 	nla_nest_end(msg, nested_attr);
875 	return 0;
876 
877 nla_put_failure:
878 	nla_nest_cancel(msg, nested_attr);
879 	return -EMSGSIZE;
880 }
881 
882 struct devlink_reload_combination {
883 	enum devlink_reload_action action;
884 	enum devlink_reload_limit limit;
885 };
886 
887 static const struct devlink_reload_combination devlink_reload_invalid_combinations[] = {
888 	{
889 		/* can't reinitialize driver with no down time */
890 		.action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
891 		.limit = DEVLINK_RELOAD_LIMIT_NO_RESET,
892 	},
893 };
894 
895 static bool
devlink_reload_combination_is_invalid(enum devlink_reload_action action,enum devlink_reload_limit limit)896 devlink_reload_combination_is_invalid(enum devlink_reload_action action,
897 				      enum devlink_reload_limit limit)
898 {
899 	int i;
900 
901 	for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++)
902 		if (devlink_reload_invalid_combinations[i].action == action &&
903 		    devlink_reload_invalid_combinations[i].limit == limit)
904 			return true;
905 	return false;
906 }
907 
908 static bool
devlink_reload_action_is_supported(struct devlink * devlink,enum devlink_reload_action action)909 devlink_reload_action_is_supported(struct devlink *devlink, enum devlink_reload_action action)
910 {
911 	return test_bit(action, &devlink->ops->reload_actions);
912 }
913 
914 static bool
devlink_reload_limit_is_supported(struct devlink * devlink,enum devlink_reload_limit limit)915 devlink_reload_limit_is_supported(struct devlink *devlink, enum devlink_reload_limit limit)
916 {
917 	return test_bit(limit, &devlink->ops->reload_limits);
918 }
919 
devlink_reload_stat_put(struct sk_buff * msg,enum devlink_reload_limit limit,u32 value)920 static int devlink_reload_stat_put(struct sk_buff *msg,
921 				   enum devlink_reload_limit limit, u32 value)
922 {
923 	struct nlattr *reload_stats_entry;
924 
925 	reload_stats_entry = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS_ENTRY);
926 	if (!reload_stats_entry)
927 		return -EMSGSIZE;
928 
929 	if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_STATS_LIMIT, limit) ||
930 	    nla_put_u32(msg, DEVLINK_ATTR_RELOAD_STATS_VALUE, value))
931 		goto nla_put_failure;
932 	nla_nest_end(msg, reload_stats_entry);
933 	return 0;
934 
935 nla_put_failure:
936 	nla_nest_cancel(msg, reload_stats_entry);
937 	return -EMSGSIZE;
938 }
939 
devlink_reload_stats_put(struct sk_buff * msg,struct devlink * devlink,bool is_remote)940 static int devlink_reload_stats_put(struct sk_buff *msg, struct devlink *devlink, bool is_remote)
941 {
942 	struct nlattr *reload_stats_attr, *act_info, *act_stats;
943 	int i, j, stat_idx;
944 	u32 value;
945 
946 	if (!is_remote)
947 		reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS);
948 	else
949 		reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_REMOTE_RELOAD_STATS);
950 
951 	if (!reload_stats_attr)
952 		return -EMSGSIZE;
953 
954 	for (i = 0; i <= DEVLINK_RELOAD_ACTION_MAX; i++) {
955 		if ((!is_remote &&
956 		     !devlink_reload_action_is_supported(devlink, i)) ||
957 		    i == DEVLINK_RELOAD_ACTION_UNSPEC)
958 			continue;
959 		act_info = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_INFO);
960 		if (!act_info)
961 			goto nla_put_failure;
962 
963 		if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_ACTION, i))
964 			goto action_info_nest_cancel;
965 		act_stats = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_STATS);
966 		if (!act_stats)
967 			goto action_info_nest_cancel;
968 
969 		for (j = 0; j <= DEVLINK_RELOAD_LIMIT_MAX; j++) {
970 			/* Remote stats are shown even if not locally supported.
971 			 * Stats of actions with unspecified limit are shown
972 			 * though drivers don't need to register unspecified
973 			 * limit.
974 			 */
975 			if ((!is_remote && j != DEVLINK_RELOAD_LIMIT_UNSPEC &&
976 			     !devlink_reload_limit_is_supported(devlink, j)) ||
977 			    devlink_reload_combination_is_invalid(i, j))
978 				continue;
979 
980 			stat_idx = j * __DEVLINK_RELOAD_ACTION_MAX + i;
981 			if (!is_remote)
982 				value = devlink->stats.reload_stats[stat_idx];
983 			else
984 				value = devlink->stats.remote_reload_stats[stat_idx];
985 			if (devlink_reload_stat_put(msg, j, value))
986 				goto action_stats_nest_cancel;
987 		}
988 		nla_nest_end(msg, act_stats);
989 		nla_nest_end(msg, act_info);
990 	}
991 	nla_nest_end(msg, reload_stats_attr);
992 	return 0;
993 
994 action_stats_nest_cancel:
995 	nla_nest_cancel(msg, act_stats);
996 action_info_nest_cancel:
997 	nla_nest_cancel(msg, act_info);
998 nla_put_failure:
999 	nla_nest_cancel(msg, reload_stats_attr);
1000 	return -EMSGSIZE;
1001 }
1002 
devlink_nl_fill(struct sk_buff * msg,struct devlink * devlink,enum devlink_command cmd,u32 portid,u32 seq,int flags)1003 static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
1004 			   enum devlink_command cmd, u32 portid,
1005 			   u32 seq, int flags)
1006 {
1007 	struct nlattr *dev_stats;
1008 	void *hdr;
1009 
1010 	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1011 	if (!hdr)
1012 		return -EMSGSIZE;
1013 
1014 	if (devlink_nl_put_handle(msg, devlink))
1015 		goto nla_put_failure;
1016 	if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_FAILED, devlink->reload_failed))
1017 		goto nla_put_failure;
1018 
1019 	dev_stats = nla_nest_start(msg, DEVLINK_ATTR_DEV_STATS);
1020 	if (!dev_stats)
1021 		goto nla_put_failure;
1022 
1023 	if (devlink_reload_stats_put(msg, devlink, false))
1024 		goto dev_stats_nest_cancel;
1025 	if (devlink_reload_stats_put(msg, devlink, true))
1026 		goto dev_stats_nest_cancel;
1027 
1028 	nla_nest_end(msg, dev_stats);
1029 	genlmsg_end(msg, hdr);
1030 	return 0;
1031 
1032 dev_stats_nest_cancel:
1033 	nla_nest_cancel(msg, dev_stats);
1034 nla_put_failure:
1035 	genlmsg_cancel(msg, hdr);
1036 	return -EMSGSIZE;
1037 }
1038 
devlink_notify(struct devlink * devlink,enum devlink_command cmd)1039 static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
1040 {
1041 	struct sk_buff *msg;
1042 	int err;
1043 
1044 	WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
1045 	WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED));
1046 
1047 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1048 	if (!msg)
1049 		return;
1050 
1051 	err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0);
1052 	if (err) {
1053 		nlmsg_free(msg);
1054 		return;
1055 	}
1056 
1057 	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
1058 				msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
1059 }
1060 
devlink_nl_port_attrs_put(struct sk_buff * msg,struct devlink_port * devlink_port)1061 static int devlink_nl_port_attrs_put(struct sk_buff *msg,
1062 				     struct devlink_port *devlink_port)
1063 {
1064 	struct devlink_port_attrs *attrs = &devlink_port->attrs;
1065 
1066 	if (!devlink_port->attrs_set)
1067 		return 0;
1068 	if (attrs->lanes) {
1069 		if (nla_put_u32(msg, DEVLINK_ATTR_PORT_LANES, attrs->lanes))
1070 			return -EMSGSIZE;
1071 	}
1072 	if (nla_put_u8(msg, DEVLINK_ATTR_PORT_SPLITTABLE, attrs->splittable))
1073 		return -EMSGSIZE;
1074 	if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour))
1075 		return -EMSGSIZE;
1076 	switch (devlink_port->attrs.flavour) {
1077 	case DEVLINK_PORT_FLAVOUR_PCI_PF:
1078 		if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
1079 				attrs->pci_pf.controller) ||
1080 		    nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_pf.pf))
1081 			return -EMSGSIZE;
1082 		if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_pf.external))
1083 			return -EMSGSIZE;
1084 		break;
1085 	case DEVLINK_PORT_FLAVOUR_PCI_VF:
1086 		if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
1087 				attrs->pci_vf.controller) ||
1088 		    nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_vf.pf) ||
1089 		    nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_VF_NUMBER, attrs->pci_vf.vf))
1090 			return -EMSGSIZE;
1091 		if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_vf.external))
1092 			return -EMSGSIZE;
1093 		break;
1094 	case DEVLINK_PORT_FLAVOUR_PCI_SF:
1095 		if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
1096 				attrs->pci_sf.controller) ||
1097 		    nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER,
1098 				attrs->pci_sf.pf) ||
1099 		    nla_put_u32(msg, DEVLINK_ATTR_PORT_PCI_SF_NUMBER,
1100 				attrs->pci_sf.sf))
1101 			return -EMSGSIZE;
1102 		break;
1103 	case DEVLINK_PORT_FLAVOUR_PHYSICAL:
1104 	case DEVLINK_PORT_FLAVOUR_CPU:
1105 	case DEVLINK_PORT_FLAVOUR_DSA:
1106 		if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER,
1107 				attrs->phys.port_number))
1108 			return -EMSGSIZE;
1109 		if (!attrs->split)
1110 			return 0;
1111 		if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
1112 				attrs->phys.port_number))
1113 			return -EMSGSIZE;
1114 		if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER,
1115 				attrs->phys.split_subport_number))
1116 			return -EMSGSIZE;
1117 		break;
1118 	default:
1119 		break;
1120 	}
1121 	return 0;
1122 }
1123 
devlink_port_fn_hw_addr_fill(const struct devlink_ops * ops,struct devlink_port * port,struct sk_buff * msg,struct netlink_ext_ack * extack,bool * msg_updated)1124 static int devlink_port_fn_hw_addr_fill(const struct devlink_ops *ops,
1125 					struct devlink_port *port,
1126 					struct sk_buff *msg,
1127 					struct netlink_ext_ack *extack,
1128 					bool *msg_updated)
1129 {
1130 	u8 hw_addr[MAX_ADDR_LEN];
1131 	int hw_addr_len;
1132 	int err;
1133 
1134 	if (!ops->port_function_hw_addr_get)
1135 		return 0;
1136 
1137 	err = ops->port_function_hw_addr_get(port, hw_addr, &hw_addr_len,
1138 					     extack);
1139 	if (err) {
1140 		if (err == -EOPNOTSUPP)
1141 			return 0;
1142 		return err;
1143 	}
1144 	err = nla_put(msg, DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR, hw_addr_len, hw_addr);
1145 	if (err)
1146 		return err;
1147 	*msg_updated = true;
1148 	return 0;
1149 }
1150 
devlink_nl_rate_fill(struct sk_buff * msg,struct devlink_rate * devlink_rate,enum devlink_command cmd,u32 portid,u32 seq,int flags,struct netlink_ext_ack * extack)1151 static int devlink_nl_rate_fill(struct sk_buff *msg,
1152 				struct devlink_rate *devlink_rate,
1153 				enum devlink_command cmd, u32 portid, u32 seq,
1154 				int flags, struct netlink_ext_ack *extack)
1155 {
1156 	struct devlink *devlink = devlink_rate->devlink;
1157 	void *hdr;
1158 
1159 	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1160 	if (!hdr)
1161 		return -EMSGSIZE;
1162 
1163 	if (devlink_nl_put_handle(msg, devlink))
1164 		goto nla_put_failure;
1165 
1166 	if (nla_put_u16(msg, DEVLINK_ATTR_RATE_TYPE, devlink_rate->type))
1167 		goto nla_put_failure;
1168 
1169 	if (devlink_rate_is_leaf(devlink_rate)) {
1170 		if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
1171 				devlink_rate->devlink_port->index))
1172 			goto nla_put_failure;
1173 	} else if (devlink_rate_is_node(devlink_rate)) {
1174 		if (nla_put_string(msg, DEVLINK_ATTR_RATE_NODE_NAME,
1175 				   devlink_rate->name))
1176 			goto nla_put_failure;
1177 	}
1178 
1179 	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_RATE_TX_SHARE,
1180 			      devlink_rate->tx_share, DEVLINK_ATTR_PAD))
1181 		goto nla_put_failure;
1182 
1183 	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_RATE_TX_MAX,
1184 			      devlink_rate->tx_max, DEVLINK_ATTR_PAD))
1185 		goto nla_put_failure;
1186 
1187 	if (devlink_rate->parent)
1188 		if (nla_put_string(msg, DEVLINK_ATTR_RATE_PARENT_NODE_NAME,
1189 				   devlink_rate->parent->name))
1190 			goto nla_put_failure;
1191 
1192 	genlmsg_end(msg, hdr);
1193 	return 0;
1194 
1195 nla_put_failure:
1196 	genlmsg_cancel(msg, hdr);
1197 	return -EMSGSIZE;
1198 }
1199 
1200 static bool
devlink_port_fn_state_valid(enum devlink_port_fn_state state)1201 devlink_port_fn_state_valid(enum devlink_port_fn_state state)
1202 {
1203 	return state == DEVLINK_PORT_FN_STATE_INACTIVE ||
1204 	       state == DEVLINK_PORT_FN_STATE_ACTIVE;
1205 }
1206 
1207 static bool
devlink_port_fn_opstate_valid(enum devlink_port_fn_opstate opstate)1208 devlink_port_fn_opstate_valid(enum devlink_port_fn_opstate opstate)
1209 {
1210 	return opstate == DEVLINK_PORT_FN_OPSTATE_DETACHED ||
1211 	       opstate == DEVLINK_PORT_FN_OPSTATE_ATTACHED;
1212 }
1213 
devlink_port_fn_state_fill(const struct devlink_ops * ops,struct devlink_port * port,struct sk_buff * msg,struct netlink_ext_ack * extack,bool * msg_updated)1214 static int devlink_port_fn_state_fill(const struct devlink_ops *ops,
1215 				      struct devlink_port *port,
1216 				      struct sk_buff *msg,
1217 				      struct netlink_ext_ack *extack,
1218 				      bool *msg_updated)
1219 {
1220 	enum devlink_port_fn_opstate opstate;
1221 	enum devlink_port_fn_state state;
1222 	int err;
1223 
1224 	if (!ops->port_fn_state_get)
1225 		return 0;
1226 
1227 	err = ops->port_fn_state_get(port, &state, &opstate, extack);
1228 	if (err) {
1229 		if (err == -EOPNOTSUPP)
1230 			return 0;
1231 		return err;
1232 	}
1233 	if (!devlink_port_fn_state_valid(state)) {
1234 		WARN_ON_ONCE(1);
1235 		NL_SET_ERR_MSG_MOD(extack, "Invalid state read from driver");
1236 		return -EINVAL;
1237 	}
1238 	if (!devlink_port_fn_opstate_valid(opstate)) {
1239 		WARN_ON_ONCE(1);
1240 		NL_SET_ERR_MSG_MOD(extack,
1241 				   "Invalid operational state read from driver");
1242 		return -EINVAL;
1243 	}
1244 	if (nla_put_u8(msg, DEVLINK_PORT_FN_ATTR_STATE, state) ||
1245 	    nla_put_u8(msg, DEVLINK_PORT_FN_ATTR_OPSTATE, opstate))
1246 		return -EMSGSIZE;
1247 	*msg_updated = true;
1248 	return 0;
1249 }
1250 
1251 static int
devlink_nl_port_function_attrs_put(struct sk_buff * msg,struct devlink_port * port,struct netlink_ext_ack * extack)1252 devlink_nl_port_function_attrs_put(struct sk_buff *msg, struct devlink_port *port,
1253 				   struct netlink_ext_ack *extack)
1254 {
1255 	const struct devlink_ops *ops;
1256 	struct nlattr *function_attr;
1257 	bool msg_updated = false;
1258 	int err;
1259 
1260 	function_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PORT_FUNCTION);
1261 	if (!function_attr)
1262 		return -EMSGSIZE;
1263 
1264 	ops = port->devlink->ops;
1265 	err = devlink_port_fn_hw_addr_fill(ops, port, msg, extack,
1266 					   &msg_updated);
1267 	if (err)
1268 		goto out;
1269 	err = devlink_port_fn_state_fill(ops, port, msg, extack, &msg_updated);
1270 out:
1271 	if (err || !msg_updated)
1272 		nla_nest_cancel(msg, function_attr);
1273 	else
1274 		nla_nest_end(msg, function_attr);
1275 	return err;
1276 }
1277 
devlink_nl_port_fill(struct sk_buff * msg,struct devlink_port * devlink_port,enum devlink_command cmd,u32 portid,u32 seq,int flags,struct netlink_ext_ack * extack)1278 static int devlink_nl_port_fill(struct sk_buff *msg,
1279 				struct devlink_port *devlink_port,
1280 				enum devlink_command cmd, u32 portid, u32 seq,
1281 				int flags, struct netlink_ext_ack *extack)
1282 {
1283 	struct devlink *devlink = devlink_port->devlink;
1284 	void *hdr;
1285 
1286 	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1287 	if (!hdr)
1288 		return -EMSGSIZE;
1289 
1290 	if (devlink_nl_put_handle(msg, devlink))
1291 		goto nla_put_failure;
1292 	if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1293 		goto nla_put_failure;
1294 
1295 	/* Hold rtnl lock while accessing port's netdev attributes. */
1296 	rtnl_lock();
1297 	spin_lock_bh(&devlink_port->type_lock);
1298 	if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
1299 		goto nla_put_failure_type_locked;
1300 	if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
1301 	    nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
1302 			devlink_port->desired_type))
1303 		goto nla_put_failure_type_locked;
1304 	if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
1305 		struct net *net = devlink_net(devlink_port->devlink);
1306 		struct net_device *netdev = devlink_port->type_dev;
1307 
1308 		if (netdev && net_eq(net, dev_net(netdev)) &&
1309 		    (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
1310 				 netdev->ifindex) ||
1311 		     nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
1312 				    netdev->name)))
1313 			goto nla_put_failure_type_locked;
1314 	}
1315 	if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
1316 		struct ib_device *ibdev = devlink_port->type_dev;
1317 
1318 		if (ibdev &&
1319 		    nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
1320 				   ibdev->name))
1321 			goto nla_put_failure_type_locked;
1322 	}
1323 	spin_unlock_bh(&devlink_port->type_lock);
1324 	rtnl_unlock();
1325 	if (devlink_nl_port_attrs_put(msg, devlink_port))
1326 		goto nla_put_failure;
1327 	if (devlink_nl_port_function_attrs_put(msg, devlink_port, extack))
1328 		goto nla_put_failure;
1329 	if (devlink_port->linecard &&
1330 	    nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX,
1331 			devlink_port->linecard->index))
1332 		goto nla_put_failure;
1333 
1334 	genlmsg_end(msg, hdr);
1335 	return 0;
1336 
1337 nla_put_failure_type_locked:
1338 	spin_unlock_bh(&devlink_port->type_lock);
1339 	rtnl_unlock();
1340 nla_put_failure:
1341 	genlmsg_cancel(msg, hdr);
1342 	return -EMSGSIZE;
1343 }
1344 
devlink_port_notify(struct devlink_port * devlink_port,enum devlink_command cmd)1345 static void devlink_port_notify(struct devlink_port *devlink_port,
1346 				enum devlink_command cmd)
1347 {
1348 	struct devlink *devlink = devlink_port->devlink;
1349 	struct sk_buff *msg;
1350 	int err;
1351 
1352 	WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
1353 
1354 	if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
1355 		return;
1356 
1357 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1358 	if (!msg)
1359 		return;
1360 
1361 	err = devlink_nl_port_fill(msg, devlink_port, cmd, 0, 0, 0, NULL);
1362 	if (err) {
1363 		nlmsg_free(msg);
1364 		return;
1365 	}
1366 
1367 	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
1368 				0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
1369 }
1370 
devlink_rate_notify(struct devlink_rate * devlink_rate,enum devlink_command cmd)1371 static void devlink_rate_notify(struct devlink_rate *devlink_rate,
1372 				enum devlink_command cmd)
1373 {
1374 	struct devlink *devlink = devlink_rate->devlink;
1375 	struct sk_buff *msg;
1376 	int err;
1377 
1378 	WARN_ON(cmd != DEVLINK_CMD_RATE_NEW && cmd != DEVLINK_CMD_RATE_DEL);
1379 
1380 	if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
1381 		return;
1382 
1383 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1384 	if (!msg)
1385 		return;
1386 
1387 	err = devlink_nl_rate_fill(msg, devlink_rate, cmd, 0, 0, 0, NULL);
1388 	if (err) {
1389 		nlmsg_free(msg);
1390 		return;
1391 	}
1392 
1393 	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
1394 				0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
1395 }
1396 
devlink_nl_cmd_rate_get_dumpit(struct sk_buff * msg,struct netlink_callback * cb)1397 static int devlink_nl_cmd_rate_get_dumpit(struct sk_buff *msg,
1398 					  struct netlink_callback *cb)
1399 {
1400 	struct devlink_rate *devlink_rate;
1401 	struct devlink *devlink;
1402 	int start = cb->args[0];
1403 	unsigned long index;
1404 	int idx = 0;
1405 	int err = 0;
1406 
1407 	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
1408 		devl_lock(devlink);
1409 		list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
1410 			enum devlink_command cmd = DEVLINK_CMD_RATE_NEW;
1411 			u32 id = NETLINK_CB(cb->skb).portid;
1412 
1413 			if (idx < start) {
1414 				idx++;
1415 				continue;
1416 			}
1417 			err = devlink_nl_rate_fill(msg, devlink_rate, cmd, id,
1418 						   cb->nlh->nlmsg_seq,
1419 						   NLM_F_MULTI, NULL);
1420 			if (err) {
1421 				devl_unlock(devlink);
1422 				devlink_put(devlink);
1423 				goto out;
1424 			}
1425 			idx++;
1426 		}
1427 		devl_unlock(devlink);
1428 		devlink_put(devlink);
1429 	}
1430 out:
1431 	if (err != -EMSGSIZE)
1432 		return err;
1433 
1434 	cb->args[0] = idx;
1435 	return msg->len;
1436 }
1437 
devlink_nl_cmd_rate_get_doit(struct sk_buff * skb,struct genl_info * info)1438 static int devlink_nl_cmd_rate_get_doit(struct sk_buff *skb,
1439 					struct genl_info *info)
1440 {
1441 	struct devlink_rate *devlink_rate = info->user_ptr[1];
1442 	struct sk_buff *msg;
1443 	int err;
1444 
1445 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1446 	if (!msg)
1447 		return -ENOMEM;
1448 
1449 	err = devlink_nl_rate_fill(msg, devlink_rate, DEVLINK_CMD_RATE_NEW,
1450 				   info->snd_portid, info->snd_seq, 0,
1451 				   info->extack);
1452 	if (err) {
1453 		nlmsg_free(msg);
1454 		return err;
1455 	}
1456 
1457 	return genlmsg_reply(msg, info);
1458 }
1459 
1460 static bool
devlink_rate_is_parent_node(struct devlink_rate * devlink_rate,struct devlink_rate * parent)1461 devlink_rate_is_parent_node(struct devlink_rate *devlink_rate,
1462 			    struct devlink_rate *parent)
1463 {
1464 	while (parent) {
1465 		if (parent == devlink_rate)
1466 			return true;
1467 		parent = parent->parent;
1468 	}
1469 	return false;
1470 }
1471 
devlink_nl_cmd_get_doit(struct sk_buff * skb,struct genl_info * info)1472 static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
1473 {
1474 	struct devlink *devlink = info->user_ptr[0];
1475 	struct sk_buff *msg;
1476 	int err;
1477 
1478 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1479 	if (!msg)
1480 		return -ENOMEM;
1481 
1482 	err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
1483 			      info->snd_portid, info->snd_seq, 0);
1484 	if (err) {
1485 		nlmsg_free(msg);
1486 		return err;
1487 	}
1488 
1489 	return genlmsg_reply(msg, info);
1490 }
1491 
devlink_nl_cmd_get_dumpit(struct sk_buff * msg,struct netlink_callback * cb)1492 static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
1493 				     struct netlink_callback *cb)
1494 {
1495 	struct devlink *devlink;
1496 	int start = cb->args[0];
1497 	unsigned long index;
1498 	int idx = 0;
1499 	int err;
1500 
1501 	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
1502 		if (idx < start) {
1503 			idx++;
1504 			devlink_put(devlink);
1505 			continue;
1506 		}
1507 
1508 		devl_lock(devlink);
1509 		err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
1510 				      NETLINK_CB(cb->skb).portid,
1511 				      cb->nlh->nlmsg_seq, NLM_F_MULTI);
1512 		devl_unlock(devlink);
1513 		devlink_put(devlink);
1514 
1515 		if (err)
1516 			goto out;
1517 		idx++;
1518 	}
1519 out:
1520 	cb->args[0] = idx;
1521 	return msg->len;
1522 }
1523 
devlink_nl_cmd_port_get_doit(struct sk_buff * skb,struct genl_info * info)1524 static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
1525 					struct genl_info *info)
1526 {
1527 	struct devlink_port *devlink_port = info->user_ptr[1];
1528 	struct sk_buff *msg;
1529 	int err;
1530 
1531 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1532 	if (!msg)
1533 		return -ENOMEM;
1534 
1535 	err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_PORT_NEW,
1536 				   info->snd_portid, info->snd_seq, 0,
1537 				   info->extack);
1538 	if (err) {
1539 		nlmsg_free(msg);
1540 		return err;
1541 	}
1542 
1543 	return genlmsg_reply(msg, info);
1544 }
1545 
devlink_nl_cmd_port_get_dumpit(struct sk_buff * msg,struct netlink_callback * cb)1546 static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
1547 					  struct netlink_callback *cb)
1548 {
1549 	struct devlink *devlink;
1550 	struct devlink_port *devlink_port;
1551 	int start = cb->args[0];
1552 	unsigned long index;
1553 	int idx = 0;
1554 	int err;
1555 
1556 	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
1557 		devl_lock(devlink);
1558 		list_for_each_entry(devlink_port, &devlink->port_list, list) {
1559 			if (idx < start) {
1560 				idx++;
1561 				continue;
1562 			}
1563 			err = devlink_nl_port_fill(msg, devlink_port,
1564 						   DEVLINK_CMD_NEW,
1565 						   NETLINK_CB(cb->skb).portid,
1566 						   cb->nlh->nlmsg_seq,
1567 						   NLM_F_MULTI, cb->extack);
1568 			if (err) {
1569 				devl_unlock(devlink);
1570 				devlink_put(devlink);
1571 				goto out;
1572 			}
1573 			idx++;
1574 		}
1575 		devl_unlock(devlink);
1576 		devlink_put(devlink);
1577 	}
1578 out:
1579 	cb->args[0] = idx;
1580 	return msg->len;
1581 }
1582 
devlink_port_type_set(struct devlink_port * devlink_port,enum devlink_port_type port_type)1583 static int devlink_port_type_set(struct devlink_port *devlink_port,
1584 				 enum devlink_port_type port_type)
1585 
1586 {
1587 	int err;
1588 
1589 	if (!devlink_port->devlink->ops->port_type_set)
1590 		return -EOPNOTSUPP;
1591 
1592 	if (port_type == devlink_port->type)
1593 		return 0;
1594 
1595 	err = devlink_port->devlink->ops->port_type_set(devlink_port,
1596 							port_type);
1597 	if (err)
1598 		return err;
1599 
1600 	devlink_port->desired_type = port_type;
1601 	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
1602 	return 0;
1603 }
1604 
devlink_port_function_hw_addr_set(struct devlink_port * port,const struct nlattr * attr,struct netlink_ext_ack * extack)1605 static int devlink_port_function_hw_addr_set(struct devlink_port *port,
1606 					     const struct nlattr *attr,
1607 					     struct netlink_ext_ack *extack)
1608 {
1609 	const struct devlink_ops *ops = port->devlink->ops;
1610 	const u8 *hw_addr;
1611 	int hw_addr_len;
1612 
1613 	hw_addr = nla_data(attr);
1614 	hw_addr_len = nla_len(attr);
1615 	if (hw_addr_len > MAX_ADDR_LEN) {
1616 		NL_SET_ERR_MSG_MOD(extack, "Port function hardware address too long");
1617 		return -EINVAL;
1618 	}
1619 	if (port->type == DEVLINK_PORT_TYPE_ETH) {
1620 		if (hw_addr_len != ETH_ALEN) {
1621 			NL_SET_ERR_MSG_MOD(extack, "Address must be 6 bytes for Ethernet device");
1622 			return -EINVAL;
1623 		}
1624 		if (!is_unicast_ether_addr(hw_addr)) {
1625 			NL_SET_ERR_MSG_MOD(extack, "Non-unicast hardware address unsupported");
1626 			return -EINVAL;
1627 		}
1628 	}
1629 
1630 	if (!ops->port_function_hw_addr_set) {
1631 		NL_SET_ERR_MSG_MOD(extack, "Port doesn't support function attributes");
1632 		return -EOPNOTSUPP;
1633 	}
1634 
1635 	return ops->port_function_hw_addr_set(port, hw_addr, hw_addr_len,
1636 					      extack);
1637 }
1638 
devlink_port_fn_state_set(struct devlink_port * port,const struct nlattr * attr,struct netlink_ext_ack * extack)1639 static int devlink_port_fn_state_set(struct devlink_port *port,
1640 				     const struct nlattr *attr,
1641 				     struct netlink_ext_ack *extack)
1642 {
1643 	enum devlink_port_fn_state state;
1644 	const struct devlink_ops *ops;
1645 
1646 	state = nla_get_u8(attr);
1647 	ops = port->devlink->ops;
1648 	if (!ops->port_fn_state_set) {
1649 		NL_SET_ERR_MSG_MOD(extack,
1650 				   "Function does not support state setting");
1651 		return -EOPNOTSUPP;
1652 	}
1653 	return ops->port_fn_state_set(port, state, extack);
1654 }
1655 
devlink_port_function_set(struct devlink_port * port,const struct nlattr * attr,struct netlink_ext_ack * extack)1656 static int devlink_port_function_set(struct devlink_port *port,
1657 				     const struct nlattr *attr,
1658 				     struct netlink_ext_ack *extack)
1659 {
1660 	struct nlattr *tb[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1];
1661 	int err;
1662 
1663 	err = nla_parse_nested(tb, DEVLINK_PORT_FUNCTION_ATTR_MAX, attr,
1664 			       devlink_function_nl_policy, extack);
1665 	if (err < 0) {
1666 		NL_SET_ERR_MSG_MOD(extack, "Fail to parse port function attributes");
1667 		return err;
1668 	}
1669 
1670 	attr = tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR];
1671 	if (attr) {
1672 		err = devlink_port_function_hw_addr_set(port, attr, extack);
1673 		if (err)
1674 			return err;
1675 	}
1676 	/* Keep this as the last function attribute set, so that when
1677 	 * multiple port function attributes are set along with state,
1678 	 * Those can be applied first before activating the state.
1679 	 */
1680 	attr = tb[DEVLINK_PORT_FN_ATTR_STATE];
1681 	if (attr)
1682 		err = devlink_port_fn_state_set(port, attr, extack);
1683 
1684 	if (!err)
1685 		devlink_port_notify(port, DEVLINK_CMD_PORT_NEW);
1686 	return err;
1687 }
1688 
devlink_nl_cmd_port_set_doit(struct sk_buff * skb,struct genl_info * info)1689 static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
1690 					struct genl_info *info)
1691 {
1692 	struct devlink_port *devlink_port = info->user_ptr[1];
1693 	int err;
1694 
1695 	if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
1696 		enum devlink_port_type port_type;
1697 
1698 		port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
1699 		err = devlink_port_type_set(devlink_port, port_type);
1700 		if (err)
1701 			return err;
1702 	}
1703 
1704 	if (info->attrs[DEVLINK_ATTR_PORT_FUNCTION]) {
1705 		struct nlattr *attr = info->attrs[DEVLINK_ATTR_PORT_FUNCTION];
1706 		struct netlink_ext_ack *extack = info->extack;
1707 
1708 		err = devlink_port_function_set(devlink_port, attr, extack);
1709 		if (err)
1710 			return err;
1711 	}
1712 
1713 	return 0;
1714 }
1715 
devlink_nl_cmd_port_split_doit(struct sk_buff * skb,struct genl_info * info)1716 static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
1717 					  struct genl_info *info)
1718 {
1719 	struct devlink_port *devlink_port = info->user_ptr[1];
1720 	struct devlink *devlink = info->user_ptr[0];
1721 	u32 count;
1722 
1723 	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PORT_SPLIT_COUNT))
1724 		return -EINVAL;
1725 	if (!devlink->ops->port_split)
1726 		return -EOPNOTSUPP;
1727 
1728 	count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
1729 
1730 	if (!devlink_port->attrs.splittable) {
1731 		/* Split ports cannot be split. */
1732 		if (devlink_port->attrs.split)
1733 			NL_SET_ERR_MSG_MOD(info->extack, "Port cannot be split further");
1734 		else
1735 			NL_SET_ERR_MSG_MOD(info->extack, "Port cannot be split");
1736 		return -EINVAL;
1737 	}
1738 
1739 	if (count < 2 || !is_power_of_2(count) || count > devlink_port->attrs.lanes) {
1740 		NL_SET_ERR_MSG_MOD(info->extack, "Invalid split count");
1741 		return -EINVAL;
1742 	}
1743 
1744 	return devlink->ops->port_split(devlink, devlink_port, count,
1745 					info->extack);
1746 }
1747 
devlink_nl_cmd_port_unsplit_doit(struct sk_buff * skb,struct genl_info * info)1748 static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
1749 					    struct genl_info *info)
1750 {
1751 	struct devlink_port *devlink_port = info->user_ptr[1];
1752 	struct devlink *devlink = info->user_ptr[0];
1753 
1754 	if (!devlink->ops->port_unsplit)
1755 		return -EOPNOTSUPP;
1756 	return devlink->ops->port_unsplit(devlink, devlink_port, info->extack);
1757 }
1758 
devlink_port_new_notify(struct devlink * devlink,unsigned int port_index,struct genl_info * info)1759 static int devlink_port_new_notify(struct devlink *devlink,
1760 				   unsigned int port_index,
1761 				   struct genl_info *info)
1762 {
1763 	struct devlink_port *devlink_port;
1764 	struct sk_buff *msg;
1765 	int err;
1766 
1767 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1768 	if (!msg)
1769 		return -ENOMEM;
1770 
1771 	lockdep_assert_held(&devlink->lock);
1772 	devlink_port = devlink_port_get_by_index(devlink, port_index);
1773 	if (!devlink_port) {
1774 		err = -ENODEV;
1775 		goto out;
1776 	}
1777 
1778 	err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_NEW,
1779 				   info->snd_portid, info->snd_seq, 0, NULL);
1780 	if (err)
1781 		goto out;
1782 
1783 	return genlmsg_reply(msg, info);
1784 
1785 out:
1786 	nlmsg_free(msg);
1787 	return err;
1788 }
1789 
devlink_nl_cmd_port_new_doit(struct sk_buff * skb,struct genl_info * info)1790 static int devlink_nl_cmd_port_new_doit(struct sk_buff *skb,
1791 					struct genl_info *info)
1792 {
1793 	struct netlink_ext_ack *extack = info->extack;
1794 	struct devlink_port_new_attrs new_attrs = {};
1795 	struct devlink *devlink = info->user_ptr[0];
1796 	unsigned int new_port_index;
1797 	int err;
1798 
1799 	if (!devlink->ops->port_new || !devlink->ops->port_del)
1800 		return -EOPNOTSUPP;
1801 
1802 	if (!info->attrs[DEVLINK_ATTR_PORT_FLAVOUR] ||
1803 	    !info->attrs[DEVLINK_ATTR_PORT_PCI_PF_NUMBER]) {
1804 		NL_SET_ERR_MSG_MOD(extack, "Port flavour or PCI PF are not specified");
1805 		return -EINVAL;
1806 	}
1807 	new_attrs.flavour = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_FLAVOUR]);
1808 	new_attrs.pfnum =
1809 		nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_PCI_PF_NUMBER]);
1810 
1811 	if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
1812 		/* Port index of the new port being created by driver. */
1813 		new_attrs.port_index =
1814 			nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
1815 		new_attrs.port_index_valid = true;
1816 	}
1817 	if (info->attrs[DEVLINK_ATTR_PORT_CONTROLLER_NUMBER]) {
1818 		new_attrs.controller =
1819 			nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_CONTROLLER_NUMBER]);
1820 		new_attrs.controller_valid = true;
1821 	}
1822 	if (new_attrs.flavour == DEVLINK_PORT_FLAVOUR_PCI_SF &&
1823 	    info->attrs[DEVLINK_ATTR_PORT_PCI_SF_NUMBER]) {
1824 		new_attrs.sfnum = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_PCI_SF_NUMBER]);
1825 		new_attrs.sfnum_valid = true;
1826 	}
1827 
1828 	err = devlink->ops->port_new(devlink, &new_attrs, extack,
1829 				     &new_port_index);
1830 	if (err)
1831 		return err;
1832 
1833 	err = devlink_port_new_notify(devlink, new_port_index, info);
1834 	if (err && err != -ENODEV) {
1835 		/* Fail to send the response; destroy newly created port. */
1836 		devlink->ops->port_del(devlink, new_port_index, extack);
1837 	}
1838 	return err;
1839 }
1840 
devlink_nl_cmd_port_del_doit(struct sk_buff * skb,struct genl_info * info)1841 static int devlink_nl_cmd_port_del_doit(struct sk_buff *skb,
1842 					struct genl_info *info)
1843 {
1844 	struct netlink_ext_ack *extack = info->extack;
1845 	struct devlink *devlink = info->user_ptr[0];
1846 	unsigned int port_index;
1847 
1848 	if (!devlink->ops->port_del)
1849 		return -EOPNOTSUPP;
1850 
1851 	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PORT_INDEX)) {
1852 		NL_SET_ERR_MSG_MOD(extack, "Port index is not specified");
1853 		return -EINVAL;
1854 	}
1855 	port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
1856 
1857 	return devlink->ops->port_del(devlink, port_index, extack);
1858 }
1859 
1860 static int
devlink_nl_rate_parent_node_set(struct devlink_rate * devlink_rate,struct genl_info * info,struct nlattr * nla_parent)1861 devlink_nl_rate_parent_node_set(struct devlink_rate *devlink_rate,
1862 				struct genl_info *info,
1863 				struct nlattr *nla_parent)
1864 {
1865 	struct devlink *devlink = devlink_rate->devlink;
1866 	const char *parent_name = nla_data(nla_parent);
1867 	const struct devlink_ops *ops = devlink->ops;
1868 	size_t len = strlen(parent_name);
1869 	struct devlink_rate *parent;
1870 	int err = -EOPNOTSUPP;
1871 
1872 	parent = devlink_rate->parent;
1873 	if (parent && len) {
1874 		NL_SET_ERR_MSG_MOD(info->extack, "Rate object already has parent.");
1875 		return -EBUSY;
1876 	} else if (parent && !len) {
1877 		if (devlink_rate_is_leaf(devlink_rate))
1878 			err = ops->rate_leaf_parent_set(devlink_rate, NULL,
1879 							devlink_rate->priv, NULL,
1880 							info->extack);
1881 		else if (devlink_rate_is_node(devlink_rate))
1882 			err = ops->rate_node_parent_set(devlink_rate, NULL,
1883 							devlink_rate->priv, NULL,
1884 							info->extack);
1885 		if (err)
1886 			return err;
1887 
1888 		refcount_dec(&parent->refcnt);
1889 		devlink_rate->parent = NULL;
1890 	} else if (!parent && len) {
1891 		parent = devlink_rate_node_get_by_name(devlink, parent_name);
1892 		if (IS_ERR(parent))
1893 			return -ENODEV;
1894 
1895 		if (parent == devlink_rate) {
1896 			NL_SET_ERR_MSG_MOD(info->extack, "Parent to self is not allowed");
1897 			return -EINVAL;
1898 		}
1899 
1900 		if (devlink_rate_is_node(devlink_rate) &&
1901 		    devlink_rate_is_parent_node(devlink_rate, parent->parent)) {
1902 			NL_SET_ERR_MSG_MOD(info->extack, "Node is already a parent of parent node.");
1903 			return -EEXIST;
1904 		}
1905 
1906 		if (devlink_rate_is_leaf(devlink_rate))
1907 			err = ops->rate_leaf_parent_set(devlink_rate, parent,
1908 							devlink_rate->priv, parent->priv,
1909 							info->extack);
1910 		else if (devlink_rate_is_node(devlink_rate))
1911 			err = ops->rate_node_parent_set(devlink_rate, parent,
1912 							devlink_rate->priv, parent->priv,
1913 							info->extack);
1914 		if (err)
1915 			return err;
1916 
1917 		refcount_inc(&parent->refcnt);
1918 		devlink_rate->parent = parent;
1919 	}
1920 
1921 	return 0;
1922 }
1923 
devlink_nl_rate_set(struct devlink_rate * devlink_rate,const struct devlink_ops * ops,struct genl_info * info)1924 static int devlink_nl_rate_set(struct devlink_rate *devlink_rate,
1925 			       const struct devlink_ops *ops,
1926 			       struct genl_info *info)
1927 {
1928 	struct nlattr *nla_parent, **attrs = info->attrs;
1929 	int err = -EOPNOTSUPP;
1930 	u64 rate;
1931 
1932 	if (attrs[DEVLINK_ATTR_RATE_TX_SHARE]) {
1933 		rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_SHARE]);
1934 		if (devlink_rate_is_leaf(devlink_rate))
1935 			err = ops->rate_leaf_tx_share_set(devlink_rate, devlink_rate->priv,
1936 							  rate, info->extack);
1937 		else if (devlink_rate_is_node(devlink_rate))
1938 			err = ops->rate_node_tx_share_set(devlink_rate, devlink_rate->priv,
1939 							  rate, info->extack);
1940 		if (err)
1941 			return err;
1942 		devlink_rate->tx_share = rate;
1943 	}
1944 
1945 	if (attrs[DEVLINK_ATTR_RATE_TX_MAX]) {
1946 		rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_MAX]);
1947 		if (devlink_rate_is_leaf(devlink_rate))
1948 			err = ops->rate_leaf_tx_max_set(devlink_rate, devlink_rate->priv,
1949 							rate, info->extack);
1950 		else if (devlink_rate_is_node(devlink_rate))
1951 			err = ops->rate_node_tx_max_set(devlink_rate, devlink_rate->priv,
1952 							rate, info->extack);
1953 		if (err)
1954 			return err;
1955 		devlink_rate->tx_max = rate;
1956 	}
1957 
1958 	nla_parent = attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME];
1959 	if (nla_parent) {
1960 		err = devlink_nl_rate_parent_node_set(devlink_rate, info,
1961 						      nla_parent);
1962 		if (err)
1963 			return err;
1964 	}
1965 
1966 	return 0;
1967 }
1968 
devlink_rate_set_ops_supported(const struct devlink_ops * ops,struct genl_info * info,enum devlink_rate_type type)1969 static bool devlink_rate_set_ops_supported(const struct devlink_ops *ops,
1970 					   struct genl_info *info,
1971 					   enum devlink_rate_type type)
1972 {
1973 	struct nlattr **attrs = info->attrs;
1974 
1975 	if (type == DEVLINK_RATE_TYPE_LEAF) {
1976 		if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_leaf_tx_share_set) {
1977 			NL_SET_ERR_MSG_MOD(info->extack, "TX share set isn't supported for the leafs");
1978 			return false;
1979 		}
1980 		if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_leaf_tx_max_set) {
1981 			NL_SET_ERR_MSG_MOD(info->extack, "TX max set isn't supported for the leafs");
1982 			return false;
1983 		}
1984 		if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] &&
1985 		    !ops->rate_leaf_parent_set) {
1986 			NL_SET_ERR_MSG_MOD(info->extack, "Parent set isn't supported for the leafs");
1987 			return false;
1988 		}
1989 	} else if (type == DEVLINK_RATE_TYPE_NODE) {
1990 		if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_node_tx_share_set) {
1991 			NL_SET_ERR_MSG_MOD(info->extack, "TX share set isn't supported for the nodes");
1992 			return false;
1993 		}
1994 		if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_node_tx_max_set) {
1995 			NL_SET_ERR_MSG_MOD(info->extack, "TX max set isn't supported for the nodes");
1996 			return false;
1997 		}
1998 		if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] &&
1999 		    !ops->rate_node_parent_set) {
2000 			NL_SET_ERR_MSG_MOD(info->extack, "Parent set isn't supported for the nodes");
2001 			return false;
2002 		}
2003 	} else {
2004 		WARN(1, "Unknown type of rate object");
2005 		return false;
2006 	}
2007 
2008 	return true;
2009 }
2010 
devlink_nl_cmd_rate_set_doit(struct sk_buff * skb,struct genl_info * info)2011 static int devlink_nl_cmd_rate_set_doit(struct sk_buff *skb,
2012 					struct genl_info *info)
2013 {
2014 	struct devlink_rate *devlink_rate = info->user_ptr[1];
2015 	struct devlink *devlink = devlink_rate->devlink;
2016 	const struct devlink_ops *ops = devlink->ops;
2017 	int err;
2018 
2019 	if (!ops || !devlink_rate_set_ops_supported(ops, info, devlink_rate->type))
2020 		return -EOPNOTSUPP;
2021 
2022 	err = devlink_nl_rate_set(devlink_rate, ops, info);
2023 
2024 	if (!err)
2025 		devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW);
2026 	return err;
2027 }
2028 
devlink_nl_cmd_rate_new_doit(struct sk_buff * skb,struct genl_info * info)2029 static int devlink_nl_cmd_rate_new_doit(struct sk_buff *skb,
2030 					struct genl_info *info)
2031 {
2032 	struct devlink *devlink = info->user_ptr[0];
2033 	struct devlink_rate *rate_node;
2034 	const struct devlink_ops *ops;
2035 	int err;
2036 
2037 	ops = devlink->ops;
2038 	if (!ops || !ops->rate_node_new || !ops->rate_node_del) {
2039 		NL_SET_ERR_MSG_MOD(info->extack, "Rate nodes aren't supported");
2040 		return -EOPNOTSUPP;
2041 	}
2042 
2043 	if (!devlink_rate_set_ops_supported(ops, info, DEVLINK_RATE_TYPE_NODE))
2044 		return -EOPNOTSUPP;
2045 
2046 	rate_node = devlink_rate_node_get_from_attrs(devlink, info->attrs);
2047 	if (!IS_ERR(rate_node))
2048 		return -EEXIST;
2049 	else if (rate_node == ERR_PTR(-EINVAL))
2050 		return -EINVAL;
2051 
2052 	rate_node = kzalloc(sizeof(*rate_node), GFP_KERNEL);
2053 	if (!rate_node)
2054 		return -ENOMEM;
2055 
2056 	rate_node->devlink = devlink;
2057 	rate_node->type = DEVLINK_RATE_TYPE_NODE;
2058 	rate_node->name = nla_strdup(info->attrs[DEVLINK_ATTR_RATE_NODE_NAME], GFP_KERNEL);
2059 	if (!rate_node->name) {
2060 		err = -ENOMEM;
2061 		goto err_strdup;
2062 	}
2063 
2064 	err = ops->rate_node_new(rate_node, &rate_node->priv, info->extack);
2065 	if (err)
2066 		goto err_node_new;
2067 
2068 	err = devlink_nl_rate_set(rate_node, ops, info);
2069 	if (err)
2070 		goto err_rate_set;
2071 
2072 	refcount_set(&rate_node->refcnt, 1);
2073 	list_add(&rate_node->list, &devlink->rate_list);
2074 	devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
2075 	return 0;
2076 
2077 err_rate_set:
2078 	ops->rate_node_del(rate_node, rate_node->priv, info->extack);
2079 err_node_new:
2080 	kfree(rate_node->name);
2081 err_strdup:
2082 	kfree(rate_node);
2083 	return err;
2084 }
2085 
devlink_nl_cmd_rate_del_doit(struct sk_buff * skb,struct genl_info * info)2086 static int devlink_nl_cmd_rate_del_doit(struct sk_buff *skb,
2087 					struct genl_info *info)
2088 {
2089 	struct devlink_rate *rate_node = info->user_ptr[1];
2090 	struct devlink *devlink = rate_node->devlink;
2091 	const struct devlink_ops *ops = devlink->ops;
2092 	int err;
2093 
2094 	if (refcount_read(&rate_node->refcnt) > 1) {
2095 		NL_SET_ERR_MSG_MOD(info->extack, "Node has children. Cannot delete node.");
2096 		return -EBUSY;
2097 	}
2098 
2099 	devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL);
2100 	err = ops->rate_node_del(rate_node, rate_node->priv, info->extack);
2101 	if (rate_node->parent)
2102 		refcount_dec(&rate_node->parent->refcnt);
2103 	list_del(&rate_node->list);
2104 	kfree(rate_node->name);
2105 	kfree(rate_node);
2106 	return err;
2107 }
2108 
2109 struct devlink_linecard_type {
2110 	const char *type;
2111 	const void *priv;
2112 };
2113 
devlink_nl_linecard_fill(struct sk_buff * msg,struct devlink * devlink,struct devlink_linecard * linecard,enum devlink_command cmd,u32 portid,u32 seq,int flags,struct netlink_ext_ack * extack)2114 static int devlink_nl_linecard_fill(struct sk_buff *msg,
2115 				    struct devlink *devlink,
2116 				    struct devlink_linecard *linecard,
2117 				    enum devlink_command cmd, u32 portid,
2118 				    u32 seq, int flags,
2119 				    struct netlink_ext_ack *extack)
2120 {
2121 	struct devlink_linecard_type *linecard_type;
2122 	struct nlattr *attr;
2123 	void *hdr;
2124 	int i;
2125 
2126 	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2127 	if (!hdr)
2128 		return -EMSGSIZE;
2129 
2130 	if (devlink_nl_put_handle(msg, devlink))
2131 		goto nla_put_failure;
2132 	if (nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX, linecard->index))
2133 		goto nla_put_failure;
2134 	if (nla_put_u8(msg, DEVLINK_ATTR_LINECARD_STATE, linecard->state))
2135 		goto nla_put_failure;
2136 	if (linecard->type &&
2137 	    nla_put_string(msg, DEVLINK_ATTR_LINECARD_TYPE, linecard->type))
2138 		goto nla_put_failure;
2139 
2140 	if (linecard->types_count) {
2141 		attr = nla_nest_start(msg,
2142 				      DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES);
2143 		if (!attr)
2144 			goto nla_put_failure;
2145 		for (i = 0; i < linecard->types_count; i++) {
2146 			linecard_type = &linecard->types[i];
2147 			if (nla_put_string(msg, DEVLINK_ATTR_LINECARD_TYPE,
2148 					   linecard_type->type)) {
2149 				nla_nest_cancel(msg, attr);
2150 				goto nla_put_failure;
2151 			}
2152 		}
2153 		nla_nest_end(msg, attr);
2154 	}
2155 
2156 	if (linecard->nested_devlink &&
2157 	    devlink_nl_put_nested_handle(msg, linecard->nested_devlink))
2158 		goto nla_put_failure;
2159 
2160 	genlmsg_end(msg, hdr);
2161 	return 0;
2162 
2163 nla_put_failure:
2164 	genlmsg_cancel(msg, hdr);
2165 	return -EMSGSIZE;
2166 }
2167 
devlink_linecard_notify(struct devlink_linecard * linecard,enum devlink_command cmd)2168 static void devlink_linecard_notify(struct devlink_linecard *linecard,
2169 				    enum devlink_command cmd)
2170 {
2171 	struct devlink *devlink = linecard->devlink;
2172 	struct sk_buff *msg;
2173 	int err;
2174 
2175 	WARN_ON(cmd != DEVLINK_CMD_LINECARD_NEW &&
2176 		cmd != DEVLINK_CMD_LINECARD_DEL);
2177 
2178 	if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
2179 		return;
2180 
2181 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2182 	if (!msg)
2183 		return;
2184 
2185 	err = devlink_nl_linecard_fill(msg, devlink, linecard, cmd, 0, 0, 0,
2186 				       NULL);
2187 	if (err) {
2188 		nlmsg_free(msg);
2189 		return;
2190 	}
2191 
2192 	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
2193 				msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
2194 }
2195 
devlink_nl_cmd_linecard_get_doit(struct sk_buff * skb,struct genl_info * info)2196 static int devlink_nl_cmd_linecard_get_doit(struct sk_buff *skb,
2197 					    struct genl_info *info)
2198 {
2199 	struct devlink_linecard *linecard = info->user_ptr[1];
2200 	struct devlink *devlink = linecard->devlink;
2201 	struct sk_buff *msg;
2202 	int err;
2203 
2204 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2205 	if (!msg)
2206 		return -ENOMEM;
2207 
2208 	mutex_lock(&linecard->state_lock);
2209 	err = devlink_nl_linecard_fill(msg, devlink, linecard,
2210 				       DEVLINK_CMD_LINECARD_NEW,
2211 				       info->snd_portid, info->snd_seq, 0,
2212 				       info->extack);
2213 	mutex_unlock(&linecard->state_lock);
2214 	if (err) {
2215 		nlmsg_free(msg);
2216 		return err;
2217 	}
2218 
2219 	return genlmsg_reply(msg, info);
2220 }
2221 
devlink_nl_cmd_linecard_get_dumpit(struct sk_buff * msg,struct netlink_callback * cb)2222 static int devlink_nl_cmd_linecard_get_dumpit(struct sk_buff *msg,
2223 					      struct netlink_callback *cb)
2224 {
2225 	struct devlink_linecard *linecard;
2226 	struct devlink *devlink;
2227 	int start = cb->args[0];
2228 	unsigned long index;
2229 	int idx = 0;
2230 	int err;
2231 
2232 	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
2233 		mutex_lock(&devlink->linecards_lock);
2234 		list_for_each_entry(linecard, &devlink->linecard_list, list) {
2235 			if (idx < start) {
2236 				idx++;
2237 				continue;
2238 			}
2239 			mutex_lock(&linecard->state_lock);
2240 			err = devlink_nl_linecard_fill(msg, devlink, linecard,
2241 						       DEVLINK_CMD_LINECARD_NEW,
2242 						       NETLINK_CB(cb->skb).portid,
2243 						       cb->nlh->nlmsg_seq,
2244 						       NLM_F_MULTI,
2245 						       cb->extack);
2246 			mutex_unlock(&linecard->state_lock);
2247 			if (err) {
2248 				mutex_unlock(&devlink->linecards_lock);
2249 				devlink_put(devlink);
2250 				goto out;
2251 			}
2252 			idx++;
2253 		}
2254 		mutex_unlock(&devlink->linecards_lock);
2255 		devlink_put(devlink);
2256 	}
2257 out:
2258 	cb->args[0] = idx;
2259 	return msg->len;
2260 }
2261 
2262 static struct devlink_linecard_type *
devlink_linecard_type_lookup(struct devlink_linecard * linecard,const char * type)2263 devlink_linecard_type_lookup(struct devlink_linecard *linecard,
2264 			     const char *type)
2265 {
2266 	struct devlink_linecard_type *linecard_type;
2267 	int i;
2268 
2269 	for (i = 0; i < linecard->types_count; i++) {
2270 		linecard_type = &linecard->types[i];
2271 		if (!strcmp(type, linecard_type->type))
2272 			return linecard_type;
2273 	}
2274 	return NULL;
2275 }
2276 
devlink_linecard_type_set(struct devlink_linecard * linecard,const char * type,struct netlink_ext_ack * extack)2277 static int devlink_linecard_type_set(struct devlink_linecard *linecard,
2278 				     const char *type,
2279 				     struct netlink_ext_ack *extack)
2280 {
2281 	const struct devlink_linecard_ops *ops = linecard->ops;
2282 	struct devlink_linecard_type *linecard_type;
2283 	int err;
2284 
2285 	mutex_lock(&linecard->state_lock);
2286 	if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING) {
2287 		NL_SET_ERR_MSG_MOD(extack, "Line card is currently being provisioned");
2288 		err = -EBUSY;
2289 		goto out;
2290 	}
2291 	if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONING) {
2292 		NL_SET_ERR_MSG_MOD(extack, "Line card is currently being unprovisioned");
2293 		err = -EBUSY;
2294 		goto out;
2295 	}
2296 
2297 	linecard_type = devlink_linecard_type_lookup(linecard, type);
2298 	if (!linecard_type) {
2299 		NL_SET_ERR_MSG_MOD(extack, "Unsupported line card type provided");
2300 		err = -EINVAL;
2301 		goto out;
2302 	}
2303 
2304 	if (linecard->state != DEVLINK_LINECARD_STATE_UNPROVISIONED &&
2305 	    linecard->state != DEVLINK_LINECARD_STATE_PROVISIONING_FAILED) {
2306 		NL_SET_ERR_MSG_MOD(extack, "Line card already provisioned");
2307 		err = -EBUSY;
2308 		/* Check if the line card is provisioned in the same
2309 		 * way the user asks. In case it is, make the operation
2310 		 * to return success.
2311 		 */
2312 		if (ops->same_provision &&
2313 		    ops->same_provision(linecard, linecard->priv,
2314 					linecard_type->type,
2315 					linecard_type->priv))
2316 			err = 0;
2317 		goto out;
2318 	}
2319 
2320 	linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING;
2321 	linecard->type = linecard_type->type;
2322 	devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
2323 	mutex_unlock(&linecard->state_lock);
2324 	err = ops->provision(linecard, linecard->priv, linecard_type->type,
2325 			     linecard_type->priv, extack);
2326 	if (err) {
2327 		/* Provisioning failed. Assume the linecard is unprovisioned
2328 		 * for future operations.
2329 		 */
2330 		mutex_lock(&linecard->state_lock);
2331 		linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
2332 		linecard->type = NULL;
2333 		devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
2334 		mutex_unlock(&linecard->state_lock);
2335 	}
2336 	return err;
2337 
2338 out:
2339 	mutex_unlock(&linecard->state_lock);
2340 	return err;
2341 }
2342 
devlink_linecard_type_unset(struct devlink_linecard * linecard,struct netlink_ext_ack * extack)2343 static int devlink_linecard_type_unset(struct devlink_linecard *linecard,
2344 				       struct netlink_ext_ack *extack)
2345 {
2346 	int err;
2347 
2348 	mutex_lock(&linecard->state_lock);
2349 	if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING) {
2350 		NL_SET_ERR_MSG_MOD(extack, "Line card is currently being provisioned");
2351 		err = -EBUSY;
2352 		goto out;
2353 	}
2354 	if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONING) {
2355 		NL_SET_ERR_MSG_MOD(extack, "Line card is currently being unprovisioned");
2356 		err = -EBUSY;
2357 		goto out;
2358 	}
2359 	if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING_FAILED) {
2360 		linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
2361 		linecard->type = NULL;
2362 		devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
2363 		err = 0;
2364 		goto out;
2365 	}
2366 
2367 	if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONED) {
2368 		NL_SET_ERR_MSG_MOD(extack, "Line card is not provisioned");
2369 		err = 0;
2370 		goto out;
2371 	}
2372 	linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONING;
2373 	devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
2374 	mutex_unlock(&linecard->state_lock);
2375 	err = linecard->ops->unprovision(linecard, linecard->priv,
2376 					 extack);
2377 	if (err) {
2378 		/* Unprovisioning failed. Assume the linecard is unprovisioned
2379 		 * for future operations.
2380 		 */
2381 		mutex_lock(&linecard->state_lock);
2382 		linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
2383 		linecard->type = NULL;
2384 		devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
2385 		mutex_unlock(&linecard->state_lock);
2386 	}
2387 	return err;
2388 
2389 out:
2390 	mutex_unlock(&linecard->state_lock);
2391 	return err;
2392 }
2393 
devlink_nl_cmd_linecard_set_doit(struct sk_buff * skb,struct genl_info * info)2394 static int devlink_nl_cmd_linecard_set_doit(struct sk_buff *skb,
2395 					    struct genl_info *info)
2396 {
2397 	struct devlink_linecard *linecard = info->user_ptr[1];
2398 	struct netlink_ext_ack *extack = info->extack;
2399 	int err;
2400 
2401 	if (info->attrs[DEVLINK_ATTR_LINECARD_TYPE]) {
2402 		const char *type;
2403 
2404 		type = nla_data(info->attrs[DEVLINK_ATTR_LINECARD_TYPE]);
2405 		if (strcmp(type, "")) {
2406 			err = devlink_linecard_type_set(linecard, type, extack);
2407 			if (err)
2408 				return err;
2409 		} else {
2410 			err = devlink_linecard_type_unset(linecard, extack);
2411 			if (err)
2412 				return err;
2413 		}
2414 	}
2415 
2416 	return 0;
2417 }
2418 
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)2419 static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
2420 			      struct devlink_sb *devlink_sb,
2421 			      enum devlink_command cmd, u32 portid,
2422 			      u32 seq, int flags)
2423 {
2424 	void *hdr;
2425 
2426 	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2427 	if (!hdr)
2428 		return -EMSGSIZE;
2429 
2430 	if (devlink_nl_put_handle(msg, devlink))
2431 		goto nla_put_failure;
2432 	if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
2433 		goto nla_put_failure;
2434 	if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size))
2435 		goto nla_put_failure;
2436 	if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT,
2437 			devlink_sb->ingress_pools_count))
2438 		goto nla_put_failure;
2439 	if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT,
2440 			devlink_sb->egress_pools_count))
2441 		goto nla_put_failure;
2442 	if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT,
2443 			devlink_sb->ingress_tc_count))
2444 		goto nla_put_failure;
2445 	if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT,
2446 			devlink_sb->egress_tc_count))
2447 		goto nla_put_failure;
2448 
2449 	genlmsg_end(msg, hdr);
2450 	return 0;
2451 
2452 nla_put_failure:
2453 	genlmsg_cancel(msg, hdr);
2454 	return -EMSGSIZE;
2455 }
2456 
devlink_nl_cmd_sb_get_doit(struct sk_buff * skb,struct genl_info * info)2457 static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb,
2458 				      struct genl_info *info)
2459 {
2460 	struct devlink *devlink = info->user_ptr[0];
2461 	struct devlink_sb *devlink_sb;
2462 	struct sk_buff *msg;
2463 	int err;
2464 
2465 	devlink_sb = devlink_sb_get_from_info(devlink, info);
2466 	if (IS_ERR(devlink_sb))
2467 		return PTR_ERR(devlink_sb);
2468 
2469 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2470 	if (!msg)
2471 		return -ENOMEM;
2472 
2473 	err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
2474 				 DEVLINK_CMD_SB_NEW,
2475 				 info->snd_portid, info->snd_seq, 0);
2476 	if (err) {
2477 		nlmsg_free(msg);
2478 		return err;
2479 	}
2480 
2481 	return genlmsg_reply(msg, info);
2482 }
2483 
devlink_nl_cmd_sb_get_dumpit(struct sk_buff * msg,struct netlink_callback * cb)2484 static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg,
2485 					struct netlink_callback *cb)
2486 {
2487 	struct devlink *devlink;
2488 	struct devlink_sb *devlink_sb;
2489 	int start = cb->args[0];
2490 	unsigned long index;
2491 	int idx = 0;
2492 	int err;
2493 
2494 	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
2495 		devl_lock(devlink);
2496 		list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
2497 			if (idx < start) {
2498 				idx++;
2499 				continue;
2500 			}
2501 			err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
2502 						 DEVLINK_CMD_SB_NEW,
2503 						 NETLINK_CB(cb->skb).portid,
2504 						 cb->nlh->nlmsg_seq,
2505 						 NLM_F_MULTI);
2506 			if (err) {
2507 				devl_unlock(devlink);
2508 				devlink_put(devlink);
2509 				goto out;
2510 			}
2511 			idx++;
2512 		}
2513 		devl_unlock(devlink);
2514 		devlink_put(devlink);
2515 	}
2516 out:
2517 	cb->args[0] = idx;
2518 	return msg->len;
2519 }
2520 
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)2521 static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink,
2522 				   struct devlink_sb *devlink_sb,
2523 				   u16 pool_index, enum devlink_command cmd,
2524 				   u32 portid, u32 seq, int flags)
2525 {
2526 	struct devlink_sb_pool_info pool_info;
2527 	void *hdr;
2528 	int err;
2529 
2530 	err = devlink->ops->sb_pool_get(devlink, devlink_sb->index,
2531 					pool_index, &pool_info);
2532 	if (err)
2533 		return err;
2534 
2535 	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2536 	if (!hdr)
2537 		return -EMSGSIZE;
2538 
2539 	if (devlink_nl_put_handle(msg, devlink))
2540 		goto nla_put_failure;
2541 	if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
2542 		goto nla_put_failure;
2543 	if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
2544 		goto nla_put_failure;
2545 	if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type))
2546 		goto nla_put_failure;
2547 	if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size))
2548 		goto nla_put_failure;
2549 	if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE,
2550 		       pool_info.threshold_type))
2551 		goto nla_put_failure;
2552 	if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_CELL_SIZE,
2553 			pool_info.cell_size))
2554 		goto nla_put_failure;
2555 
2556 	genlmsg_end(msg, hdr);
2557 	return 0;
2558 
2559 nla_put_failure:
2560 	genlmsg_cancel(msg, hdr);
2561 	return -EMSGSIZE;
2562 }
2563 
devlink_nl_cmd_sb_pool_get_doit(struct sk_buff * skb,struct genl_info * info)2564 static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb,
2565 					   struct genl_info *info)
2566 {
2567 	struct devlink *devlink = info->user_ptr[0];
2568 	struct devlink_sb *devlink_sb;
2569 	struct sk_buff *msg;
2570 	u16 pool_index;
2571 	int err;
2572 
2573 	devlink_sb = devlink_sb_get_from_info(devlink, info);
2574 	if (IS_ERR(devlink_sb))
2575 		return PTR_ERR(devlink_sb);
2576 
2577 	err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2578 						  &pool_index);
2579 	if (err)
2580 		return err;
2581 
2582 	if (!devlink->ops->sb_pool_get)
2583 		return -EOPNOTSUPP;
2584 
2585 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2586 	if (!msg)
2587 		return -ENOMEM;
2588 
2589 	err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index,
2590 				      DEVLINK_CMD_SB_POOL_NEW,
2591 				      info->snd_portid, info->snd_seq, 0);
2592 	if (err) {
2593 		nlmsg_free(msg);
2594 		return err;
2595 	}
2596 
2597 	return genlmsg_reply(msg, info);
2598 }
2599 
__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)2600 static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
2601 				struct devlink *devlink,
2602 				struct devlink_sb *devlink_sb,
2603 				u32 portid, u32 seq)
2604 {
2605 	u16 pool_count = devlink_sb_pool_count(devlink_sb);
2606 	u16 pool_index;
2607 	int err;
2608 
2609 	for (pool_index = 0; pool_index < pool_count; pool_index++) {
2610 		if (*p_idx < start) {
2611 			(*p_idx)++;
2612 			continue;
2613 		}
2614 		err = devlink_nl_sb_pool_fill(msg, devlink,
2615 					      devlink_sb,
2616 					      pool_index,
2617 					      DEVLINK_CMD_SB_POOL_NEW,
2618 					      portid, seq, NLM_F_MULTI);
2619 		if (err)
2620 			return err;
2621 		(*p_idx)++;
2622 	}
2623 	return 0;
2624 }
2625 
devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff * msg,struct netlink_callback * cb)2626 static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg,
2627 					     struct netlink_callback *cb)
2628 {
2629 	struct devlink *devlink;
2630 	struct devlink_sb *devlink_sb;
2631 	int start = cb->args[0];
2632 	unsigned long index;
2633 	int idx = 0;
2634 	int err = 0;
2635 
2636 	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
2637 		if (!devlink->ops->sb_pool_get)
2638 			goto retry;
2639 
2640 		devl_lock(devlink);
2641 		list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
2642 			err = __sb_pool_get_dumpit(msg, start, &idx, devlink,
2643 						   devlink_sb,
2644 						   NETLINK_CB(cb->skb).portid,
2645 						   cb->nlh->nlmsg_seq);
2646 			if (err == -EOPNOTSUPP) {
2647 				err = 0;
2648 			} else if (err) {
2649 				devl_unlock(devlink);
2650 				devlink_put(devlink);
2651 				goto out;
2652 			}
2653 		}
2654 		devl_unlock(devlink);
2655 retry:
2656 		devlink_put(devlink);
2657 	}
2658 out:
2659 	if (err != -EMSGSIZE)
2660 		return err;
2661 
2662 	cb->args[0] = idx;
2663 	return msg->len;
2664 }
2665 
devlink_sb_pool_set(struct devlink * devlink,unsigned int sb_index,u16 pool_index,u32 size,enum devlink_sb_threshold_type threshold_type,struct netlink_ext_ack * extack)2666 static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
2667 			       u16 pool_index, u32 size,
2668 			       enum devlink_sb_threshold_type threshold_type,
2669 			       struct netlink_ext_ack *extack)
2670 
2671 {
2672 	const struct devlink_ops *ops = devlink->ops;
2673 
2674 	if (ops->sb_pool_set)
2675 		return ops->sb_pool_set(devlink, sb_index, pool_index,
2676 					size, threshold_type, extack);
2677 	return -EOPNOTSUPP;
2678 }
2679 
devlink_nl_cmd_sb_pool_set_doit(struct sk_buff * skb,struct genl_info * info)2680 static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb,
2681 					   struct genl_info *info)
2682 {
2683 	struct devlink *devlink = info->user_ptr[0];
2684 	enum devlink_sb_threshold_type threshold_type;
2685 	struct devlink_sb *devlink_sb;
2686 	u16 pool_index;
2687 	u32 size;
2688 	int err;
2689 
2690 	devlink_sb = devlink_sb_get_from_info(devlink, info);
2691 	if (IS_ERR(devlink_sb))
2692 		return PTR_ERR(devlink_sb);
2693 
2694 	err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2695 						  &pool_index);
2696 	if (err)
2697 		return err;
2698 
2699 	err = devlink_sb_th_type_get_from_info(info, &threshold_type);
2700 	if (err)
2701 		return err;
2702 
2703 	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_POOL_SIZE))
2704 		return -EINVAL;
2705 
2706 	size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]);
2707 	return devlink_sb_pool_set(devlink, devlink_sb->index,
2708 				   pool_index, size, threshold_type,
2709 				   info->extack);
2710 }
2711 
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)2712 static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg,
2713 					struct devlink *devlink,
2714 					struct devlink_port *devlink_port,
2715 					struct devlink_sb *devlink_sb,
2716 					u16 pool_index,
2717 					enum devlink_command cmd,
2718 					u32 portid, u32 seq, int flags)
2719 {
2720 	const struct devlink_ops *ops = devlink->ops;
2721 	u32 threshold;
2722 	void *hdr;
2723 	int err;
2724 
2725 	err = ops->sb_port_pool_get(devlink_port, devlink_sb->index,
2726 				    pool_index, &threshold);
2727 	if (err)
2728 		return err;
2729 
2730 	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2731 	if (!hdr)
2732 		return -EMSGSIZE;
2733 
2734 	if (devlink_nl_put_handle(msg, devlink))
2735 		goto nla_put_failure;
2736 	if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
2737 		goto nla_put_failure;
2738 	if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
2739 		goto nla_put_failure;
2740 	if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
2741 		goto nla_put_failure;
2742 	if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
2743 		goto nla_put_failure;
2744 
2745 	if (ops->sb_occ_port_pool_get) {
2746 		u32 cur;
2747 		u32 max;
2748 
2749 		err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index,
2750 						pool_index, &cur, &max);
2751 		if (err && err != -EOPNOTSUPP)
2752 			goto sb_occ_get_failure;
2753 		if (!err) {
2754 			if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
2755 				goto nla_put_failure;
2756 			if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
2757 				goto nla_put_failure;
2758 		}
2759 	}
2760 
2761 	genlmsg_end(msg, hdr);
2762 	return 0;
2763 
2764 nla_put_failure:
2765 	err = -EMSGSIZE;
2766 sb_occ_get_failure:
2767 	genlmsg_cancel(msg, hdr);
2768 	return err;
2769 }
2770 
devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff * skb,struct genl_info * info)2771 static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,
2772 						struct genl_info *info)
2773 {
2774 	struct devlink_port *devlink_port = info->user_ptr[1];
2775 	struct devlink *devlink = devlink_port->devlink;
2776 	struct devlink_sb *devlink_sb;
2777 	struct sk_buff *msg;
2778 	u16 pool_index;
2779 	int err;
2780 
2781 	devlink_sb = devlink_sb_get_from_info(devlink, info);
2782 	if (IS_ERR(devlink_sb))
2783 		return PTR_ERR(devlink_sb);
2784 
2785 	err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2786 						  &pool_index);
2787 	if (err)
2788 		return err;
2789 
2790 	if (!devlink->ops->sb_port_pool_get)
2791 		return -EOPNOTSUPP;
2792 
2793 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2794 	if (!msg)
2795 		return -ENOMEM;
2796 
2797 	err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port,
2798 					   devlink_sb, pool_index,
2799 					   DEVLINK_CMD_SB_PORT_POOL_NEW,
2800 					   info->snd_portid, info->snd_seq, 0);
2801 	if (err) {
2802 		nlmsg_free(msg);
2803 		return err;
2804 	}
2805 
2806 	return genlmsg_reply(msg, info);
2807 }
2808 
__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)2809 static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
2810 				     struct devlink *devlink,
2811 				     struct devlink_sb *devlink_sb,
2812 				     u32 portid, u32 seq)
2813 {
2814 	struct devlink_port *devlink_port;
2815 	u16 pool_count = devlink_sb_pool_count(devlink_sb);
2816 	u16 pool_index;
2817 	int err;
2818 
2819 	list_for_each_entry(devlink_port, &devlink->port_list, list) {
2820 		for (pool_index = 0; pool_index < pool_count; pool_index++) {
2821 			if (*p_idx < start) {
2822 				(*p_idx)++;
2823 				continue;
2824 			}
2825 			err = devlink_nl_sb_port_pool_fill(msg, devlink,
2826 							   devlink_port,
2827 							   devlink_sb,
2828 							   pool_index,
2829 							   DEVLINK_CMD_SB_PORT_POOL_NEW,
2830 							   portid, seq,
2831 							   NLM_F_MULTI);
2832 			if (err)
2833 				return err;
2834 			(*p_idx)++;
2835 		}
2836 	}
2837 	return 0;
2838 }
2839 
devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff * msg,struct netlink_callback * cb)2840 static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg,
2841 						  struct netlink_callback *cb)
2842 {
2843 	struct devlink *devlink;
2844 	struct devlink_sb *devlink_sb;
2845 	int start = cb->args[0];
2846 	unsigned long index;
2847 	int idx = 0;
2848 	int err = 0;
2849 
2850 	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
2851 		if (!devlink->ops->sb_port_pool_get)
2852 			goto retry;
2853 
2854 		devl_lock(devlink);
2855 		list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
2856 			err = __sb_port_pool_get_dumpit(msg, start, &idx,
2857 							devlink, devlink_sb,
2858 							NETLINK_CB(cb->skb).portid,
2859 							cb->nlh->nlmsg_seq);
2860 			if (err == -EOPNOTSUPP) {
2861 				err = 0;
2862 			} else if (err) {
2863 				devl_unlock(devlink);
2864 				devlink_put(devlink);
2865 				goto out;
2866 			}
2867 		}
2868 		devl_unlock(devlink);
2869 retry:
2870 		devlink_put(devlink);
2871 	}
2872 out:
2873 	if (err != -EMSGSIZE)
2874 		return err;
2875 
2876 	cb->args[0] = idx;
2877 	return msg->len;
2878 }
2879 
devlink_sb_port_pool_set(struct devlink_port * devlink_port,unsigned int sb_index,u16 pool_index,u32 threshold,struct netlink_ext_ack * extack)2880 static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
2881 				    unsigned int sb_index, u16 pool_index,
2882 				    u32 threshold,
2883 				    struct netlink_ext_ack *extack)
2884 
2885 {
2886 	const struct devlink_ops *ops = devlink_port->devlink->ops;
2887 
2888 	if (ops->sb_port_pool_set)
2889 		return ops->sb_port_pool_set(devlink_port, sb_index,
2890 					     pool_index, threshold, extack);
2891 	return -EOPNOTSUPP;
2892 }
2893 
devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff * skb,struct genl_info * info)2894 static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb,
2895 						struct genl_info *info)
2896 {
2897 	struct devlink_port *devlink_port = info->user_ptr[1];
2898 	struct devlink *devlink = info->user_ptr[0];
2899 	struct devlink_sb *devlink_sb;
2900 	u16 pool_index;
2901 	u32 threshold;
2902 	int err;
2903 
2904 	devlink_sb = devlink_sb_get_from_info(devlink, info);
2905 	if (IS_ERR(devlink_sb))
2906 		return PTR_ERR(devlink_sb);
2907 
2908 	err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2909 						  &pool_index);
2910 	if (err)
2911 		return err;
2912 
2913 	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_THRESHOLD))
2914 		return -EINVAL;
2915 
2916 	threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
2917 	return devlink_sb_port_pool_set(devlink_port, devlink_sb->index,
2918 					pool_index, threshold, info->extack);
2919 }
2920 
2921 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)2922 devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink,
2923 				struct devlink_port *devlink_port,
2924 				struct devlink_sb *devlink_sb, u16 tc_index,
2925 				enum devlink_sb_pool_type pool_type,
2926 				enum devlink_command cmd,
2927 				u32 portid, u32 seq, int flags)
2928 {
2929 	const struct devlink_ops *ops = devlink->ops;
2930 	u16 pool_index;
2931 	u32 threshold;
2932 	void *hdr;
2933 	int err;
2934 
2935 	err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index,
2936 				       tc_index, pool_type,
2937 				       &pool_index, &threshold);
2938 	if (err)
2939 		return err;
2940 
2941 	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2942 	if (!hdr)
2943 		return -EMSGSIZE;
2944 
2945 	if (devlink_nl_put_handle(msg, devlink))
2946 		goto nla_put_failure;
2947 	if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
2948 		goto nla_put_failure;
2949 	if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
2950 		goto nla_put_failure;
2951 	if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index))
2952 		goto nla_put_failure;
2953 	if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type))
2954 		goto nla_put_failure;
2955 	if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
2956 		goto nla_put_failure;
2957 	if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
2958 		goto nla_put_failure;
2959 
2960 	if (ops->sb_occ_tc_port_bind_get) {
2961 		u32 cur;
2962 		u32 max;
2963 
2964 		err = ops->sb_occ_tc_port_bind_get(devlink_port,
2965 						   devlink_sb->index,
2966 						   tc_index, pool_type,
2967 						   &cur, &max);
2968 		if (err && err != -EOPNOTSUPP)
2969 			return err;
2970 		if (!err) {
2971 			if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
2972 				goto nla_put_failure;
2973 			if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
2974 				goto nla_put_failure;
2975 		}
2976 	}
2977 
2978 	genlmsg_end(msg, hdr);
2979 	return 0;
2980 
2981 nla_put_failure:
2982 	genlmsg_cancel(msg, hdr);
2983 	return -EMSGSIZE;
2984 }
2985 
devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff * skb,struct genl_info * info)2986 static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,
2987 						   struct genl_info *info)
2988 {
2989 	struct devlink_port *devlink_port = info->user_ptr[1];
2990 	struct devlink *devlink = devlink_port->devlink;
2991 	struct devlink_sb *devlink_sb;
2992 	struct sk_buff *msg;
2993 	enum devlink_sb_pool_type pool_type;
2994 	u16 tc_index;
2995 	int err;
2996 
2997 	devlink_sb = devlink_sb_get_from_info(devlink, info);
2998 	if (IS_ERR(devlink_sb))
2999 		return PTR_ERR(devlink_sb);
3000 
3001 	err = devlink_sb_pool_type_get_from_info(info, &pool_type);
3002 	if (err)
3003 		return err;
3004 
3005 	err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
3006 						pool_type, &tc_index);
3007 	if (err)
3008 		return err;
3009 
3010 	if (!devlink->ops->sb_tc_pool_bind_get)
3011 		return -EOPNOTSUPP;
3012 
3013 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3014 	if (!msg)
3015 		return -ENOMEM;
3016 
3017 	err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port,
3018 					      devlink_sb, tc_index, pool_type,
3019 					      DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
3020 					      info->snd_portid,
3021 					      info->snd_seq, 0);
3022 	if (err) {
3023 		nlmsg_free(msg);
3024 		return err;
3025 	}
3026 
3027 	return genlmsg_reply(msg, info);
3028 }
3029 
__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)3030 static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
3031 					int start, int *p_idx,
3032 					struct devlink *devlink,
3033 					struct devlink_sb *devlink_sb,
3034 					u32 portid, u32 seq)
3035 {
3036 	struct devlink_port *devlink_port;
3037 	u16 tc_index;
3038 	int err;
3039 
3040 	list_for_each_entry(devlink_port, &devlink->port_list, list) {
3041 		for (tc_index = 0;
3042 		     tc_index < devlink_sb->ingress_tc_count; tc_index++) {
3043 			if (*p_idx < start) {
3044 				(*p_idx)++;
3045 				continue;
3046 			}
3047 			err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
3048 							      devlink_port,
3049 							      devlink_sb,
3050 							      tc_index,
3051 							      DEVLINK_SB_POOL_TYPE_INGRESS,
3052 							      DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
3053 							      portid, seq,
3054 							      NLM_F_MULTI);
3055 			if (err)
3056 				return err;
3057 			(*p_idx)++;
3058 		}
3059 		for (tc_index = 0;
3060 		     tc_index < devlink_sb->egress_tc_count; tc_index++) {
3061 			if (*p_idx < start) {
3062 				(*p_idx)++;
3063 				continue;
3064 			}
3065 			err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
3066 							      devlink_port,
3067 							      devlink_sb,
3068 							      tc_index,
3069 							      DEVLINK_SB_POOL_TYPE_EGRESS,
3070 							      DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
3071 							      portid, seq,
3072 							      NLM_F_MULTI);
3073 			if (err)
3074 				return err;
3075 			(*p_idx)++;
3076 		}
3077 	}
3078 	return 0;
3079 }
3080 
3081 static int
devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff * msg,struct netlink_callback * cb)3082 devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
3083 					  struct netlink_callback *cb)
3084 {
3085 	struct devlink *devlink;
3086 	struct devlink_sb *devlink_sb;
3087 	int start = cb->args[0];
3088 	unsigned long index;
3089 	int idx = 0;
3090 	int err = 0;
3091 
3092 	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
3093 		if (!devlink->ops->sb_tc_pool_bind_get)
3094 			goto retry;
3095 
3096 		devl_lock(devlink);
3097 		list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
3098 			err = __sb_tc_pool_bind_get_dumpit(msg, start, &idx,
3099 							   devlink,
3100 							   devlink_sb,
3101 							   NETLINK_CB(cb->skb).portid,
3102 							   cb->nlh->nlmsg_seq);
3103 			if (err == -EOPNOTSUPP) {
3104 				err = 0;
3105 			} else if (err) {
3106 				devl_unlock(devlink);
3107 				devlink_put(devlink);
3108 				goto out;
3109 			}
3110 		}
3111 		devl_unlock(devlink);
3112 retry:
3113 		devlink_put(devlink);
3114 	}
3115 out:
3116 	if (err != -EMSGSIZE)
3117 		return err;
3118 
3119 	cb->args[0] = idx;
3120 	return msg->len;
3121 }
3122 
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,struct netlink_ext_ack * extack)3123 static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port,
3124 				       unsigned int sb_index, u16 tc_index,
3125 				       enum devlink_sb_pool_type pool_type,
3126 				       u16 pool_index, u32 threshold,
3127 				       struct netlink_ext_ack *extack)
3128 
3129 {
3130 	const struct devlink_ops *ops = devlink_port->devlink->ops;
3131 
3132 	if (ops->sb_tc_pool_bind_set)
3133 		return ops->sb_tc_pool_bind_set(devlink_port, sb_index,
3134 						tc_index, pool_type,
3135 						pool_index, threshold, extack);
3136 	return -EOPNOTSUPP;
3137 }
3138 
devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff * skb,struct genl_info * info)3139 static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb,
3140 						   struct genl_info *info)
3141 {
3142 	struct devlink_port *devlink_port = info->user_ptr[1];
3143 	struct devlink *devlink = info->user_ptr[0];
3144 	enum devlink_sb_pool_type pool_type;
3145 	struct devlink_sb *devlink_sb;
3146 	u16 tc_index;
3147 	u16 pool_index;
3148 	u32 threshold;
3149 	int err;
3150 
3151 	devlink_sb = devlink_sb_get_from_info(devlink, info);
3152 	if (IS_ERR(devlink_sb))
3153 		return PTR_ERR(devlink_sb);
3154 
3155 	err = devlink_sb_pool_type_get_from_info(info, &pool_type);
3156 	if (err)
3157 		return err;
3158 
3159 	err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
3160 						pool_type, &tc_index);
3161 	if (err)
3162 		return err;
3163 
3164 	err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
3165 						  &pool_index);
3166 	if (err)
3167 		return err;
3168 
3169 	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_THRESHOLD))
3170 		return -EINVAL;
3171 
3172 	threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
3173 	return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index,
3174 					   tc_index, pool_type,
3175 					   pool_index, threshold, info->extack);
3176 }
3177 
devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff * skb,struct genl_info * info)3178 static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
3179 					       struct genl_info *info)
3180 {
3181 	struct devlink *devlink = info->user_ptr[0];
3182 	const struct devlink_ops *ops = devlink->ops;
3183 	struct devlink_sb *devlink_sb;
3184 
3185 	devlink_sb = devlink_sb_get_from_info(devlink, info);
3186 	if (IS_ERR(devlink_sb))
3187 		return PTR_ERR(devlink_sb);
3188 
3189 	if (ops->sb_occ_snapshot)
3190 		return ops->sb_occ_snapshot(devlink, devlink_sb->index);
3191 	return -EOPNOTSUPP;
3192 }
3193 
devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff * skb,struct genl_info * info)3194 static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
3195 						struct genl_info *info)
3196 {
3197 	struct devlink *devlink = info->user_ptr[0];
3198 	const struct devlink_ops *ops = devlink->ops;
3199 	struct devlink_sb *devlink_sb;
3200 
3201 	devlink_sb = devlink_sb_get_from_info(devlink, info);
3202 	if (IS_ERR(devlink_sb))
3203 		return PTR_ERR(devlink_sb);
3204 
3205 	if (ops->sb_occ_max_clear)
3206 		return ops->sb_occ_max_clear(devlink, devlink_sb->index);
3207 	return -EOPNOTSUPP;
3208 }
3209 
devlink_nl_eswitch_fill(struct sk_buff * msg,struct devlink * devlink,enum devlink_command cmd,u32 portid,u32 seq,int flags)3210 static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
3211 				   enum devlink_command cmd, u32 portid,
3212 				   u32 seq, int flags)
3213 {
3214 	const struct devlink_ops *ops = devlink->ops;
3215 	enum devlink_eswitch_encap_mode encap_mode;
3216 	u8 inline_mode;
3217 	void *hdr;
3218 	int err = 0;
3219 	u16 mode;
3220 
3221 	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
3222 	if (!hdr)
3223 		return -EMSGSIZE;
3224 
3225 	err = devlink_nl_put_handle(msg, devlink);
3226 	if (err)
3227 		goto nla_put_failure;
3228 
3229 	if (ops->eswitch_mode_get) {
3230 		err = ops->eswitch_mode_get(devlink, &mode);
3231 		if (err)
3232 			goto nla_put_failure;
3233 		err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode);
3234 		if (err)
3235 			goto nla_put_failure;
3236 	}
3237 
3238 	if (ops->eswitch_inline_mode_get) {
3239 		err = ops->eswitch_inline_mode_get(devlink, &inline_mode);
3240 		if (err)
3241 			goto nla_put_failure;
3242 		err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE,
3243 				 inline_mode);
3244 		if (err)
3245 			goto nla_put_failure;
3246 	}
3247 
3248 	if (ops->eswitch_encap_mode_get) {
3249 		err = ops->eswitch_encap_mode_get(devlink, &encap_mode);
3250 		if (err)
3251 			goto nla_put_failure;
3252 		err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode);
3253 		if (err)
3254 			goto nla_put_failure;
3255 	}
3256 
3257 	genlmsg_end(msg, hdr);
3258 	return 0;
3259 
3260 nla_put_failure:
3261 	genlmsg_cancel(msg, hdr);
3262 	return err;
3263 }
3264 
devlink_nl_cmd_eswitch_get_doit(struct sk_buff * skb,struct genl_info * info)3265 static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb,
3266 					   struct genl_info *info)
3267 {
3268 	struct devlink *devlink = info->user_ptr[0];
3269 	struct sk_buff *msg;
3270 	int err;
3271 
3272 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3273 	if (!msg)
3274 		return -ENOMEM;
3275 
3276 	err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET,
3277 				      info->snd_portid, info->snd_seq, 0);
3278 
3279 	if (err) {
3280 		nlmsg_free(msg);
3281 		return err;
3282 	}
3283 
3284 	return genlmsg_reply(msg, info);
3285 }
3286 
devlink_rate_nodes_check(struct devlink * devlink,u16 mode,struct netlink_ext_ack * extack)3287 static int devlink_rate_nodes_check(struct devlink *devlink, u16 mode,
3288 				    struct netlink_ext_ack *extack)
3289 {
3290 	struct devlink_rate *devlink_rate;
3291 
3292 	list_for_each_entry(devlink_rate, &devlink->rate_list, list)
3293 		if (devlink_rate_is_node(devlink_rate)) {
3294 			NL_SET_ERR_MSG_MOD(extack, "Rate node(s) exists.");
3295 			return -EBUSY;
3296 		}
3297 	return 0;
3298 }
3299 
devlink_nl_cmd_eswitch_set_doit(struct sk_buff * skb,struct genl_info * info)3300 static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb,
3301 					   struct genl_info *info)
3302 {
3303 	struct devlink *devlink = info->user_ptr[0];
3304 	const struct devlink_ops *ops = devlink->ops;
3305 	enum devlink_eswitch_encap_mode encap_mode;
3306 	u8 inline_mode;
3307 	int err = 0;
3308 	u16 mode;
3309 
3310 	if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) {
3311 		if (!ops->eswitch_mode_set)
3312 			return -EOPNOTSUPP;
3313 		mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
3314 		err = devlink_rate_nodes_check(devlink, mode, info->extack);
3315 		if (err)
3316 			return err;
3317 		err = ops->eswitch_mode_set(devlink, mode, info->extack);
3318 		if (err)
3319 			return err;
3320 	}
3321 
3322 	if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) {
3323 		if (!ops->eswitch_inline_mode_set)
3324 			return -EOPNOTSUPP;
3325 		inline_mode = nla_get_u8(
3326 				info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]);
3327 		err = ops->eswitch_inline_mode_set(devlink, inline_mode,
3328 						   info->extack);
3329 		if (err)
3330 			return err;
3331 	}
3332 
3333 	if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) {
3334 		if (!ops->eswitch_encap_mode_set)
3335 			return -EOPNOTSUPP;
3336 		encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]);
3337 		err = ops->eswitch_encap_mode_set(devlink, encap_mode,
3338 						  info->extack);
3339 		if (err)
3340 			return err;
3341 	}
3342 
3343 	return 0;
3344 }
3345 
devlink_dpipe_match_put(struct sk_buff * skb,struct devlink_dpipe_match * match)3346 int devlink_dpipe_match_put(struct sk_buff *skb,
3347 			    struct devlink_dpipe_match *match)
3348 {
3349 	struct devlink_dpipe_header *header = match->header;
3350 	struct devlink_dpipe_field *field = &header->fields[match->field_id];
3351 	struct nlattr *match_attr;
3352 
3353 	match_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_MATCH);
3354 	if (!match_attr)
3355 		return -EMSGSIZE;
3356 
3357 	if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) ||
3358 	    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) ||
3359 	    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
3360 	    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
3361 	    nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
3362 		goto nla_put_failure;
3363 
3364 	nla_nest_end(skb, match_attr);
3365 	return 0;
3366 
3367 nla_put_failure:
3368 	nla_nest_cancel(skb, match_attr);
3369 	return -EMSGSIZE;
3370 }
3371 EXPORT_SYMBOL_GPL(devlink_dpipe_match_put);
3372 
devlink_dpipe_matches_put(struct devlink_dpipe_table * table,struct sk_buff * skb)3373 static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table,
3374 				     struct sk_buff *skb)
3375 {
3376 	struct nlattr *matches_attr;
3377 
3378 	matches_attr = nla_nest_start_noflag(skb,
3379 					     DEVLINK_ATTR_DPIPE_TABLE_MATCHES);
3380 	if (!matches_attr)
3381 		return -EMSGSIZE;
3382 
3383 	if (table->table_ops->matches_dump(table->priv, skb))
3384 		goto nla_put_failure;
3385 
3386 	nla_nest_end(skb, matches_attr);
3387 	return 0;
3388 
3389 nla_put_failure:
3390 	nla_nest_cancel(skb, matches_attr);
3391 	return -EMSGSIZE;
3392 }
3393 
devlink_dpipe_action_put(struct sk_buff * skb,struct devlink_dpipe_action * action)3394 int devlink_dpipe_action_put(struct sk_buff *skb,
3395 			     struct devlink_dpipe_action *action)
3396 {
3397 	struct devlink_dpipe_header *header = action->header;
3398 	struct devlink_dpipe_field *field = &header->fields[action->field_id];
3399 	struct nlattr *action_attr;
3400 
3401 	action_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ACTION);
3402 	if (!action_attr)
3403 		return -EMSGSIZE;
3404 
3405 	if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) ||
3406 	    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) ||
3407 	    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
3408 	    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
3409 	    nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
3410 		goto nla_put_failure;
3411 
3412 	nla_nest_end(skb, action_attr);
3413 	return 0;
3414 
3415 nla_put_failure:
3416 	nla_nest_cancel(skb, action_attr);
3417 	return -EMSGSIZE;
3418 }
3419 EXPORT_SYMBOL_GPL(devlink_dpipe_action_put);
3420 
devlink_dpipe_actions_put(struct devlink_dpipe_table * table,struct sk_buff * skb)3421 static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table,
3422 				     struct sk_buff *skb)
3423 {
3424 	struct nlattr *actions_attr;
3425 
3426 	actions_attr = nla_nest_start_noflag(skb,
3427 					     DEVLINK_ATTR_DPIPE_TABLE_ACTIONS);
3428 	if (!actions_attr)
3429 		return -EMSGSIZE;
3430 
3431 	if (table->table_ops->actions_dump(table->priv, skb))
3432 		goto nla_put_failure;
3433 
3434 	nla_nest_end(skb, actions_attr);
3435 	return 0;
3436 
3437 nla_put_failure:
3438 	nla_nest_cancel(skb, actions_attr);
3439 	return -EMSGSIZE;
3440 }
3441 
devlink_dpipe_table_put(struct sk_buff * skb,struct devlink_dpipe_table * table)3442 static int devlink_dpipe_table_put(struct sk_buff *skb,
3443 				   struct devlink_dpipe_table *table)
3444 {
3445 	struct nlattr *table_attr;
3446 	u64 table_size;
3447 
3448 	table_size = table->table_ops->size_get(table->priv);
3449 	table_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLE);
3450 	if (!table_attr)
3451 		return -EMSGSIZE;
3452 
3453 	if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) ||
3454 	    nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size,
3455 			      DEVLINK_ATTR_PAD))
3456 		goto nla_put_failure;
3457 	if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
3458 		       table->counters_enabled))
3459 		goto nla_put_failure;
3460 
3461 	if (table->resource_valid) {
3462 		if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID,
3463 				      table->resource_id, DEVLINK_ATTR_PAD) ||
3464 		    nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS,
3465 				      table->resource_units, DEVLINK_ATTR_PAD))
3466 			goto nla_put_failure;
3467 	}
3468 	if (devlink_dpipe_matches_put(table, skb))
3469 		goto nla_put_failure;
3470 
3471 	if (devlink_dpipe_actions_put(table, skb))
3472 		goto nla_put_failure;
3473 
3474 	nla_nest_end(skb, table_attr);
3475 	return 0;
3476 
3477 nla_put_failure:
3478 	nla_nest_cancel(skb, table_attr);
3479 	return -EMSGSIZE;
3480 }
3481 
devlink_dpipe_send_and_alloc_skb(struct sk_buff ** pskb,struct genl_info * info)3482 static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb,
3483 					    struct genl_info *info)
3484 {
3485 	int err;
3486 
3487 	if (*pskb) {
3488 		err = genlmsg_reply(*pskb, info);
3489 		if (err)
3490 			return err;
3491 	}
3492 	*pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
3493 	if (!*pskb)
3494 		return -ENOMEM;
3495 	return 0;
3496 }
3497 
devlink_dpipe_tables_fill(struct genl_info * info,enum devlink_command cmd,int flags,struct list_head * dpipe_tables,const char * table_name)3498 static int devlink_dpipe_tables_fill(struct genl_info *info,
3499 				     enum devlink_command cmd, int flags,
3500 				     struct list_head *dpipe_tables,
3501 				     const char *table_name)
3502 {
3503 	struct devlink *devlink = info->user_ptr[0];
3504 	struct devlink_dpipe_table *table;
3505 	struct nlattr *tables_attr;
3506 	struct sk_buff *skb = NULL;
3507 	struct nlmsghdr *nlh;
3508 	bool incomplete;
3509 	void *hdr;
3510 	int i;
3511 	int err;
3512 
3513 	table = list_first_entry(dpipe_tables,
3514 				 struct devlink_dpipe_table, list);
3515 start_again:
3516 	err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3517 	if (err)
3518 		return err;
3519 
3520 	hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
3521 			  &devlink_nl_family, NLM_F_MULTI, cmd);
3522 	if (!hdr) {
3523 		nlmsg_free(skb);
3524 		return -EMSGSIZE;
3525 	}
3526 
3527 	if (devlink_nl_put_handle(skb, devlink))
3528 		goto nla_put_failure;
3529 	tables_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLES);
3530 	if (!tables_attr)
3531 		goto nla_put_failure;
3532 
3533 	i = 0;
3534 	incomplete = false;
3535 	list_for_each_entry_from(table, dpipe_tables, list) {
3536 		if (!table_name) {
3537 			err = devlink_dpipe_table_put(skb, table);
3538 			if (err) {
3539 				if (!i)
3540 					goto err_table_put;
3541 				incomplete = true;
3542 				break;
3543 			}
3544 		} else {
3545 			if (!strcmp(table->name, table_name)) {
3546 				err = devlink_dpipe_table_put(skb, table);
3547 				if (err)
3548 					break;
3549 			}
3550 		}
3551 		i++;
3552 	}
3553 
3554 	nla_nest_end(skb, tables_attr);
3555 	genlmsg_end(skb, hdr);
3556 	if (incomplete)
3557 		goto start_again;
3558 
3559 send_done:
3560 	nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
3561 			NLMSG_DONE, 0, flags | NLM_F_MULTI);
3562 	if (!nlh) {
3563 		err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3564 		if (err)
3565 			return err;
3566 		goto send_done;
3567 	}
3568 
3569 	return genlmsg_reply(skb, info);
3570 
3571 nla_put_failure:
3572 	err = -EMSGSIZE;
3573 err_table_put:
3574 	nlmsg_free(skb);
3575 	return err;
3576 }
3577 
devlink_nl_cmd_dpipe_table_get(struct sk_buff * skb,struct genl_info * info)3578 static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb,
3579 					  struct genl_info *info)
3580 {
3581 	struct devlink *devlink = info->user_ptr[0];
3582 	const char *table_name =  NULL;
3583 
3584 	if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
3585 		table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
3586 
3587 	return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0,
3588 					 &devlink->dpipe_table_list,
3589 					 table_name);
3590 }
3591 
devlink_dpipe_value_put(struct sk_buff * skb,struct devlink_dpipe_value * value)3592 static int devlink_dpipe_value_put(struct sk_buff *skb,
3593 				   struct devlink_dpipe_value *value)
3594 {
3595 	if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE,
3596 		    value->value_size, value->value))
3597 		return -EMSGSIZE;
3598 	if (value->mask)
3599 		if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK,
3600 			    value->value_size, value->mask))
3601 			return -EMSGSIZE;
3602 	if (value->mapping_valid)
3603 		if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING,
3604 				value->mapping_value))
3605 			return -EMSGSIZE;
3606 	return 0;
3607 }
3608 
devlink_dpipe_action_value_put(struct sk_buff * skb,struct devlink_dpipe_value * value)3609 static int devlink_dpipe_action_value_put(struct sk_buff *skb,
3610 					  struct devlink_dpipe_value *value)
3611 {
3612 	if (!value->action)
3613 		return -EINVAL;
3614 	if (devlink_dpipe_action_put(skb, value->action))
3615 		return -EMSGSIZE;
3616 	if (devlink_dpipe_value_put(skb, value))
3617 		return -EMSGSIZE;
3618 	return 0;
3619 }
3620 
devlink_dpipe_action_values_put(struct sk_buff * skb,struct devlink_dpipe_value * values,unsigned int values_count)3621 static int devlink_dpipe_action_values_put(struct sk_buff *skb,
3622 					   struct devlink_dpipe_value *values,
3623 					   unsigned int values_count)
3624 {
3625 	struct nlattr *action_attr;
3626 	int i;
3627 	int err;
3628 
3629 	for (i = 0; i < values_count; i++) {
3630 		action_attr = nla_nest_start_noflag(skb,
3631 						    DEVLINK_ATTR_DPIPE_ACTION_VALUE);
3632 		if (!action_attr)
3633 			return -EMSGSIZE;
3634 		err = devlink_dpipe_action_value_put(skb, &values[i]);
3635 		if (err)
3636 			goto err_action_value_put;
3637 		nla_nest_end(skb, action_attr);
3638 	}
3639 	return 0;
3640 
3641 err_action_value_put:
3642 	nla_nest_cancel(skb, action_attr);
3643 	return err;
3644 }
3645 
devlink_dpipe_match_value_put(struct sk_buff * skb,struct devlink_dpipe_value * value)3646 static int devlink_dpipe_match_value_put(struct sk_buff *skb,
3647 					 struct devlink_dpipe_value *value)
3648 {
3649 	if (!value->match)
3650 		return -EINVAL;
3651 	if (devlink_dpipe_match_put(skb, value->match))
3652 		return -EMSGSIZE;
3653 	if (devlink_dpipe_value_put(skb, value))
3654 		return -EMSGSIZE;
3655 	return 0;
3656 }
3657 
devlink_dpipe_match_values_put(struct sk_buff * skb,struct devlink_dpipe_value * values,unsigned int values_count)3658 static int devlink_dpipe_match_values_put(struct sk_buff *skb,
3659 					  struct devlink_dpipe_value *values,
3660 					  unsigned int values_count)
3661 {
3662 	struct nlattr *match_attr;
3663 	int i;
3664 	int err;
3665 
3666 	for (i = 0; i < values_count; i++) {
3667 		match_attr = nla_nest_start_noflag(skb,
3668 						   DEVLINK_ATTR_DPIPE_MATCH_VALUE);
3669 		if (!match_attr)
3670 			return -EMSGSIZE;
3671 		err = devlink_dpipe_match_value_put(skb, &values[i]);
3672 		if (err)
3673 			goto err_match_value_put;
3674 		nla_nest_end(skb, match_attr);
3675 	}
3676 	return 0;
3677 
3678 err_match_value_put:
3679 	nla_nest_cancel(skb, match_attr);
3680 	return err;
3681 }
3682 
devlink_dpipe_entry_put(struct sk_buff * skb,struct devlink_dpipe_entry * entry)3683 static int devlink_dpipe_entry_put(struct sk_buff *skb,
3684 				   struct devlink_dpipe_entry *entry)
3685 {
3686 	struct nlattr *entry_attr, *matches_attr, *actions_attr;
3687 	int err;
3688 
3689 	entry_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ENTRY);
3690 	if (!entry_attr)
3691 		return  -EMSGSIZE;
3692 
3693 	if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index,
3694 			      DEVLINK_ATTR_PAD))
3695 		goto nla_put_failure;
3696 	if (entry->counter_valid)
3697 		if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER,
3698 				      entry->counter, DEVLINK_ATTR_PAD))
3699 			goto nla_put_failure;
3700 
3701 	matches_attr = nla_nest_start_noflag(skb,
3702 					     DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES);
3703 	if (!matches_attr)
3704 		goto nla_put_failure;
3705 
3706 	err = devlink_dpipe_match_values_put(skb, entry->match_values,
3707 					     entry->match_values_count);
3708 	if (err) {
3709 		nla_nest_cancel(skb, matches_attr);
3710 		goto err_match_values_put;
3711 	}
3712 	nla_nest_end(skb, matches_attr);
3713 
3714 	actions_attr = nla_nest_start_noflag(skb,
3715 					     DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES);
3716 	if (!actions_attr)
3717 		goto nla_put_failure;
3718 
3719 	err = devlink_dpipe_action_values_put(skb, entry->action_values,
3720 					      entry->action_values_count);
3721 	if (err) {
3722 		nla_nest_cancel(skb, actions_attr);
3723 		goto err_action_values_put;
3724 	}
3725 	nla_nest_end(skb, actions_attr);
3726 
3727 	nla_nest_end(skb, entry_attr);
3728 	return 0;
3729 
3730 nla_put_failure:
3731 	err = -EMSGSIZE;
3732 err_match_values_put:
3733 err_action_values_put:
3734 	nla_nest_cancel(skb, entry_attr);
3735 	return err;
3736 }
3737 
3738 static struct devlink_dpipe_table *
devlink_dpipe_table_find(struct list_head * dpipe_tables,const char * table_name,struct devlink * devlink)3739 devlink_dpipe_table_find(struct list_head *dpipe_tables,
3740 			 const char *table_name, struct devlink *devlink)
3741 {
3742 	struct devlink_dpipe_table *table;
3743 	list_for_each_entry_rcu(table, dpipe_tables, list,
3744 				lockdep_is_held(&devlink->lock)) {
3745 		if (!strcmp(table->name, table_name))
3746 			return table;
3747 	}
3748 	return NULL;
3749 }
3750 
devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx * dump_ctx)3751 int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx)
3752 {
3753 	struct devlink *devlink;
3754 	int err;
3755 
3756 	err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb,
3757 					       dump_ctx->info);
3758 	if (err)
3759 		return err;
3760 
3761 	dump_ctx->hdr = genlmsg_put(dump_ctx->skb,
3762 				    dump_ctx->info->snd_portid,
3763 				    dump_ctx->info->snd_seq,
3764 				    &devlink_nl_family, NLM_F_MULTI,
3765 				    dump_ctx->cmd);
3766 	if (!dump_ctx->hdr)
3767 		goto nla_put_failure;
3768 
3769 	devlink = dump_ctx->info->user_ptr[0];
3770 	if (devlink_nl_put_handle(dump_ctx->skb, devlink))
3771 		goto nla_put_failure;
3772 	dump_ctx->nest = nla_nest_start_noflag(dump_ctx->skb,
3773 					       DEVLINK_ATTR_DPIPE_ENTRIES);
3774 	if (!dump_ctx->nest)
3775 		goto nla_put_failure;
3776 	return 0;
3777 
3778 nla_put_failure:
3779 	nlmsg_free(dump_ctx->skb);
3780 	return -EMSGSIZE;
3781 }
3782 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare);
3783 
devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx * dump_ctx,struct devlink_dpipe_entry * entry)3784 int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx,
3785 				   struct devlink_dpipe_entry *entry)
3786 {
3787 	return devlink_dpipe_entry_put(dump_ctx->skb, entry);
3788 }
3789 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append);
3790 
devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx * dump_ctx)3791 int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx)
3792 {
3793 	nla_nest_end(dump_ctx->skb, dump_ctx->nest);
3794 	genlmsg_end(dump_ctx->skb, dump_ctx->hdr);
3795 	return 0;
3796 }
3797 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close);
3798 
devlink_dpipe_entry_clear(struct devlink_dpipe_entry * entry)3799 void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry)
3800 
3801 {
3802 	unsigned int value_count, value_index;
3803 	struct devlink_dpipe_value *value;
3804 
3805 	value = entry->action_values;
3806 	value_count = entry->action_values_count;
3807 	for (value_index = 0; value_index < value_count; value_index++) {
3808 		kfree(value[value_index].value);
3809 		kfree(value[value_index].mask);
3810 	}
3811 
3812 	value = entry->match_values;
3813 	value_count = entry->match_values_count;
3814 	for (value_index = 0; value_index < value_count; value_index++) {
3815 		kfree(value[value_index].value);
3816 		kfree(value[value_index].mask);
3817 	}
3818 }
3819 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_clear);
3820 
devlink_dpipe_entries_fill(struct genl_info * info,enum devlink_command cmd,int flags,struct devlink_dpipe_table * table)3821 static int devlink_dpipe_entries_fill(struct genl_info *info,
3822 				      enum devlink_command cmd, int flags,
3823 				      struct devlink_dpipe_table *table)
3824 {
3825 	struct devlink_dpipe_dump_ctx dump_ctx;
3826 	struct nlmsghdr *nlh;
3827 	int err;
3828 
3829 	dump_ctx.skb = NULL;
3830 	dump_ctx.cmd = cmd;
3831 	dump_ctx.info = info;
3832 
3833 	err = table->table_ops->entries_dump(table->priv,
3834 					     table->counters_enabled,
3835 					     &dump_ctx);
3836 	if (err)
3837 		return err;
3838 
3839 send_done:
3840 	nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq,
3841 			NLMSG_DONE, 0, flags | NLM_F_MULTI);
3842 	if (!nlh) {
3843 		err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info);
3844 		if (err)
3845 			return err;
3846 		goto send_done;
3847 	}
3848 	return genlmsg_reply(dump_ctx.skb, info);
3849 }
3850 
devlink_nl_cmd_dpipe_entries_get(struct sk_buff * skb,struct genl_info * info)3851 static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
3852 					    struct genl_info *info)
3853 {
3854 	struct devlink *devlink = info->user_ptr[0];
3855 	struct devlink_dpipe_table *table;
3856 	const char *table_name;
3857 
3858 	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_DPIPE_TABLE_NAME))
3859 		return -EINVAL;
3860 
3861 	table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
3862 	table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
3863 					 table_name, devlink);
3864 	if (!table)
3865 		return -EINVAL;
3866 
3867 	if (!table->table_ops->entries_dump)
3868 		return -EINVAL;
3869 
3870 	return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET,
3871 					  0, table);
3872 }
3873 
devlink_dpipe_fields_put(struct sk_buff * skb,const struct devlink_dpipe_header * header)3874 static int devlink_dpipe_fields_put(struct sk_buff *skb,
3875 				    const struct devlink_dpipe_header *header)
3876 {
3877 	struct devlink_dpipe_field *field;
3878 	struct nlattr *field_attr;
3879 	int i;
3880 
3881 	for (i = 0; i < header->fields_count; i++) {
3882 		field = &header->fields[i];
3883 		field_attr = nla_nest_start_noflag(skb,
3884 						   DEVLINK_ATTR_DPIPE_FIELD);
3885 		if (!field_attr)
3886 			return -EMSGSIZE;
3887 		if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) ||
3888 		    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
3889 		    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) ||
3890 		    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type))
3891 			goto nla_put_failure;
3892 		nla_nest_end(skb, field_attr);
3893 	}
3894 	return 0;
3895 
3896 nla_put_failure:
3897 	nla_nest_cancel(skb, field_attr);
3898 	return -EMSGSIZE;
3899 }
3900 
devlink_dpipe_header_put(struct sk_buff * skb,struct devlink_dpipe_header * header)3901 static int devlink_dpipe_header_put(struct sk_buff *skb,
3902 				    struct devlink_dpipe_header *header)
3903 {
3904 	struct nlattr *fields_attr, *header_attr;
3905 	int err;
3906 
3907 	header_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADER);
3908 	if (!header_attr)
3909 		return -EMSGSIZE;
3910 
3911 	if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) ||
3912 	    nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
3913 	    nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
3914 		goto nla_put_failure;
3915 
3916 	fields_attr = nla_nest_start_noflag(skb,
3917 					    DEVLINK_ATTR_DPIPE_HEADER_FIELDS);
3918 	if (!fields_attr)
3919 		goto nla_put_failure;
3920 
3921 	err = devlink_dpipe_fields_put(skb, header);
3922 	if (err) {
3923 		nla_nest_cancel(skb, fields_attr);
3924 		goto nla_put_failure;
3925 	}
3926 	nla_nest_end(skb, fields_attr);
3927 	nla_nest_end(skb, header_attr);
3928 	return 0;
3929 
3930 nla_put_failure:
3931 	err = -EMSGSIZE;
3932 	nla_nest_cancel(skb, header_attr);
3933 	return err;
3934 }
3935 
devlink_dpipe_headers_fill(struct genl_info * info,enum devlink_command cmd,int flags,struct devlink_dpipe_headers * dpipe_headers)3936 static int devlink_dpipe_headers_fill(struct genl_info *info,
3937 				      enum devlink_command cmd, int flags,
3938 				      struct devlink_dpipe_headers *
3939 				      dpipe_headers)
3940 {
3941 	struct devlink *devlink = info->user_ptr[0];
3942 	struct nlattr *headers_attr;
3943 	struct sk_buff *skb = NULL;
3944 	struct nlmsghdr *nlh;
3945 	void *hdr;
3946 	int i, j;
3947 	int err;
3948 
3949 	i = 0;
3950 start_again:
3951 	err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3952 	if (err)
3953 		return err;
3954 
3955 	hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
3956 			  &devlink_nl_family, NLM_F_MULTI, cmd);
3957 	if (!hdr) {
3958 		nlmsg_free(skb);
3959 		return -EMSGSIZE;
3960 	}
3961 
3962 	if (devlink_nl_put_handle(skb, devlink))
3963 		goto nla_put_failure;
3964 	headers_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADERS);
3965 	if (!headers_attr)
3966 		goto nla_put_failure;
3967 
3968 	j = 0;
3969 	for (; i < dpipe_headers->headers_count; i++) {
3970 		err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]);
3971 		if (err) {
3972 			if (!j)
3973 				goto err_table_put;
3974 			break;
3975 		}
3976 		j++;
3977 	}
3978 	nla_nest_end(skb, headers_attr);
3979 	genlmsg_end(skb, hdr);
3980 	if (i != dpipe_headers->headers_count)
3981 		goto start_again;
3982 
3983 send_done:
3984 	nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
3985 			NLMSG_DONE, 0, flags | NLM_F_MULTI);
3986 	if (!nlh) {
3987 		err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3988 		if (err)
3989 			return err;
3990 		goto send_done;
3991 	}
3992 	return genlmsg_reply(skb, info);
3993 
3994 nla_put_failure:
3995 	err = -EMSGSIZE;
3996 err_table_put:
3997 	nlmsg_free(skb);
3998 	return err;
3999 }
4000 
devlink_nl_cmd_dpipe_headers_get(struct sk_buff * skb,struct genl_info * info)4001 static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb,
4002 					    struct genl_info *info)
4003 {
4004 	struct devlink *devlink = info->user_ptr[0];
4005 
4006 	if (!devlink->dpipe_headers)
4007 		return -EOPNOTSUPP;
4008 	return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET,
4009 					  0, devlink->dpipe_headers);
4010 }
4011 
devlink_dpipe_table_counters_set(struct devlink * devlink,const char * table_name,bool enable)4012 static int devlink_dpipe_table_counters_set(struct devlink *devlink,
4013 					    const char *table_name,
4014 					    bool enable)
4015 {
4016 	struct devlink_dpipe_table *table;
4017 
4018 	table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
4019 					 table_name, devlink);
4020 	if (!table)
4021 		return -EINVAL;
4022 
4023 	if (table->counter_control_extern)
4024 		return -EOPNOTSUPP;
4025 
4026 	if (!(table->counters_enabled ^ enable))
4027 		return 0;
4028 
4029 	table->counters_enabled = enable;
4030 	if (table->table_ops->counters_set_update)
4031 		table->table_ops->counters_set_update(table->priv, enable);
4032 	return 0;
4033 }
4034 
devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff * skb,struct genl_info * info)4035 static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb,
4036 						   struct genl_info *info)
4037 {
4038 	struct devlink *devlink = info->user_ptr[0];
4039 	const char *table_name;
4040 	bool counters_enable;
4041 
4042 	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_DPIPE_TABLE_NAME) ||
4043 	    GENL_REQ_ATTR_CHECK(info,
4044 				DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED))
4045 		return -EINVAL;
4046 
4047 	table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
4048 	counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]);
4049 
4050 	return devlink_dpipe_table_counters_set(devlink, table_name,
4051 						counters_enable);
4052 }
4053 
4054 static struct devlink_resource *
devlink_resource_find(struct devlink * devlink,struct devlink_resource * resource,u64 resource_id)4055 devlink_resource_find(struct devlink *devlink,
4056 		      struct devlink_resource *resource, u64 resource_id)
4057 {
4058 	struct list_head *resource_list;
4059 
4060 	if (resource)
4061 		resource_list = &resource->resource_list;
4062 	else
4063 		resource_list = &devlink->resource_list;
4064 
4065 	list_for_each_entry(resource, resource_list, list) {
4066 		struct devlink_resource *child_resource;
4067 
4068 		if (resource->id == resource_id)
4069 			return resource;
4070 
4071 		child_resource = devlink_resource_find(devlink, resource,
4072 						       resource_id);
4073 		if (child_resource)
4074 			return child_resource;
4075 	}
4076 	return NULL;
4077 }
4078 
4079 static void
devlink_resource_validate_children(struct devlink_resource * resource)4080 devlink_resource_validate_children(struct devlink_resource *resource)
4081 {
4082 	struct devlink_resource *child_resource;
4083 	bool size_valid = true;
4084 	u64 parts_size = 0;
4085 
4086 	if (list_empty(&resource->resource_list))
4087 		goto out;
4088 
4089 	list_for_each_entry(child_resource, &resource->resource_list, list)
4090 		parts_size += child_resource->size_new;
4091 
4092 	if (parts_size > resource->size_new)
4093 		size_valid = false;
4094 out:
4095 	resource->size_valid = size_valid;
4096 }
4097 
4098 static int
devlink_resource_validate_size(struct devlink_resource * resource,u64 size,struct netlink_ext_ack * extack)4099 devlink_resource_validate_size(struct devlink_resource *resource, u64 size,
4100 			       struct netlink_ext_ack *extack)
4101 {
4102 	u64 reminder;
4103 	int err = 0;
4104 
4105 	if (size > resource->size_params.size_max) {
4106 		NL_SET_ERR_MSG_MOD(extack, "Size larger than maximum");
4107 		err = -EINVAL;
4108 	}
4109 
4110 	if (size < resource->size_params.size_min) {
4111 		NL_SET_ERR_MSG_MOD(extack, "Size smaller than minimum");
4112 		err = -EINVAL;
4113 	}
4114 
4115 	div64_u64_rem(size, resource->size_params.size_granularity, &reminder);
4116 	if (reminder) {
4117 		NL_SET_ERR_MSG_MOD(extack, "Wrong granularity");
4118 		err = -EINVAL;
4119 	}
4120 
4121 	return err;
4122 }
4123 
devlink_nl_cmd_resource_set(struct sk_buff * skb,struct genl_info * info)4124 static int devlink_nl_cmd_resource_set(struct sk_buff *skb,
4125 				       struct genl_info *info)
4126 {
4127 	struct devlink *devlink = info->user_ptr[0];
4128 	struct devlink_resource *resource;
4129 	u64 resource_id;
4130 	u64 size;
4131 	int err;
4132 
4133 	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_RESOURCE_ID) ||
4134 	    GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_RESOURCE_SIZE))
4135 		return -EINVAL;
4136 	resource_id = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_ID]);
4137 
4138 	resource = devlink_resource_find(devlink, NULL, resource_id);
4139 	if (!resource)
4140 		return -EINVAL;
4141 
4142 	size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]);
4143 	err = devlink_resource_validate_size(resource, size, info->extack);
4144 	if (err)
4145 		return err;
4146 
4147 	resource->size_new = size;
4148 	devlink_resource_validate_children(resource);
4149 	if (resource->parent)
4150 		devlink_resource_validate_children(resource->parent);
4151 	return 0;
4152 }
4153 
4154 static int
devlink_resource_size_params_put(struct devlink_resource * resource,struct sk_buff * skb)4155 devlink_resource_size_params_put(struct devlink_resource *resource,
4156 				 struct sk_buff *skb)
4157 {
4158 	struct devlink_resource_size_params *size_params;
4159 
4160 	size_params = &resource->size_params;
4161 	if (nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_GRAN,
4162 			      size_params->size_granularity, DEVLINK_ATTR_PAD) ||
4163 	    nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MAX,
4164 			      size_params->size_max, DEVLINK_ATTR_PAD) ||
4165 	    nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MIN,
4166 			      size_params->size_min, DEVLINK_ATTR_PAD) ||
4167 	    nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_UNIT, size_params->unit))
4168 		return -EMSGSIZE;
4169 	return 0;
4170 }
4171 
devlink_resource_occ_put(struct devlink_resource * resource,struct sk_buff * skb)4172 static int devlink_resource_occ_put(struct devlink_resource *resource,
4173 				    struct sk_buff *skb)
4174 {
4175 	if (!resource->occ_get)
4176 		return 0;
4177 	return nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_OCC,
4178 				 resource->occ_get(resource->occ_get_priv),
4179 				 DEVLINK_ATTR_PAD);
4180 }
4181 
devlink_resource_put(struct devlink * devlink,struct sk_buff * skb,struct devlink_resource * resource)4182 static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb,
4183 				struct devlink_resource *resource)
4184 {
4185 	struct devlink_resource *child_resource;
4186 	struct nlattr *child_resource_attr;
4187 	struct nlattr *resource_attr;
4188 
4189 	resource_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_RESOURCE);
4190 	if (!resource_attr)
4191 		return -EMSGSIZE;
4192 
4193 	if (nla_put_string(skb, DEVLINK_ATTR_RESOURCE_NAME, resource->name) ||
4194 	    nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE, resource->size,
4195 			      DEVLINK_ATTR_PAD) ||
4196 	    nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_ID, resource->id,
4197 			      DEVLINK_ATTR_PAD))
4198 		goto nla_put_failure;
4199 	if (resource->size != resource->size_new)
4200 		nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_NEW,
4201 				  resource->size_new, DEVLINK_ATTR_PAD);
4202 	if (devlink_resource_occ_put(resource, skb))
4203 		goto nla_put_failure;
4204 	if (devlink_resource_size_params_put(resource, skb))
4205 		goto nla_put_failure;
4206 	if (list_empty(&resource->resource_list))
4207 		goto out;
4208 
4209 	if (nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_SIZE_VALID,
4210 		       resource->size_valid))
4211 		goto nla_put_failure;
4212 
4213 	child_resource_attr = nla_nest_start_noflag(skb,
4214 						    DEVLINK_ATTR_RESOURCE_LIST);
4215 	if (!child_resource_attr)
4216 		goto nla_put_failure;
4217 
4218 	list_for_each_entry(child_resource, &resource->resource_list, list) {
4219 		if (devlink_resource_put(devlink, skb, child_resource))
4220 			goto resource_put_failure;
4221 	}
4222 
4223 	nla_nest_end(skb, child_resource_attr);
4224 out:
4225 	nla_nest_end(skb, resource_attr);
4226 	return 0;
4227 
4228 resource_put_failure:
4229 	nla_nest_cancel(skb, child_resource_attr);
4230 nla_put_failure:
4231 	nla_nest_cancel(skb, resource_attr);
4232 	return -EMSGSIZE;
4233 }
4234 
devlink_resource_fill(struct genl_info * info,enum devlink_command cmd,int flags)4235 static int devlink_resource_fill(struct genl_info *info,
4236 				 enum devlink_command cmd, int flags)
4237 {
4238 	struct devlink *devlink = info->user_ptr[0];
4239 	struct devlink_resource *resource;
4240 	struct nlattr *resources_attr;
4241 	struct sk_buff *skb = NULL;
4242 	struct nlmsghdr *nlh;
4243 	bool incomplete;
4244 	void *hdr;
4245 	int i;
4246 	int err;
4247 
4248 	resource = list_first_entry(&devlink->resource_list,
4249 				    struct devlink_resource, list);
4250 start_again:
4251 	err = devlink_dpipe_send_and_alloc_skb(&skb, info);
4252 	if (err)
4253 		return err;
4254 
4255 	hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
4256 			  &devlink_nl_family, NLM_F_MULTI, cmd);
4257 	if (!hdr) {
4258 		nlmsg_free(skb);
4259 		return -EMSGSIZE;
4260 	}
4261 
4262 	if (devlink_nl_put_handle(skb, devlink))
4263 		goto nla_put_failure;
4264 
4265 	resources_attr = nla_nest_start_noflag(skb,
4266 					       DEVLINK_ATTR_RESOURCE_LIST);
4267 	if (!resources_attr)
4268 		goto nla_put_failure;
4269 
4270 	incomplete = false;
4271 	i = 0;
4272 	list_for_each_entry_from(resource, &devlink->resource_list, list) {
4273 		err = devlink_resource_put(devlink, skb, resource);
4274 		if (err) {
4275 			if (!i)
4276 				goto err_resource_put;
4277 			incomplete = true;
4278 			break;
4279 		}
4280 		i++;
4281 	}
4282 	nla_nest_end(skb, resources_attr);
4283 	genlmsg_end(skb, hdr);
4284 	if (incomplete)
4285 		goto start_again;
4286 send_done:
4287 	nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
4288 			NLMSG_DONE, 0, flags | NLM_F_MULTI);
4289 	if (!nlh) {
4290 		err = devlink_dpipe_send_and_alloc_skb(&skb, info);
4291 		if (err)
4292 			return err;
4293 		goto send_done;
4294 	}
4295 	return genlmsg_reply(skb, info);
4296 
4297 nla_put_failure:
4298 	err = -EMSGSIZE;
4299 err_resource_put:
4300 	nlmsg_free(skb);
4301 	return err;
4302 }
4303 
devlink_nl_cmd_resource_dump(struct sk_buff * skb,struct genl_info * info)4304 static int devlink_nl_cmd_resource_dump(struct sk_buff *skb,
4305 					struct genl_info *info)
4306 {
4307 	struct devlink *devlink = info->user_ptr[0];
4308 
4309 	if (list_empty(&devlink->resource_list))
4310 		return -EOPNOTSUPP;
4311 
4312 	return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0);
4313 }
4314 
4315 static int
devlink_resources_validate(struct devlink * devlink,struct devlink_resource * resource,struct genl_info * info)4316 devlink_resources_validate(struct devlink *devlink,
4317 			   struct devlink_resource *resource,
4318 			   struct genl_info *info)
4319 {
4320 	struct list_head *resource_list;
4321 	int err = 0;
4322 
4323 	if (resource)
4324 		resource_list = &resource->resource_list;
4325 	else
4326 		resource_list = &devlink->resource_list;
4327 
4328 	list_for_each_entry(resource, resource_list, list) {
4329 		if (!resource->size_valid)
4330 			return -EINVAL;
4331 		err = devlink_resources_validate(devlink, resource, info);
4332 		if (err)
4333 			return err;
4334 	}
4335 	return err;
4336 }
4337 
devlink_netns_get(struct sk_buff * skb,struct genl_info * info)4338 static struct net *devlink_netns_get(struct sk_buff *skb,
4339 				     struct genl_info *info)
4340 {
4341 	struct nlattr *netns_pid_attr = info->attrs[DEVLINK_ATTR_NETNS_PID];
4342 	struct nlattr *netns_fd_attr = info->attrs[DEVLINK_ATTR_NETNS_FD];
4343 	struct nlattr *netns_id_attr = info->attrs[DEVLINK_ATTR_NETNS_ID];
4344 	struct net *net;
4345 
4346 	if (!!netns_pid_attr + !!netns_fd_attr + !!netns_id_attr > 1) {
4347 		NL_SET_ERR_MSG_MOD(info->extack, "multiple netns identifying attributes specified");
4348 		return ERR_PTR(-EINVAL);
4349 	}
4350 
4351 	if (netns_pid_attr) {
4352 		net = get_net_ns_by_pid(nla_get_u32(netns_pid_attr));
4353 	} else if (netns_fd_attr) {
4354 		net = get_net_ns_by_fd(nla_get_u32(netns_fd_attr));
4355 	} else if (netns_id_attr) {
4356 		net = get_net_ns_by_id(sock_net(skb->sk),
4357 				       nla_get_u32(netns_id_attr));
4358 		if (!net)
4359 			net = ERR_PTR(-EINVAL);
4360 	} else {
4361 		WARN_ON(1);
4362 		net = ERR_PTR(-EINVAL);
4363 	}
4364 	if (IS_ERR(net)) {
4365 		NL_SET_ERR_MSG_MOD(info->extack, "Unknown network namespace");
4366 		return ERR_PTR(-EINVAL);
4367 	}
4368 	if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) {
4369 		put_net(net);
4370 		return ERR_PTR(-EPERM);
4371 	}
4372 	return net;
4373 }
4374 
4375 static void devlink_param_notify(struct devlink *devlink,
4376 				 unsigned int port_index,
4377 				 struct devlink_param_item *param_item,
4378 				 enum devlink_command cmd);
4379 
devlink_ns_change_notify(struct devlink * devlink,struct net * dest_net,struct net * curr_net,bool new)4380 static void devlink_ns_change_notify(struct devlink *devlink,
4381 				     struct net *dest_net, struct net *curr_net,
4382 				     bool new)
4383 {
4384 	struct devlink_param_item *param_item;
4385 	enum devlink_command cmd;
4386 
4387 	/* Userspace needs to be notified about devlink objects
4388 	 * removed from original and entering new network namespace.
4389 	 * The rest of the devlink objects are re-created during
4390 	 * reload process so the notifications are generated separatelly.
4391 	 */
4392 
4393 	if (!dest_net || net_eq(dest_net, curr_net))
4394 		return;
4395 
4396 	if (new)
4397 		devlink_notify(devlink, DEVLINK_CMD_NEW);
4398 
4399 	cmd = new ? DEVLINK_CMD_PARAM_NEW : DEVLINK_CMD_PARAM_DEL;
4400 	list_for_each_entry(param_item, &devlink->param_list, list)
4401 		devlink_param_notify(devlink, 0, param_item, cmd);
4402 
4403 	if (!new)
4404 		devlink_notify(devlink, DEVLINK_CMD_DEL);
4405 }
4406 
devlink_reload_supported(const struct devlink_ops * ops)4407 static bool devlink_reload_supported(const struct devlink_ops *ops)
4408 {
4409 	return ops->reload_down && ops->reload_up;
4410 }
4411 
devlink_reload_failed_set(struct devlink * devlink,bool reload_failed)4412 static void devlink_reload_failed_set(struct devlink *devlink,
4413 				      bool reload_failed)
4414 {
4415 	if (devlink->reload_failed == reload_failed)
4416 		return;
4417 	devlink->reload_failed = reload_failed;
4418 	devlink_notify(devlink, DEVLINK_CMD_NEW);
4419 }
4420 
devlink_is_reload_failed(const struct devlink * devlink)4421 bool devlink_is_reload_failed(const struct devlink *devlink)
4422 {
4423 	return devlink->reload_failed;
4424 }
4425 EXPORT_SYMBOL_GPL(devlink_is_reload_failed);
4426 
4427 static void
__devlink_reload_stats_update(struct devlink * devlink,u32 * reload_stats,enum devlink_reload_limit limit,u32 actions_performed)4428 __devlink_reload_stats_update(struct devlink *devlink, u32 *reload_stats,
4429 			      enum devlink_reload_limit limit, u32 actions_performed)
4430 {
4431 	unsigned long actions = actions_performed;
4432 	int stat_idx;
4433 	int action;
4434 
4435 	for_each_set_bit(action, &actions, __DEVLINK_RELOAD_ACTION_MAX) {
4436 		stat_idx = limit * __DEVLINK_RELOAD_ACTION_MAX + action;
4437 		reload_stats[stat_idx]++;
4438 	}
4439 	devlink_notify(devlink, DEVLINK_CMD_NEW);
4440 }
4441 
4442 static void
devlink_reload_stats_update(struct devlink * devlink,enum devlink_reload_limit limit,u32 actions_performed)4443 devlink_reload_stats_update(struct devlink *devlink, enum devlink_reload_limit limit,
4444 			    u32 actions_performed)
4445 {
4446 	__devlink_reload_stats_update(devlink, devlink->stats.reload_stats, limit,
4447 				      actions_performed);
4448 }
4449 
4450 /**
4451  *	devlink_remote_reload_actions_performed - Update devlink on reload actions
4452  *	  performed which are not a direct result of devlink reload call.
4453  *
4454  *	This should be called by a driver after performing reload actions in case it was not
4455  *	a result of devlink reload call. For example fw_activate was performed as a result
4456  *	of devlink reload triggered fw_activate on another host.
4457  *	The motivation for this function is to keep data on reload actions performed on this
4458  *	function whether it was done due to direct devlink reload call or not.
4459  *
4460  *	@devlink: devlink
4461  *	@limit: reload limit
4462  *	@actions_performed: bitmask of actions performed
4463  */
devlink_remote_reload_actions_performed(struct devlink * devlink,enum devlink_reload_limit limit,u32 actions_performed)4464 void devlink_remote_reload_actions_performed(struct devlink *devlink,
4465 					     enum devlink_reload_limit limit,
4466 					     u32 actions_performed)
4467 {
4468 	if (WARN_ON(!actions_performed ||
4469 		    actions_performed & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) ||
4470 		    actions_performed >= BIT(__DEVLINK_RELOAD_ACTION_MAX) ||
4471 		    limit > DEVLINK_RELOAD_LIMIT_MAX))
4472 		return;
4473 
4474 	__devlink_reload_stats_update(devlink, devlink->stats.remote_reload_stats, limit,
4475 				      actions_performed);
4476 }
4477 EXPORT_SYMBOL_GPL(devlink_remote_reload_actions_performed);
4478 
devlink_reload(struct devlink * devlink,struct net * dest_net,enum devlink_reload_action action,enum devlink_reload_limit limit,u32 * actions_performed,struct netlink_ext_ack * extack)4479 static int devlink_reload(struct devlink *devlink, struct net *dest_net,
4480 			  enum devlink_reload_action action, enum devlink_reload_limit limit,
4481 			  u32 *actions_performed, struct netlink_ext_ack *extack)
4482 {
4483 	u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE];
4484 	struct net *curr_net;
4485 	int err;
4486 
4487 	memcpy(remote_reload_stats, devlink->stats.remote_reload_stats,
4488 	       sizeof(remote_reload_stats));
4489 
4490 	curr_net = devlink_net(devlink);
4491 	devlink_ns_change_notify(devlink, dest_net, curr_net, false);
4492 	err = devlink->ops->reload_down(devlink, !!dest_net, action, limit, extack);
4493 	if (err)
4494 		return err;
4495 
4496 	if (dest_net && !net_eq(dest_net, curr_net))
4497 		write_pnet(&devlink->_net, dest_net);
4498 
4499 	err = devlink->ops->reload_up(devlink, action, limit, actions_performed, extack);
4500 	devlink_reload_failed_set(devlink, !!err);
4501 	if (err)
4502 		return err;
4503 
4504 	devlink_ns_change_notify(devlink, dest_net, curr_net, true);
4505 	WARN_ON(!(*actions_performed & BIT(action)));
4506 	/* Catch driver on updating the remote action within devlink reload */
4507 	WARN_ON(memcmp(remote_reload_stats, devlink->stats.remote_reload_stats,
4508 		       sizeof(remote_reload_stats)));
4509 	devlink_reload_stats_update(devlink, limit, *actions_performed);
4510 	return 0;
4511 }
4512 
4513 static int
devlink_nl_reload_actions_performed_snd(struct devlink * devlink,u32 actions_performed,enum devlink_command cmd,struct genl_info * info)4514 devlink_nl_reload_actions_performed_snd(struct devlink *devlink, u32 actions_performed,
4515 					enum devlink_command cmd, struct genl_info *info)
4516 {
4517 	struct sk_buff *msg;
4518 	void *hdr;
4519 
4520 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4521 	if (!msg)
4522 		return -ENOMEM;
4523 
4524 	hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, &devlink_nl_family, 0, cmd);
4525 	if (!hdr)
4526 		goto free_msg;
4527 
4528 	if (devlink_nl_put_handle(msg, devlink))
4529 		goto nla_put_failure;
4530 
4531 	if (nla_put_bitfield32(msg, DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED, actions_performed,
4532 			       actions_performed))
4533 		goto nla_put_failure;
4534 	genlmsg_end(msg, hdr);
4535 
4536 	return genlmsg_reply(msg, info);
4537 
4538 nla_put_failure:
4539 	genlmsg_cancel(msg, hdr);
4540 free_msg:
4541 	nlmsg_free(msg);
4542 	return -EMSGSIZE;
4543 }
4544 
devlink_nl_cmd_reload(struct sk_buff * skb,struct genl_info * info)4545 static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
4546 {
4547 	struct devlink *devlink = info->user_ptr[0];
4548 	enum devlink_reload_action action;
4549 	enum devlink_reload_limit limit;
4550 	struct net *dest_net = NULL;
4551 	u32 actions_performed;
4552 	int err;
4553 
4554 	if (!(devlink->features & DEVLINK_F_RELOAD))
4555 		return -EOPNOTSUPP;
4556 
4557 	err = devlink_resources_validate(devlink, NULL, info);
4558 	if (err) {
4559 		NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed");
4560 		return err;
4561 	}
4562 
4563 	if (info->attrs[DEVLINK_ATTR_RELOAD_ACTION])
4564 		action = nla_get_u8(info->attrs[DEVLINK_ATTR_RELOAD_ACTION]);
4565 	else
4566 		action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT;
4567 
4568 	if (!devlink_reload_action_is_supported(devlink, action)) {
4569 		NL_SET_ERR_MSG_MOD(info->extack,
4570 				   "Requested reload action is not supported by the driver");
4571 		return -EOPNOTSUPP;
4572 	}
4573 
4574 	limit = DEVLINK_RELOAD_LIMIT_UNSPEC;
4575 	if (info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]) {
4576 		struct nla_bitfield32 limits;
4577 		u32 limits_selected;
4578 
4579 		limits = nla_get_bitfield32(info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]);
4580 		limits_selected = limits.value & limits.selector;
4581 		if (!limits_selected) {
4582 			NL_SET_ERR_MSG_MOD(info->extack, "Invalid limit selected");
4583 			return -EINVAL;
4584 		}
4585 		for (limit = 0 ; limit <= DEVLINK_RELOAD_LIMIT_MAX ; limit++)
4586 			if (limits_selected & BIT(limit))
4587 				break;
4588 		/* UAPI enables multiselection, but currently it is not used */
4589 		if (limits_selected != BIT(limit)) {
4590 			NL_SET_ERR_MSG_MOD(info->extack,
4591 					   "Multiselection of limit is not supported");
4592 			return -EOPNOTSUPP;
4593 		}
4594 		if (!devlink_reload_limit_is_supported(devlink, limit)) {
4595 			NL_SET_ERR_MSG_MOD(info->extack,
4596 					   "Requested limit is not supported by the driver");
4597 			return -EOPNOTSUPP;
4598 		}
4599 		if (devlink_reload_combination_is_invalid(action, limit)) {
4600 			NL_SET_ERR_MSG_MOD(info->extack,
4601 					   "Requested limit is invalid for this action");
4602 			return -EINVAL;
4603 		}
4604 	}
4605 	if (info->attrs[DEVLINK_ATTR_NETNS_PID] ||
4606 	    info->attrs[DEVLINK_ATTR_NETNS_FD] ||
4607 	    info->attrs[DEVLINK_ATTR_NETNS_ID]) {
4608 		dest_net = devlink_netns_get(skb, info);
4609 		if (IS_ERR(dest_net))
4610 			return PTR_ERR(dest_net);
4611 	}
4612 
4613 	err = devlink_reload(devlink, dest_net, action, limit, &actions_performed, info->extack);
4614 
4615 	if (dest_net)
4616 		put_net(dest_net);
4617 
4618 	if (err)
4619 		return err;
4620 	/* For backward compatibility generate reply only if attributes used by user */
4621 	if (!info->attrs[DEVLINK_ATTR_RELOAD_ACTION] && !info->attrs[DEVLINK_ATTR_RELOAD_LIMITS])
4622 		return 0;
4623 
4624 	return devlink_nl_reload_actions_performed_snd(devlink, actions_performed,
4625 						       DEVLINK_CMD_RELOAD, info);
4626 }
4627 
devlink_nl_flash_update_fill(struct sk_buff * msg,struct devlink * devlink,enum devlink_command cmd,struct devlink_flash_notify * params)4628 static int devlink_nl_flash_update_fill(struct sk_buff *msg,
4629 					struct devlink *devlink,
4630 					enum devlink_command cmd,
4631 					struct devlink_flash_notify *params)
4632 {
4633 	void *hdr;
4634 
4635 	hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd);
4636 	if (!hdr)
4637 		return -EMSGSIZE;
4638 
4639 	if (devlink_nl_put_handle(msg, devlink))
4640 		goto nla_put_failure;
4641 
4642 	if (cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS)
4643 		goto out;
4644 
4645 	if (params->status_msg &&
4646 	    nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG,
4647 			   params->status_msg))
4648 		goto nla_put_failure;
4649 	if (params->component &&
4650 	    nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT,
4651 			   params->component))
4652 		goto nla_put_failure;
4653 	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE,
4654 			      params->done, DEVLINK_ATTR_PAD))
4655 		goto nla_put_failure;
4656 	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL,
4657 			      params->total, DEVLINK_ATTR_PAD))
4658 		goto nla_put_failure;
4659 	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TIMEOUT,
4660 			      params->timeout, DEVLINK_ATTR_PAD))
4661 		goto nla_put_failure;
4662 
4663 out:
4664 	genlmsg_end(msg, hdr);
4665 	return 0;
4666 
4667 nla_put_failure:
4668 	genlmsg_cancel(msg, hdr);
4669 	return -EMSGSIZE;
4670 }
4671 
__devlink_flash_update_notify(struct devlink * devlink,enum devlink_command cmd,struct devlink_flash_notify * params)4672 static void __devlink_flash_update_notify(struct devlink *devlink,
4673 					  enum devlink_command cmd,
4674 					  struct devlink_flash_notify *params)
4675 {
4676 	struct sk_buff *msg;
4677 	int err;
4678 
4679 	WARN_ON(cmd != DEVLINK_CMD_FLASH_UPDATE &&
4680 		cmd != DEVLINK_CMD_FLASH_UPDATE_END &&
4681 		cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS);
4682 
4683 	if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
4684 		return;
4685 
4686 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4687 	if (!msg)
4688 		return;
4689 
4690 	err = devlink_nl_flash_update_fill(msg, devlink, cmd, params);
4691 	if (err)
4692 		goto out_free_msg;
4693 
4694 	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
4695 				msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
4696 	return;
4697 
4698 out_free_msg:
4699 	nlmsg_free(msg);
4700 }
4701 
devlink_flash_update_begin_notify(struct devlink * devlink)4702 static void devlink_flash_update_begin_notify(struct devlink *devlink)
4703 {
4704 	struct devlink_flash_notify params = {};
4705 
4706 	__devlink_flash_update_notify(devlink,
4707 				      DEVLINK_CMD_FLASH_UPDATE,
4708 				      &params);
4709 }
4710 
devlink_flash_update_end_notify(struct devlink * devlink)4711 static void devlink_flash_update_end_notify(struct devlink *devlink)
4712 {
4713 	struct devlink_flash_notify params = {};
4714 
4715 	__devlink_flash_update_notify(devlink,
4716 				      DEVLINK_CMD_FLASH_UPDATE_END,
4717 				      &params);
4718 }
4719 
devlink_flash_update_status_notify(struct devlink * devlink,const char * status_msg,const char * component,unsigned long done,unsigned long total)4720 void devlink_flash_update_status_notify(struct devlink *devlink,
4721 					const char *status_msg,
4722 					const char *component,
4723 					unsigned long done,
4724 					unsigned long total)
4725 {
4726 	struct devlink_flash_notify params = {
4727 		.status_msg = status_msg,
4728 		.component = component,
4729 		.done = done,
4730 		.total = total,
4731 	};
4732 
4733 	__devlink_flash_update_notify(devlink,
4734 				      DEVLINK_CMD_FLASH_UPDATE_STATUS,
4735 				      &params);
4736 }
4737 EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify);
4738 
devlink_flash_update_timeout_notify(struct devlink * devlink,const char * status_msg,const char * component,unsigned long timeout)4739 void devlink_flash_update_timeout_notify(struct devlink *devlink,
4740 					 const char *status_msg,
4741 					 const char *component,
4742 					 unsigned long timeout)
4743 {
4744 	struct devlink_flash_notify params = {
4745 		.status_msg = status_msg,
4746 		.component = component,
4747 		.timeout = timeout,
4748 	};
4749 
4750 	__devlink_flash_update_notify(devlink,
4751 				      DEVLINK_CMD_FLASH_UPDATE_STATUS,
4752 				      &params);
4753 }
4754 EXPORT_SYMBOL_GPL(devlink_flash_update_timeout_notify);
4755 
4756 struct devlink_info_req {
4757 	struct sk_buff *msg;
4758 	void (*version_cb)(const char *version_name,
4759 			   enum devlink_info_version_type version_type,
4760 			   void *version_cb_priv);
4761 	void *version_cb_priv;
4762 };
4763 
4764 struct devlink_flash_component_lookup_ctx {
4765 	const char *lookup_name;
4766 	bool lookup_name_found;
4767 };
4768 
4769 static void
devlink_flash_component_lookup_cb(const char * version_name,enum devlink_info_version_type version_type,void * version_cb_priv)4770 devlink_flash_component_lookup_cb(const char *version_name,
4771 				  enum devlink_info_version_type version_type,
4772 				  void *version_cb_priv)
4773 {
4774 	struct devlink_flash_component_lookup_ctx *lookup_ctx = version_cb_priv;
4775 
4776 	if (version_type != DEVLINK_INFO_VERSION_TYPE_COMPONENT ||
4777 	    lookup_ctx->lookup_name_found)
4778 		return;
4779 
4780 	lookup_ctx->lookup_name_found =
4781 		!strcmp(lookup_ctx->lookup_name, version_name);
4782 }
4783 
devlink_flash_component_get(struct devlink * devlink,struct nlattr * nla_component,const char ** p_component,struct netlink_ext_ack * extack)4784 static int devlink_flash_component_get(struct devlink *devlink,
4785 				       struct nlattr *nla_component,
4786 				       const char **p_component,
4787 				       struct netlink_ext_ack *extack)
4788 {
4789 	struct devlink_flash_component_lookup_ctx lookup_ctx = {};
4790 	struct devlink_info_req req = {};
4791 	const char *component;
4792 	int ret;
4793 
4794 	if (!nla_component)
4795 		return 0;
4796 
4797 	component = nla_data(nla_component);
4798 
4799 	if (!devlink->ops->info_get) {
4800 		NL_SET_ERR_MSG_ATTR(extack, nla_component,
4801 				    "component update is not supported by this device");
4802 		return -EOPNOTSUPP;
4803 	}
4804 
4805 	lookup_ctx.lookup_name = component;
4806 	req.version_cb = devlink_flash_component_lookup_cb;
4807 	req.version_cb_priv = &lookup_ctx;
4808 
4809 	ret = devlink->ops->info_get(devlink, &req, NULL);
4810 	if (ret)
4811 		return ret;
4812 
4813 	if (!lookup_ctx.lookup_name_found) {
4814 		NL_SET_ERR_MSG_ATTR(extack, nla_component,
4815 				    "selected component is not supported by this device");
4816 		return -EINVAL;
4817 	}
4818 	*p_component = component;
4819 	return 0;
4820 }
4821 
devlink_nl_cmd_flash_update(struct sk_buff * skb,struct genl_info * info)4822 static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
4823 				       struct genl_info *info)
4824 {
4825 	struct nlattr *nla_overwrite_mask, *nla_file_name;
4826 	struct devlink_flash_update_params params = {};
4827 	struct devlink *devlink = info->user_ptr[0];
4828 	const char *file_name;
4829 	u32 supported_params;
4830 	int ret;
4831 
4832 	if (!devlink->ops->flash_update)
4833 		return -EOPNOTSUPP;
4834 
4835 	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME))
4836 		return -EINVAL;
4837 
4838 	ret = devlink_flash_component_get(devlink,
4839 					  info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT],
4840 					  &params.component, info->extack);
4841 	if (ret)
4842 		return ret;
4843 
4844 	supported_params = devlink->ops->supported_flash_update_params;
4845 
4846 	nla_overwrite_mask = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK];
4847 	if (nla_overwrite_mask) {
4848 		struct nla_bitfield32 sections;
4849 
4850 		if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK)) {
4851 			NL_SET_ERR_MSG_ATTR(info->extack, nla_overwrite_mask,
4852 					    "overwrite settings are not supported by this device");
4853 			return -EOPNOTSUPP;
4854 		}
4855 		sections = nla_get_bitfield32(nla_overwrite_mask);
4856 		params.overwrite_mask = sections.value & sections.selector;
4857 	}
4858 
4859 	nla_file_name = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME];
4860 	file_name = nla_data(nla_file_name);
4861 	ret = request_firmware(&params.fw, file_name, devlink->dev);
4862 	if (ret) {
4863 		NL_SET_ERR_MSG_ATTR(info->extack, nla_file_name, "failed to locate the requested firmware file");
4864 		return ret;
4865 	}
4866 
4867 	devlink_flash_update_begin_notify(devlink);
4868 	ret = devlink->ops->flash_update(devlink, &params, info->extack);
4869 	devlink_flash_update_end_notify(devlink);
4870 
4871 	release_firmware(params.fw);
4872 
4873 	return ret;
4874 }
4875 
4876 static int
devlink_nl_selftests_fill(struct sk_buff * msg,struct devlink * devlink,u32 portid,u32 seq,int flags,struct netlink_ext_ack * extack)4877 devlink_nl_selftests_fill(struct sk_buff *msg, struct devlink *devlink,
4878 			  u32 portid, u32 seq, int flags,
4879 			  struct netlink_ext_ack *extack)
4880 {
4881 	struct nlattr *selftests;
4882 	void *hdr;
4883 	int err;
4884 	int i;
4885 
4886 	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags,
4887 			  DEVLINK_CMD_SELFTESTS_GET);
4888 	if (!hdr)
4889 		return -EMSGSIZE;
4890 
4891 	err = -EMSGSIZE;
4892 	if (devlink_nl_put_handle(msg, devlink))
4893 		goto err_cancel_msg;
4894 
4895 	selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS);
4896 	if (!selftests)
4897 		goto err_cancel_msg;
4898 
4899 	for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1;
4900 	     i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) {
4901 		if (devlink->ops->selftest_check(devlink, i, extack)) {
4902 			err = nla_put_flag(msg, i);
4903 			if (err)
4904 				goto err_cancel_msg;
4905 		}
4906 	}
4907 
4908 	nla_nest_end(msg, selftests);
4909 	genlmsg_end(msg, hdr);
4910 	return 0;
4911 
4912 err_cancel_msg:
4913 	genlmsg_cancel(msg, hdr);
4914 	return err;
4915 }
4916 
devlink_nl_cmd_selftests_get_doit(struct sk_buff * skb,struct genl_info * info)4917 static int devlink_nl_cmd_selftests_get_doit(struct sk_buff *skb,
4918 					     struct genl_info *info)
4919 {
4920 	struct devlink *devlink = info->user_ptr[0];
4921 	struct sk_buff *msg;
4922 	int err;
4923 
4924 	if (!devlink->ops->selftest_check)
4925 		return -EOPNOTSUPP;
4926 
4927 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4928 	if (!msg)
4929 		return -ENOMEM;
4930 
4931 	err = devlink_nl_selftests_fill(msg, devlink, info->snd_portid,
4932 					info->snd_seq, 0, info->extack);
4933 	if (err) {
4934 		nlmsg_free(msg);
4935 		return err;
4936 	}
4937 
4938 	return genlmsg_reply(msg, info);
4939 }
4940 
devlink_nl_cmd_selftests_get_dumpit(struct sk_buff * msg,struct netlink_callback * cb)4941 static int devlink_nl_cmd_selftests_get_dumpit(struct sk_buff *msg,
4942 					       struct netlink_callback *cb)
4943 {
4944 	struct devlink *devlink;
4945 	int start = cb->args[0];
4946 	unsigned long index;
4947 	int idx = 0;
4948 	int err = 0;
4949 
4950 	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
4951 		if (idx < start || !devlink->ops->selftest_check)
4952 			goto inc;
4953 
4954 		devl_lock(devlink);
4955 		err = devlink_nl_selftests_fill(msg, devlink,
4956 						NETLINK_CB(cb->skb).portid,
4957 						cb->nlh->nlmsg_seq, NLM_F_MULTI,
4958 						cb->extack);
4959 		devl_unlock(devlink);
4960 		if (err) {
4961 			devlink_put(devlink);
4962 			break;
4963 		}
4964 inc:
4965 		idx++;
4966 		devlink_put(devlink);
4967 	}
4968 
4969 	if (err != -EMSGSIZE)
4970 		return err;
4971 
4972 	cb->args[0] = idx;
4973 	return msg->len;
4974 }
4975 
devlink_selftest_result_put(struct sk_buff * skb,unsigned int id,enum devlink_selftest_status test_status)4976 static int devlink_selftest_result_put(struct sk_buff *skb, unsigned int id,
4977 				       enum devlink_selftest_status test_status)
4978 {
4979 	struct nlattr *result_attr;
4980 
4981 	result_attr = nla_nest_start(skb, DEVLINK_ATTR_SELFTEST_RESULT);
4982 	if (!result_attr)
4983 		return -EMSGSIZE;
4984 
4985 	if (nla_put_u32(skb, DEVLINK_ATTR_SELFTEST_RESULT_ID, id) ||
4986 	    nla_put_u8(skb, DEVLINK_ATTR_SELFTEST_RESULT_STATUS,
4987 		       test_status))
4988 		goto nla_put_failure;
4989 
4990 	nla_nest_end(skb, result_attr);
4991 	return 0;
4992 
4993 nla_put_failure:
4994 	nla_nest_cancel(skb, result_attr);
4995 	return -EMSGSIZE;
4996 }
4997 
devlink_nl_cmd_selftests_run(struct sk_buff * skb,struct genl_info * info)4998 static int devlink_nl_cmd_selftests_run(struct sk_buff *skb,
4999 					struct genl_info *info)
5000 {
5001 	struct nlattr *tb[DEVLINK_ATTR_SELFTEST_ID_MAX + 1];
5002 	struct devlink *devlink = info->user_ptr[0];
5003 	struct nlattr *attrs, *selftests;
5004 	struct sk_buff *msg;
5005 	void *hdr;
5006 	int err;
5007 	int i;
5008 
5009 	if (!devlink->ops->selftest_run || !devlink->ops->selftest_check)
5010 		return -EOPNOTSUPP;
5011 
5012 	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SELFTESTS))
5013 		return -EINVAL;
5014 
5015 	attrs = info->attrs[DEVLINK_ATTR_SELFTESTS];
5016 
5017 	err = nla_parse_nested(tb, DEVLINK_ATTR_SELFTEST_ID_MAX, attrs,
5018 			       devlink_selftest_nl_policy, info->extack);
5019 	if (err < 0)
5020 		return err;
5021 
5022 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5023 	if (!msg)
5024 		return -ENOMEM;
5025 
5026 	err = -EMSGSIZE;
5027 	hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq,
5028 			  &devlink_nl_family, 0, DEVLINK_CMD_SELFTESTS_RUN);
5029 	if (!hdr)
5030 		goto free_msg;
5031 
5032 	if (devlink_nl_put_handle(msg, devlink))
5033 		goto genlmsg_cancel;
5034 
5035 	selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS);
5036 	if (!selftests)
5037 		goto genlmsg_cancel;
5038 
5039 	for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1;
5040 	     i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) {
5041 		enum devlink_selftest_status test_status;
5042 
5043 		if (nla_get_flag(tb[i])) {
5044 			if (!devlink->ops->selftest_check(devlink, i,
5045 							  info->extack)) {
5046 				if (devlink_selftest_result_put(msg, i,
5047 								DEVLINK_SELFTEST_STATUS_SKIP))
5048 					goto selftests_nest_cancel;
5049 				continue;
5050 			}
5051 
5052 			test_status = devlink->ops->selftest_run(devlink, i,
5053 								 info->extack);
5054 			if (devlink_selftest_result_put(msg, i, test_status))
5055 				goto selftests_nest_cancel;
5056 		}
5057 	}
5058 
5059 	nla_nest_end(msg, selftests);
5060 	genlmsg_end(msg, hdr);
5061 	return genlmsg_reply(msg, info);
5062 
5063 selftests_nest_cancel:
5064 	nla_nest_cancel(msg, selftests);
5065 genlmsg_cancel:
5066 	genlmsg_cancel(msg, hdr);
5067 free_msg:
5068 	nlmsg_free(msg);
5069 	return err;
5070 }
5071 
5072 static const struct devlink_param devlink_param_generic[] = {
5073 	{
5074 		.id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET,
5075 		.name = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME,
5076 		.type = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE,
5077 	},
5078 	{
5079 		.id = DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
5080 		.name = DEVLINK_PARAM_GENERIC_MAX_MACS_NAME,
5081 		.type = DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE,
5082 	},
5083 	{
5084 		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV,
5085 		.name = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME,
5086 		.type = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE,
5087 	},
5088 	{
5089 		.id = DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT,
5090 		.name = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME,
5091 		.type = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE,
5092 	},
5093 	{
5094 		.id = DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI,
5095 		.name = DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME,
5096 		.type = DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE,
5097 	},
5098 	{
5099 		.id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX,
5100 		.name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME,
5101 		.type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE,
5102 	},
5103 	{
5104 		.id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN,
5105 		.name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME,
5106 		.type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE,
5107 	},
5108 	{
5109 		.id = DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY,
5110 		.name = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME,
5111 		.type = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE,
5112 	},
5113 	{
5114 		.id = DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE,
5115 		.name = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME,
5116 		.type = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE,
5117 	},
5118 	{
5119 		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE,
5120 		.name = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_NAME,
5121 		.type = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_TYPE,
5122 	},
5123 	{
5124 		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_REMOTE_DEV_RESET,
5125 		.name = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_NAME,
5126 		.type = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_TYPE,
5127 	},
5128 	{
5129 		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ETH,
5130 		.name = DEVLINK_PARAM_GENERIC_ENABLE_ETH_NAME,
5131 		.type = DEVLINK_PARAM_GENERIC_ENABLE_ETH_TYPE,
5132 	},
5133 	{
5134 		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_RDMA,
5135 		.name = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_NAME,
5136 		.type = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_TYPE,
5137 	},
5138 	{
5139 		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_VNET,
5140 		.name = DEVLINK_PARAM_GENERIC_ENABLE_VNET_NAME,
5141 		.type = DEVLINK_PARAM_GENERIC_ENABLE_VNET_TYPE,
5142 	},
5143 	{
5144 		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_IWARP,
5145 		.name = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_NAME,
5146 		.type = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_TYPE,
5147 	},
5148 	{
5149 		.id = DEVLINK_PARAM_GENERIC_ID_IO_EQ_SIZE,
5150 		.name = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_NAME,
5151 		.type = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_TYPE,
5152 	},
5153 	{
5154 		.id = DEVLINK_PARAM_GENERIC_ID_EVENT_EQ_SIZE,
5155 		.name = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_NAME,
5156 		.type = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_TYPE,
5157 	},
5158 };
5159 
devlink_param_generic_verify(const struct devlink_param * param)5160 static int devlink_param_generic_verify(const struct devlink_param *param)
5161 {
5162 	/* verify it match generic parameter by id and name */
5163 	if (param->id > DEVLINK_PARAM_GENERIC_ID_MAX)
5164 		return -EINVAL;
5165 	if (strcmp(param->name, devlink_param_generic[param->id].name))
5166 		return -ENOENT;
5167 
5168 	WARN_ON(param->type != devlink_param_generic[param->id].type);
5169 
5170 	return 0;
5171 }
5172 
devlink_param_driver_verify(const struct devlink_param * param)5173 static int devlink_param_driver_verify(const struct devlink_param *param)
5174 {
5175 	int i;
5176 
5177 	if (param->id <= DEVLINK_PARAM_GENERIC_ID_MAX)
5178 		return -EINVAL;
5179 	/* verify no such name in generic params */
5180 	for (i = 0; i <= DEVLINK_PARAM_GENERIC_ID_MAX; i++)
5181 		if (!strcmp(param->name, devlink_param_generic[i].name))
5182 			return -EEXIST;
5183 
5184 	return 0;
5185 }
5186 
5187 static struct devlink_param_item *
devlink_param_find_by_name(struct list_head * param_list,const char * param_name)5188 devlink_param_find_by_name(struct list_head *param_list,
5189 			   const char *param_name)
5190 {
5191 	struct devlink_param_item *param_item;
5192 
5193 	list_for_each_entry(param_item, param_list, list)
5194 		if (!strcmp(param_item->param->name, param_name))
5195 			return param_item;
5196 	return NULL;
5197 }
5198 
5199 static struct devlink_param_item *
devlink_param_find_by_id(struct list_head * param_list,u32 param_id)5200 devlink_param_find_by_id(struct list_head *param_list, u32 param_id)
5201 {
5202 	struct devlink_param_item *param_item;
5203 
5204 	list_for_each_entry(param_item, param_list, list)
5205 		if (param_item->param->id == param_id)
5206 			return param_item;
5207 	return NULL;
5208 }
5209 
5210 static bool
devlink_param_cmode_is_supported(const struct devlink_param * param,enum devlink_param_cmode cmode)5211 devlink_param_cmode_is_supported(const struct devlink_param *param,
5212 				 enum devlink_param_cmode cmode)
5213 {
5214 	return test_bit(cmode, &param->supported_cmodes);
5215 }
5216 
devlink_param_get(struct devlink * devlink,const struct devlink_param * param,struct devlink_param_gset_ctx * ctx)5217 static int devlink_param_get(struct devlink *devlink,
5218 			     const struct devlink_param *param,
5219 			     struct devlink_param_gset_ctx *ctx)
5220 {
5221 	if (!param->get)
5222 		return -EOPNOTSUPP;
5223 	return param->get(devlink, param->id, ctx);
5224 }
5225 
devlink_param_set(struct devlink * devlink,const struct devlink_param * param,struct devlink_param_gset_ctx * ctx)5226 static int devlink_param_set(struct devlink *devlink,
5227 			     const struct devlink_param *param,
5228 			     struct devlink_param_gset_ctx *ctx)
5229 {
5230 	if (!param->set)
5231 		return -EOPNOTSUPP;
5232 	return param->set(devlink, param->id, ctx);
5233 }
5234 
5235 static int
devlink_param_type_to_nla_type(enum devlink_param_type param_type)5236 devlink_param_type_to_nla_type(enum devlink_param_type param_type)
5237 {
5238 	switch (param_type) {
5239 	case DEVLINK_PARAM_TYPE_U8:
5240 		return NLA_U8;
5241 	case DEVLINK_PARAM_TYPE_U16:
5242 		return NLA_U16;
5243 	case DEVLINK_PARAM_TYPE_U32:
5244 		return NLA_U32;
5245 	case DEVLINK_PARAM_TYPE_STRING:
5246 		return NLA_STRING;
5247 	case DEVLINK_PARAM_TYPE_BOOL:
5248 		return NLA_FLAG;
5249 	default:
5250 		return -EINVAL;
5251 	}
5252 }
5253 
5254 static int
devlink_nl_param_value_fill_one(struct sk_buff * msg,enum devlink_param_type type,enum devlink_param_cmode cmode,union devlink_param_value val)5255 devlink_nl_param_value_fill_one(struct sk_buff *msg,
5256 				enum devlink_param_type type,
5257 				enum devlink_param_cmode cmode,
5258 				union devlink_param_value val)
5259 {
5260 	struct nlattr *param_value_attr;
5261 
5262 	param_value_attr = nla_nest_start_noflag(msg,
5263 						 DEVLINK_ATTR_PARAM_VALUE);
5264 	if (!param_value_attr)
5265 		goto nla_put_failure;
5266 
5267 	if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode))
5268 		goto value_nest_cancel;
5269 
5270 	switch (type) {
5271 	case DEVLINK_PARAM_TYPE_U8:
5272 		if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu8))
5273 			goto value_nest_cancel;
5274 		break;
5275 	case DEVLINK_PARAM_TYPE_U16:
5276 		if (nla_put_u16(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu16))
5277 			goto value_nest_cancel;
5278 		break;
5279 	case DEVLINK_PARAM_TYPE_U32:
5280 		if (nla_put_u32(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu32))
5281 			goto value_nest_cancel;
5282 		break;
5283 	case DEVLINK_PARAM_TYPE_STRING:
5284 		if (nla_put_string(msg, DEVLINK_ATTR_PARAM_VALUE_DATA,
5285 				   val.vstr))
5286 			goto value_nest_cancel;
5287 		break;
5288 	case DEVLINK_PARAM_TYPE_BOOL:
5289 		if (val.vbool &&
5290 		    nla_put_flag(msg, DEVLINK_ATTR_PARAM_VALUE_DATA))
5291 			goto value_nest_cancel;
5292 		break;
5293 	}
5294 
5295 	nla_nest_end(msg, param_value_attr);
5296 	return 0;
5297 
5298 value_nest_cancel:
5299 	nla_nest_cancel(msg, param_value_attr);
5300 nla_put_failure:
5301 	return -EMSGSIZE;
5302 }
5303 
devlink_nl_param_fill(struct sk_buff * msg,struct devlink * devlink,unsigned int port_index,struct devlink_param_item * param_item,enum devlink_command cmd,u32 portid,u32 seq,int flags)5304 static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
5305 				 unsigned int port_index,
5306 				 struct devlink_param_item *param_item,
5307 				 enum devlink_command cmd,
5308 				 u32 portid, u32 seq, int flags)
5309 {
5310 	union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1];
5311 	bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {};
5312 	const struct devlink_param *param = param_item->param;
5313 	struct devlink_param_gset_ctx ctx;
5314 	struct nlattr *param_values_list;
5315 	struct nlattr *param_attr;
5316 	int nla_type;
5317 	void *hdr;
5318 	int err;
5319 	int i;
5320 
5321 	/* Get value from driver part to driverinit configuration mode */
5322 	for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
5323 		if (!devlink_param_cmode_is_supported(param, i))
5324 			continue;
5325 		if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) {
5326 			if (!param_item->driverinit_value_valid)
5327 				return -EOPNOTSUPP;
5328 			param_value[i] = param_item->driverinit_value;
5329 		} else {
5330 			ctx.cmode = i;
5331 			err = devlink_param_get(devlink, param, &ctx);
5332 			if (err)
5333 				return err;
5334 			param_value[i] = ctx.val;
5335 		}
5336 		param_value_set[i] = true;
5337 	}
5338 
5339 	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
5340 	if (!hdr)
5341 		return -EMSGSIZE;
5342 
5343 	if (devlink_nl_put_handle(msg, devlink))
5344 		goto genlmsg_cancel;
5345 
5346 	if (cmd == DEVLINK_CMD_PORT_PARAM_GET ||
5347 	    cmd == DEVLINK_CMD_PORT_PARAM_NEW ||
5348 	    cmd == DEVLINK_CMD_PORT_PARAM_DEL)
5349 		if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index))
5350 			goto genlmsg_cancel;
5351 
5352 	param_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PARAM);
5353 	if (!param_attr)
5354 		goto genlmsg_cancel;
5355 	if (nla_put_string(msg, DEVLINK_ATTR_PARAM_NAME, param->name))
5356 		goto param_nest_cancel;
5357 	if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC))
5358 		goto param_nest_cancel;
5359 
5360 	nla_type = devlink_param_type_to_nla_type(param->type);
5361 	if (nla_type < 0)
5362 		goto param_nest_cancel;
5363 	if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, nla_type))
5364 		goto param_nest_cancel;
5365 
5366 	param_values_list = nla_nest_start_noflag(msg,
5367 						  DEVLINK_ATTR_PARAM_VALUES_LIST);
5368 	if (!param_values_list)
5369 		goto param_nest_cancel;
5370 
5371 	for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
5372 		if (!param_value_set[i])
5373 			continue;
5374 		err = devlink_nl_param_value_fill_one(msg, param->type,
5375 						      i, param_value[i]);
5376 		if (err)
5377 			goto values_list_nest_cancel;
5378 	}
5379 
5380 	nla_nest_end(msg, param_values_list);
5381 	nla_nest_end(msg, param_attr);
5382 	genlmsg_end(msg, hdr);
5383 	return 0;
5384 
5385 values_list_nest_cancel:
5386 	nla_nest_end(msg, param_values_list);
5387 param_nest_cancel:
5388 	nla_nest_cancel(msg, param_attr);
5389 genlmsg_cancel:
5390 	genlmsg_cancel(msg, hdr);
5391 	return -EMSGSIZE;
5392 }
5393 
devlink_param_notify(struct devlink * devlink,unsigned int port_index,struct devlink_param_item * param_item,enum devlink_command cmd)5394 static void devlink_param_notify(struct devlink *devlink,
5395 				 unsigned int port_index,
5396 				 struct devlink_param_item *param_item,
5397 				 enum devlink_command cmd)
5398 {
5399 	struct sk_buff *msg;
5400 	int err;
5401 
5402 	WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL &&
5403 		cmd != DEVLINK_CMD_PORT_PARAM_NEW &&
5404 		cmd != DEVLINK_CMD_PORT_PARAM_DEL);
5405 	ASSERT_DEVLINK_REGISTERED(devlink);
5406 
5407 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5408 	if (!msg)
5409 		return;
5410 	err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd,
5411 				    0, 0, 0);
5412 	if (err) {
5413 		nlmsg_free(msg);
5414 		return;
5415 	}
5416 
5417 	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
5418 				msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
5419 }
5420 
devlink_nl_cmd_param_get_dumpit(struct sk_buff * msg,struct netlink_callback * cb)5421 static int devlink_nl_cmd_param_get_dumpit(struct sk_buff *msg,
5422 					   struct netlink_callback *cb)
5423 {
5424 	struct devlink_param_item *param_item;
5425 	struct devlink *devlink;
5426 	int start = cb->args[0];
5427 	unsigned long index;
5428 	int idx = 0;
5429 	int err = 0;
5430 
5431 	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
5432 		devl_lock(devlink);
5433 		list_for_each_entry(param_item, &devlink->param_list, list) {
5434 			if (idx < start) {
5435 				idx++;
5436 				continue;
5437 			}
5438 			err = devlink_nl_param_fill(msg, devlink, 0, param_item,
5439 						    DEVLINK_CMD_PARAM_GET,
5440 						    NETLINK_CB(cb->skb).portid,
5441 						    cb->nlh->nlmsg_seq,
5442 						    NLM_F_MULTI);
5443 			if (err == -EOPNOTSUPP) {
5444 				err = 0;
5445 			} else if (err) {
5446 				devl_unlock(devlink);
5447 				devlink_put(devlink);
5448 				goto out;
5449 			}
5450 			idx++;
5451 		}
5452 		devl_unlock(devlink);
5453 		devlink_put(devlink);
5454 	}
5455 out:
5456 	if (err != -EMSGSIZE)
5457 		return err;
5458 
5459 	cb->args[0] = idx;
5460 	return msg->len;
5461 }
5462 
5463 static int
devlink_param_type_get_from_info(struct genl_info * info,enum devlink_param_type * param_type)5464 devlink_param_type_get_from_info(struct genl_info *info,
5465 				 enum devlink_param_type *param_type)
5466 {
5467 	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_TYPE))
5468 		return -EINVAL;
5469 
5470 	switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) {
5471 	case NLA_U8:
5472 		*param_type = DEVLINK_PARAM_TYPE_U8;
5473 		break;
5474 	case NLA_U16:
5475 		*param_type = DEVLINK_PARAM_TYPE_U16;
5476 		break;
5477 	case NLA_U32:
5478 		*param_type = DEVLINK_PARAM_TYPE_U32;
5479 		break;
5480 	case NLA_STRING:
5481 		*param_type = DEVLINK_PARAM_TYPE_STRING;
5482 		break;
5483 	case NLA_FLAG:
5484 		*param_type = DEVLINK_PARAM_TYPE_BOOL;
5485 		break;
5486 	default:
5487 		return -EINVAL;
5488 	}
5489 
5490 	return 0;
5491 }
5492 
5493 static int
devlink_param_value_get_from_info(const struct devlink_param * param,struct genl_info * info,union devlink_param_value * value)5494 devlink_param_value_get_from_info(const struct devlink_param *param,
5495 				  struct genl_info *info,
5496 				  union devlink_param_value *value)
5497 {
5498 	struct nlattr *param_data;
5499 	int len;
5500 
5501 	param_data = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA];
5502 
5503 	if (param->type != DEVLINK_PARAM_TYPE_BOOL && !param_data)
5504 		return -EINVAL;
5505 
5506 	switch (param->type) {
5507 	case DEVLINK_PARAM_TYPE_U8:
5508 		if (nla_len(param_data) != sizeof(u8))
5509 			return -EINVAL;
5510 		value->vu8 = nla_get_u8(param_data);
5511 		break;
5512 	case DEVLINK_PARAM_TYPE_U16:
5513 		if (nla_len(param_data) != sizeof(u16))
5514 			return -EINVAL;
5515 		value->vu16 = nla_get_u16(param_data);
5516 		break;
5517 	case DEVLINK_PARAM_TYPE_U32:
5518 		if (nla_len(param_data) != sizeof(u32))
5519 			return -EINVAL;
5520 		value->vu32 = nla_get_u32(param_data);
5521 		break;
5522 	case DEVLINK_PARAM_TYPE_STRING:
5523 		len = strnlen(nla_data(param_data), nla_len(param_data));
5524 		if (len == nla_len(param_data) ||
5525 		    len >= __DEVLINK_PARAM_MAX_STRING_VALUE)
5526 			return -EINVAL;
5527 		strcpy(value->vstr, nla_data(param_data));
5528 		break;
5529 	case DEVLINK_PARAM_TYPE_BOOL:
5530 		if (param_data && nla_len(param_data))
5531 			return -EINVAL;
5532 		value->vbool = nla_get_flag(param_data);
5533 		break;
5534 	}
5535 	return 0;
5536 }
5537 
5538 static struct devlink_param_item *
devlink_param_get_from_info(struct list_head * param_list,struct genl_info * info)5539 devlink_param_get_from_info(struct list_head *param_list,
5540 			    struct genl_info *info)
5541 {
5542 	char *param_name;
5543 
5544 	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_NAME))
5545 		return NULL;
5546 
5547 	param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]);
5548 	return devlink_param_find_by_name(param_list, param_name);
5549 }
5550 
devlink_nl_cmd_param_get_doit(struct sk_buff * skb,struct genl_info * info)5551 static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb,
5552 					 struct genl_info *info)
5553 {
5554 	struct devlink *devlink = info->user_ptr[0];
5555 	struct devlink_param_item *param_item;
5556 	struct sk_buff *msg;
5557 	int err;
5558 
5559 	param_item = devlink_param_get_from_info(&devlink->param_list, info);
5560 	if (!param_item)
5561 		return -EINVAL;
5562 
5563 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5564 	if (!msg)
5565 		return -ENOMEM;
5566 
5567 	err = devlink_nl_param_fill(msg, devlink, 0, param_item,
5568 				    DEVLINK_CMD_PARAM_GET,
5569 				    info->snd_portid, info->snd_seq, 0);
5570 	if (err) {
5571 		nlmsg_free(msg);
5572 		return err;
5573 	}
5574 
5575 	return genlmsg_reply(msg, info);
5576 }
5577 
__devlink_nl_cmd_param_set_doit(struct devlink * devlink,unsigned int port_index,struct list_head * param_list,struct genl_info * info,enum devlink_command cmd)5578 static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink,
5579 					   unsigned int port_index,
5580 					   struct list_head *param_list,
5581 					   struct genl_info *info,
5582 					   enum devlink_command cmd)
5583 {
5584 	enum devlink_param_type param_type;
5585 	struct devlink_param_gset_ctx ctx;
5586 	enum devlink_param_cmode cmode;
5587 	struct devlink_param_item *param_item;
5588 	const struct devlink_param *param;
5589 	union devlink_param_value value;
5590 	int err = 0;
5591 
5592 	param_item = devlink_param_get_from_info(param_list, info);
5593 	if (!param_item)
5594 		return -EINVAL;
5595 	param = param_item->param;
5596 	err = devlink_param_type_get_from_info(info, &param_type);
5597 	if (err)
5598 		return err;
5599 	if (param_type != param->type)
5600 		return -EINVAL;
5601 	err = devlink_param_value_get_from_info(param, info, &value);
5602 	if (err)
5603 		return err;
5604 	if (param->validate) {
5605 		err = param->validate(devlink, param->id, value, info->extack);
5606 		if (err)
5607 			return err;
5608 	}
5609 
5610 	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_VALUE_CMODE))
5611 		return -EINVAL;
5612 	cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]);
5613 	if (!devlink_param_cmode_is_supported(param, cmode))
5614 		return -EOPNOTSUPP;
5615 
5616 	if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) {
5617 		if (param->type == DEVLINK_PARAM_TYPE_STRING)
5618 			strcpy(param_item->driverinit_value.vstr, value.vstr);
5619 		else
5620 			param_item->driverinit_value = value;
5621 		param_item->driverinit_value_valid = true;
5622 	} else {
5623 		if (!param->set)
5624 			return -EOPNOTSUPP;
5625 		ctx.val = value;
5626 		ctx.cmode = cmode;
5627 		err = devlink_param_set(devlink, param, &ctx);
5628 		if (err)
5629 			return err;
5630 	}
5631 
5632 	devlink_param_notify(devlink, port_index, param_item, cmd);
5633 	return 0;
5634 }
5635 
devlink_nl_cmd_param_set_doit(struct sk_buff * skb,struct genl_info * info)5636 static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb,
5637 					 struct genl_info *info)
5638 {
5639 	struct devlink *devlink = info->user_ptr[0];
5640 
5641 	return __devlink_nl_cmd_param_set_doit(devlink, 0, &devlink->param_list,
5642 					       info, DEVLINK_CMD_PARAM_NEW);
5643 }
5644 
devlink_nl_cmd_port_param_get_dumpit(struct sk_buff * msg,struct netlink_callback * cb)5645 static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg,
5646 						struct netlink_callback *cb)
5647 {
5648 	NL_SET_ERR_MSG_MOD(cb->extack, "Port params are not supported");
5649 	return msg->len;
5650 }
5651 
devlink_nl_cmd_port_param_get_doit(struct sk_buff * skb,struct genl_info * info)5652 static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb,
5653 					      struct genl_info *info)
5654 {
5655 	NL_SET_ERR_MSG_MOD(info->extack, "Port params are not supported");
5656 	return -EINVAL;
5657 }
5658 
devlink_nl_cmd_port_param_set_doit(struct sk_buff * skb,struct genl_info * info)5659 static int devlink_nl_cmd_port_param_set_doit(struct sk_buff *skb,
5660 					      struct genl_info *info)
5661 {
5662 	NL_SET_ERR_MSG_MOD(info->extack, "Port params are not supported");
5663 	return -EINVAL;
5664 }
5665 
devlink_nl_region_snapshot_id_put(struct sk_buff * msg,struct devlink * devlink,struct devlink_snapshot * snapshot)5666 static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg,
5667 					     struct devlink *devlink,
5668 					     struct devlink_snapshot *snapshot)
5669 {
5670 	struct nlattr *snap_attr;
5671 	int err;
5672 
5673 	snap_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_SNAPSHOT);
5674 	if (!snap_attr)
5675 		return -EINVAL;
5676 
5677 	err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, snapshot->id);
5678 	if (err)
5679 		goto nla_put_failure;
5680 
5681 	nla_nest_end(msg, snap_attr);
5682 	return 0;
5683 
5684 nla_put_failure:
5685 	nla_nest_cancel(msg, snap_attr);
5686 	return err;
5687 }
5688 
devlink_nl_region_snapshots_id_put(struct sk_buff * msg,struct devlink * devlink,struct devlink_region * region)5689 static int devlink_nl_region_snapshots_id_put(struct sk_buff *msg,
5690 					      struct devlink *devlink,
5691 					      struct devlink_region *region)
5692 {
5693 	struct devlink_snapshot *snapshot;
5694 	struct nlattr *snapshots_attr;
5695 	int err;
5696 
5697 	snapshots_attr = nla_nest_start_noflag(msg,
5698 					       DEVLINK_ATTR_REGION_SNAPSHOTS);
5699 	if (!snapshots_attr)
5700 		return -EINVAL;
5701 
5702 	list_for_each_entry(snapshot, &region->snapshot_list, list) {
5703 		err = devlink_nl_region_snapshot_id_put(msg, devlink, snapshot);
5704 		if (err)
5705 			goto nla_put_failure;
5706 	}
5707 
5708 	nla_nest_end(msg, snapshots_attr);
5709 	return 0;
5710 
5711 nla_put_failure:
5712 	nla_nest_cancel(msg, snapshots_attr);
5713 	return err;
5714 }
5715 
devlink_nl_region_fill(struct sk_buff * msg,struct devlink * devlink,enum devlink_command cmd,u32 portid,u32 seq,int flags,struct devlink_region * region)5716 static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink,
5717 				  enum devlink_command cmd, u32 portid,
5718 				  u32 seq, int flags,
5719 				  struct devlink_region *region)
5720 {
5721 	void *hdr;
5722 	int err;
5723 
5724 	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
5725 	if (!hdr)
5726 		return -EMSGSIZE;
5727 
5728 	err = devlink_nl_put_handle(msg, devlink);
5729 	if (err)
5730 		goto nla_put_failure;
5731 
5732 	if (region->port) {
5733 		err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
5734 				  region->port->index);
5735 		if (err)
5736 			goto nla_put_failure;
5737 	}
5738 
5739 	err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->ops->name);
5740 	if (err)
5741 		goto nla_put_failure;
5742 
5743 	err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
5744 				region->size,
5745 				DEVLINK_ATTR_PAD);
5746 	if (err)
5747 		goto nla_put_failure;
5748 
5749 	err = nla_put_u32(msg, DEVLINK_ATTR_REGION_MAX_SNAPSHOTS,
5750 			  region->max_snapshots);
5751 	if (err)
5752 		goto nla_put_failure;
5753 
5754 	err = devlink_nl_region_snapshots_id_put(msg, devlink, region);
5755 	if (err)
5756 		goto nla_put_failure;
5757 
5758 	genlmsg_end(msg, hdr);
5759 	return 0;
5760 
5761 nla_put_failure:
5762 	genlmsg_cancel(msg, hdr);
5763 	return err;
5764 }
5765 
5766 static struct sk_buff *
devlink_nl_region_notify_build(struct devlink_region * region,struct devlink_snapshot * snapshot,enum devlink_command cmd,u32 portid,u32 seq)5767 devlink_nl_region_notify_build(struct devlink_region *region,
5768 			       struct devlink_snapshot *snapshot,
5769 			       enum devlink_command cmd, u32 portid, u32 seq)
5770 {
5771 	struct devlink *devlink = region->devlink;
5772 	struct sk_buff *msg;
5773 	void *hdr;
5774 	int err;
5775 
5776 
5777 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5778 	if (!msg)
5779 		return ERR_PTR(-ENOMEM);
5780 
5781 	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, 0, cmd);
5782 	if (!hdr) {
5783 		err = -EMSGSIZE;
5784 		goto out_free_msg;
5785 	}
5786 
5787 	err = devlink_nl_put_handle(msg, devlink);
5788 	if (err)
5789 		goto out_cancel_msg;
5790 
5791 	if (region->port) {
5792 		err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
5793 				  region->port->index);
5794 		if (err)
5795 			goto out_cancel_msg;
5796 	}
5797 
5798 	err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME,
5799 			     region->ops->name);
5800 	if (err)
5801 		goto out_cancel_msg;
5802 
5803 	if (snapshot) {
5804 		err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID,
5805 				  snapshot->id);
5806 		if (err)
5807 			goto out_cancel_msg;
5808 	} else {
5809 		err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
5810 					region->size, DEVLINK_ATTR_PAD);
5811 		if (err)
5812 			goto out_cancel_msg;
5813 	}
5814 	genlmsg_end(msg, hdr);
5815 
5816 	return msg;
5817 
5818 out_cancel_msg:
5819 	genlmsg_cancel(msg, hdr);
5820 out_free_msg:
5821 	nlmsg_free(msg);
5822 	return ERR_PTR(err);
5823 }
5824 
devlink_nl_region_notify(struct devlink_region * region,struct devlink_snapshot * snapshot,enum devlink_command cmd)5825 static void devlink_nl_region_notify(struct devlink_region *region,
5826 				     struct devlink_snapshot *snapshot,
5827 				     enum devlink_command cmd)
5828 {
5829 	struct devlink *devlink = region->devlink;
5830 	struct sk_buff *msg;
5831 
5832 	WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL);
5833 	if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
5834 		return;
5835 
5836 	msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0);
5837 	if (IS_ERR(msg))
5838 		return;
5839 
5840 	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
5841 				0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
5842 }
5843 
5844 /**
5845  * __devlink_snapshot_id_increment - Increment number of snapshots using an id
5846  *	@devlink: devlink instance
5847  *	@id: the snapshot id
5848  *
5849  *	Track when a new snapshot begins using an id. Load the count for the
5850  *	given id from the snapshot xarray, increment it, and store it back.
5851  *
5852  *	Called when a new snapshot is created with the given id.
5853  *
5854  *	The id *must* have been previously allocated by
5855  *	devlink_region_snapshot_id_get().
5856  *
5857  *	Returns 0 on success, or an error on failure.
5858  */
__devlink_snapshot_id_increment(struct devlink * devlink,u32 id)5859 static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id)
5860 {
5861 	unsigned long count;
5862 	void *p;
5863 	int err;
5864 
5865 	xa_lock(&devlink->snapshot_ids);
5866 	p = xa_load(&devlink->snapshot_ids, id);
5867 	if (WARN_ON(!p)) {
5868 		err = -EINVAL;
5869 		goto unlock;
5870 	}
5871 
5872 	if (WARN_ON(!xa_is_value(p))) {
5873 		err = -EINVAL;
5874 		goto unlock;
5875 	}
5876 
5877 	count = xa_to_value(p);
5878 	count++;
5879 
5880 	err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
5881 				GFP_ATOMIC));
5882 unlock:
5883 	xa_unlock(&devlink->snapshot_ids);
5884 	return err;
5885 }
5886 
5887 /**
5888  * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id
5889  *	@devlink: devlink instance
5890  *	@id: the snapshot id
5891  *
5892  *	Track when a snapshot is deleted and stops using an id. Load the count
5893  *	for the given id from the snapshot xarray, decrement it, and store it
5894  *	back.
5895  *
5896  *	If the count reaches zero, erase this id from the xarray, freeing it
5897  *	up for future re-use by devlink_region_snapshot_id_get().
5898  *
5899  *	Called when a snapshot using the given id is deleted, and when the
5900  *	initial allocator of the id is finished using it.
5901  */
__devlink_snapshot_id_decrement(struct devlink * devlink,u32 id)5902 static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id)
5903 {
5904 	unsigned long count;
5905 	void *p;
5906 
5907 	xa_lock(&devlink->snapshot_ids);
5908 	p = xa_load(&devlink->snapshot_ids, id);
5909 	if (WARN_ON(!p))
5910 		goto unlock;
5911 
5912 	if (WARN_ON(!xa_is_value(p)))
5913 		goto unlock;
5914 
5915 	count = xa_to_value(p);
5916 
5917 	if (count > 1) {
5918 		count--;
5919 		__xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
5920 			   GFP_ATOMIC);
5921 	} else {
5922 		/* If this was the last user, we can erase this id */
5923 		__xa_erase(&devlink->snapshot_ids, id);
5924 	}
5925 unlock:
5926 	xa_unlock(&devlink->snapshot_ids);
5927 }
5928 
5929 /**
5930  *	__devlink_snapshot_id_insert - Insert a specific snapshot ID
5931  *	@devlink: devlink instance
5932  *	@id: the snapshot id
5933  *
5934  *	Mark the given snapshot id as used by inserting a zero value into the
5935  *	snapshot xarray.
5936  *
5937  *	This must be called while holding the devlink instance lock. Unlike
5938  *	devlink_snapshot_id_get, the initial reference count is zero, not one.
5939  *	It is expected that the id will immediately be used before
5940  *	releasing the devlink instance lock.
5941  *
5942  *	Returns zero on success, or an error code if the snapshot id could not
5943  *	be inserted.
5944  */
__devlink_snapshot_id_insert(struct devlink * devlink,u32 id)5945 static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id)
5946 {
5947 	int err;
5948 
5949 	xa_lock(&devlink->snapshot_ids);
5950 	if (xa_load(&devlink->snapshot_ids, id)) {
5951 		xa_unlock(&devlink->snapshot_ids);
5952 		return -EEXIST;
5953 	}
5954 	err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(0),
5955 				GFP_ATOMIC));
5956 	xa_unlock(&devlink->snapshot_ids);
5957 	return err;
5958 }
5959 
5960 /**
5961  *	__devlink_region_snapshot_id_get - get snapshot ID
5962  *	@devlink: devlink instance
5963  *	@id: storage to return snapshot id
5964  *
5965  *	Allocates a new snapshot id. Returns zero on success, or a negative
5966  *	error on failure. Must be called while holding the devlink instance
5967  *	lock.
5968  *
5969  *	Snapshot IDs are tracked using an xarray which stores the number of
5970  *	users of the snapshot id.
5971  *
5972  *	Note that the caller of this function counts as a 'user', in order to
5973  *	avoid race conditions. The caller must release its hold on the
5974  *	snapshot by using devlink_region_snapshot_id_put.
5975  */
__devlink_region_snapshot_id_get(struct devlink * devlink,u32 * id)5976 static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
5977 {
5978 	return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1),
5979 			xa_limit_32b, GFP_KERNEL);
5980 }
5981 
5982 /**
5983  *	__devlink_region_snapshot_create - create a new snapshot
5984  *	This will add a new snapshot of a region. The snapshot
5985  *	will be stored on the region struct and can be accessed
5986  *	from devlink. This is useful for future analyses of snapshots.
5987  *	Multiple snapshots can be created on a region.
5988  *	The @snapshot_id should be obtained using the getter function.
5989  *
5990  *	Must be called only while holding the region snapshot lock.
5991  *
5992  *	@region: devlink region of the snapshot
5993  *	@data: snapshot data
5994  *	@snapshot_id: snapshot id to be created
5995  */
5996 static int
__devlink_region_snapshot_create(struct devlink_region * region,u8 * data,u32 snapshot_id)5997 __devlink_region_snapshot_create(struct devlink_region *region,
5998 				 u8 *data, u32 snapshot_id)
5999 {
6000 	struct devlink *devlink = region->devlink;
6001 	struct devlink_snapshot *snapshot;
6002 	int err;
6003 
6004 	lockdep_assert_held(&region->snapshot_lock);
6005 
6006 	/* check if region can hold one more snapshot */
6007 	if (region->cur_snapshots == region->max_snapshots)
6008 		return -ENOSPC;
6009 
6010 	if (devlink_region_snapshot_get_by_id(region, snapshot_id))
6011 		return -EEXIST;
6012 
6013 	snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL);
6014 	if (!snapshot)
6015 		return -ENOMEM;
6016 
6017 	err = __devlink_snapshot_id_increment(devlink, snapshot_id);
6018 	if (err)
6019 		goto err_snapshot_id_increment;
6020 
6021 	snapshot->id = snapshot_id;
6022 	snapshot->region = region;
6023 	snapshot->data = data;
6024 
6025 	list_add_tail(&snapshot->list, &region->snapshot_list);
6026 
6027 	region->cur_snapshots++;
6028 
6029 	devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW);
6030 	return 0;
6031 
6032 err_snapshot_id_increment:
6033 	kfree(snapshot);
6034 	return err;
6035 }
6036 
devlink_region_snapshot_del(struct devlink_region * region,struct devlink_snapshot * snapshot)6037 static void devlink_region_snapshot_del(struct devlink_region *region,
6038 					struct devlink_snapshot *snapshot)
6039 {
6040 	struct devlink *devlink = region->devlink;
6041 
6042 	lockdep_assert_held(&region->snapshot_lock);
6043 
6044 	devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL);
6045 	region->cur_snapshots--;
6046 	list_del(&snapshot->list);
6047 	region->ops->destructor(snapshot->data);
6048 	__devlink_snapshot_id_decrement(devlink, snapshot->id);
6049 	kfree(snapshot);
6050 }
6051 
devlink_nl_cmd_region_get_doit(struct sk_buff * skb,struct genl_info * info)6052 static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb,
6053 					  struct genl_info *info)
6054 {
6055 	struct devlink *devlink = info->user_ptr[0];
6056 	struct devlink_port *port = NULL;
6057 	struct devlink_region *region;
6058 	const char *region_name;
6059 	struct sk_buff *msg;
6060 	unsigned int index;
6061 	int err;
6062 
6063 	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME))
6064 		return -EINVAL;
6065 
6066 	if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
6067 		index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
6068 
6069 		port = devlink_port_get_by_index(devlink, index);
6070 		if (!port)
6071 			return -ENODEV;
6072 	}
6073 
6074 	region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
6075 	if (port)
6076 		region = devlink_port_region_get_by_name(port, region_name);
6077 	else
6078 		region = devlink_region_get_by_name(devlink, region_name);
6079 
6080 	if (!region)
6081 		return -EINVAL;
6082 
6083 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6084 	if (!msg)
6085 		return -ENOMEM;
6086 
6087 	err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET,
6088 				     info->snd_portid, info->snd_seq, 0,
6089 				     region);
6090 	if (err) {
6091 		nlmsg_free(msg);
6092 		return err;
6093 	}
6094 
6095 	return genlmsg_reply(msg, info);
6096 }
6097 
devlink_nl_cmd_region_get_port_dumpit(struct sk_buff * msg,struct netlink_callback * cb,struct devlink_port * port,int * idx,int start)6098 static int devlink_nl_cmd_region_get_port_dumpit(struct sk_buff *msg,
6099 						 struct netlink_callback *cb,
6100 						 struct devlink_port *port,
6101 						 int *idx,
6102 						 int start)
6103 {
6104 	struct devlink_region *region;
6105 	int err = 0;
6106 
6107 	list_for_each_entry(region, &port->region_list, list) {
6108 		if (*idx < start) {
6109 			(*idx)++;
6110 			continue;
6111 		}
6112 		err = devlink_nl_region_fill(msg, port->devlink,
6113 					     DEVLINK_CMD_REGION_GET,
6114 					     NETLINK_CB(cb->skb).portid,
6115 					     cb->nlh->nlmsg_seq,
6116 					     NLM_F_MULTI, region);
6117 		if (err)
6118 			goto out;
6119 		(*idx)++;
6120 	}
6121 
6122 out:
6123 	return err;
6124 }
6125 
devlink_nl_cmd_region_get_devlink_dumpit(struct sk_buff * msg,struct netlink_callback * cb,struct devlink * devlink,int * idx,int start)6126 static int devlink_nl_cmd_region_get_devlink_dumpit(struct sk_buff *msg,
6127 						    struct netlink_callback *cb,
6128 						    struct devlink *devlink,
6129 						    int *idx,
6130 						    int start)
6131 {
6132 	struct devlink_region *region;
6133 	struct devlink_port *port;
6134 	int err = 0;
6135 
6136 	devl_lock(devlink);
6137 	list_for_each_entry(region, &devlink->region_list, list) {
6138 		if (*idx < start) {
6139 			(*idx)++;
6140 			continue;
6141 		}
6142 		err = devlink_nl_region_fill(msg, devlink,
6143 					     DEVLINK_CMD_REGION_GET,
6144 					     NETLINK_CB(cb->skb).portid,
6145 					     cb->nlh->nlmsg_seq,
6146 					     NLM_F_MULTI, region);
6147 		if (err)
6148 			goto out;
6149 		(*idx)++;
6150 	}
6151 
6152 	list_for_each_entry(port, &devlink->port_list, list) {
6153 		err = devlink_nl_cmd_region_get_port_dumpit(msg, cb, port, idx,
6154 							    start);
6155 		if (err)
6156 			goto out;
6157 	}
6158 
6159 out:
6160 	devl_unlock(devlink);
6161 	return err;
6162 }
6163 
devlink_nl_cmd_region_get_dumpit(struct sk_buff * msg,struct netlink_callback * cb)6164 static int devlink_nl_cmd_region_get_dumpit(struct sk_buff *msg,
6165 					    struct netlink_callback *cb)
6166 {
6167 	struct devlink *devlink;
6168 	int start = cb->args[0];
6169 	unsigned long index;
6170 	int idx = 0;
6171 	int err = 0;
6172 
6173 	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
6174 		err = devlink_nl_cmd_region_get_devlink_dumpit(msg, cb, devlink,
6175 							       &idx, start);
6176 		devlink_put(devlink);
6177 		if (err)
6178 			goto out;
6179 	}
6180 out:
6181 	cb->args[0] = idx;
6182 	return msg->len;
6183 }
6184 
devlink_nl_cmd_region_del(struct sk_buff * skb,struct genl_info * info)6185 static int devlink_nl_cmd_region_del(struct sk_buff *skb,
6186 				     struct genl_info *info)
6187 {
6188 	struct devlink *devlink = info->user_ptr[0];
6189 	struct devlink_snapshot *snapshot;
6190 	struct devlink_port *port = NULL;
6191 	struct devlink_region *region;
6192 	const char *region_name;
6193 	unsigned int index;
6194 	u32 snapshot_id;
6195 
6196 	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME) ||
6197 	    GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_SNAPSHOT_ID))
6198 		return -EINVAL;
6199 
6200 	region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
6201 	snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
6202 
6203 	if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
6204 		index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
6205 
6206 		port = devlink_port_get_by_index(devlink, index);
6207 		if (!port)
6208 			return -ENODEV;
6209 	}
6210 
6211 	if (port)
6212 		region = devlink_port_region_get_by_name(port, region_name);
6213 	else
6214 		region = devlink_region_get_by_name(devlink, region_name);
6215 
6216 	if (!region)
6217 		return -EINVAL;
6218 
6219 	mutex_lock(&region->snapshot_lock);
6220 	snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
6221 	if (!snapshot) {
6222 		mutex_unlock(&region->snapshot_lock);
6223 		return -EINVAL;
6224 	}
6225 
6226 	devlink_region_snapshot_del(region, snapshot);
6227 	mutex_unlock(&region->snapshot_lock);
6228 	return 0;
6229 }
6230 
6231 static int
devlink_nl_cmd_region_new(struct sk_buff * skb,struct genl_info * info)6232 devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
6233 {
6234 	struct devlink *devlink = info->user_ptr[0];
6235 	struct devlink_snapshot *snapshot;
6236 	struct devlink_port *port = NULL;
6237 	struct nlattr *snapshot_id_attr;
6238 	struct devlink_region *region;
6239 	const char *region_name;
6240 	unsigned int index;
6241 	u32 snapshot_id;
6242 	u8 *data;
6243 	int err;
6244 
6245 	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME)) {
6246 		NL_SET_ERR_MSG_MOD(info->extack, "No region name provided");
6247 		return -EINVAL;
6248 	}
6249 
6250 	region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
6251 
6252 	if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
6253 		index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
6254 
6255 		port = devlink_port_get_by_index(devlink, index);
6256 		if (!port)
6257 			return -ENODEV;
6258 	}
6259 
6260 	if (port)
6261 		region = devlink_port_region_get_by_name(port, region_name);
6262 	else
6263 		region = devlink_region_get_by_name(devlink, region_name);
6264 
6265 	if (!region) {
6266 		NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not exist");
6267 		return -EINVAL;
6268 	}
6269 
6270 	if (!region->ops->snapshot) {
6271 		NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not support taking an immediate snapshot");
6272 		return -EOPNOTSUPP;
6273 	}
6274 
6275 	mutex_lock(&region->snapshot_lock);
6276 
6277 	if (region->cur_snapshots == region->max_snapshots) {
6278 		NL_SET_ERR_MSG_MOD(info->extack, "The region has reached the maximum number of stored snapshots");
6279 		err = -ENOSPC;
6280 		goto unlock;
6281 	}
6282 
6283 	snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID];
6284 	if (snapshot_id_attr) {
6285 		snapshot_id = nla_get_u32(snapshot_id_attr);
6286 
6287 		if (devlink_region_snapshot_get_by_id(region, snapshot_id)) {
6288 			NL_SET_ERR_MSG_MOD(info->extack, "The requested snapshot id is already in use");
6289 			err = -EEXIST;
6290 			goto unlock;
6291 		}
6292 
6293 		err = __devlink_snapshot_id_insert(devlink, snapshot_id);
6294 		if (err)
6295 			goto unlock;
6296 	} else {
6297 		err = __devlink_region_snapshot_id_get(devlink, &snapshot_id);
6298 		if (err) {
6299 			NL_SET_ERR_MSG_MOD(info->extack, "Failed to allocate a new snapshot id");
6300 			goto unlock;
6301 		}
6302 	}
6303 
6304 	if (port)
6305 		err = region->port_ops->snapshot(port, region->port_ops,
6306 						 info->extack, &data);
6307 	else
6308 		err = region->ops->snapshot(devlink, region->ops,
6309 					    info->extack, &data);
6310 	if (err)
6311 		goto err_snapshot_capture;
6312 
6313 	err = __devlink_region_snapshot_create(region, data, snapshot_id);
6314 	if (err)
6315 		goto err_snapshot_create;
6316 
6317 	if (!snapshot_id_attr) {
6318 		struct sk_buff *msg;
6319 
6320 		snapshot = devlink_region_snapshot_get_by_id(region,
6321 							     snapshot_id);
6322 		if (WARN_ON(!snapshot)) {
6323 			err = -EINVAL;
6324 			goto unlock;
6325 		}
6326 
6327 		msg = devlink_nl_region_notify_build(region, snapshot,
6328 						     DEVLINK_CMD_REGION_NEW,
6329 						     info->snd_portid,
6330 						     info->snd_seq);
6331 		err = PTR_ERR_OR_ZERO(msg);
6332 		if (err)
6333 			goto err_notify;
6334 
6335 		err = genlmsg_reply(msg, info);
6336 		if (err)
6337 			goto err_notify;
6338 	}
6339 
6340 	mutex_unlock(&region->snapshot_lock);
6341 	return 0;
6342 
6343 err_snapshot_create:
6344 	region->ops->destructor(data);
6345 err_snapshot_capture:
6346 	__devlink_snapshot_id_decrement(devlink, snapshot_id);
6347 	mutex_unlock(&region->snapshot_lock);
6348 	return err;
6349 
6350 err_notify:
6351 	devlink_region_snapshot_del(region, snapshot);
6352 unlock:
6353 	mutex_unlock(&region->snapshot_lock);
6354 	return err;
6355 }
6356 
devlink_nl_cmd_region_read_chunk_fill(struct sk_buff * msg,struct devlink * devlink,u8 * chunk,u32 chunk_size,u64 addr)6357 static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg,
6358 						 struct devlink *devlink,
6359 						 u8 *chunk, u32 chunk_size,
6360 						 u64 addr)
6361 {
6362 	struct nlattr *chunk_attr;
6363 	int err;
6364 
6365 	chunk_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_CHUNK);
6366 	if (!chunk_attr)
6367 		return -EINVAL;
6368 
6369 	err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk);
6370 	if (err)
6371 		goto nla_put_failure;
6372 
6373 	err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr,
6374 				DEVLINK_ATTR_PAD);
6375 	if (err)
6376 		goto nla_put_failure;
6377 
6378 	nla_nest_end(msg, chunk_attr);
6379 	return 0;
6380 
6381 nla_put_failure:
6382 	nla_nest_cancel(msg, chunk_attr);
6383 	return err;
6384 }
6385 
6386 #define DEVLINK_REGION_READ_CHUNK_SIZE 256
6387 
devlink_nl_region_read_snapshot_fill(struct sk_buff * skb,struct devlink * devlink,struct devlink_region * region,struct nlattr ** attrs,u64 start_offset,u64 end_offset,u64 * new_offset)6388 static int devlink_nl_region_read_snapshot_fill(struct sk_buff *skb,
6389 						struct devlink *devlink,
6390 						struct devlink_region *region,
6391 						struct nlattr **attrs,
6392 						u64 start_offset,
6393 						u64 end_offset,
6394 						u64 *new_offset)
6395 {
6396 	struct devlink_snapshot *snapshot;
6397 	u64 curr_offset = start_offset;
6398 	u32 snapshot_id;
6399 	int err = 0;
6400 
6401 	*new_offset = start_offset;
6402 
6403 	snapshot_id = nla_get_u32(attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
6404 	snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
6405 	if (!snapshot)
6406 		return -EINVAL;
6407 
6408 	while (curr_offset < end_offset) {
6409 		u32 data_size;
6410 		u8 *data;
6411 
6412 		if (end_offset - curr_offset < DEVLINK_REGION_READ_CHUNK_SIZE)
6413 			data_size = end_offset - curr_offset;
6414 		else
6415 			data_size = DEVLINK_REGION_READ_CHUNK_SIZE;
6416 
6417 		data = &snapshot->data[curr_offset];
6418 		err = devlink_nl_cmd_region_read_chunk_fill(skb, devlink,
6419 							    data, data_size,
6420 							    curr_offset);
6421 		if (err)
6422 			break;
6423 
6424 		curr_offset += data_size;
6425 	}
6426 	*new_offset = curr_offset;
6427 
6428 	return err;
6429 }
6430 
devlink_nl_cmd_region_read_dumpit(struct sk_buff * skb,struct netlink_callback * cb)6431 static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
6432 					     struct netlink_callback *cb)
6433 {
6434 	const struct genl_dumpit_info *info = genl_dumpit_info(cb);
6435 	u64 ret_offset, start_offset, end_offset = U64_MAX;
6436 	struct nlattr **attrs = info->attrs;
6437 	struct devlink_port *port = NULL;
6438 	struct devlink_region *region;
6439 	struct nlattr *chunks_attr;
6440 	const char *region_name;
6441 	struct devlink *devlink;
6442 	unsigned int index;
6443 	void *hdr;
6444 	int err;
6445 
6446 	start_offset = *((u64 *)&cb->args[0]);
6447 
6448 	devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs);
6449 	if (IS_ERR(devlink))
6450 		return PTR_ERR(devlink);
6451 
6452 	devl_lock(devlink);
6453 
6454 	if (!attrs[DEVLINK_ATTR_REGION_NAME] ||
6455 	    !attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]) {
6456 		err = -EINVAL;
6457 		goto out_unlock;
6458 	}
6459 
6460 	if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
6461 		index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
6462 
6463 		port = devlink_port_get_by_index(devlink, index);
6464 		if (!port) {
6465 			err = -ENODEV;
6466 			goto out_unlock;
6467 		}
6468 	}
6469 
6470 	region_name = nla_data(attrs[DEVLINK_ATTR_REGION_NAME]);
6471 
6472 	if (port)
6473 		region = devlink_port_region_get_by_name(port, region_name);
6474 	else
6475 		region = devlink_region_get_by_name(devlink, region_name);
6476 
6477 	if (!region) {
6478 		err = -EINVAL;
6479 		goto out_unlock;
6480 	}
6481 
6482 	if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] &&
6483 	    attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) {
6484 		if (!start_offset)
6485 			start_offset =
6486 				nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
6487 
6488 		end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
6489 		end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]);
6490 	}
6491 
6492 	if (end_offset > region->size)
6493 		end_offset = region->size;
6494 
6495 	/* return 0 if there is no further data to read */
6496 	if (start_offset == end_offset) {
6497 		err = 0;
6498 		goto out_unlock;
6499 	}
6500 
6501 	hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
6502 			  &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI,
6503 			  DEVLINK_CMD_REGION_READ);
6504 	if (!hdr) {
6505 		err = -EMSGSIZE;
6506 		goto out_unlock;
6507 	}
6508 
6509 	err = devlink_nl_put_handle(skb, devlink);
6510 	if (err)
6511 		goto nla_put_failure;
6512 
6513 	if (region->port) {
6514 		err = nla_put_u32(skb, DEVLINK_ATTR_PORT_INDEX,
6515 				  region->port->index);
6516 		if (err)
6517 			goto nla_put_failure;
6518 	}
6519 
6520 	err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name);
6521 	if (err)
6522 		goto nla_put_failure;
6523 
6524 	chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS);
6525 	if (!chunks_attr) {
6526 		err = -EMSGSIZE;
6527 		goto nla_put_failure;
6528 	}
6529 
6530 	err = devlink_nl_region_read_snapshot_fill(skb, devlink,
6531 						   region, attrs,
6532 						   start_offset,
6533 						   end_offset, &ret_offset);
6534 
6535 	if (err && err != -EMSGSIZE)
6536 		goto nla_put_failure;
6537 
6538 	/* Check if there was any progress done to prevent infinite loop */
6539 	if (ret_offset == start_offset) {
6540 		err = -EINVAL;
6541 		goto nla_put_failure;
6542 	}
6543 
6544 	*((u64 *)&cb->args[0]) = ret_offset;
6545 
6546 	nla_nest_end(skb, chunks_attr);
6547 	genlmsg_end(skb, hdr);
6548 	devl_unlock(devlink);
6549 	devlink_put(devlink);
6550 	return skb->len;
6551 
6552 nla_put_failure:
6553 	genlmsg_cancel(skb, hdr);
6554 out_unlock:
6555 	devl_unlock(devlink);
6556 	devlink_put(devlink);
6557 	return err;
6558 }
6559 
devlink_info_driver_name_put(struct devlink_info_req * req,const char * name)6560 int devlink_info_driver_name_put(struct devlink_info_req *req, const char *name)
6561 {
6562 	if (!req->msg)
6563 		return 0;
6564 	return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME, name);
6565 }
6566 EXPORT_SYMBOL_GPL(devlink_info_driver_name_put);
6567 
devlink_info_serial_number_put(struct devlink_info_req * req,const char * sn)6568 int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn)
6569 {
6570 	if (!req->msg)
6571 		return 0;
6572 	return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn);
6573 }
6574 EXPORT_SYMBOL_GPL(devlink_info_serial_number_put);
6575 
devlink_info_board_serial_number_put(struct devlink_info_req * req,const char * bsn)6576 int devlink_info_board_serial_number_put(struct devlink_info_req *req,
6577 					 const char *bsn)
6578 {
6579 	if (!req->msg)
6580 		return 0;
6581 	return nla_put_string(req->msg, DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER,
6582 			      bsn);
6583 }
6584 EXPORT_SYMBOL_GPL(devlink_info_board_serial_number_put);
6585 
devlink_info_version_put(struct devlink_info_req * req,int attr,const char * version_name,const char * version_value,enum devlink_info_version_type version_type)6586 static int devlink_info_version_put(struct devlink_info_req *req, int attr,
6587 				    const char *version_name,
6588 				    const char *version_value,
6589 				    enum devlink_info_version_type version_type)
6590 {
6591 	struct nlattr *nest;
6592 	int err;
6593 
6594 	if (req->version_cb)
6595 		req->version_cb(version_name, version_type,
6596 				req->version_cb_priv);
6597 
6598 	if (!req->msg)
6599 		return 0;
6600 
6601 	nest = nla_nest_start_noflag(req->msg, attr);
6602 	if (!nest)
6603 		return -EMSGSIZE;
6604 
6605 	err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME,
6606 			     version_name);
6607 	if (err)
6608 		goto nla_put_failure;
6609 
6610 	err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE,
6611 			     version_value);
6612 	if (err)
6613 		goto nla_put_failure;
6614 
6615 	nla_nest_end(req->msg, nest);
6616 
6617 	return 0;
6618 
6619 nla_put_failure:
6620 	nla_nest_cancel(req->msg, nest);
6621 	return err;
6622 }
6623 
devlink_info_version_fixed_put(struct devlink_info_req * req,const char * version_name,const char * version_value)6624 int devlink_info_version_fixed_put(struct devlink_info_req *req,
6625 				   const char *version_name,
6626 				   const char *version_value)
6627 {
6628 	return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED,
6629 					version_name, version_value,
6630 					DEVLINK_INFO_VERSION_TYPE_NONE);
6631 }
6632 EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put);
6633 
devlink_info_version_stored_put(struct devlink_info_req * req,const char * version_name,const char * version_value)6634 int devlink_info_version_stored_put(struct devlink_info_req *req,
6635 				    const char *version_name,
6636 				    const char *version_value)
6637 {
6638 	return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED,
6639 					version_name, version_value,
6640 					DEVLINK_INFO_VERSION_TYPE_NONE);
6641 }
6642 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put);
6643 
devlink_info_version_stored_put_ext(struct devlink_info_req * req,const char * version_name,const char * version_value,enum devlink_info_version_type version_type)6644 int devlink_info_version_stored_put_ext(struct devlink_info_req *req,
6645 					const char *version_name,
6646 					const char *version_value,
6647 					enum devlink_info_version_type version_type)
6648 {
6649 	return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED,
6650 					version_name, version_value,
6651 					version_type);
6652 }
6653 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put_ext);
6654 
devlink_info_version_running_put(struct devlink_info_req * req,const char * version_name,const char * version_value)6655 int devlink_info_version_running_put(struct devlink_info_req *req,
6656 				     const char *version_name,
6657 				     const char *version_value)
6658 {
6659 	return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING,
6660 					version_name, version_value,
6661 					DEVLINK_INFO_VERSION_TYPE_NONE);
6662 }
6663 EXPORT_SYMBOL_GPL(devlink_info_version_running_put);
6664 
devlink_info_version_running_put_ext(struct devlink_info_req * req,const char * version_name,const char * version_value,enum devlink_info_version_type version_type)6665 int devlink_info_version_running_put_ext(struct devlink_info_req *req,
6666 					 const char *version_name,
6667 					 const char *version_value,
6668 					 enum devlink_info_version_type version_type)
6669 {
6670 	return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING,
6671 					version_name, version_value,
6672 					version_type);
6673 }
6674 EXPORT_SYMBOL_GPL(devlink_info_version_running_put_ext);
6675 
6676 static int
devlink_nl_info_fill(struct sk_buff * msg,struct devlink * devlink,enum devlink_command cmd,u32 portid,u32 seq,int flags,struct netlink_ext_ack * extack)6677 devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
6678 		     enum devlink_command cmd, u32 portid,
6679 		     u32 seq, int flags, struct netlink_ext_ack *extack)
6680 {
6681 	struct devlink_info_req req = {};
6682 	void *hdr;
6683 	int err;
6684 
6685 	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
6686 	if (!hdr)
6687 		return -EMSGSIZE;
6688 
6689 	err = -EMSGSIZE;
6690 	if (devlink_nl_put_handle(msg, devlink))
6691 		goto err_cancel_msg;
6692 
6693 	req.msg = msg;
6694 	err = devlink->ops->info_get(devlink, &req, extack);
6695 	if (err)
6696 		goto err_cancel_msg;
6697 
6698 	genlmsg_end(msg, hdr);
6699 	return 0;
6700 
6701 err_cancel_msg:
6702 	genlmsg_cancel(msg, hdr);
6703 	return err;
6704 }
6705 
devlink_nl_cmd_info_get_doit(struct sk_buff * skb,struct genl_info * info)6706 static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb,
6707 					struct genl_info *info)
6708 {
6709 	struct devlink *devlink = info->user_ptr[0];
6710 	struct sk_buff *msg;
6711 	int err;
6712 
6713 	if (!devlink->ops->info_get)
6714 		return -EOPNOTSUPP;
6715 
6716 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6717 	if (!msg)
6718 		return -ENOMEM;
6719 
6720 	err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
6721 				   info->snd_portid, info->snd_seq, 0,
6722 				   info->extack);
6723 	if (err) {
6724 		nlmsg_free(msg);
6725 		return err;
6726 	}
6727 
6728 	return genlmsg_reply(msg, info);
6729 }
6730 
devlink_nl_cmd_info_get_dumpit(struct sk_buff * msg,struct netlink_callback * cb)6731 static int devlink_nl_cmd_info_get_dumpit(struct sk_buff *msg,
6732 					  struct netlink_callback *cb)
6733 {
6734 	struct devlink *devlink;
6735 	int start = cb->args[0];
6736 	unsigned long index;
6737 	int idx = 0;
6738 	int err = 0;
6739 
6740 	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
6741 		if (idx < start || !devlink->ops->info_get)
6742 			goto inc;
6743 
6744 		devl_lock(devlink);
6745 		err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
6746 					   NETLINK_CB(cb->skb).portid,
6747 					   cb->nlh->nlmsg_seq, NLM_F_MULTI,
6748 					   cb->extack);
6749 		devl_unlock(devlink);
6750 		if (err == -EOPNOTSUPP)
6751 			err = 0;
6752 		else if (err) {
6753 			devlink_put(devlink);
6754 			break;
6755 		}
6756 inc:
6757 		idx++;
6758 		devlink_put(devlink);
6759 	}
6760 
6761 	if (err != -EMSGSIZE)
6762 		return err;
6763 
6764 	cb->args[0] = idx;
6765 	return msg->len;
6766 }
6767 
6768 struct devlink_fmsg_item {
6769 	struct list_head list;
6770 	int attrtype;
6771 	u8 nla_type;
6772 	u16 len;
6773 	int value[];
6774 };
6775 
6776 struct devlink_fmsg {
6777 	struct list_head item_list;
6778 	bool putting_binary; /* This flag forces enclosing of binary data
6779 			      * in an array brackets. It forces using
6780 			      * of designated API:
6781 			      * devlink_fmsg_binary_pair_nest_start()
6782 			      * devlink_fmsg_binary_pair_nest_end()
6783 			      */
6784 };
6785 
devlink_fmsg_alloc(void)6786 static struct devlink_fmsg *devlink_fmsg_alloc(void)
6787 {
6788 	struct devlink_fmsg *fmsg;
6789 
6790 	fmsg = kzalloc(sizeof(*fmsg), GFP_KERNEL);
6791 	if (!fmsg)
6792 		return NULL;
6793 
6794 	INIT_LIST_HEAD(&fmsg->item_list);
6795 
6796 	return fmsg;
6797 }
6798 
devlink_fmsg_free(struct devlink_fmsg * fmsg)6799 static void devlink_fmsg_free(struct devlink_fmsg *fmsg)
6800 {
6801 	struct devlink_fmsg_item *item, *tmp;
6802 
6803 	list_for_each_entry_safe(item, tmp, &fmsg->item_list, list) {
6804 		list_del(&item->list);
6805 		kfree(item);
6806 	}
6807 	kfree(fmsg);
6808 }
6809 
devlink_fmsg_nest_common(struct devlink_fmsg * fmsg,int attrtype)6810 static int devlink_fmsg_nest_common(struct devlink_fmsg *fmsg,
6811 				    int attrtype)
6812 {
6813 	struct devlink_fmsg_item *item;
6814 
6815 	item = kzalloc(sizeof(*item), GFP_KERNEL);
6816 	if (!item)
6817 		return -ENOMEM;
6818 
6819 	item->attrtype = attrtype;
6820 	list_add_tail(&item->list, &fmsg->item_list);
6821 
6822 	return 0;
6823 }
6824 
devlink_fmsg_obj_nest_start(struct devlink_fmsg * fmsg)6825 int devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg)
6826 {
6827 	if (fmsg->putting_binary)
6828 		return -EINVAL;
6829 
6830 	return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_OBJ_NEST_START);
6831 }
6832 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start);
6833 
devlink_fmsg_nest_end(struct devlink_fmsg * fmsg)6834 static int devlink_fmsg_nest_end(struct devlink_fmsg *fmsg)
6835 {
6836 	if (fmsg->putting_binary)
6837 		return -EINVAL;
6838 
6839 	return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_NEST_END);
6840 }
6841 
devlink_fmsg_obj_nest_end(struct devlink_fmsg * fmsg)6842 int devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg)
6843 {
6844 	if (fmsg->putting_binary)
6845 		return -EINVAL;
6846 
6847 	return devlink_fmsg_nest_end(fmsg);
6848 }
6849 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end);
6850 
6851 #define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN)
6852 
devlink_fmsg_put_name(struct devlink_fmsg * fmsg,const char * name)6853 static int devlink_fmsg_put_name(struct devlink_fmsg *fmsg, const char *name)
6854 {
6855 	struct devlink_fmsg_item *item;
6856 
6857 	if (fmsg->putting_binary)
6858 		return -EINVAL;
6859 
6860 	if (strlen(name) + 1 > DEVLINK_FMSG_MAX_SIZE)
6861 		return -EMSGSIZE;
6862 
6863 	item = kzalloc(sizeof(*item) + strlen(name) + 1, GFP_KERNEL);
6864 	if (!item)
6865 		return -ENOMEM;
6866 
6867 	item->nla_type = NLA_NUL_STRING;
6868 	item->len = strlen(name) + 1;
6869 	item->attrtype = DEVLINK_ATTR_FMSG_OBJ_NAME;
6870 	memcpy(&item->value, name, item->len);
6871 	list_add_tail(&item->list, &fmsg->item_list);
6872 
6873 	return 0;
6874 }
6875 
devlink_fmsg_pair_nest_start(struct devlink_fmsg * fmsg,const char * name)6876 int devlink_fmsg_pair_nest_start(struct devlink_fmsg *fmsg, const char *name)
6877 {
6878 	int err;
6879 
6880 	if (fmsg->putting_binary)
6881 		return -EINVAL;
6882 
6883 	err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_PAIR_NEST_START);
6884 	if (err)
6885 		return err;
6886 
6887 	err = devlink_fmsg_put_name(fmsg, name);
6888 	if (err)
6889 		return err;
6890 
6891 	return 0;
6892 }
6893 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start);
6894 
devlink_fmsg_pair_nest_end(struct devlink_fmsg * fmsg)6895 int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg)
6896 {
6897 	if (fmsg->putting_binary)
6898 		return -EINVAL;
6899 
6900 	return devlink_fmsg_nest_end(fmsg);
6901 }
6902 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end);
6903 
devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg * fmsg,const char * name)6904 int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg,
6905 				     const char *name)
6906 {
6907 	int err;
6908 
6909 	if (fmsg->putting_binary)
6910 		return -EINVAL;
6911 
6912 	err = devlink_fmsg_pair_nest_start(fmsg, name);
6913 	if (err)
6914 		return err;
6915 
6916 	err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_ARR_NEST_START);
6917 	if (err)
6918 		return err;
6919 
6920 	return 0;
6921 }
6922 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start);
6923 
devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg * fmsg)6924 int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg)
6925 {
6926 	int err;
6927 
6928 	if (fmsg->putting_binary)
6929 		return -EINVAL;
6930 
6931 	err = devlink_fmsg_nest_end(fmsg);
6932 	if (err)
6933 		return err;
6934 
6935 	err = devlink_fmsg_nest_end(fmsg);
6936 	if (err)
6937 		return err;
6938 
6939 	return 0;
6940 }
6941 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end);
6942 
devlink_fmsg_binary_pair_nest_start(struct devlink_fmsg * fmsg,const char * name)6943 int devlink_fmsg_binary_pair_nest_start(struct devlink_fmsg *fmsg,
6944 					const char *name)
6945 {
6946 	int err;
6947 
6948 	err = devlink_fmsg_arr_pair_nest_start(fmsg, name);
6949 	if (err)
6950 		return err;
6951 
6952 	fmsg->putting_binary = true;
6953 	return err;
6954 }
6955 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_start);
6956 
devlink_fmsg_binary_pair_nest_end(struct devlink_fmsg * fmsg)6957 int devlink_fmsg_binary_pair_nest_end(struct devlink_fmsg *fmsg)
6958 {
6959 	if (!fmsg->putting_binary)
6960 		return -EINVAL;
6961 
6962 	fmsg->putting_binary = false;
6963 	return devlink_fmsg_arr_pair_nest_end(fmsg);
6964 }
6965 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_end);
6966 
devlink_fmsg_put_value(struct devlink_fmsg * fmsg,const void * value,u16 value_len,u8 value_nla_type)6967 static int devlink_fmsg_put_value(struct devlink_fmsg *fmsg,
6968 				  const void *value, u16 value_len,
6969 				  u8 value_nla_type)
6970 {
6971 	struct devlink_fmsg_item *item;
6972 
6973 	if (value_len > DEVLINK_FMSG_MAX_SIZE)
6974 		return -EMSGSIZE;
6975 
6976 	item = kzalloc(sizeof(*item) + value_len, GFP_KERNEL);
6977 	if (!item)
6978 		return -ENOMEM;
6979 
6980 	item->nla_type = value_nla_type;
6981 	item->len = value_len;
6982 	item->attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
6983 	memcpy(&item->value, value, item->len);
6984 	list_add_tail(&item->list, &fmsg->item_list);
6985 
6986 	return 0;
6987 }
6988 
devlink_fmsg_bool_put(struct devlink_fmsg * fmsg,bool value)6989 static int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value)
6990 {
6991 	if (fmsg->putting_binary)
6992 		return -EINVAL;
6993 
6994 	return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_FLAG);
6995 }
6996 
devlink_fmsg_u8_put(struct devlink_fmsg * fmsg,u8 value)6997 static int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value)
6998 {
6999 	if (fmsg->putting_binary)
7000 		return -EINVAL;
7001 
7002 	return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U8);
7003 }
7004 
devlink_fmsg_u32_put(struct devlink_fmsg * fmsg,u32 value)7005 int devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value)
7006 {
7007 	if (fmsg->putting_binary)
7008 		return -EINVAL;
7009 
7010 	return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U32);
7011 }
7012 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put);
7013 
devlink_fmsg_u64_put(struct devlink_fmsg * fmsg,u64 value)7014 static int devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value)
7015 {
7016 	if (fmsg->putting_binary)
7017 		return -EINVAL;
7018 
7019 	return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U64);
7020 }
7021 
devlink_fmsg_string_put(struct devlink_fmsg * fmsg,const char * value)7022 int devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value)
7023 {
7024 	if (fmsg->putting_binary)
7025 		return -EINVAL;
7026 
7027 	return devlink_fmsg_put_value(fmsg, value, strlen(value) + 1,
7028 				      NLA_NUL_STRING);
7029 }
7030 EXPORT_SYMBOL_GPL(devlink_fmsg_string_put);
7031 
devlink_fmsg_binary_put(struct devlink_fmsg * fmsg,const void * value,u16 value_len)7032 int devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value,
7033 			    u16 value_len)
7034 {
7035 	if (!fmsg->putting_binary)
7036 		return -EINVAL;
7037 
7038 	return devlink_fmsg_put_value(fmsg, value, value_len, NLA_BINARY);
7039 }
7040 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put);
7041 
devlink_fmsg_bool_pair_put(struct devlink_fmsg * fmsg,const char * name,bool value)7042 int devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name,
7043 			       bool value)
7044 {
7045 	int err;
7046 
7047 	err = devlink_fmsg_pair_nest_start(fmsg, name);
7048 	if (err)
7049 		return err;
7050 
7051 	err = devlink_fmsg_bool_put(fmsg, value);
7052 	if (err)
7053 		return err;
7054 
7055 	err = devlink_fmsg_pair_nest_end(fmsg);
7056 	if (err)
7057 		return err;
7058 
7059 	return 0;
7060 }
7061 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put);
7062 
devlink_fmsg_u8_pair_put(struct devlink_fmsg * fmsg,const char * name,u8 value)7063 int devlink_fmsg_u8_pair_put(struct devlink_fmsg *fmsg, const char *name,
7064 			     u8 value)
7065 {
7066 	int err;
7067 
7068 	err = devlink_fmsg_pair_nest_start(fmsg, name);
7069 	if (err)
7070 		return err;
7071 
7072 	err = devlink_fmsg_u8_put(fmsg, value);
7073 	if (err)
7074 		return err;
7075 
7076 	err = devlink_fmsg_pair_nest_end(fmsg);
7077 	if (err)
7078 		return err;
7079 
7080 	return 0;
7081 }
7082 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put);
7083 
devlink_fmsg_u32_pair_put(struct devlink_fmsg * fmsg,const char * name,u32 value)7084 int devlink_fmsg_u32_pair_put(struct devlink_fmsg *fmsg, const char *name,
7085 			      u32 value)
7086 {
7087 	int err;
7088 
7089 	err = devlink_fmsg_pair_nest_start(fmsg, name);
7090 	if (err)
7091 		return err;
7092 
7093 	err = devlink_fmsg_u32_put(fmsg, value);
7094 	if (err)
7095 		return err;
7096 
7097 	err = devlink_fmsg_pair_nest_end(fmsg);
7098 	if (err)
7099 		return err;
7100 
7101 	return 0;
7102 }
7103 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put);
7104 
devlink_fmsg_u64_pair_put(struct devlink_fmsg * fmsg,const char * name,u64 value)7105 int devlink_fmsg_u64_pair_put(struct devlink_fmsg *fmsg, const char *name,
7106 			      u64 value)
7107 {
7108 	int err;
7109 
7110 	err = devlink_fmsg_pair_nest_start(fmsg, name);
7111 	if (err)
7112 		return err;
7113 
7114 	err = devlink_fmsg_u64_put(fmsg, value);
7115 	if (err)
7116 		return err;
7117 
7118 	err = devlink_fmsg_pair_nest_end(fmsg);
7119 	if (err)
7120 		return err;
7121 
7122 	return 0;
7123 }
7124 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put);
7125 
devlink_fmsg_string_pair_put(struct devlink_fmsg * fmsg,const char * name,const char * value)7126 int devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name,
7127 				 const char *value)
7128 {
7129 	int err;
7130 
7131 	err = devlink_fmsg_pair_nest_start(fmsg, name);
7132 	if (err)
7133 		return err;
7134 
7135 	err = devlink_fmsg_string_put(fmsg, value);
7136 	if (err)
7137 		return err;
7138 
7139 	err = devlink_fmsg_pair_nest_end(fmsg);
7140 	if (err)
7141 		return err;
7142 
7143 	return 0;
7144 }
7145 EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put);
7146 
devlink_fmsg_binary_pair_put(struct devlink_fmsg * fmsg,const char * name,const void * value,u32 value_len)7147 int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name,
7148 				 const void *value, u32 value_len)
7149 {
7150 	u32 data_size;
7151 	int end_err;
7152 	u32 offset;
7153 	int err;
7154 
7155 	err = devlink_fmsg_binary_pair_nest_start(fmsg, name);
7156 	if (err)
7157 		return err;
7158 
7159 	for (offset = 0; offset < value_len; offset += data_size) {
7160 		data_size = value_len - offset;
7161 		if (data_size > DEVLINK_FMSG_MAX_SIZE)
7162 			data_size = DEVLINK_FMSG_MAX_SIZE;
7163 		err = devlink_fmsg_binary_put(fmsg, value + offset, data_size);
7164 		if (err)
7165 			break;
7166 		/* Exit from loop with a break (instead of
7167 		 * return) to make sure putting_binary is turned off in
7168 		 * devlink_fmsg_binary_pair_nest_end
7169 		 */
7170 	}
7171 
7172 	end_err = devlink_fmsg_binary_pair_nest_end(fmsg);
7173 	if (end_err)
7174 		err = end_err;
7175 
7176 	return err;
7177 }
7178 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put);
7179 
7180 static int
devlink_fmsg_item_fill_type(struct devlink_fmsg_item * msg,struct sk_buff * skb)7181 devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb)
7182 {
7183 	switch (msg->nla_type) {
7184 	case NLA_FLAG:
7185 	case NLA_U8:
7186 	case NLA_U32:
7187 	case NLA_U64:
7188 	case NLA_NUL_STRING:
7189 	case NLA_BINARY:
7190 		return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE,
7191 				  msg->nla_type);
7192 	default:
7193 		return -EINVAL;
7194 	}
7195 }
7196 
7197 static int
devlink_fmsg_item_fill_data(struct devlink_fmsg_item * msg,struct sk_buff * skb)7198 devlink_fmsg_item_fill_data(struct devlink_fmsg_item *msg, struct sk_buff *skb)
7199 {
7200 	int attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
7201 	u8 tmp;
7202 
7203 	switch (msg->nla_type) {
7204 	case NLA_FLAG:
7205 		/* Always provide flag data, regardless of its value */
7206 		tmp = *(bool *) msg->value;
7207 
7208 		return nla_put_u8(skb, attrtype, tmp);
7209 	case NLA_U8:
7210 		return nla_put_u8(skb, attrtype, *(u8 *) msg->value);
7211 	case NLA_U32:
7212 		return nla_put_u32(skb, attrtype, *(u32 *) msg->value);
7213 	case NLA_U64:
7214 		return nla_put_u64_64bit(skb, attrtype, *(u64 *) msg->value,
7215 					 DEVLINK_ATTR_PAD);
7216 	case NLA_NUL_STRING:
7217 		return nla_put_string(skb, attrtype, (char *) &msg->value);
7218 	case NLA_BINARY:
7219 		return nla_put(skb, attrtype, msg->len, (void *) &msg->value);
7220 	default:
7221 		return -EINVAL;
7222 	}
7223 }
7224 
7225 static int
devlink_fmsg_prepare_skb(struct devlink_fmsg * fmsg,struct sk_buff * skb,int * start)7226 devlink_fmsg_prepare_skb(struct devlink_fmsg *fmsg, struct sk_buff *skb,
7227 			 int *start)
7228 {
7229 	struct devlink_fmsg_item *item;
7230 	struct nlattr *fmsg_nlattr;
7231 	int i = 0;
7232 	int err;
7233 
7234 	fmsg_nlattr = nla_nest_start_noflag(skb, DEVLINK_ATTR_FMSG);
7235 	if (!fmsg_nlattr)
7236 		return -EMSGSIZE;
7237 
7238 	list_for_each_entry(item, &fmsg->item_list, list) {
7239 		if (i < *start) {
7240 			i++;
7241 			continue;
7242 		}
7243 
7244 		switch (item->attrtype) {
7245 		case DEVLINK_ATTR_FMSG_OBJ_NEST_START:
7246 		case DEVLINK_ATTR_FMSG_PAIR_NEST_START:
7247 		case DEVLINK_ATTR_FMSG_ARR_NEST_START:
7248 		case DEVLINK_ATTR_FMSG_NEST_END:
7249 			err = nla_put_flag(skb, item->attrtype);
7250 			break;
7251 		case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA:
7252 			err = devlink_fmsg_item_fill_type(item, skb);
7253 			if (err)
7254 				break;
7255 			err = devlink_fmsg_item_fill_data(item, skb);
7256 			break;
7257 		case DEVLINK_ATTR_FMSG_OBJ_NAME:
7258 			err = nla_put_string(skb, item->attrtype,
7259 					     (char *) &item->value);
7260 			break;
7261 		default:
7262 			err = -EINVAL;
7263 			break;
7264 		}
7265 		if (!err)
7266 			*start = ++i;
7267 		else
7268 			break;
7269 	}
7270 
7271 	nla_nest_end(skb, fmsg_nlattr);
7272 	return err;
7273 }
7274 
devlink_fmsg_snd(struct devlink_fmsg * fmsg,struct genl_info * info,enum devlink_command cmd,int flags)7275 static int devlink_fmsg_snd(struct devlink_fmsg *fmsg,
7276 			    struct genl_info *info,
7277 			    enum devlink_command cmd, int flags)
7278 {
7279 	struct nlmsghdr *nlh;
7280 	struct sk_buff *skb;
7281 	bool last = false;
7282 	int index = 0;
7283 	void *hdr;
7284 	int err;
7285 
7286 	while (!last) {
7287 		int tmp_index = index;
7288 
7289 		skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
7290 		if (!skb)
7291 			return -ENOMEM;
7292 
7293 		hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
7294 				  &devlink_nl_family, flags | NLM_F_MULTI, cmd);
7295 		if (!hdr) {
7296 			err = -EMSGSIZE;
7297 			goto nla_put_failure;
7298 		}
7299 
7300 		err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
7301 		if (!err)
7302 			last = true;
7303 		else if (err != -EMSGSIZE || tmp_index == index)
7304 			goto nla_put_failure;
7305 
7306 		genlmsg_end(skb, hdr);
7307 		err = genlmsg_reply(skb, info);
7308 		if (err)
7309 			return err;
7310 	}
7311 
7312 	skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
7313 	if (!skb)
7314 		return -ENOMEM;
7315 	nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
7316 			NLMSG_DONE, 0, flags | NLM_F_MULTI);
7317 	if (!nlh) {
7318 		err = -EMSGSIZE;
7319 		goto nla_put_failure;
7320 	}
7321 
7322 	return genlmsg_reply(skb, info);
7323 
7324 nla_put_failure:
7325 	nlmsg_free(skb);
7326 	return err;
7327 }
7328 
devlink_fmsg_dumpit(struct devlink_fmsg * fmsg,struct sk_buff * skb,struct netlink_callback * cb,enum devlink_command cmd)7329 static int devlink_fmsg_dumpit(struct devlink_fmsg *fmsg, struct sk_buff *skb,
7330 			       struct netlink_callback *cb,
7331 			       enum devlink_command cmd)
7332 {
7333 	int index = cb->args[0];
7334 	int tmp_index = index;
7335 	void *hdr;
7336 	int err;
7337 
7338 	hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
7339 			  &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, cmd);
7340 	if (!hdr) {
7341 		err = -EMSGSIZE;
7342 		goto nla_put_failure;
7343 	}
7344 
7345 	err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
7346 	if ((err && err != -EMSGSIZE) || tmp_index == index)
7347 		goto nla_put_failure;
7348 
7349 	cb->args[0] = index;
7350 	genlmsg_end(skb, hdr);
7351 	return skb->len;
7352 
7353 nla_put_failure:
7354 	genlmsg_cancel(skb, hdr);
7355 	return err;
7356 }
7357 
7358 struct devlink_health_reporter {
7359 	struct list_head list;
7360 	void *priv;
7361 	const struct devlink_health_reporter_ops *ops;
7362 	struct devlink *devlink;
7363 	struct devlink_port *devlink_port;
7364 	struct devlink_fmsg *dump_fmsg;
7365 	struct mutex dump_lock; /* lock parallel read/write from dump buffers */
7366 	u64 graceful_period;
7367 	bool auto_recover;
7368 	bool auto_dump;
7369 	u8 health_state;
7370 	u64 dump_ts;
7371 	u64 dump_real_ts;
7372 	u64 error_count;
7373 	u64 recovery_count;
7374 	u64 last_recovery_ts;
7375 	refcount_t refcount;
7376 };
7377 
7378 void *
devlink_health_reporter_priv(struct devlink_health_reporter * reporter)7379 devlink_health_reporter_priv(struct devlink_health_reporter *reporter)
7380 {
7381 	return reporter->priv;
7382 }
7383 EXPORT_SYMBOL_GPL(devlink_health_reporter_priv);
7384 
7385 static struct devlink_health_reporter *
__devlink_health_reporter_find_by_name(struct list_head * reporter_list,struct mutex * list_lock,const char * reporter_name)7386 __devlink_health_reporter_find_by_name(struct list_head *reporter_list,
7387 				       struct mutex *list_lock,
7388 				       const char *reporter_name)
7389 {
7390 	struct devlink_health_reporter *reporter;
7391 
7392 	lockdep_assert_held(list_lock);
7393 	list_for_each_entry(reporter, reporter_list, list)
7394 		if (!strcmp(reporter->ops->name, reporter_name))
7395 			return reporter;
7396 	return NULL;
7397 }
7398 
7399 static struct devlink_health_reporter *
devlink_health_reporter_find_by_name(struct devlink * devlink,const char * reporter_name)7400 devlink_health_reporter_find_by_name(struct devlink *devlink,
7401 				     const char *reporter_name)
7402 {
7403 	return __devlink_health_reporter_find_by_name(&devlink->reporter_list,
7404 						      &devlink->reporters_lock,
7405 						      reporter_name);
7406 }
7407 
7408 static struct devlink_health_reporter *
devlink_port_health_reporter_find_by_name(struct devlink_port * devlink_port,const char * reporter_name)7409 devlink_port_health_reporter_find_by_name(struct devlink_port *devlink_port,
7410 					  const char *reporter_name)
7411 {
7412 	return __devlink_health_reporter_find_by_name(&devlink_port->reporter_list,
7413 						      &devlink_port->reporters_lock,
7414 						      reporter_name);
7415 }
7416 
7417 static struct devlink_health_reporter *
__devlink_health_reporter_create(struct devlink * devlink,const struct devlink_health_reporter_ops * ops,u64 graceful_period,void * priv)7418 __devlink_health_reporter_create(struct devlink *devlink,
7419 				 const struct devlink_health_reporter_ops *ops,
7420 				 u64 graceful_period, void *priv)
7421 {
7422 	struct devlink_health_reporter *reporter;
7423 
7424 	if (WARN_ON(graceful_period && !ops->recover))
7425 		return ERR_PTR(-EINVAL);
7426 
7427 	reporter = kzalloc(sizeof(*reporter), GFP_KERNEL);
7428 	if (!reporter)
7429 		return ERR_PTR(-ENOMEM);
7430 
7431 	reporter->priv = priv;
7432 	reporter->ops = ops;
7433 	reporter->devlink = devlink;
7434 	reporter->graceful_period = graceful_period;
7435 	reporter->auto_recover = !!ops->recover;
7436 	reporter->auto_dump = !!ops->dump;
7437 	mutex_init(&reporter->dump_lock);
7438 	refcount_set(&reporter->refcount, 1);
7439 	return reporter;
7440 }
7441 
7442 /**
7443  *	devlink_port_health_reporter_create - create devlink health reporter for
7444  *	                                      specified port instance
7445  *
7446  *	@port: devlink_port which should contain the new reporter
7447  *	@ops: ops
7448  *	@graceful_period: to avoid recovery loops, in msecs
7449  *	@priv: priv
7450  */
7451 struct devlink_health_reporter *
devlink_port_health_reporter_create(struct devlink_port * port,const struct devlink_health_reporter_ops * ops,u64 graceful_period,void * priv)7452 devlink_port_health_reporter_create(struct devlink_port *port,
7453 				    const struct devlink_health_reporter_ops *ops,
7454 				    u64 graceful_period, void *priv)
7455 {
7456 	struct devlink_health_reporter *reporter;
7457 
7458 	mutex_lock(&port->reporters_lock);
7459 	if (__devlink_health_reporter_find_by_name(&port->reporter_list,
7460 						   &port->reporters_lock, ops->name)) {
7461 		reporter = ERR_PTR(-EEXIST);
7462 		goto unlock;
7463 	}
7464 
7465 	reporter = __devlink_health_reporter_create(port->devlink, ops,
7466 						    graceful_period, priv);
7467 	if (IS_ERR(reporter))
7468 		goto unlock;
7469 
7470 	reporter->devlink_port = port;
7471 	list_add_tail(&reporter->list, &port->reporter_list);
7472 unlock:
7473 	mutex_unlock(&port->reporters_lock);
7474 	return reporter;
7475 }
7476 EXPORT_SYMBOL_GPL(devlink_port_health_reporter_create);
7477 
7478 /**
7479  *	devlink_health_reporter_create - create devlink health reporter
7480  *
7481  *	@devlink: devlink
7482  *	@ops: ops
7483  *	@graceful_period: to avoid recovery loops, in msecs
7484  *	@priv: priv
7485  */
7486 struct devlink_health_reporter *
devlink_health_reporter_create(struct devlink * devlink,const struct devlink_health_reporter_ops * ops,u64 graceful_period,void * priv)7487 devlink_health_reporter_create(struct devlink *devlink,
7488 			       const struct devlink_health_reporter_ops *ops,
7489 			       u64 graceful_period, void *priv)
7490 {
7491 	struct devlink_health_reporter *reporter;
7492 
7493 	mutex_lock(&devlink->reporters_lock);
7494 	if (devlink_health_reporter_find_by_name(devlink, ops->name)) {
7495 		reporter = ERR_PTR(-EEXIST);
7496 		goto unlock;
7497 	}
7498 
7499 	reporter = __devlink_health_reporter_create(devlink, ops,
7500 						    graceful_period, priv);
7501 	if (IS_ERR(reporter))
7502 		goto unlock;
7503 
7504 	list_add_tail(&reporter->list, &devlink->reporter_list);
7505 unlock:
7506 	mutex_unlock(&devlink->reporters_lock);
7507 	return reporter;
7508 }
7509 EXPORT_SYMBOL_GPL(devlink_health_reporter_create);
7510 
7511 static void
devlink_health_reporter_free(struct devlink_health_reporter * reporter)7512 devlink_health_reporter_free(struct devlink_health_reporter *reporter)
7513 {
7514 	mutex_destroy(&reporter->dump_lock);
7515 	if (reporter->dump_fmsg)
7516 		devlink_fmsg_free(reporter->dump_fmsg);
7517 	kfree(reporter);
7518 }
7519 
7520 static void
devlink_health_reporter_put(struct devlink_health_reporter * reporter)7521 devlink_health_reporter_put(struct devlink_health_reporter *reporter)
7522 {
7523 	if (refcount_dec_and_test(&reporter->refcount))
7524 		devlink_health_reporter_free(reporter);
7525 }
7526 
7527 static void
__devlink_health_reporter_destroy(struct devlink_health_reporter * reporter)7528 __devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
7529 {
7530 	list_del(&reporter->list);
7531 	devlink_health_reporter_put(reporter);
7532 }
7533 
7534 /**
7535  *	devlink_health_reporter_destroy - destroy devlink health reporter
7536  *
7537  *	@reporter: devlink health reporter to destroy
7538  */
7539 void
devlink_health_reporter_destroy(struct devlink_health_reporter * reporter)7540 devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
7541 {
7542 	struct mutex *lock = &reporter->devlink->reporters_lock;
7543 
7544 	mutex_lock(lock);
7545 	__devlink_health_reporter_destroy(reporter);
7546 	mutex_unlock(lock);
7547 }
7548 EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy);
7549 
7550 /**
7551  *	devlink_port_health_reporter_destroy - destroy devlink port health reporter
7552  *
7553  *	@reporter: devlink health reporter to destroy
7554  */
7555 void
devlink_port_health_reporter_destroy(struct devlink_health_reporter * reporter)7556 devlink_port_health_reporter_destroy(struct devlink_health_reporter *reporter)
7557 {
7558 	struct mutex *lock = &reporter->devlink_port->reporters_lock;
7559 
7560 	mutex_lock(lock);
7561 	__devlink_health_reporter_destroy(reporter);
7562 	mutex_unlock(lock);
7563 }
7564 EXPORT_SYMBOL_GPL(devlink_port_health_reporter_destroy);
7565 
7566 static int
devlink_nl_health_reporter_fill(struct sk_buff * msg,struct devlink_health_reporter * reporter,enum devlink_command cmd,u32 portid,u32 seq,int flags)7567 devlink_nl_health_reporter_fill(struct sk_buff *msg,
7568 				struct devlink_health_reporter *reporter,
7569 				enum devlink_command cmd, u32 portid,
7570 				u32 seq, int flags)
7571 {
7572 	struct devlink *devlink = reporter->devlink;
7573 	struct nlattr *reporter_attr;
7574 	void *hdr;
7575 
7576 	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
7577 	if (!hdr)
7578 		return -EMSGSIZE;
7579 
7580 	if (devlink_nl_put_handle(msg, devlink))
7581 		goto genlmsg_cancel;
7582 
7583 	if (reporter->devlink_port) {
7584 		if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, reporter->devlink_port->index))
7585 			goto genlmsg_cancel;
7586 	}
7587 	reporter_attr = nla_nest_start_noflag(msg,
7588 					      DEVLINK_ATTR_HEALTH_REPORTER);
7589 	if (!reporter_attr)
7590 		goto genlmsg_cancel;
7591 	if (nla_put_string(msg, DEVLINK_ATTR_HEALTH_REPORTER_NAME,
7592 			   reporter->ops->name))
7593 		goto reporter_nest_cancel;
7594 	if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_STATE,
7595 		       reporter->health_state))
7596 		goto reporter_nest_cancel;
7597 	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT,
7598 			      reporter->error_count, DEVLINK_ATTR_PAD))
7599 		goto reporter_nest_cancel;
7600 	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT,
7601 			      reporter->recovery_count, DEVLINK_ATTR_PAD))
7602 		goto reporter_nest_cancel;
7603 	if (reporter->ops->recover &&
7604 	    nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD,
7605 			      reporter->graceful_period,
7606 			      DEVLINK_ATTR_PAD))
7607 		goto reporter_nest_cancel;
7608 	if (reporter->ops->recover &&
7609 	    nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER,
7610 		       reporter->auto_recover))
7611 		goto reporter_nest_cancel;
7612 	if (reporter->dump_fmsg &&
7613 	    nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS,
7614 			      jiffies_to_msecs(reporter->dump_ts),
7615 			      DEVLINK_ATTR_PAD))
7616 		goto reporter_nest_cancel;
7617 	if (reporter->dump_fmsg &&
7618 	    nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS,
7619 			      reporter->dump_real_ts, DEVLINK_ATTR_PAD))
7620 		goto reporter_nest_cancel;
7621 	if (reporter->ops->dump &&
7622 	    nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP,
7623 		       reporter->auto_dump))
7624 		goto reporter_nest_cancel;
7625 
7626 	nla_nest_end(msg, reporter_attr);
7627 	genlmsg_end(msg, hdr);
7628 	return 0;
7629 
7630 reporter_nest_cancel:
7631 	nla_nest_end(msg, reporter_attr);
7632 genlmsg_cancel:
7633 	genlmsg_cancel(msg, hdr);
7634 	return -EMSGSIZE;
7635 }
7636 
devlink_recover_notify(struct devlink_health_reporter * reporter,enum devlink_command cmd)7637 static void devlink_recover_notify(struct devlink_health_reporter *reporter,
7638 				   enum devlink_command cmd)
7639 {
7640 	struct devlink *devlink = reporter->devlink;
7641 	struct sk_buff *msg;
7642 	int err;
7643 
7644 	WARN_ON(cmd != DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
7645 	WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED));
7646 
7647 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7648 	if (!msg)
7649 		return;
7650 
7651 	err = devlink_nl_health_reporter_fill(msg, reporter, cmd, 0, 0, 0);
7652 	if (err) {
7653 		nlmsg_free(msg);
7654 		return;
7655 	}
7656 
7657 	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
7658 				0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
7659 }
7660 
7661 void
devlink_health_reporter_recovery_done(struct devlink_health_reporter * reporter)7662 devlink_health_reporter_recovery_done(struct devlink_health_reporter *reporter)
7663 {
7664 	reporter->recovery_count++;
7665 	reporter->last_recovery_ts = jiffies;
7666 }
7667 EXPORT_SYMBOL_GPL(devlink_health_reporter_recovery_done);
7668 
7669 static int
devlink_health_reporter_recover(struct devlink_health_reporter * reporter,void * priv_ctx,struct netlink_ext_ack * extack)7670 devlink_health_reporter_recover(struct devlink_health_reporter *reporter,
7671 				void *priv_ctx, struct netlink_ext_ack *extack)
7672 {
7673 	int err;
7674 
7675 	if (reporter->health_state == DEVLINK_HEALTH_REPORTER_STATE_HEALTHY)
7676 		return 0;
7677 
7678 	if (!reporter->ops->recover)
7679 		return -EOPNOTSUPP;
7680 
7681 	err = reporter->ops->recover(reporter, priv_ctx, extack);
7682 	if (err)
7683 		return err;
7684 
7685 	devlink_health_reporter_recovery_done(reporter);
7686 	reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY;
7687 	devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
7688 
7689 	return 0;
7690 }
7691 
7692 static void
devlink_health_dump_clear(struct devlink_health_reporter * reporter)7693 devlink_health_dump_clear(struct devlink_health_reporter *reporter)
7694 {
7695 	if (!reporter->dump_fmsg)
7696 		return;
7697 	devlink_fmsg_free(reporter->dump_fmsg);
7698 	reporter->dump_fmsg = NULL;
7699 }
7700 
devlink_health_do_dump(struct devlink_health_reporter * reporter,void * priv_ctx,struct netlink_ext_ack * extack)7701 static int devlink_health_do_dump(struct devlink_health_reporter *reporter,
7702 				  void *priv_ctx,
7703 				  struct netlink_ext_ack *extack)
7704 {
7705 	int err;
7706 
7707 	if (!reporter->ops->dump)
7708 		return 0;
7709 
7710 	if (reporter->dump_fmsg)
7711 		return 0;
7712 
7713 	reporter->dump_fmsg = devlink_fmsg_alloc();
7714 	if (!reporter->dump_fmsg) {
7715 		err = -ENOMEM;
7716 		return err;
7717 	}
7718 
7719 	err = devlink_fmsg_obj_nest_start(reporter->dump_fmsg);
7720 	if (err)
7721 		goto dump_err;
7722 
7723 	err = reporter->ops->dump(reporter, reporter->dump_fmsg,
7724 				  priv_ctx, extack);
7725 	if (err)
7726 		goto dump_err;
7727 
7728 	err = devlink_fmsg_obj_nest_end(reporter->dump_fmsg);
7729 	if (err)
7730 		goto dump_err;
7731 
7732 	reporter->dump_ts = jiffies;
7733 	reporter->dump_real_ts = ktime_get_real_ns();
7734 
7735 	return 0;
7736 
7737 dump_err:
7738 	devlink_health_dump_clear(reporter);
7739 	return err;
7740 }
7741 
devlink_health_report(struct devlink_health_reporter * reporter,const char * msg,void * priv_ctx)7742 int devlink_health_report(struct devlink_health_reporter *reporter,
7743 			  const char *msg, void *priv_ctx)
7744 {
7745 	enum devlink_health_reporter_state prev_health_state;
7746 	struct devlink *devlink = reporter->devlink;
7747 	unsigned long recover_ts_threshold;
7748 	int ret;
7749 
7750 	/* write a log message of the current error */
7751 	WARN_ON(!msg);
7752 	trace_devlink_health_report(devlink, reporter->ops->name, msg);
7753 	reporter->error_count++;
7754 	prev_health_state = reporter->health_state;
7755 	reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
7756 	devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
7757 
7758 	/* abort if the previous error wasn't recovered */
7759 	recover_ts_threshold = reporter->last_recovery_ts +
7760 			       msecs_to_jiffies(reporter->graceful_period);
7761 	if (reporter->auto_recover &&
7762 	    (prev_health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY ||
7763 	     (reporter->last_recovery_ts && reporter->recovery_count &&
7764 	      time_is_after_jiffies(recover_ts_threshold)))) {
7765 		trace_devlink_health_recover_aborted(devlink,
7766 						     reporter->ops->name,
7767 						     reporter->health_state,
7768 						     jiffies -
7769 						     reporter->last_recovery_ts);
7770 		return -ECANCELED;
7771 	}
7772 
7773 	reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
7774 
7775 	if (reporter->auto_dump) {
7776 		mutex_lock(&reporter->dump_lock);
7777 		/* store current dump of current error, for later analysis */
7778 		devlink_health_do_dump(reporter, priv_ctx, NULL);
7779 		mutex_unlock(&reporter->dump_lock);
7780 	}
7781 
7782 	if (!reporter->auto_recover)
7783 		return 0;
7784 
7785 	devl_lock(devlink);
7786 	ret = devlink_health_reporter_recover(reporter, priv_ctx, NULL);
7787 	devl_unlock(devlink);
7788 
7789 	return ret;
7790 }
7791 EXPORT_SYMBOL_GPL(devlink_health_report);
7792 
7793 static struct devlink_health_reporter *
devlink_health_reporter_get_from_attrs(struct devlink * devlink,struct nlattr ** attrs)7794 devlink_health_reporter_get_from_attrs(struct devlink *devlink,
7795 				       struct nlattr **attrs)
7796 {
7797 	struct devlink_health_reporter *reporter;
7798 	struct devlink_port *devlink_port;
7799 	char *reporter_name;
7800 
7801 	if (!attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME])
7802 		return NULL;
7803 
7804 	reporter_name = nla_data(attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]);
7805 	devlink_port = devlink_port_get_from_attrs(devlink, attrs);
7806 	if (IS_ERR(devlink_port)) {
7807 		mutex_lock(&devlink->reporters_lock);
7808 		reporter = devlink_health_reporter_find_by_name(devlink, reporter_name);
7809 		if (reporter)
7810 			refcount_inc(&reporter->refcount);
7811 		mutex_unlock(&devlink->reporters_lock);
7812 	} else {
7813 		mutex_lock(&devlink_port->reporters_lock);
7814 		reporter = devlink_port_health_reporter_find_by_name(devlink_port, reporter_name);
7815 		if (reporter)
7816 			refcount_inc(&reporter->refcount);
7817 		mutex_unlock(&devlink_port->reporters_lock);
7818 	}
7819 
7820 	return reporter;
7821 }
7822 
7823 static struct devlink_health_reporter *
devlink_health_reporter_get_from_info(struct devlink * devlink,struct genl_info * info)7824 devlink_health_reporter_get_from_info(struct devlink *devlink,
7825 				      struct genl_info *info)
7826 {
7827 	return devlink_health_reporter_get_from_attrs(devlink, info->attrs);
7828 }
7829 
7830 static struct devlink_health_reporter *
devlink_health_reporter_get_from_cb(struct netlink_callback * cb)7831 devlink_health_reporter_get_from_cb(struct netlink_callback *cb)
7832 {
7833 	const struct genl_dumpit_info *info = genl_dumpit_info(cb);
7834 	struct devlink_health_reporter *reporter;
7835 	struct nlattr **attrs = info->attrs;
7836 	struct devlink *devlink;
7837 
7838 	devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs);
7839 	if (IS_ERR(devlink))
7840 		return NULL;
7841 
7842 	reporter = devlink_health_reporter_get_from_attrs(devlink, attrs);
7843 	devlink_put(devlink);
7844 	return reporter;
7845 }
7846 
7847 void
devlink_health_reporter_state_update(struct devlink_health_reporter * reporter,enum devlink_health_reporter_state state)7848 devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
7849 				     enum devlink_health_reporter_state state)
7850 {
7851 	if (WARN_ON(state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY &&
7852 		    state != DEVLINK_HEALTH_REPORTER_STATE_ERROR))
7853 		return;
7854 
7855 	if (reporter->health_state == state)
7856 		return;
7857 
7858 	reporter->health_state = state;
7859 	trace_devlink_health_reporter_state_update(reporter->devlink,
7860 						   reporter->ops->name, state);
7861 	devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
7862 }
7863 EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update);
7864 
devlink_nl_cmd_health_reporter_get_doit(struct sk_buff * skb,struct genl_info * info)7865 static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb,
7866 						   struct genl_info *info)
7867 {
7868 	struct devlink *devlink = info->user_ptr[0];
7869 	struct devlink_health_reporter *reporter;
7870 	struct sk_buff *msg;
7871 	int err;
7872 
7873 	reporter = devlink_health_reporter_get_from_info(devlink, info);
7874 	if (!reporter)
7875 		return -EINVAL;
7876 
7877 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7878 	if (!msg) {
7879 		err = -ENOMEM;
7880 		goto out;
7881 	}
7882 
7883 	err = devlink_nl_health_reporter_fill(msg, reporter,
7884 					      DEVLINK_CMD_HEALTH_REPORTER_GET,
7885 					      info->snd_portid, info->snd_seq,
7886 					      0);
7887 	if (err) {
7888 		nlmsg_free(msg);
7889 		goto out;
7890 	}
7891 
7892 	err = genlmsg_reply(msg, info);
7893 out:
7894 	devlink_health_reporter_put(reporter);
7895 	return err;
7896 }
7897 
7898 static int
devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff * msg,struct netlink_callback * cb)7899 devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff *msg,
7900 					  struct netlink_callback *cb)
7901 {
7902 	struct devlink_health_reporter *reporter;
7903 	struct devlink_port *port;
7904 	struct devlink *devlink;
7905 	int start = cb->args[0];
7906 	unsigned long index;
7907 	int idx = 0;
7908 	int err;
7909 
7910 	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
7911 		mutex_lock(&devlink->reporters_lock);
7912 		list_for_each_entry(reporter, &devlink->reporter_list,
7913 				    list) {
7914 			if (idx < start) {
7915 				idx++;
7916 				continue;
7917 			}
7918 			err = devlink_nl_health_reporter_fill(
7919 				msg, reporter, DEVLINK_CMD_HEALTH_REPORTER_GET,
7920 				NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
7921 				NLM_F_MULTI);
7922 			if (err) {
7923 				mutex_unlock(&devlink->reporters_lock);
7924 				devlink_put(devlink);
7925 				goto out;
7926 			}
7927 			idx++;
7928 		}
7929 		mutex_unlock(&devlink->reporters_lock);
7930 		devlink_put(devlink);
7931 	}
7932 
7933 	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
7934 		devl_lock(devlink);
7935 		list_for_each_entry(port, &devlink->port_list, list) {
7936 			mutex_lock(&port->reporters_lock);
7937 			list_for_each_entry(reporter, &port->reporter_list, list) {
7938 				if (idx < start) {
7939 					idx++;
7940 					continue;
7941 				}
7942 				err = devlink_nl_health_reporter_fill(
7943 					msg, reporter,
7944 					DEVLINK_CMD_HEALTH_REPORTER_GET,
7945 					NETLINK_CB(cb->skb).portid,
7946 					cb->nlh->nlmsg_seq, NLM_F_MULTI);
7947 				if (err) {
7948 					mutex_unlock(&port->reporters_lock);
7949 					devl_unlock(devlink);
7950 					devlink_put(devlink);
7951 					goto out;
7952 				}
7953 				idx++;
7954 			}
7955 			mutex_unlock(&port->reporters_lock);
7956 		}
7957 		devl_unlock(devlink);
7958 		devlink_put(devlink);
7959 	}
7960 out:
7961 	cb->args[0] = idx;
7962 	return msg->len;
7963 }
7964 
7965 static int
devlink_nl_cmd_health_reporter_set_doit(struct sk_buff * skb,struct genl_info * info)7966 devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb,
7967 					struct genl_info *info)
7968 {
7969 	struct devlink *devlink = info->user_ptr[0];
7970 	struct devlink_health_reporter *reporter;
7971 	int err;
7972 
7973 	reporter = devlink_health_reporter_get_from_info(devlink, info);
7974 	if (!reporter)
7975 		return -EINVAL;
7976 
7977 	if (!reporter->ops->recover &&
7978 	    (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] ||
7979 	     info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])) {
7980 		err = -EOPNOTSUPP;
7981 		goto out;
7982 	}
7983 	if (!reporter->ops->dump &&
7984 	    info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]) {
7985 		err = -EOPNOTSUPP;
7986 		goto out;
7987 	}
7988 
7989 	if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD])
7990 		reporter->graceful_period =
7991 			nla_get_u64(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]);
7992 
7993 	if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])
7994 		reporter->auto_recover =
7995 			nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]);
7996 
7997 	if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP])
7998 		reporter->auto_dump =
7999 		nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]);
8000 
8001 	devlink_health_reporter_put(reporter);
8002 	return 0;
8003 out:
8004 	devlink_health_reporter_put(reporter);
8005 	return err;
8006 }
8007 
devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff * skb,struct genl_info * info)8008 static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb,
8009 						       struct genl_info *info)
8010 {
8011 	struct devlink *devlink = info->user_ptr[0];
8012 	struct devlink_health_reporter *reporter;
8013 	int err;
8014 
8015 	reporter = devlink_health_reporter_get_from_info(devlink, info);
8016 	if (!reporter)
8017 		return -EINVAL;
8018 
8019 	err = devlink_health_reporter_recover(reporter, NULL, info->extack);
8020 
8021 	devlink_health_reporter_put(reporter);
8022 	return err;
8023 }
8024 
devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff * skb,struct genl_info * info)8025 static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb,
8026 							struct genl_info *info)
8027 {
8028 	struct devlink *devlink = info->user_ptr[0];
8029 	struct devlink_health_reporter *reporter;
8030 	struct devlink_fmsg *fmsg;
8031 	int err;
8032 
8033 	reporter = devlink_health_reporter_get_from_info(devlink, info);
8034 	if (!reporter)
8035 		return -EINVAL;
8036 
8037 	if (!reporter->ops->diagnose) {
8038 		devlink_health_reporter_put(reporter);
8039 		return -EOPNOTSUPP;
8040 	}
8041 
8042 	fmsg = devlink_fmsg_alloc();
8043 	if (!fmsg) {
8044 		devlink_health_reporter_put(reporter);
8045 		return -ENOMEM;
8046 	}
8047 
8048 	err = devlink_fmsg_obj_nest_start(fmsg);
8049 	if (err)
8050 		goto out;
8051 
8052 	err = reporter->ops->diagnose(reporter, fmsg, info->extack);
8053 	if (err)
8054 		goto out;
8055 
8056 	err = devlink_fmsg_obj_nest_end(fmsg);
8057 	if (err)
8058 		goto out;
8059 
8060 	err = devlink_fmsg_snd(fmsg, info,
8061 			       DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 0);
8062 
8063 out:
8064 	devlink_fmsg_free(fmsg);
8065 	devlink_health_reporter_put(reporter);
8066 	return err;
8067 }
8068 
8069 static int
devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff * skb,struct netlink_callback * cb)8070 devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff *skb,
8071 					       struct netlink_callback *cb)
8072 {
8073 	struct devlink_health_reporter *reporter;
8074 	u64 start = cb->args[0];
8075 	int err;
8076 
8077 	reporter = devlink_health_reporter_get_from_cb(cb);
8078 	if (!reporter)
8079 		return -EINVAL;
8080 
8081 	if (!reporter->ops->dump) {
8082 		err = -EOPNOTSUPP;
8083 		goto out;
8084 	}
8085 	mutex_lock(&reporter->dump_lock);
8086 	if (!start) {
8087 		err = devlink_health_do_dump(reporter, NULL, cb->extack);
8088 		if (err)
8089 			goto unlock;
8090 		cb->args[1] = reporter->dump_ts;
8091 	}
8092 	if (!reporter->dump_fmsg || cb->args[1] != reporter->dump_ts) {
8093 		NL_SET_ERR_MSG_MOD(cb->extack, "Dump trampled, please retry");
8094 		err = -EAGAIN;
8095 		goto unlock;
8096 	}
8097 
8098 	err = devlink_fmsg_dumpit(reporter->dump_fmsg, skb, cb,
8099 				  DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET);
8100 unlock:
8101 	mutex_unlock(&reporter->dump_lock);
8102 out:
8103 	devlink_health_reporter_put(reporter);
8104 	return err;
8105 }
8106 
8107 static int
devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff * skb,struct genl_info * info)8108 devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb,
8109 					       struct genl_info *info)
8110 {
8111 	struct devlink *devlink = info->user_ptr[0];
8112 	struct devlink_health_reporter *reporter;
8113 
8114 	reporter = devlink_health_reporter_get_from_info(devlink, info);
8115 	if (!reporter)
8116 		return -EINVAL;
8117 
8118 	if (!reporter->ops->dump) {
8119 		devlink_health_reporter_put(reporter);
8120 		return -EOPNOTSUPP;
8121 	}
8122 
8123 	mutex_lock(&reporter->dump_lock);
8124 	devlink_health_dump_clear(reporter);
8125 	mutex_unlock(&reporter->dump_lock);
8126 	devlink_health_reporter_put(reporter);
8127 	return 0;
8128 }
8129 
devlink_nl_cmd_health_reporter_test_doit(struct sk_buff * skb,struct genl_info * info)8130 static int devlink_nl_cmd_health_reporter_test_doit(struct sk_buff *skb,
8131 						    struct genl_info *info)
8132 {
8133 	struct devlink *devlink = info->user_ptr[0];
8134 	struct devlink_health_reporter *reporter;
8135 	int err;
8136 
8137 	reporter = devlink_health_reporter_get_from_info(devlink, info);
8138 	if (!reporter)
8139 		return -EINVAL;
8140 
8141 	if (!reporter->ops->test) {
8142 		devlink_health_reporter_put(reporter);
8143 		return -EOPNOTSUPP;
8144 	}
8145 
8146 	err = reporter->ops->test(reporter, info->extack);
8147 
8148 	devlink_health_reporter_put(reporter);
8149 	return err;
8150 }
8151 
8152 struct devlink_stats {
8153 	u64_stats_t rx_bytes;
8154 	u64_stats_t rx_packets;
8155 	struct u64_stats_sync syncp;
8156 };
8157 
8158 /**
8159  * struct devlink_trap_policer_item - Packet trap policer attributes.
8160  * @policer: Immutable packet trap policer attributes.
8161  * @rate: Rate in packets / sec.
8162  * @burst: Burst size in packets.
8163  * @list: trap_policer_list member.
8164  *
8165  * Describes packet trap policer attributes. Created by devlink during trap
8166  * policer registration.
8167  */
8168 struct devlink_trap_policer_item {
8169 	const struct devlink_trap_policer *policer;
8170 	u64 rate;
8171 	u64 burst;
8172 	struct list_head list;
8173 };
8174 
8175 /**
8176  * struct devlink_trap_group_item - Packet trap group attributes.
8177  * @group: Immutable packet trap group attributes.
8178  * @policer_item: Associated policer item. Can be NULL.
8179  * @list: trap_group_list member.
8180  * @stats: Trap group statistics.
8181  *
8182  * Describes packet trap group attributes. Created by devlink during trap
8183  * group registration.
8184  */
8185 struct devlink_trap_group_item {
8186 	const struct devlink_trap_group *group;
8187 	struct devlink_trap_policer_item *policer_item;
8188 	struct list_head list;
8189 	struct devlink_stats __percpu *stats;
8190 };
8191 
8192 /**
8193  * struct devlink_trap_item - Packet trap attributes.
8194  * @trap: Immutable packet trap attributes.
8195  * @group_item: Associated group item.
8196  * @list: trap_list member.
8197  * @action: Trap action.
8198  * @stats: Trap statistics.
8199  * @priv: Driver private information.
8200  *
8201  * Describes both mutable and immutable packet trap attributes. Created by
8202  * devlink during trap registration and used for all trap related operations.
8203  */
8204 struct devlink_trap_item {
8205 	const struct devlink_trap *trap;
8206 	struct devlink_trap_group_item *group_item;
8207 	struct list_head list;
8208 	enum devlink_trap_action action;
8209 	struct devlink_stats __percpu *stats;
8210 	void *priv;
8211 };
8212 
8213 static struct devlink_trap_policer_item *
devlink_trap_policer_item_lookup(struct devlink * devlink,u32 id)8214 devlink_trap_policer_item_lookup(struct devlink *devlink, u32 id)
8215 {
8216 	struct devlink_trap_policer_item *policer_item;
8217 
8218 	list_for_each_entry(policer_item, &devlink->trap_policer_list, list) {
8219 		if (policer_item->policer->id == id)
8220 			return policer_item;
8221 	}
8222 
8223 	return NULL;
8224 }
8225 
8226 static struct devlink_trap_item *
devlink_trap_item_lookup(struct devlink * devlink,const char * name)8227 devlink_trap_item_lookup(struct devlink *devlink, const char *name)
8228 {
8229 	struct devlink_trap_item *trap_item;
8230 
8231 	list_for_each_entry(trap_item, &devlink->trap_list, list) {
8232 		if (!strcmp(trap_item->trap->name, name))
8233 			return trap_item;
8234 	}
8235 
8236 	return NULL;
8237 }
8238 
8239 static struct devlink_trap_item *
devlink_trap_item_get_from_info(struct devlink * devlink,struct genl_info * info)8240 devlink_trap_item_get_from_info(struct devlink *devlink,
8241 				struct genl_info *info)
8242 {
8243 	struct nlattr *attr;
8244 
8245 	if (!info->attrs[DEVLINK_ATTR_TRAP_NAME])
8246 		return NULL;
8247 	attr = info->attrs[DEVLINK_ATTR_TRAP_NAME];
8248 
8249 	return devlink_trap_item_lookup(devlink, nla_data(attr));
8250 }
8251 
8252 static int
devlink_trap_action_get_from_info(struct genl_info * info,enum devlink_trap_action * p_trap_action)8253 devlink_trap_action_get_from_info(struct genl_info *info,
8254 				  enum devlink_trap_action *p_trap_action)
8255 {
8256 	u8 val;
8257 
8258 	val = nla_get_u8(info->attrs[DEVLINK_ATTR_TRAP_ACTION]);
8259 	switch (val) {
8260 	case DEVLINK_TRAP_ACTION_DROP:
8261 	case DEVLINK_TRAP_ACTION_TRAP:
8262 	case DEVLINK_TRAP_ACTION_MIRROR:
8263 		*p_trap_action = val;
8264 		break;
8265 	default:
8266 		return -EINVAL;
8267 	}
8268 
8269 	return 0;
8270 }
8271 
devlink_trap_metadata_put(struct sk_buff * msg,const struct devlink_trap * trap)8272 static int devlink_trap_metadata_put(struct sk_buff *msg,
8273 				     const struct devlink_trap *trap)
8274 {
8275 	struct nlattr *attr;
8276 
8277 	attr = nla_nest_start(msg, DEVLINK_ATTR_TRAP_METADATA);
8278 	if (!attr)
8279 		return -EMSGSIZE;
8280 
8281 	if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT) &&
8282 	    nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT))
8283 		goto nla_put_failure;
8284 	if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE) &&
8285 	    nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE))
8286 		goto nla_put_failure;
8287 
8288 	nla_nest_end(msg, attr);
8289 
8290 	return 0;
8291 
8292 nla_put_failure:
8293 	nla_nest_cancel(msg, attr);
8294 	return -EMSGSIZE;
8295 }
8296 
devlink_trap_stats_read(struct devlink_stats __percpu * trap_stats,struct devlink_stats * stats)8297 static void devlink_trap_stats_read(struct devlink_stats __percpu *trap_stats,
8298 				    struct devlink_stats *stats)
8299 {
8300 	int i;
8301 
8302 	memset(stats, 0, sizeof(*stats));
8303 	for_each_possible_cpu(i) {
8304 		struct devlink_stats *cpu_stats;
8305 		u64 rx_packets, rx_bytes;
8306 		unsigned int start;
8307 
8308 		cpu_stats = per_cpu_ptr(trap_stats, i);
8309 		do {
8310 			start = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
8311 			rx_packets = u64_stats_read(&cpu_stats->rx_packets);
8312 			rx_bytes = u64_stats_read(&cpu_stats->rx_bytes);
8313 		} while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start));
8314 
8315 		u64_stats_add(&stats->rx_packets, rx_packets);
8316 		u64_stats_add(&stats->rx_bytes, rx_bytes);
8317 	}
8318 }
8319 
8320 static int
devlink_trap_group_stats_put(struct sk_buff * msg,struct devlink_stats __percpu * trap_stats)8321 devlink_trap_group_stats_put(struct sk_buff *msg,
8322 			     struct devlink_stats __percpu *trap_stats)
8323 {
8324 	struct devlink_stats stats;
8325 	struct nlattr *attr;
8326 
8327 	devlink_trap_stats_read(trap_stats, &stats);
8328 
8329 	attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
8330 	if (!attr)
8331 		return -EMSGSIZE;
8332 
8333 	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS,
8334 			      u64_stats_read(&stats.rx_packets),
8335 			      DEVLINK_ATTR_PAD))
8336 		goto nla_put_failure;
8337 
8338 	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES,
8339 			      u64_stats_read(&stats.rx_bytes),
8340 			      DEVLINK_ATTR_PAD))
8341 		goto nla_put_failure;
8342 
8343 	nla_nest_end(msg, attr);
8344 
8345 	return 0;
8346 
8347 nla_put_failure:
8348 	nla_nest_cancel(msg, attr);
8349 	return -EMSGSIZE;
8350 }
8351 
devlink_trap_stats_put(struct sk_buff * msg,struct devlink * devlink,const struct devlink_trap_item * trap_item)8352 static int devlink_trap_stats_put(struct sk_buff *msg, struct devlink *devlink,
8353 				  const struct devlink_trap_item *trap_item)
8354 {
8355 	struct devlink_stats stats;
8356 	struct nlattr *attr;
8357 	u64 drops = 0;
8358 	int err;
8359 
8360 	if (devlink->ops->trap_drop_counter_get) {
8361 		err = devlink->ops->trap_drop_counter_get(devlink,
8362 							  trap_item->trap,
8363 							  &drops);
8364 		if (err)
8365 			return err;
8366 	}
8367 
8368 	devlink_trap_stats_read(trap_item->stats, &stats);
8369 
8370 	attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
8371 	if (!attr)
8372 		return -EMSGSIZE;
8373 
8374 	if (devlink->ops->trap_drop_counter_get &&
8375 	    nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops,
8376 			      DEVLINK_ATTR_PAD))
8377 		goto nla_put_failure;
8378 
8379 	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS,
8380 			      u64_stats_read(&stats.rx_packets),
8381 			      DEVLINK_ATTR_PAD))
8382 		goto nla_put_failure;
8383 
8384 	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES,
8385 			      u64_stats_read(&stats.rx_bytes),
8386 			      DEVLINK_ATTR_PAD))
8387 		goto nla_put_failure;
8388 
8389 	nla_nest_end(msg, attr);
8390 
8391 	return 0;
8392 
8393 nla_put_failure:
8394 	nla_nest_cancel(msg, attr);
8395 	return -EMSGSIZE;
8396 }
8397 
devlink_nl_trap_fill(struct sk_buff * msg,struct devlink * devlink,const struct devlink_trap_item * trap_item,enum devlink_command cmd,u32 portid,u32 seq,int flags)8398 static int devlink_nl_trap_fill(struct sk_buff *msg, struct devlink *devlink,
8399 				const struct devlink_trap_item *trap_item,
8400 				enum devlink_command cmd, u32 portid, u32 seq,
8401 				int flags)
8402 {
8403 	struct devlink_trap_group_item *group_item = trap_item->group_item;
8404 	void *hdr;
8405 	int err;
8406 
8407 	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
8408 	if (!hdr)
8409 		return -EMSGSIZE;
8410 
8411 	if (devlink_nl_put_handle(msg, devlink))
8412 		goto nla_put_failure;
8413 
8414 	if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
8415 			   group_item->group->name))
8416 		goto nla_put_failure;
8417 
8418 	if (nla_put_string(msg, DEVLINK_ATTR_TRAP_NAME, trap_item->trap->name))
8419 		goto nla_put_failure;
8420 
8421 	if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_TYPE, trap_item->trap->type))
8422 		goto nla_put_failure;
8423 
8424 	if (trap_item->trap->generic &&
8425 	    nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
8426 		goto nla_put_failure;
8427 
8428 	if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_ACTION, trap_item->action))
8429 		goto nla_put_failure;
8430 
8431 	err = devlink_trap_metadata_put(msg, trap_item->trap);
8432 	if (err)
8433 		goto nla_put_failure;
8434 
8435 	err = devlink_trap_stats_put(msg, devlink, trap_item);
8436 	if (err)
8437 		goto nla_put_failure;
8438 
8439 	genlmsg_end(msg, hdr);
8440 
8441 	return 0;
8442 
8443 nla_put_failure:
8444 	genlmsg_cancel(msg, hdr);
8445 	return -EMSGSIZE;
8446 }
8447 
devlink_nl_cmd_trap_get_doit(struct sk_buff * skb,struct genl_info * info)8448 static int devlink_nl_cmd_trap_get_doit(struct sk_buff *skb,
8449 					struct genl_info *info)
8450 {
8451 	struct netlink_ext_ack *extack = info->extack;
8452 	struct devlink *devlink = info->user_ptr[0];
8453 	struct devlink_trap_item *trap_item;
8454 	struct sk_buff *msg;
8455 	int err;
8456 
8457 	if (list_empty(&devlink->trap_list))
8458 		return -EOPNOTSUPP;
8459 
8460 	trap_item = devlink_trap_item_get_from_info(devlink, info);
8461 	if (!trap_item) {
8462 		NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
8463 		return -ENOENT;
8464 	}
8465 
8466 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8467 	if (!msg)
8468 		return -ENOMEM;
8469 
8470 	err = devlink_nl_trap_fill(msg, devlink, trap_item,
8471 				   DEVLINK_CMD_TRAP_NEW, info->snd_portid,
8472 				   info->snd_seq, 0);
8473 	if (err)
8474 		goto err_trap_fill;
8475 
8476 	return genlmsg_reply(msg, info);
8477 
8478 err_trap_fill:
8479 	nlmsg_free(msg);
8480 	return err;
8481 }
8482 
devlink_nl_cmd_trap_get_dumpit(struct sk_buff * msg,struct netlink_callback * cb)8483 static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff *msg,
8484 					  struct netlink_callback *cb)
8485 {
8486 	struct devlink_trap_item *trap_item;
8487 	struct devlink *devlink;
8488 	int start = cb->args[0];
8489 	unsigned long index;
8490 	int idx = 0;
8491 	int err;
8492 
8493 	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
8494 		devl_lock(devlink);
8495 		list_for_each_entry(trap_item, &devlink->trap_list, list) {
8496 			if (idx < start) {
8497 				idx++;
8498 				continue;
8499 			}
8500 			err = devlink_nl_trap_fill(msg, devlink, trap_item,
8501 						   DEVLINK_CMD_TRAP_NEW,
8502 						   NETLINK_CB(cb->skb).portid,
8503 						   cb->nlh->nlmsg_seq,
8504 						   NLM_F_MULTI);
8505 			if (err) {
8506 				devl_unlock(devlink);
8507 				devlink_put(devlink);
8508 				goto out;
8509 			}
8510 			idx++;
8511 		}
8512 		devl_unlock(devlink);
8513 		devlink_put(devlink);
8514 	}
8515 out:
8516 	cb->args[0] = idx;
8517 	return msg->len;
8518 }
8519 
__devlink_trap_action_set(struct devlink * devlink,struct devlink_trap_item * trap_item,enum devlink_trap_action trap_action,struct netlink_ext_ack * extack)8520 static int __devlink_trap_action_set(struct devlink *devlink,
8521 				     struct devlink_trap_item *trap_item,
8522 				     enum devlink_trap_action trap_action,
8523 				     struct netlink_ext_ack *extack)
8524 {
8525 	int err;
8526 
8527 	if (trap_item->action != trap_action &&
8528 	    trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) {
8529 		NL_SET_ERR_MSG_MOD(extack, "Cannot change action of non-drop traps. Skipping");
8530 		return 0;
8531 	}
8532 
8533 	err = devlink->ops->trap_action_set(devlink, trap_item->trap,
8534 					    trap_action, extack);
8535 	if (err)
8536 		return err;
8537 
8538 	trap_item->action = trap_action;
8539 
8540 	return 0;
8541 }
8542 
devlink_trap_action_set(struct devlink * devlink,struct devlink_trap_item * trap_item,struct genl_info * info)8543 static int devlink_trap_action_set(struct devlink *devlink,
8544 				   struct devlink_trap_item *trap_item,
8545 				   struct genl_info *info)
8546 {
8547 	enum devlink_trap_action trap_action;
8548 	int err;
8549 
8550 	if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
8551 		return 0;
8552 
8553 	err = devlink_trap_action_get_from_info(info, &trap_action);
8554 	if (err) {
8555 		NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
8556 		return -EINVAL;
8557 	}
8558 
8559 	return __devlink_trap_action_set(devlink, trap_item, trap_action,
8560 					 info->extack);
8561 }
8562 
devlink_nl_cmd_trap_set_doit(struct sk_buff * skb,struct genl_info * info)8563 static int devlink_nl_cmd_trap_set_doit(struct sk_buff *skb,
8564 					struct genl_info *info)
8565 {
8566 	struct netlink_ext_ack *extack = info->extack;
8567 	struct devlink *devlink = info->user_ptr[0];
8568 	struct devlink_trap_item *trap_item;
8569 
8570 	if (list_empty(&devlink->trap_list))
8571 		return -EOPNOTSUPP;
8572 
8573 	trap_item = devlink_trap_item_get_from_info(devlink, info);
8574 	if (!trap_item) {
8575 		NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
8576 		return -ENOENT;
8577 	}
8578 
8579 	return devlink_trap_action_set(devlink, trap_item, info);
8580 }
8581 
8582 static struct devlink_trap_group_item *
devlink_trap_group_item_lookup(struct devlink * devlink,const char * name)8583 devlink_trap_group_item_lookup(struct devlink *devlink, const char *name)
8584 {
8585 	struct devlink_trap_group_item *group_item;
8586 
8587 	list_for_each_entry(group_item, &devlink->trap_group_list, list) {
8588 		if (!strcmp(group_item->group->name, name))
8589 			return group_item;
8590 	}
8591 
8592 	return NULL;
8593 }
8594 
8595 static struct devlink_trap_group_item *
devlink_trap_group_item_lookup_by_id(struct devlink * devlink,u16 id)8596 devlink_trap_group_item_lookup_by_id(struct devlink *devlink, u16 id)
8597 {
8598 	struct devlink_trap_group_item *group_item;
8599 
8600 	list_for_each_entry(group_item, &devlink->trap_group_list, list) {
8601 		if (group_item->group->id == id)
8602 			return group_item;
8603 	}
8604 
8605 	return NULL;
8606 }
8607 
8608 static struct devlink_trap_group_item *
devlink_trap_group_item_get_from_info(struct devlink * devlink,struct genl_info * info)8609 devlink_trap_group_item_get_from_info(struct devlink *devlink,
8610 				      struct genl_info *info)
8611 {
8612 	char *name;
8613 
8614 	if (!info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME])
8615 		return NULL;
8616 	name = nla_data(info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]);
8617 
8618 	return devlink_trap_group_item_lookup(devlink, name);
8619 }
8620 
8621 static int
devlink_nl_trap_group_fill(struct sk_buff * msg,struct devlink * devlink,const struct devlink_trap_group_item * group_item,enum devlink_command cmd,u32 portid,u32 seq,int flags)8622 devlink_nl_trap_group_fill(struct sk_buff *msg, struct devlink *devlink,
8623 			   const struct devlink_trap_group_item *group_item,
8624 			   enum devlink_command cmd, u32 portid, u32 seq,
8625 			   int flags)
8626 {
8627 	void *hdr;
8628 	int err;
8629 
8630 	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
8631 	if (!hdr)
8632 		return -EMSGSIZE;
8633 
8634 	if (devlink_nl_put_handle(msg, devlink))
8635 		goto nla_put_failure;
8636 
8637 	if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
8638 			   group_item->group->name))
8639 		goto nla_put_failure;
8640 
8641 	if (group_item->group->generic &&
8642 	    nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
8643 		goto nla_put_failure;
8644 
8645 	if (group_item->policer_item &&
8646 	    nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
8647 			group_item->policer_item->policer->id))
8648 		goto nla_put_failure;
8649 
8650 	err = devlink_trap_group_stats_put(msg, group_item->stats);
8651 	if (err)
8652 		goto nla_put_failure;
8653 
8654 	genlmsg_end(msg, hdr);
8655 
8656 	return 0;
8657 
8658 nla_put_failure:
8659 	genlmsg_cancel(msg, hdr);
8660 	return -EMSGSIZE;
8661 }
8662 
devlink_nl_cmd_trap_group_get_doit(struct sk_buff * skb,struct genl_info * info)8663 static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff *skb,
8664 					      struct genl_info *info)
8665 {
8666 	struct netlink_ext_ack *extack = info->extack;
8667 	struct devlink *devlink = info->user_ptr[0];
8668 	struct devlink_trap_group_item *group_item;
8669 	struct sk_buff *msg;
8670 	int err;
8671 
8672 	if (list_empty(&devlink->trap_group_list))
8673 		return -EOPNOTSUPP;
8674 
8675 	group_item = devlink_trap_group_item_get_from_info(devlink, info);
8676 	if (!group_item) {
8677 		NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
8678 		return -ENOENT;
8679 	}
8680 
8681 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8682 	if (!msg)
8683 		return -ENOMEM;
8684 
8685 	err = devlink_nl_trap_group_fill(msg, devlink, group_item,
8686 					 DEVLINK_CMD_TRAP_GROUP_NEW,
8687 					 info->snd_portid, info->snd_seq, 0);
8688 	if (err)
8689 		goto err_trap_group_fill;
8690 
8691 	return genlmsg_reply(msg, info);
8692 
8693 err_trap_group_fill:
8694 	nlmsg_free(msg);
8695 	return err;
8696 }
8697 
devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff * msg,struct netlink_callback * cb)8698 static int devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff *msg,
8699 						struct netlink_callback *cb)
8700 {
8701 	enum devlink_command cmd = DEVLINK_CMD_TRAP_GROUP_NEW;
8702 	struct devlink_trap_group_item *group_item;
8703 	u32 portid = NETLINK_CB(cb->skb).portid;
8704 	struct devlink *devlink;
8705 	int start = cb->args[0];
8706 	unsigned long index;
8707 	int idx = 0;
8708 	int err;
8709 
8710 	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
8711 		devl_lock(devlink);
8712 		list_for_each_entry(group_item, &devlink->trap_group_list,
8713 				    list) {
8714 			if (idx < start) {
8715 				idx++;
8716 				continue;
8717 			}
8718 			err = devlink_nl_trap_group_fill(msg, devlink,
8719 							 group_item, cmd,
8720 							 portid,
8721 							 cb->nlh->nlmsg_seq,
8722 							 NLM_F_MULTI);
8723 			if (err) {
8724 				devl_unlock(devlink);
8725 				devlink_put(devlink);
8726 				goto out;
8727 			}
8728 			idx++;
8729 		}
8730 		devl_unlock(devlink);
8731 		devlink_put(devlink);
8732 	}
8733 out:
8734 	cb->args[0] = idx;
8735 	return msg->len;
8736 }
8737 
8738 static int
__devlink_trap_group_action_set(struct devlink * devlink,struct devlink_trap_group_item * group_item,enum devlink_trap_action trap_action,struct netlink_ext_ack * extack)8739 __devlink_trap_group_action_set(struct devlink *devlink,
8740 				struct devlink_trap_group_item *group_item,
8741 				enum devlink_trap_action trap_action,
8742 				struct netlink_ext_ack *extack)
8743 {
8744 	const char *group_name = group_item->group->name;
8745 	struct devlink_trap_item *trap_item;
8746 	int err;
8747 
8748 	if (devlink->ops->trap_group_action_set) {
8749 		err = devlink->ops->trap_group_action_set(devlink, group_item->group,
8750 							  trap_action, extack);
8751 		if (err)
8752 			return err;
8753 
8754 		list_for_each_entry(trap_item, &devlink->trap_list, list) {
8755 			if (strcmp(trap_item->group_item->group->name, group_name))
8756 				continue;
8757 			if (trap_item->action != trap_action &&
8758 			    trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP)
8759 				continue;
8760 			trap_item->action = trap_action;
8761 		}
8762 
8763 		return 0;
8764 	}
8765 
8766 	list_for_each_entry(trap_item, &devlink->trap_list, list) {
8767 		if (strcmp(trap_item->group_item->group->name, group_name))
8768 			continue;
8769 		err = __devlink_trap_action_set(devlink, trap_item,
8770 						trap_action, extack);
8771 		if (err)
8772 			return err;
8773 	}
8774 
8775 	return 0;
8776 }
8777 
8778 static int
devlink_trap_group_action_set(struct devlink * devlink,struct devlink_trap_group_item * group_item,struct genl_info * info,bool * p_modified)8779 devlink_trap_group_action_set(struct devlink *devlink,
8780 			      struct devlink_trap_group_item *group_item,
8781 			      struct genl_info *info, bool *p_modified)
8782 {
8783 	enum devlink_trap_action trap_action;
8784 	int err;
8785 
8786 	if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
8787 		return 0;
8788 
8789 	err = devlink_trap_action_get_from_info(info, &trap_action);
8790 	if (err) {
8791 		NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
8792 		return -EINVAL;
8793 	}
8794 
8795 	err = __devlink_trap_group_action_set(devlink, group_item, trap_action,
8796 					      info->extack);
8797 	if (err)
8798 		return err;
8799 
8800 	*p_modified = true;
8801 
8802 	return 0;
8803 }
8804 
devlink_trap_group_set(struct devlink * devlink,struct devlink_trap_group_item * group_item,struct genl_info * info)8805 static int devlink_trap_group_set(struct devlink *devlink,
8806 				  struct devlink_trap_group_item *group_item,
8807 				  struct genl_info *info)
8808 {
8809 	struct devlink_trap_policer_item *policer_item;
8810 	struct netlink_ext_ack *extack = info->extack;
8811 	const struct devlink_trap_policer *policer;
8812 	struct nlattr **attrs = info->attrs;
8813 	int err;
8814 
8815 	if (!attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
8816 		return 0;
8817 
8818 	if (!devlink->ops->trap_group_set)
8819 		return -EOPNOTSUPP;
8820 
8821 	policer_item = group_item->policer_item;
8822 	if (attrs[DEVLINK_ATTR_TRAP_POLICER_ID]) {
8823 		u32 policer_id;
8824 
8825 		policer_id = nla_get_u32(attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
8826 		policer_item = devlink_trap_policer_item_lookup(devlink,
8827 								policer_id);
8828 		if (policer_id && !policer_item) {
8829 			NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
8830 			return -ENOENT;
8831 		}
8832 	}
8833 	policer = policer_item ? policer_item->policer : NULL;
8834 
8835 	err = devlink->ops->trap_group_set(devlink, group_item->group, policer,
8836 					   extack);
8837 	if (err)
8838 		return err;
8839 
8840 	group_item->policer_item = policer_item;
8841 
8842 	return 0;
8843 }
8844 
devlink_nl_cmd_trap_group_set_doit(struct sk_buff * skb,struct genl_info * info)8845 static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff *skb,
8846 					      struct genl_info *info)
8847 {
8848 	struct netlink_ext_ack *extack = info->extack;
8849 	struct devlink *devlink = info->user_ptr[0];
8850 	struct devlink_trap_group_item *group_item;
8851 	bool modified = false;
8852 	int err;
8853 
8854 	if (list_empty(&devlink->trap_group_list))
8855 		return -EOPNOTSUPP;
8856 
8857 	group_item = devlink_trap_group_item_get_from_info(devlink, info);
8858 	if (!group_item) {
8859 		NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
8860 		return -ENOENT;
8861 	}
8862 
8863 	err = devlink_trap_group_action_set(devlink, group_item, info,
8864 					    &modified);
8865 	if (err)
8866 		return err;
8867 
8868 	err = devlink_trap_group_set(devlink, group_item, info);
8869 	if (err)
8870 		goto err_trap_group_set;
8871 
8872 	return 0;
8873 
8874 err_trap_group_set:
8875 	if (modified)
8876 		NL_SET_ERR_MSG_MOD(extack, "Trap group set failed, but some changes were committed already");
8877 	return err;
8878 }
8879 
8880 static struct devlink_trap_policer_item *
devlink_trap_policer_item_get_from_info(struct devlink * devlink,struct genl_info * info)8881 devlink_trap_policer_item_get_from_info(struct devlink *devlink,
8882 					struct genl_info *info)
8883 {
8884 	u32 id;
8885 
8886 	if (!info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
8887 		return NULL;
8888 	id = nla_get_u32(info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
8889 
8890 	return devlink_trap_policer_item_lookup(devlink, id);
8891 }
8892 
8893 static int
devlink_trap_policer_stats_put(struct sk_buff * msg,struct devlink * devlink,const struct devlink_trap_policer * policer)8894 devlink_trap_policer_stats_put(struct sk_buff *msg, struct devlink *devlink,
8895 			       const struct devlink_trap_policer *policer)
8896 {
8897 	struct nlattr *attr;
8898 	u64 drops;
8899 	int err;
8900 
8901 	if (!devlink->ops->trap_policer_counter_get)
8902 		return 0;
8903 
8904 	err = devlink->ops->trap_policer_counter_get(devlink, policer, &drops);
8905 	if (err)
8906 		return err;
8907 
8908 	attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
8909 	if (!attr)
8910 		return -EMSGSIZE;
8911 
8912 	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops,
8913 			      DEVLINK_ATTR_PAD))
8914 		goto nla_put_failure;
8915 
8916 	nla_nest_end(msg, attr);
8917 
8918 	return 0;
8919 
8920 nla_put_failure:
8921 	nla_nest_cancel(msg, attr);
8922 	return -EMSGSIZE;
8923 }
8924 
8925 static int
devlink_nl_trap_policer_fill(struct sk_buff * msg,struct devlink * devlink,const struct devlink_trap_policer_item * policer_item,enum devlink_command cmd,u32 portid,u32 seq,int flags)8926 devlink_nl_trap_policer_fill(struct sk_buff *msg, struct devlink *devlink,
8927 			     const struct devlink_trap_policer_item *policer_item,
8928 			     enum devlink_command cmd, u32 portid, u32 seq,
8929 			     int flags)
8930 {
8931 	void *hdr;
8932 	int err;
8933 
8934 	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
8935 	if (!hdr)
8936 		return -EMSGSIZE;
8937 
8938 	if (devlink_nl_put_handle(msg, devlink))
8939 		goto nla_put_failure;
8940 
8941 	if (nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
8942 			policer_item->policer->id))
8943 		goto nla_put_failure;
8944 
8945 	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_RATE,
8946 			      policer_item->rate, DEVLINK_ATTR_PAD))
8947 		goto nla_put_failure;
8948 
8949 	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_BURST,
8950 			      policer_item->burst, DEVLINK_ATTR_PAD))
8951 		goto nla_put_failure;
8952 
8953 	err = devlink_trap_policer_stats_put(msg, devlink,
8954 					     policer_item->policer);
8955 	if (err)
8956 		goto nla_put_failure;
8957 
8958 	genlmsg_end(msg, hdr);
8959 
8960 	return 0;
8961 
8962 nla_put_failure:
8963 	genlmsg_cancel(msg, hdr);
8964 	return -EMSGSIZE;
8965 }
8966 
devlink_nl_cmd_trap_policer_get_doit(struct sk_buff * skb,struct genl_info * info)8967 static int devlink_nl_cmd_trap_policer_get_doit(struct sk_buff *skb,
8968 						struct genl_info *info)
8969 {
8970 	struct devlink_trap_policer_item *policer_item;
8971 	struct netlink_ext_ack *extack = info->extack;
8972 	struct devlink *devlink = info->user_ptr[0];
8973 	struct sk_buff *msg;
8974 	int err;
8975 
8976 	if (list_empty(&devlink->trap_policer_list))
8977 		return -EOPNOTSUPP;
8978 
8979 	policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
8980 	if (!policer_item) {
8981 		NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
8982 		return -ENOENT;
8983 	}
8984 
8985 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8986 	if (!msg)
8987 		return -ENOMEM;
8988 
8989 	err = devlink_nl_trap_policer_fill(msg, devlink, policer_item,
8990 					   DEVLINK_CMD_TRAP_POLICER_NEW,
8991 					   info->snd_portid, info->snd_seq, 0);
8992 	if (err)
8993 		goto err_trap_policer_fill;
8994 
8995 	return genlmsg_reply(msg, info);
8996 
8997 err_trap_policer_fill:
8998 	nlmsg_free(msg);
8999 	return err;
9000 }
9001 
devlink_nl_cmd_trap_policer_get_dumpit(struct sk_buff * msg,struct netlink_callback * cb)9002 static int devlink_nl_cmd_trap_policer_get_dumpit(struct sk_buff *msg,
9003 						  struct netlink_callback *cb)
9004 {
9005 	enum devlink_command cmd = DEVLINK_CMD_TRAP_POLICER_NEW;
9006 	struct devlink_trap_policer_item *policer_item;
9007 	u32 portid = NETLINK_CB(cb->skb).portid;
9008 	struct devlink *devlink;
9009 	int start = cb->args[0];
9010 	unsigned long index;
9011 	int idx = 0;
9012 	int err;
9013 
9014 	devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
9015 		devl_lock(devlink);
9016 		list_for_each_entry(policer_item, &devlink->trap_policer_list,
9017 				    list) {
9018 			if (idx < start) {
9019 				idx++;
9020 				continue;
9021 			}
9022 			err = devlink_nl_trap_policer_fill(msg, devlink,
9023 							   policer_item, cmd,
9024 							   portid,
9025 							   cb->nlh->nlmsg_seq,
9026 							   NLM_F_MULTI);
9027 			if (err) {
9028 				devl_unlock(devlink);
9029 				devlink_put(devlink);
9030 				goto out;
9031 			}
9032 			idx++;
9033 		}
9034 		devl_unlock(devlink);
9035 		devlink_put(devlink);
9036 	}
9037 out:
9038 	cb->args[0] = idx;
9039 	return msg->len;
9040 }
9041 
9042 static int
devlink_trap_policer_set(struct devlink * devlink,struct devlink_trap_policer_item * policer_item,struct genl_info * info)9043 devlink_trap_policer_set(struct devlink *devlink,
9044 			 struct devlink_trap_policer_item *policer_item,
9045 			 struct genl_info *info)
9046 {
9047 	struct netlink_ext_ack *extack = info->extack;
9048 	struct nlattr **attrs = info->attrs;
9049 	u64 rate, burst;
9050 	int err;
9051 
9052 	rate = policer_item->rate;
9053 	burst = policer_item->burst;
9054 
9055 	if (attrs[DEVLINK_ATTR_TRAP_POLICER_RATE])
9056 		rate = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_RATE]);
9057 
9058 	if (attrs[DEVLINK_ATTR_TRAP_POLICER_BURST])
9059 		burst = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_BURST]);
9060 
9061 	if (rate < policer_item->policer->min_rate) {
9062 		NL_SET_ERR_MSG_MOD(extack, "Policer rate lower than limit");
9063 		return -EINVAL;
9064 	}
9065 
9066 	if (rate > policer_item->policer->max_rate) {
9067 		NL_SET_ERR_MSG_MOD(extack, "Policer rate higher than limit");
9068 		return -EINVAL;
9069 	}
9070 
9071 	if (burst < policer_item->policer->min_burst) {
9072 		NL_SET_ERR_MSG_MOD(extack, "Policer burst size lower than limit");
9073 		return -EINVAL;
9074 	}
9075 
9076 	if (burst > policer_item->policer->max_burst) {
9077 		NL_SET_ERR_MSG_MOD(extack, "Policer burst size higher than limit");
9078 		return -EINVAL;
9079 	}
9080 
9081 	err = devlink->ops->trap_policer_set(devlink, policer_item->policer,
9082 					     rate, burst, info->extack);
9083 	if (err)
9084 		return err;
9085 
9086 	policer_item->rate = rate;
9087 	policer_item->burst = burst;
9088 
9089 	return 0;
9090 }
9091 
devlink_nl_cmd_trap_policer_set_doit(struct sk_buff * skb,struct genl_info * info)9092 static int devlink_nl_cmd_trap_policer_set_doit(struct sk_buff *skb,
9093 						struct genl_info *info)
9094 {
9095 	struct devlink_trap_policer_item *policer_item;
9096 	struct netlink_ext_ack *extack = info->extack;
9097 	struct devlink *devlink = info->user_ptr[0];
9098 
9099 	if (list_empty(&devlink->trap_policer_list))
9100 		return -EOPNOTSUPP;
9101 
9102 	if (!devlink->ops->trap_policer_set)
9103 		return -EOPNOTSUPP;
9104 
9105 	policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
9106 	if (!policer_item) {
9107 		NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
9108 		return -ENOENT;
9109 	}
9110 
9111 	return devlink_trap_policer_set(devlink, policer_item, info);
9112 }
9113 
9114 static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
9115 	[DEVLINK_ATTR_UNSPEC] = { .strict_start_type =
9116 		DEVLINK_ATTR_TRAP_POLICER_ID },
9117 	[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
9118 	[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
9119 	[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 },
9120 	[DEVLINK_ATTR_PORT_TYPE] = NLA_POLICY_RANGE(NLA_U16, DEVLINK_PORT_TYPE_AUTO,
9121 						    DEVLINK_PORT_TYPE_IB),
9122 	[DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 },
9123 	[DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 },
9124 	[DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 },
9125 	[DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 },
9126 	[DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 },
9127 	[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 },
9128 	[DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
9129 	[DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
9130 	[DEVLINK_ATTR_ESWITCH_MODE] = NLA_POLICY_RANGE(NLA_U16, DEVLINK_ESWITCH_MODE_LEGACY,
9131 						       DEVLINK_ESWITCH_MODE_SWITCHDEV),
9132 	[DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 },
9133 	[DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 },
9134 	[DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING },
9135 	[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 },
9136 	[DEVLINK_ATTR_RESOURCE_ID] = { .type = NLA_U64},
9137 	[DEVLINK_ATTR_RESOURCE_SIZE] = { .type = NLA_U64},
9138 	[DEVLINK_ATTR_PARAM_NAME] = { .type = NLA_NUL_STRING },
9139 	[DEVLINK_ATTR_PARAM_TYPE] = { .type = NLA_U8 },
9140 	[DEVLINK_ATTR_PARAM_VALUE_CMODE] = { .type = NLA_U8 },
9141 	[DEVLINK_ATTR_REGION_NAME] = { .type = NLA_NUL_STRING },
9142 	[DEVLINK_ATTR_REGION_SNAPSHOT_ID] = { .type = NLA_U32 },
9143 	[DEVLINK_ATTR_REGION_CHUNK_ADDR] = { .type = NLA_U64 },
9144 	[DEVLINK_ATTR_REGION_CHUNK_LEN] = { .type = NLA_U64 },
9145 	[DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING },
9146 	[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] = { .type = NLA_U64 },
9147 	[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER] = { .type = NLA_U8 },
9148 	[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME] = { .type = NLA_NUL_STRING },
9149 	[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT] = { .type = NLA_NUL_STRING },
9150 	[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK] =
9151 		NLA_POLICY_BITFIELD32(DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS),
9152 	[DEVLINK_ATTR_TRAP_NAME] = { .type = NLA_NUL_STRING },
9153 	[DEVLINK_ATTR_TRAP_ACTION] = { .type = NLA_U8 },
9154 	[DEVLINK_ATTR_TRAP_GROUP_NAME] = { .type = NLA_NUL_STRING },
9155 	[DEVLINK_ATTR_NETNS_PID] = { .type = NLA_U32 },
9156 	[DEVLINK_ATTR_NETNS_FD] = { .type = NLA_U32 },
9157 	[DEVLINK_ATTR_NETNS_ID] = { .type = NLA_U32 },
9158 	[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP] = { .type = NLA_U8 },
9159 	[DEVLINK_ATTR_TRAP_POLICER_ID] = { .type = NLA_U32 },
9160 	[DEVLINK_ATTR_TRAP_POLICER_RATE] = { .type = NLA_U64 },
9161 	[DEVLINK_ATTR_TRAP_POLICER_BURST] = { .type = NLA_U64 },
9162 	[DEVLINK_ATTR_PORT_FUNCTION] = { .type = NLA_NESTED },
9163 	[DEVLINK_ATTR_RELOAD_ACTION] = NLA_POLICY_RANGE(NLA_U8, DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
9164 							DEVLINK_RELOAD_ACTION_MAX),
9165 	[DEVLINK_ATTR_RELOAD_LIMITS] = NLA_POLICY_BITFIELD32(DEVLINK_RELOAD_LIMITS_VALID_MASK),
9166 	[DEVLINK_ATTR_PORT_FLAVOUR] = { .type = NLA_U16 },
9167 	[DEVLINK_ATTR_PORT_PCI_PF_NUMBER] = { .type = NLA_U16 },
9168 	[DEVLINK_ATTR_PORT_PCI_SF_NUMBER] = { .type = NLA_U32 },
9169 	[DEVLINK_ATTR_PORT_CONTROLLER_NUMBER] = { .type = NLA_U32 },
9170 	[DEVLINK_ATTR_RATE_TYPE] = { .type = NLA_U16 },
9171 	[DEVLINK_ATTR_RATE_TX_SHARE] = { .type = NLA_U64 },
9172 	[DEVLINK_ATTR_RATE_TX_MAX] = { .type = NLA_U64 },
9173 	[DEVLINK_ATTR_RATE_NODE_NAME] = { .type = NLA_NUL_STRING },
9174 	[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] = { .type = NLA_NUL_STRING },
9175 	[DEVLINK_ATTR_LINECARD_INDEX] = { .type = NLA_U32 },
9176 	[DEVLINK_ATTR_LINECARD_TYPE] = { .type = NLA_NUL_STRING },
9177 	[DEVLINK_ATTR_SELFTESTS] = { .type = NLA_NESTED },
9178 };
9179 
9180 static const struct genl_small_ops devlink_nl_ops[] = {
9181 	{
9182 		.cmd = DEVLINK_CMD_GET,
9183 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9184 		.doit = devlink_nl_cmd_get_doit,
9185 		.dumpit = devlink_nl_cmd_get_dumpit,
9186 		/* can be retrieved by unprivileged users */
9187 	},
9188 	{
9189 		.cmd = DEVLINK_CMD_PORT_GET,
9190 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9191 		.doit = devlink_nl_cmd_port_get_doit,
9192 		.dumpit = devlink_nl_cmd_port_get_dumpit,
9193 		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9194 		/* can be retrieved by unprivileged users */
9195 	},
9196 	{
9197 		.cmd = DEVLINK_CMD_PORT_SET,
9198 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9199 		.doit = devlink_nl_cmd_port_set_doit,
9200 		.flags = GENL_ADMIN_PERM,
9201 		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9202 	},
9203 	{
9204 		.cmd = DEVLINK_CMD_RATE_GET,
9205 		.doit = devlink_nl_cmd_rate_get_doit,
9206 		.dumpit = devlink_nl_cmd_rate_get_dumpit,
9207 		.internal_flags = DEVLINK_NL_FLAG_NEED_RATE,
9208 		/* can be retrieved by unprivileged users */
9209 	},
9210 	{
9211 		.cmd = DEVLINK_CMD_RATE_SET,
9212 		.doit = devlink_nl_cmd_rate_set_doit,
9213 		.flags = GENL_ADMIN_PERM,
9214 		.internal_flags = DEVLINK_NL_FLAG_NEED_RATE,
9215 	},
9216 	{
9217 		.cmd = DEVLINK_CMD_RATE_NEW,
9218 		.doit = devlink_nl_cmd_rate_new_doit,
9219 		.flags = GENL_ADMIN_PERM,
9220 	},
9221 	{
9222 		.cmd = DEVLINK_CMD_RATE_DEL,
9223 		.doit = devlink_nl_cmd_rate_del_doit,
9224 		.flags = GENL_ADMIN_PERM,
9225 		.internal_flags = DEVLINK_NL_FLAG_NEED_RATE_NODE,
9226 	},
9227 	{
9228 		.cmd = DEVLINK_CMD_PORT_SPLIT,
9229 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9230 		.doit = devlink_nl_cmd_port_split_doit,
9231 		.flags = GENL_ADMIN_PERM,
9232 		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9233 	},
9234 	{
9235 		.cmd = DEVLINK_CMD_PORT_UNSPLIT,
9236 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9237 		.doit = devlink_nl_cmd_port_unsplit_doit,
9238 		.flags = GENL_ADMIN_PERM,
9239 		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9240 	},
9241 	{
9242 		.cmd = DEVLINK_CMD_PORT_NEW,
9243 		.doit = devlink_nl_cmd_port_new_doit,
9244 		.flags = GENL_ADMIN_PERM,
9245 	},
9246 	{
9247 		.cmd = DEVLINK_CMD_PORT_DEL,
9248 		.doit = devlink_nl_cmd_port_del_doit,
9249 		.flags = GENL_ADMIN_PERM,
9250 	},
9251 	{
9252 		.cmd = DEVLINK_CMD_LINECARD_GET,
9253 		.doit = devlink_nl_cmd_linecard_get_doit,
9254 		.dumpit = devlink_nl_cmd_linecard_get_dumpit,
9255 		.internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD,
9256 		/* can be retrieved by unprivileged users */
9257 	},
9258 	{
9259 		.cmd = DEVLINK_CMD_LINECARD_SET,
9260 		.doit = devlink_nl_cmd_linecard_set_doit,
9261 		.flags = GENL_ADMIN_PERM,
9262 		.internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD,
9263 	},
9264 	{
9265 		.cmd = DEVLINK_CMD_SB_GET,
9266 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9267 		.doit = devlink_nl_cmd_sb_get_doit,
9268 		.dumpit = devlink_nl_cmd_sb_get_dumpit,
9269 		/* can be retrieved by unprivileged users */
9270 	},
9271 	{
9272 		.cmd = DEVLINK_CMD_SB_POOL_GET,
9273 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9274 		.doit = devlink_nl_cmd_sb_pool_get_doit,
9275 		.dumpit = devlink_nl_cmd_sb_pool_get_dumpit,
9276 		/* can be retrieved by unprivileged users */
9277 	},
9278 	{
9279 		.cmd = DEVLINK_CMD_SB_POOL_SET,
9280 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9281 		.doit = devlink_nl_cmd_sb_pool_set_doit,
9282 		.flags = GENL_ADMIN_PERM,
9283 	},
9284 	{
9285 		.cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
9286 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9287 		.doit = devlink_nl_cmd_sb_port_pool_get_doit,
9288 		.dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit,
9289 		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9290 		/* can be retrieved by unprivileged users */
9291 	},
9292 	{
9293 		.cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
9294 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9295 		.doit = devlink_nl_cmd_sb_port_pool_set_doit,
9296 		.flags = GENL_ADMIN_PERM,
9297 		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9298 	},
9299 	{
9300 		.cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
9301 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9302 		.doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
9303 		.dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit,
9304 		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9305 		/* can be retrieved by unprivileged users */
9306 	},
9307 	{
9308 		.cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
9309 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9310 		.doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
9311 		.flags = GENL_ADMIN_PERM,
9312 		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9313 	},
9314 	{
9315 		.cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
9316 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9317 		.doit = devlink_nl_cmd_sb_occ_snapshot_doit,
9318 		.flags = GENL_ADMIN_PERM,
9319 	},
9320 	{
9321 		.cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
9322 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9323 		.doit = devlink_nl_cmd_sb_occ_max_clear_doit,
9324 		.flags = GENL_ADMIN_PERM,
9325 	},
9326 	{
9327 		.cmd = DEVLINK_CMD_ESWITCH_GET,
9328 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9329 		.doit = devlink_nl_cmd_eswitch_get_doit,
9330 		.flags = GENL_ADMIN_PERM,
9331 	},
9332 	{
9333 		.cmd = DEVLINK_CMD_ESWITCH_SET,
9334 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9335 		.doit = devlink_nl_cmd_eswitch_set_doit,
9336 		.flags = GENL_ADMIN_PERM,
9337 	},
9338 	{
9339 		.cmd = DEVLINK_CMD_DPIPE_TABLE_GET,
9340 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9341 		.doit = devlink_nl_cmd_dpipe_table_get,
9342 		/* can be retrieved by unprivileged users */
9343 	},
9344 	{
9345 		.cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET,
9346 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9347 		.doit = devlink_nl_cmd_dpipe_entries_get,
9348 		/* can be retrieved by unprivileged users */
9349 	},
9350 	{
9351 		.cmd = DEVLINK_CMD_DPIPE_HEADERS_GET,
9352 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9353 		.doit = devlink_nl_cmd_dpipe_headers_get,
9354 		/* can be retrieved by unprivileged users */
9355 	},
9356 	{
9357 		.cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
9358 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9359 		.doit = devlink_nl_cmd_dpipe_table_counters_set,
9360 		.flags = GENL_ADMIN_PERM,
9361 	},
9362 	{
9363 		.cmd = DEVLINK_CMD_RESOURCE_SET,
9364 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9365 		.doit = devlink_nl_cmd_resource_set,
9366 		.flags = GENL_ADMIN_PERM,
9367 	},
9368 	{
9369 		.cmd = DEVLINK_CMD_RESOURCE_DUMP,
9370 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9371 		.doit = devlink_nl_cmd_resource_dump,
9372 		/* can be retrieved by unprivileged users */
9373 	},
9374 	{
9375 		.cmd = DEVLINK_CMD_RELOAD,
9376 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9377 		.doit = devlink_nl_cmd_reload,
9378 		.flags = GENL_ADMIN_PERM,
9379 	},
9380 	{
9381 		.cmd = DEVLINK_CMD_PARAM_GET,
9382 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9383 		.doit = devlink_nl_cmd_param_get_doit,
9384 		.dumpit = devlink_nl_cmd_param_get_dumpit,
9385 		/* can be retrieved by unprivileged users */
9386 	},
9387 	{
9388 		.cmd = DEVLINK_CMD_PARAM_SET,
9389 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9390 		.doit = devlink_nl_cmd_param_set_doit,
9391 		.flags = GENL_ADMIN_PERM,
9392 	},
9393 	{
9394 		.cmd = DEVLINK_CMD_PORT_PARAM_GET,
9395 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9396 		.doit = devlink_nl_cmd_port_param_get_doit,
9397 		.dumpit = devlink_nl_cmd_port_param_get_dumpit,
9398 		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9399 		/* can be retrieved by unprivileged users */
9400 	},
9401 	{
9402 		.cmd = DEVLINK_CMD_PORT_PARAM_SET,
9403 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9404 		.doit = devlink_nl_cmd_port_param_set_doit,
9405 		.flags = GENL_ADMIN_PERM,
9406 		.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9407 	},
9408 	{
9409 		.cmd = DEVLINK_CMD_REGION_GET,
9410 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9411 		.doit = devlink_nl_cmd_region_get_doit,
9412 		.dumpit = devlink_nl_cmd_region_get_dumpit,
9413 		.flags = GENL_ADMIN_PERM,
9414 	},
9415 	{
9416 		.cmd = DEVLINK_CMD_REGION_NEW,
9417 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9418 		.doit = devlink_nl_cmd_region_new,
9419 		.flags = GENL_ADMIN_PERM,
9420 	},
9421 	{
9422 		.cmd = DEVLINK_CMD_REGION_DEL,
9423 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9424 		.doit = devlink_nl_cmd_region_del,
9425 		.flags = GENL_ADMIN_PERM,
9426 	},
9427 	{
9428 		.cmd = DEVLINK_CMD_REGION_READ,
9429 		.validate = GENL_DONT_VALIDATE_STRICT |
9430 			    GENL_DONT_VALIDATE_DUMP_STRICT,
9431 		.dumpit = devlink_nl_cmd_region_read_dumpit,
9432 		.flags = GENL_ADMIN_PERM,
9433 	},
9434 	{
9435 		.cmd = DEVLINK_CMD_INFO_GET,
9436 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9437 		.doit = devlink_nl_cmd_info_get_doit,
9438 		.dumpit = devlink_nl_cmd_info_get_dumpit,
9439 		/* can be retrieved by unprivileged users */
9440 	},
9441 	{
9442 		.cmd = DEVLINK_CMD_HEALTH_REPORTER_GET,
9443 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9444 		.doit = devlink_nl_cmd_health_reporter_get_doit,
9445 		.dumpit = devlink_nl_cmd_health_reporter_get_dumpit,
9446 		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9447 		/* can be retrieved by unprivileged users */
9448 	},
9449 	{
9450 		.cmd = DEVLINK_CMD_HEALTH_REPORTER_SET,
9451 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9452 		.doit = devlink_nl_cmd_health_reporter_set_doit,
9453 		.flags = GENL_ADMIN_PERM,
9454 		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9455 	},
9456 	{
9457 		.cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER,
9458 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9459 		.doit = devlink_nl_cmd_health_reporter_recover_doit,
9460 		.flags = GENL_ADMIN_PERM,
9461 		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9462 	},
9463 	{
9464 		.cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE,
9465 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9466 		.doit = devlink_nl_cmd_health_reporter_diagnose_doit,
9467 		.flags = GENL_ADMIN_PERM,
9468 		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9469 	},
9470 	{
9471 		.cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET,
9472 		.validate = GENL_DONT_VALIDATE_STRICT |
9473 			    GENL_DONT_VALIDATE_DUMP_STRICT,
9474 		.dumpit = devlink_nl_cmd_health_reporter_dump_get_dumpit,
9475 		.flags = GENL_ADMIN_PERM,
9476 	},
9477 	{
9478 		.cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR,
9479 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9480 		.doit = devlink_nl_cmd_health_reporter_dump_clear_doit,
9481 		.flags = GENL_ADMIN_PERM,
9482 		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9483 	},
9484 	{
9485 		.cmd = DEVLINK_CMD_HEALTH_REPORTER_TEST,
9486 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9487 		.doit = devlink_nl_cmd_health_reporter_test_doit,
9488 		.flags = GENL_ADMIN_PERM,
9489 		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9490 	},
9491 	{
9492 		.cmd = DEVLINK_CMD_FLASH_UPDATE,
9493 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9494 		.doit = devlink_nl_cmd_flash_update,
9495 		.flags = GENL_ADMIN_PERM,
9496 	},
9497 	{
9498 		.cmd = DEVLINK_CMD_TRAP_GET,
9499 		.doit = devlink_nl_cmd_trap_get_doit,
9500 		.dumpit = devlink_nl_cmd_trap_get_dumpit,
9501 		/* can be retrieved by unprivileged users */
9502 	},
9503 	{
9504 		.cmd = DEVLINK_CMD_TRAP_SET,
9505 		.doit = devlink_nl_cmd_trap_set_doit,
9506 		.flags = GENL_ADMIN_PERM,
9507 	},
9508 	{
9509 		.cmd = DEVLINK_CMD_TRAP_GROUP_GET,
9510 		.doit = devlink_nl_cmd_trap_group_get_doit,
9511 		.dumpit = devlink_nl_cmd_trap_group_get_dumpit,
9512 		/* can be retrieved by unprivileged users */
9513 	},
9514 	{
9515 		.cmd = DEVLINK_CMD_TRAP_GROUP_SET,
9516 		.doit = devlink_nl_cmd_trap_group_set_doit,
9517 		.flags = GENL_ADMIN_PERM,
9518 	},
9519 	{
9520 		.cmd = DEVLINK_CMD_TRAP_POLICER_GET,
9521 		.doit = devlink_nl_cmd_trap_policer_get_doit,
9522 		.dumpit = devlink_nl_cmd_trap_policer_get_dumpit,
9523 		/* can be retrieved by unprivileged users */
9524 	},
9525 	{
9526 		.cmd = DEVLINK_CMD_TRAP_POLICER_SET,
9527 		.doit = devlink_nl_cmd_trap_policer_set_doit,
9528 		.flags = GENL_ADMIN_PERM,
9529 	},
9530 	{
9531 		.cmd = DEVLINK_CMD_SELFTESTS_GET,
9532 		.doit = devlink_nl_cmd_selftests_get_doit,
9533 		.dumpit = devlink_nl_cmd_selftests_get_dumpit
9534 		/* can be retrieved by unprivileged users */
9535 	},
9536 	{
9537 		.cmd = DEVLINK_CMD_SELFTESTS_RUN,
9538 		.doit = devlink_nl_cmd_selftests_run,
9539 		.flags = GENL_ADMIN_PERM,
9540 	},
9541 };
9542 
9543 static struct genl_family devlink_nl_family __ro_after_init = {
9544 	.name		= DEVLINK_GENL_NAME,
9545 	.version	= DEVLINK_GENL_VERSION,
9546 	.maxattr	= DEVLINK_ATTR_MAX,
9547 	.policy = devlink_nl_policy,
9548 	.netnsok	= true,
9549 	.parallel_ops	= true,
9550 	.pre_doit	= devlink_nl_pre_doit,
9551 	.post_doit	= devlink_nl_post_doit,
9552 	.module		= THIS_MODULE,
9553 	.small_ops	= devlink_nl_ops,
9554 	.n_small_ops	= ARRAY_SIZE(devlink_nl_ops),
9555 	.resv_start_op	= DEVLINK_CMD_SELFTESTS_RUN + 1,
9556 	.mcgrps		= devlink_nl_mcgrps,
9557 	.n_mcgrps	= ARRAY_SIZE(devlink_nl_mcgrps),
9558 };
9559 
devlink_reload_actions_valid(const struct devlink_ops * ops)9560 static bool devlink_reload_actions_valid(const struct devlink_ops *ops)
9561 {
9562 	const struct devlink_reload_combination *comb;
9563 	int i;
9564 
9565 	if (!devlink_reload_supported(ops)) {
9566 		if (WARN_ON(ops->reload_actions))
9567 			return false;
9568 		return true;
9569 	}
9570 
9571 	if (WARN_ON(!ops->reload_actions ||
9572 		    ops->reload_actions & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) ||
9573 		    ops->reload_actions >= BIT(__DEVLINK_RELOAD_ACTION_MAX)))
9574 		return false;
9575 
9576 	if (WARN_ON(ops->reload_limits & BIT(DEVLINK_RELOAD_LIMIT_UNSPEC) ||
9577 		    ops->reload_limits >= BIT(__DEVLINK_RELOAD_LIMIT_MAX)))
9578 		return false;
9579 
9580 	for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++)  {
9581 		comb = &devlink_reload_invalid_combinations[i];
9582 		if (ops->reload_actions == BIT(comb->action) &&
9583 		    ops->reload_limits == BIT(comb->limit))
9584 			return false;
9585 	}
9586 	return true;
9587 }
9588 
9589 /**
9590  *	devlink_set_features - Set devlink supported features
9591  *
9592  *	@devlink: devlink
9593  *	@features: devlink support features
9594  *
9595  *	This interface allows us to set reload ops separatelly from
9596  *	the devlink_alloc.
9597  */
devlink_set_features(struct devlink * devlink,u64 features)9598 void devlink_set_features(struct devlink *devlink, u64 features)
9599 {
9600 	ASSERT_DEVLINK_NOT_REGISTERED(devlink);
9601 
9602 	WARN_ON(features & DEVLINK_F_RELOAD &&
9603 		!devlink_reload_supported(devlink->ops));
9604 	devlink->features = features;
9605 }
9606 EXPORT_SYMBOL_GPL(devlink_set_features);
9607 
9608 /**
9609  *	devlink_alloc_ns - Allocate new devlink instance resources
9610  *	in specific namespace
9611  *
9612  *	@ops: ops
9613  *	@priv_size: size of user private data
9614  *	@net: net namespace
9615  *	@dev: parent device
9616  *
9617  *	Allocate new devlink instance resources, including devlink index
9618  *	and name.
9619  */
devlink_alloc_ns(const struct devlink_ops * ops,size_t priv_size,struct net * net,struct device * dev)9620 struct devlink *devlink_alloc_ns(const struct devlink_ops *ops,
9621 				 size_t priv_size, struct net *net,
9622 				 struct device *dev)
9623 {
9624 	struct devlink *devlink;
9625 	static u32 last_id;
9626 	int ret;
9627 
9628 	WARN_ON(!ops || !dev);
9629 	if (!devlink_reload_actions_valid(ops))
9630 		return NULL;
9631 
9632 	devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
9633 	if (!devlink)
9634 		return NULL;
9635 
9636 	ret = xa_alloc_cyclic(&devlinks, &devlink->index, devlink, xa_limit_31b,
9637 			      &last_id, GFP_KERNEL);
9638 	if (ret < 0) {
9639 		kfree(devlink);
9640 		return NULL;
9641 	}
9642 
9643 	devlink->dev = dev;
9644 	devlink->ops = ops;
9645 	xa_init_flags(&devlink->snapshot_ids, XA_FLAGS_ALLOC);
9646 	write_pnet(&devlink->_net, net);
9647 	INIT_LIST_HEAD(&devlink->port_list);
9648 	INIT_LIST_HEAD(&devlink->rate_list);
9649 	INIT_LIST_HEAD(&devlink->linecard_list);
9650 	INIT_LIST_HEAD(&devlink->sb_list);
9651 	INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list);
9652 	INIT_LIST_HEAD(&devlink->resource_list);
9653 	INIT_LIST_HEAD(&devlink->param_list);
9654 	INIT_LIST_HEAD(&devlink->region_list);
9655 	INIT_LIST_HEAD(&devlink->reporter_list);
9656 	INIT_LIST_HEAD(&devlink->trap_list);
9657 	INIT_LIST_HEAD(&devlink->trap_group_list);
9658 	INIT_LIST_HEAD(&devlink->trap_policer_list);
9659 	lockdep_register_key(&devlink->lock_key);
9660 	mutex_init(&devlink->lock);
9661 	lockdep_set_class(&devlink->lock, &devlink->lock_key);
9662 	mutex_init(&devlink->reporters_lock);
9663 	mutex_init(&devlink->linecards_lock);
9664 	refcount_set(&devlink->refcount, 1);
9665 	init_completion(&devlink->comp);
9666 
9667 	return devlink;
9668 }
9669 EXPORT_SYMBOL_GPL(devlink_alloc_ns);
9670 
9671 static void
9672 devlink_trap_policer_notify(struct devlink *devlink,
9673 			    const struct devlink_trap_policer_item *policer_item,
9674 			    enum devlink_command cmd);
9675 static void
9676 devlink_trap_group_notify(struct devlink *devlink,
9677 			  const struct devlink_trap_group_item *group_item,
9678 			  enum devlink_command cmd);
9679 static void devlink_trap_notify(struct devlink *devlink,
9680 				const struct devlink_trap_item *trap_item,
9681 				enum devlink_command cmd);
9682 
devlink_notify_register(struct devlink * devlink)9683 static void devlink_notify_register(struct devlink *devlink)
9684 {
9685 	struct devlink_trap_policer_item *policer_item;
9686 	struct devlink_trap_group_item *group_item;
9687 	struct devlink_param_item *param_item;
9688 	struct devlink_trap_item *trap_item;
9689 	struct devlink_port *devlink_port;
9690 	struct devlink_linecard *linecard;
9691 	struct devlink_rate *rate_node;
9692 	struct devlink_region *region;
9693 
9694 	devlink_notify(devlink, DEVLINK_CMD_NEW);
9695 	list_for_each_entry(linecard, &devlink->linecard_list, list)
9696 		devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
9697 
9698 	list_for_each_entry(devlink_port, &devlink->port_list, list)
9699 		devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
9700 
9701 	list_for_each_entry(policer_item, &devlink->trap_policer_list, list)
9702 		devlink_trap_policer_notify(devlink, policer_item,
9703 					    DEVLINK_CMD_TRAP_POLICER_NEW);
9704 
9705 	list_for_each_entry(group_item, &devlink->trap_group_list, list)
9706 		devlink_trap_group_notify(devlink, group_item,
9707 					  DEVLINK_CMD_TRAP_GROUP_NEW);
9708 
9709 	list_for_each_entry(trap_item, &devlink->trap_list, list)
9710 		devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
9711 
9712 	list_for_each_entry(rate_node, &devlink->rate_list, list)
9713 		devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
9714 
9715 	list_for_each_entry(region, &devlink->region_list, list)
9716 		devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
9717 
9718 	list_for_each_entry(param_item, &devlink->param_list, list)
9719 		devlink_param_notify(devlink, 0, param_item,
9720 				     DEVLINK_CMD_PARAM_NEW);
9721 }
9722 
devlink_notify_unregister(struct devlink * devlink)9723 static void devlink_notify_unregister(struct devlink *devlink)
9724 {
9725 	struct devlink_trap_policer_item *policer_item;
9726 	struct devlink_trap_group_item *group_item;
9727 	struct devlink_param_item *param_item;
9728 	struct devlink_trap_item *trap_item;
9729 	struct devlink_port *devlink_port;
9730 	struct devlink_linecard *linecard;
9731 	struct devlink_rate *rate_node;
9732 	struct devlink_region *region;
9733 
9734 	list_for_each_entry_reverse(param_item, &devlink->param_list, list)
9735 		devlink_param_notify(devlink, 0, param_item,
9736 				     DEVLINK_CMD_PARAM_DEL);
9737 
9738 	list_for_each_entry_reverse(region, &devlink->region_list, list)
9739 		devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
9740 
9741 	list_for_each_entry_reverse(rate_node, &devlink->rate_list, list)
9742 		devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL);
9743 
9744 	list_for_each_entry_reverse(trap_item, &devlink->trap_list, list)
9745 		devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL);
9746 
9747 	list_for_each_entry_reverse(group_item, &devlink->trap_group_list, list)
9748 		devlink_trap_group_notify(devlink, group_item,
9749 					  DEVLINK_CMD_TRAP_GROUP_DEL);
9750 	list_for_each_entry_reverse(policer_item, &devlink->trap_policer_list,
9751 				    list)
9752 		devlink_trap_policer_notify(devlink, policer_item,
9753 					    DEVLINK_CMD_TRAP_POLICER_DEL);
9754 
9755 	list_for_each_entry_reverse(devlink_port, &devlink->port_list, list)
9756 		devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
9757 	list_for_each_entry_reverse(linecard, &devlink->linecard_list, list)
9758 		devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_DEL);
9759 	devlink_notify(devlink, DEVLINK_CMD_DEL);
9760 }
9761 
9762 /**
9763  *	devlink_register - Register devlink instance
9764  *
9765  *	@devlink: devlink
9766  */
devlink_register(struct devlink * devlink)9767 void devlink_register(struct devlink *devlink)
9768 {
9769 	ASSERT_DEVLINK_NOT_REGISTERED(devlink);
9770 	/* Make sure that we are in .probe() routine */
9771 
9772 	xa_set_mark(&devlinks, devlink->index, DEVLINK_REGISTERED);
9773 	devlink_notify_register(devlink);
9774 }
9775 EXPORT_SYMBOL_GPL(devlink_register);
9776 
9777 /**
9778  *	devlink_unregister - Unregister devlink instance
9779  *
9780  *	@devlink: devlink
9781  */
devlink_unregister(struct devlink * devlink)9782 void devlink_unregister(struct devlink *devlink)
9783 {
9784 	ASSERT_DEVLINK_REGISTERED(devlink);
9785 	/* Make sure that we are in .remove() routine */
9786 
9787 	xa_set_mark(&devlinks, devlink->index, DEVLINK_UNREGISTERING);
9788 	devlink_put(devlink);
9789 	wait_for_completion(&devlink->comp);
9790 
9791 	devlink_notify_unregister(devlink);
9792 	xa_clear_mark(&devlinks, devlink->index, DEVLINK_REGISTERED);
9793 	xa_clear_mark(&devlinks, devlink->index, DEVLINK_UNREGISTERING);
9794 }
9795 EXPORT_SYMBOL_GPL(devlink_unregister);
9796 
9797 /**
9798  *	devlink_free - Free devlink instance resources
9799  *
9800  *	@devlink: devlink
9801  */
devlink_free(struct devlink * devlink)9802 void devlink_free(struct devlink *devlink)
9803 {
9804 	ASSERT_DEVLINK_NOT_REGISTERED(devlink);
9805 
9806 	mutex_destroy(&devlink->linecards_lock);
9807 	mutex_destroy(&devlink->reporters_lock);
9808 	mutex_destroy(&devlink->lock);
9809 	lockdep_unregister_key(&devlink->lock_key);
9810 	WARN_ON(!list_empty(&devlink->trap_policer_list));
9811 	WARN_ON(!list_empty(&devlink->trap_group_list));
9812 	WARN_ON(!list_empty(&devlink->trap_list));
9813 	WARN_ON(!list_empty(&devlink->reporter_list));
9814 	WARN_ON(!list_empty(&devlink->region_list));
9815 	WARN_ON(!list_empty(&devlink->param_list));
9816 	WARN_ON(!list_empty(&devlink->resource_list));
9817 	WARN_ON(!list_empty(&devlink->dpipe_table_list));
9818 	WARN_ON(!list_empty(&devlink->sb_list));
9819 	WARN_ON(!list_empty(&devlink->rate_list));
9820 	WARN_ON(!list_empty(&devlink->linecard_list));
9821 	WARN_ON(!list_empty(&devlink->port_list));
9822 
9823 	xa_destroy(&devlink->snapshot_ids);
9824 	xa_erase(&devlinks, devlink->index);
9825 
9826 	kfree(devlink);
9827 }
9828 EXPORT_SYMBOL_GPL(devlink_free);
9829 
devlink_port_type_warn(struct work_struct * work)9830 static void devlink_port_type_warn(struct work_struct *work)
9831 {
9832 	struct devlink_port *port = container_of(to_delayed_work(work),
9833 						 struct devlink_port,
9834 						 type_warn_dw);
9835 	dev_warn(port->devlink->dev, "Type was not set for devlink port.");
9836 }
9837 
devlink_port_type_should_warn(struct devlink_port * devlink_port)9838 static bool devlink_port_type_should_warn(struct devlink_port *devlink_port)
9839 {
9840 	/* Ignore CPU and DSA flavours. */
9841 	return devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_CPU &&
9842 	       devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_DSA &&
9843 	       devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_UNUSED;
9844 }
9845 
9846 #define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 3600)
9847 
devlink_port_type_warn_schedule(struct devlink_port * devlink_port)9848 static void devlink_port_type_warn_schedule(struct devlink_port *devlink_port)
9849 {
9850 	if (!devlink_port_type_should_warn(devlink_port))
9851 		return;
9852 	/* Schedule a work to WARN in case driver does not set port
9853 	 * type within timeout.
9854 	 */
9855 	schedule_delayed_work(&devlink_port->type_warn_dw,
9856 			      DEVLINK_PORT_TYPE_WARN_TIMEOUT);
9857 }
9858 
devlink_port_type_warn_cancel(struct devlink_port * devlink_port)9859 static void devlink_port_type_warn_cancel(struct devlink_port *devlink_port)
9860 {
9861 	if (!devlink_port_type_should_warn(devlink_port))
9862 		return;
9863 	cancel_delayed_work_sync(&devlink_port->type_warn_dw);
9864 }
9865 
9866 /**
9867  * devlink_port_init() - Init devlink port
9868  *
9869  * @devlink: devlink
9870  * @devlink_port: devlink port
9871  *
9872  * Initialize essencial stuff that is needed for functions
9873  * that may be called before devlink port registration.
9874  * Call to this function is optional and not needed
9875  * in case the driver does not use such functions.
9876  */
devlink_port_init(struct devlink * devlink,struct devlink_port * devlink_port)9877 void devlink_port_init(struct devlink *devlink,
9878 		       struct devlink_port *devlink_port)
9879 {
9880 	if (devlink_port->initialized)
9881 		return;
9882 	devlink_port->devlink = devlink;
9883 	INIT_LIST_HEAD(&devlink_port->region_list);
9884 	devlink_port->initialized = true;
9885 }
9886 EXPORT_SYMBOL_GPL(devlink_port_init);
9887 
9888 /**
9889  * devlink_port_fini() - Deinitialize devlink port
9890  *
9891  * @devlink_port: devlink port
9892  *
9893  * Deinitialize essencial stuff that is in use for functions
9894  * that may be called after devlink port unregistration.
9895  * Call to this function is optional and not needed
9896  * in case the driver does not use such functions.
9897  */
devlink_port_fini(struct devlink_port * devlink_port)9898 void devlink_port_fini(struct devlink_port *devlink_port)
9899 {
9900 	WARN_ON(!list_empty(&devlink_port->region_list));
9901 }
9902 EXPORT_SYMBOL_GPL(devlink_port_fini);
9903 
9904 /**
9905  * devl_port_register() - Register devlink port
9906  *
9907  * @devlink: devlink
9908  * @devlink_port: devlink port
9909  * @port_index: driver-specific numerical identifier of the port
9910  *
9911  * Register devlink port with provided port index. User can use
9912  * any indexing, even hw-related one. devlink_port structure
9913  * is convenient to be embedded inside user driver private structure.
9914  * Note that the caller should take care of zeroing the devlink_port
9915  * structure.
9916  */
devl_port_register(struct devlink * devlink,struct devlink_port * devlink_port,unsigned int port_index)9917 int devl_port_register(struct devlink *devlink,
9918 		       struct devlink_port *devlink_port,
9919 		       unsigned int port_index)
9920 {
9921 	devl_assert_locked(devlink);
9922 
9923 	if (devlink_port_index_exists(devlink, port_index))
9924 		return -EEXIST;
9925 
9926 	ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
9927 
9928 	devlink_port_init(devlink, devlink_port);
9929 	devlink_port->registered = true;
9930 	devlink_port->index = port_index;
9931 	spin_lock_init(&devlink_port->type_lock);
9932 	INIT_LIST_HEAD(&devlink_port->reporter_list);
9933 	mutex_init(&devlink_port->reporters_lock);
9934 	list_add_tail(&devlink_port->list, &devlink->port_list);
9935 
9936 	INIT_DELAYED_WORK(&devlink_port->type_warn_dw, &devlink_port_type_warn);
9937 	devlink_port_type_warn_schedule(devlink_port);
9938 	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
9939 	return 0;
9940 }
9941 EXPORT_SYMBOL_GPL(devl_port_register);
9942 
9943 /**
9944  *	devlink_port_register - Register devlink port
9945  *
9946  *	@devlink: devlink
9947  *	@devlink_port: devlink port
9948  *	@port_index: driver-specific numerical identifier of the port
9949  *
9950  *	Register devlink port with provided port index. User can use
9951  *	any indexing, even hw-related one. devlink_port structure
9952  *	is convenient to be embedded inside user driver private structure.
9953  *	Note that the caller should take care of zeroing the devlink_port
9954  *	structure.
9955  *
9956  *	Context: Takes and release devlink->lock <mutex>.
9957  */
devlink_port_register(struct devlink * devlink,struct devlink_port * devlink_port,unsigned int port_index)9958 int devlink_port_register(struct devlink *devlink,
9959 			  struct devlink_port *devlink_port,
9960 			  unsigned int port_index)
9961 {
9962 	int err;
9963 
9964 	devl_lock(devlink);
9965 	err = devl_port_register(devlink, devlink_port, port_index);
9966 	devl_unlock(devlink);
9967 	return err;
9968 }
9969 EXPORT_SYMBOL_GPL(devlink_port_register);
9970 
9971 /**
9972  * devl_port_unregister() - Unregister devlink port
9973  *
9974  * @devlink_port: devlink port
9975  */
devl_port_unregister(struct devlink_port * devlink_port)9976 void devl_port_unregister(struct devlink_port *devlink_port)
9977 {
9978 	lockdep_assert_held(&devlink_port->devlink->lock);
9979 
9980 	devlink_port_type_warn_cancel(devlink_port);
9981 	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
9982 	list_del(&devlink_port->list);
9983 	WARN_ON(!list_empty(&devlink_port->reporter_list));
9984 	mutex_destroy(&devlink_port->reporters_lock);
9985 	devlink_port->registered = false;
9986 }
9987 EXPORT_SYMBOL_GPL(devl_port_unregister);
9988 
9989 /**
9990  *	devlink_port_unregister - Unregister devlink port
9991  *
9992  *	@devlink_port: devlink port
9993  *
9994  *	Context: Takes and release devlink->lock <mutex>.
9995  */
devlink_port_unregister(struct devlink_port * devlink_port)9996 void devlink_port_unregister(struct devlink_port *devlink_port)
9997 {
9998 	struct devlink *devlink = devlink_port->devlink;
9999 
10000 	devl_lock(devlink);
10001 	devl_port_unregister(devlink_port);
10002 	devl_unlock(devlink);
10003 }
10004 EXPORT_SYMBOL_GPL(devlink_port_unregister);
10005 
__devlink_port_type_set(struct devlink_port * devlink_port,enum devlink_port_type type,void * type_dev)10006 static void __devlink_port_type_set(struct devlink_port *devlink_port,
10007 				    enum devlink_port_type type,
10008 				    void *type_dev)
10009 {
10010 	ASSERT_DEVLINK_PORT_REGISTERED(devlink_port);
10011 
10012 	devlink_port_type_warn_cancel(devlink_port);
10013 	spin_lock_bh(&devlink_port->type_lock);
10014 	devlink_port->type = type;
10015 	devlink_port->type_dev = type_dev;
10016 	spin_unlock_bh(&devlink_port->type_lock);
10017 	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
10018 }
10019 
devlink_port_type_netdev_checks(struct devlink_port * devlink_port,struct net_device * netdev)10020 static void devlink_port_type_netdev_checks(struct devlink_port *devlink_port,
10021 					    struct net_device *netdev)
10022 {
10023 	const struct net_device_ops *ops = netdev->netdev_ops;
10024 
10025 	/* If driver registers devlink port, it should set devlink port
10026 	 * attributes accordingly so the compat functions are called
10027 	 * and the original ops are not used.
10028 	 */
10029 	if (ops->ndo_get_phys_port_name) {
10030 		/* Some drivers use the same set of ndos for netdevs
10031 		 * that have devlink_port registered and also for
10032 		 * those who don't. Make sure that ndo_get_phys_port_name
10033 		 * returns -EOPNOTSUPP here in case it is defined.
10034 		 * Warn if not.
10035 		 */
10036 		char name[IFNAMSIZ];
10037 		int err;
10038 
10039 		err = ops->ndo_get_phys_port_name(netdev, name, sizeof(name));
10040 		WARN_ON(err != -EOPNOTSUPP);
10041 	}
10042 	if (ops->ndo_get_port_parent_id) {
10043 		/* Some drivers use the same set of ndos for netdevs
10044 		 * that have devlink_port registered and also for
10045 		 * those who don't. Make sure that ndo_get_port_parent_id
10046 		 * returns -EOPNOTSUPP here in case it is defined.
10047 		 * Warn if not.
10048 		 */
10049 		struct netdev_phys_item_id ppid;
10050 		int err;
10051 
10052 		err = ops->ndo_get_port_parent_id(netdev, &ppid);
10053 		WARN_ON(err != -EOPNOTSUPP);
10054 	}
10055 }
10056 
10057 /**
10058  *	devlink_port_type_eth_set - Set port type to Ethernet
10059  *
10060  *	@devlink_port: devlink port
10061  *	@netdev: related netdevice
10062  */
devlink_port_type_eth_set(struct devlink_port * devlink_port,struct net_device * netdev)10063 void devlink_port_type_eth_set(struct devlink_port *devlink_port,
10064 			       struct net_device *netdev)
10065 {
10066 	if (netdev)
10067 		devlink_port_type_netdev_checks(devlink_port, netdev);
10068 	else
10069 		dev_warn(devlink_port->devlink->dev,
10070 			 "devlink port type for port %d set to Ethernet without a software interface reference, device type not supported by the kernel?\n",
10071 			 devlink_port->index);
10072 
10073 	__devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, netdev);
10074 }
10075 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
10076 
10077 /**
10078  *	devlink_port_type_ib_set - Set port type to InfiniBand
10079  *
10080  *	@devlink_port: devlink port
10081  *	@ibdev: related IB device
10082  */
devlink_port_type_ib_set(struct devlink_port * devlink_port,struct ib_device * ibdev)10083 void devlink_port_type_ib_set(struct devlink_port *devlink_port,
10084 			      struct ib_device *ibdev)
10085 {
10086 	__devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_IB, ibdev);
10087 }
10088 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
10089 
10090 /**
10091  *	devlink_port_type_clear - Clear port type
10092  *
10093  *	@devlink_port: devlink port
10094  */
devlink_port_type_clear(struct devlink_port * devlink_port)10095 void devlink_port_type_clear(struct devlink_port *devlink_port)
10096 {
10097 	__devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, NULL);
10098 	devlink_port_type_warn_schedule(devlink_port);
10099 }
10100 EXPORT_SYMBOL_GPL(devlink_port_type_clear);
10101 
__devlink_port_attrs_set(struct devlink_port * devlink_port,enum devlink_port_flavour flavour)10102 static int __devlink_port_attrs_set(struct devlink_port *devlink_port,
10103 				    enum devlink_port_flavour flavour)
10104 {
10105 	struct devlink_port_attrs *attrs = &devlink_port->attrs;
10106 
10107 	devlink_port->attrs_set = true;
10108 	attrs->flavour = flavour;
10109 	if (attrs->switch_id.id_len) {
10110 		devlink_port->switch_port = true;
10111 		if (WARN_ON(attrs->switch_id.id_len > MAX_PHYS_ITEM_ID_LEN))
10112 			attrs->switch_id.id_len = MAX_PHYS_ITEM_ID_LEN;
10113 	} else {
10114 		devlink_port->switch_port = false;
10115 	}
10116 	return 0;
10117 }
10118 
10119 /**
10120  *	devlink_port_attrs_set - Set port attributes
10121  *
10122  *	@devlink_port: devlink port
10123  *	@attrs: devlink port attrs
10124  */
devlink_port_attrs_set(struct devlink_port * devlink_port,struct devlink_port_attrs * attrs)10125 void devlink_port_attrs_set(struct devlink_port *devlink_port,
10126 			    struct devlink_port_attrs *attrs)
10127 {
10128 	int ret;
10129 
10130 	ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
10131 
10132 	devlink_port->attrs = *attrs;
10133 	ret = __devlink_port_attrs_set(devlink_port, attrs->flavour);
10134 	if (ret)
10135 		return;
10136 	WARN_ON(attrs->splittable && attrs->split);
10137 }
10138 EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
10139 
10140 /**
10141  *	devlink_port_attrs_pci_pf_set - Set PCI PF port attributes
10142  *
10143  *	@devlink_port: devlink port
10144  *	@controller: associated controller number for the devlink port instance
10145  *	@pf: associated PF for the devlink port instance
10146  *	@external: indicates if the port is for an external controller
10147  */
devlink_port_attrs_pci_pf_set(struct devlink_port * devlink_port,u32 controller,u16 pf,bool external)10148 void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u32 controller,
10149 				   u16 pf, bool external)
10150 {
10151 	struct devlink_port_attrs *attrs = &devlink_port->attrs;
10152 	int ret;
10153 
10154 	ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
10155 
10156 	ret = __devlink_port_attrs_set(devlink_port,
10157 				       DEVLINK_PORT_FLAVOUR_PCI_PF);
10158 	if (ret)
10159 		return;
10160 	attrs->pci_pf.controller = controller;
10161 	attrs->pci_pf.pf = pf;
10162 	attrs->pci_pf.external = external;
10163 }
10164 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set);
10165 
10166 /**
10167  *	devlink_port_attrs_pci_vf_set - Set PCI VF port attributes
10168  *
10169  *	@devlink_port: devlink port
10170  *	@controller: associated controller number for the devlink port instance
10171  *	@pf: associated PF for the devlink port instance
10172  *	@vf: associated VF of a PF for the devlink port instance
10173  *	@external: indicates if the port is for an external controller
10174  */
devlink_port_attrs_pci_vf_set(struct devlink_port * devlink_port,u32 controller,u16 pf,u16 vf,bool external)10175 void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port, u32 controller,
10176 				   u16 pf, u16 vf, bool external)
10177 {
10178 	struct devlink_port_attrs *attrs = &devlink_port->attrs;
10179 	int ret;
10180 
10181 	ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
10182 
10183 	ret = __devlink_port_attrs_set(devlink_port,
10184 				       DEVLINK_PORT_FLAVOUR_PCI_VF);
10185 	if (ret)
10186 		return;
10187 	attrs->pci_vf.controller = controller;
10188 	attrs->pci_vf.pf = pf;
10189 	attrs->pci_vf.vf = vf;
10190 	attrs->pci_vf.external = external;
10191 }
10192 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set);
10193 
10194 /**
10195  *	devlink_port_attrs_pci_sf_set - Set PCI SF port attributes
10196  *
10197  *	@devlink_port: devlink port
10198  *	@controller: associated controller number for the devlink port instance
10199  *	@pf: associated PF for the devlink port instance
10200  *	@sf: associated SF of a PF for the devlink port instance
10201  *	@external: indicates if the port is for an external controller
10202  */
devlink_port_attrs_pci_sf_set(struct devlink_port * devlink_port,u32 controller,u16 pf,u32 sf,bool external)10203 void devlink_port_attrs_pci_sf_set(struct devlink_port *devlink_port, u32 controller,
10204 				   u16 pf, u32 sf, bool external)
10205 {
10206 	struct devlink_port_attrs *attrs = &devlink_port->attrs;
10207 	int ret;
10208 
10209 	ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
10210 
10211 	ret = __devlink_port_attrs_set(devlink_port,
10212 				       DEVLINK_PORT_FLAVOUR_PCI_SF);
10213 	if (ret)
10214 		return;
10215 	attrs->pci_sf.controller = controller;
10216 	attrs->pci_sf.pf = pf;
10217 	attrs->pci_sf.sf = sf;
10218 	attrs->pci_sf.external = external;
10219 }
10220 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_sf_set);
10221 
10222 /**
10223  * devl_rate_leaf_create - create devlink rate leaf
10224  * @devlink_port: devlink port object to create rate object on
10225  * @priv: driver private data
10226  *
10227  * Create devlink rate object of type leaf on provided @devlink_port.
10228  */
devl_rate_leaf_create(struct devlink_port * devlink_port,void * priv)10229 int devl_rate_leaf_create(struct devlink_port *devlink_port, void *priv)
10230 {
10231 	struct devlink *devlink = devlink_port->devlink;
10232 	struct devlink_rate *devlink_rate;
10233 
10234 	devl_assert_locked(devlink_port->devlink);
10235 
10236 	if (WARN_ON(devlink_port->devlink_rate))
10237 		return -EBUSY;
10238 
10239 	devlink_rate = kzalloc(sizeof(*devlink_rate), GFP_KERNEL);
10240 	if (!devlink_rate)
10241 		return -ENOMEM;
10242 
10243 	devlink_rate->type = DEVLINK_RATE_TYPE_LEAF;
10244 	devlink_rate->devlink = devlink;
10245 	devlink_rate->devlink_port = devlink_port;
10246 	devlink_rate->priv = priv;
10247 	list_add_tail(&devlink_rate->list, &devlink->rate_list);
10248 	devlink_port->devlink_rate = devlink_rate;
10249 	devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW);
10250 
10251 	return 0;
10252 }
10253 EXPORT_SYMBOL_GPL(devl_rate_leaf_create);
10254 
10255 /**
10256  * devl_rate_leaf_destroy - destroy devlink rate leaf
10257  *
10258  * @devlink_port: devlink port linked to the rate object
10259  *
10260  * Destroy the devlink rate object of type leaf on provided @devlink_port.
10261  */
devl_rate_leaf_destroy(struct devlink_port * devlink_port)10262 void devl_rate_leaf_destroy(struct devlink_port *devlink_port)
10263 {
10264 	struct devlink_rate *devlink_rate = devlink_port->devlink_rate;
10265 
10266 	devl_assert_locked(devlink_port->devlink);
10267 	if (!devlink_rate)
10268 		return;
10269 
10270 	devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_DEL);
10271 	if (devlink_rate->parent)
10272 		refcount_dec(&devlink_rate->parent->refcnt);
10273 	list_del(&devlink_rate->list);
10274 	devlink_port->devlink_rate = NULL;
10275 	kfree(devlink_rate);
10276 }
10277 EXPORT_SYMBOL_GPL(devl_rate_leaf_destroy);
10278 
10279 /**
10280  * devl_rate_nodes_destroy - destroy all devlink rate nodes on device
10281  * @devlink: devlink instance
10282  *
10283  * Unset parent for all rate objects and destroy all rate nodes
10284  * on specified device.
10285  */
devl_rate_nodes_destroy(struct devlink * devlink)10286 void devl_rate_nodes_destroy(struct devlink *devlink)
10287 {
10288 	static struct devlink_rate *devlink_rate, *tmp;
10289 	const struct devlink_ops *ops = devlink->ops;
10290 
10291 	devl_assert_locked(devlink);
10292 
10293 	list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
10294 		if (!devlink_rate->parent)
10295 			continue;
10296 
10297 		refcount_dec(&devlink_rate->parent->refcnt);
10298 		if (devlink_rate_is_leaf(devlink_rate))
10299 			ops->rate_leaf_parent_set(devlink_rate, NULL, devlink_rate->priv,
10300 						  NULL, NULL);
10301 		else if (devlink_rate_is_node(devlink_rate))
10302 			ops->rate_node_parent_set(devlink_rate, NULL, devlink_rate->priv,
10303 						  NULL, NULL);
10304 	}
10305 	list_for_each_entry_safe(devlink_rate, tmp, &devlink->rate_list, list) {
10306 		if (devlink_rate_is_node(devlink_rate)) {
10307 			ops->rate_node_del(devlink_rate, devlink_rate->priv, NULL);
10308 			list_del(&devlink_rate->list);
10309 			kfree(devlink_rate->name);
10310 			kfree(devlink_rate);
10311 		}
10312 	}
10313 }
10314 EXPORT_SYMBOL_GPL(devl_rate_nodes_destroy);
10315 
10316 /**
10317  *	devlink_port_linecard_set - Link port with a linecard
10318  *
10319  *	@devlink_port: devlink port
10320  *	@linecard: devlink linecard
10321  */
devlink_port_linecard_set(struct devlink_port * devlink_port,struct devlink_linecard * linecard)10322 void devlink_port_linecard_set(struct devlink_port *devlink_port,
10323 			       struct devlink_linecard *linecard)
10324 {
10325 	ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
10326 
10327 	devlink_port->linecard = linecard;
10328 }
10329 EXPORT_SYMBOL_GPL(devlink_port_linecard_set);
10330 
__devlink_port_phys_port_name_get(struct devlink_port * devlink_port,char * name,size_t len)10331 static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
10332 					     char *name, size_t len)
10333 {
10334 	struct devlink_port_attrs *attrs = &devlink_port->attrs;
10335 	int n = 0;
10336 
10337 	if (!devlink_port->attrs_set)
10338 		return -EOPNOTSUPP;
10339 
10340 	switch (attrs->flavour) {
10341 	case DEVLINK_PORT_FLAVOUR_PHYSICAL:
10342 		if (devlink_port->linecard)
10343 			n = snprintf(name, len, "l%u",
10344 				     devlink_port->linecard->index);
10345 		if (n < len)
10346 			n += snprintf(name + n, len - n, "p%u",
10347 				      attrs->phys.port_number);
10348 		if (n < len && attrs->split)
10349 			n += snprintf(name + n, len - n, "s%u",
10350 				      attrs->phys.split_subport_number);
10351 		break;
10352 	case DEVLINK_PORT_FLAVOUR_CPU:
10353 	case DEVLINK_PORT_FLAVOUR_DSA:
10354 	case DEVLINK_PORT_FLAVOUR_UNUSED:
10355 		/* As CPU and DSA ports do not have a netdevice associated
10356 		 * case should not ever happen.
10357 		 */
10358 		WARN_ON(1);
10359 		return -EINVAL;
10360 	case DEVLINK_PORT_FLAVOUR_PCI_PF:
10361 		if (attrs->pci_pf.external) {
10362 			n = snprintf(name, len, "c%u", attrs->pci_pf.controller);
10363 			if (n >= len)
10364 				return -EINVAL;
10365 			len -= n;
10366 			name += n;
10367 		}
10368 		n = snprintf(name, len, "pf%u", attrs->pci_pf.pf);
10369 		break;
10370 	case DEVLINK_PORT_FLAVOUR_PCI_VF:
10371 		if (attrs->pci_vf.external) {
10372 			n = snprintf(name, len, "c%u", attrs->pci_vf.controller);
10373 			if (n >= len)
10374 				return -EINVAL;
10375 			len -= n;
10376 			name += n;
10377 		}
10378 		n = snprintf(name, len, "pf%uvf%u",
10379 			     attrs->pci_vf.pf, attrs->pci_vf.vf);
10380 		break;
10381 	case DEVLINK_PORT_FLAVOUR_PCI_SF:
10382 		if (attrs->pci_sf.external) {
10383 			n = snprintf(name, len, "c%u", attrs->pci_sf.controller);
10384 			if (n >= len)
10385 				return -EINVAL;
10386 			len -= n;
10387 			name += n;
10388 		}
10389 		n = snprintf(name, len, "pf%usf%u", attrs->pci_sf.pf,
10390 			     attrs->pci_sf.sf);
10391 		break;
10392 	case DEVLINK_PORT_FLAVOUR_VIRTUAL:
10393 		return -EOPNOTSUPP;
10394 	}
10395 
10396 	if (n >= len)
10397 		return -EINVAL;
10398 
10399 	return 0;
10400 }
10401 
devlink_linecard_types_init(struct devlink_linecard * linecard)10402 static int devlink_linecard_types_init(struct devlink_linecard *linecard)
10403 {
10404 	struct devlink_linecard_type *linecard_type;
10405 	unsigned int count;
10406 	int i;
10407 
10408 	count = linecard->ops->types_count(linecard, linecard->priv);
10409 	linecard->types = kmalloc_array(count, sizeof(*linecard_type),
10410 					GFP_KERNEL);
10411 	if (!linecard->types)
10412 		return -ENOMEM;
10413 	linecard->types_count = count;
10414 
10415 	for (i = 0; i < count; i++) {
10416 		linecard_type = &linecard->types[i];
10417 		linecard->ops->types_get(linecard, linecard->priv, i,
10418 					 &linecard_type->type,
10419 					 &linecard_type->priv);
10420 	}
10421 	return 0;
10422 }
10423 
devlink_linecard_types_fini(struct devlink_linecard * linecard)10424 static void devlink_linecard_types_fini(struct devlink_linecard *linecard)
10425 {
10426 	kfree(linecard->types);
10427 }
10428 
10429 /**
10430  *	devlink_linecard_create - Create devlink linecard
10431  *
10432  *	@devlink: devlink
10433  *	@linecard_index: driver-specific numerical identifier of the linecard
10434  *	@ops: linecards ops
10435  *	@priv: user priv pointer
10436  *
10437  *	Create devlink linecard instance with provided linecard index.
10438  *	Caller can use any indexing, even hw-related one.
10439  *
10440  *	Return: Line card structure or an ERR_PTR() encoded error code.
10441  */
10442 struct devlink_linecard *
devlink_linecard_create(struct devlink * devlink,unsigned int linecard_index,const struct devlink_linecard_ops * ops,void * priv)10443 devlink_linecard_create(struct devlink *devlink, unsigned int linecard_index,
10444 			const struct devlink_linecard_ops *ops, void *priv)
10445 {
10446 	struct devlink_linecard *linecard;
10447 	int err;
10448 
10449 	if (WARN_ON(!ops || !ops->provision || !ops->unprovision ||
10450 		    !ops->types_count || !ops->types_get))
10451 		return ERR_PTR(-EINVAL);
10452 
10453 	mutex_lock(&devlink->linecards_lock);
10454 	if (devlink_linecard_index_exists(devlink, linecard_index)) {
10455 		mutex_unlock(&devlink->linecards_lock);
10456 		return ERR_PTR(-EEXIST);
10457 	}
10458 
10459 	linecard = kzalloc(sizeof(*linecard), GFP_KERNEL);
10460 	if (!linecard) {
10461 		mutex_unlock(&devlink->linecards_lock);
10462 		return ERR_PTR(-ENOMEM);
10463 	}
10464 
10465 	linecard->devlink = devlink;
10466 	linecard->index = linecard_index;
10467 	linecard->ops = ops;
10468 	linecard->priv = priv;
10469 	linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
10470 	mutex_init(&linecard->state_lock);
10471 
10472 	err = devlink_linecard_types_init(linecard);
10473 	if (err) {
10474 		mutex_destroy(&linecard->state_lock);
10475 		kfree(linecard);
10476 		mutex_unlock(&devlink->linecards_lock);
10477 		return ERR_PTR(err);
10478 	}
10479 
10480 	list_add_tail(&linecard->list, &devlink->linecard_list);
10481 	refcount_set(&linecard->refcount, 1);
10482 	mutex_unlock(&devlink->linecards_lock);
10483 	devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10484 	return linecard;
10485 }
10486 EXPORT_SYMBOL_GPL(devlink_linecard_create);
10487 
10488 /**
10489  *	devlink_linecard_destroy - Destroy devlink linecard
10490  *
10491  *	@linecard: devlink linecard
10492  */
devlink_linecard_destroy(struct devlink_linecard * linecard)10493 void devlink_linecard_destroy(struct devlink_linecard *linecard)
10494 {
10495 	struct devlink *devlink = linecard->devlink;
10496 
10497 	devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_DEL);
10498 	mutex_lock(&devlink->linecards_lock);
10499 	list_del(&linecard->list);
10500 	devlink_linecard_types_fini(linecard);
10501 	mutex_unlock(&devlink->linecards_lock);
10502 	devlink_linecard_put(linecard);
10503 }
10504 EXPORT_SYMBOL_GPL(devlink_linecard_destroy);
10505 
10506 /**
10507  *	devlink_linecard_provision_set - Set provisioning on linecard
10508  *
10509  *	@linecard: devlink linecard
10510  *	@type: linecard type
10511  *
10512  *	This is either called directly from the provision() op call or
10513  *	as a result of the provision() op call asynchronously.
10514  */
devlink_linecard_provision_set(struct devlink_linecard * linecard,const char * type)10515 void devlink_linecard_provision_set(struct devlink_linecard *linecard,
10516 				    const char *type)
10517 {
10518 	mutex_lock(&linecard->state_lock);
10519 	WARN_ON(linecard->type && strcmp(linecard->type, type));
10520 	linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED;
10521 	linecard->type = type;
10522 	devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10523 	mutex_unlock(&linecard->state_lock);
10524 }
10525 EXPORT_SYMBOL_GPL(devlink_linecard_provision_set);
10526 
10527 /**
10528  *	devlink_linecard_provision_clear - Clear provisioning on linecard
10529  *
10530  *	@linecard: devlink linecard
10531  *
10532  *	This is either called directly from the unprovision() op call or
10533  *	as a result of the unprovision() op call asynchronously.
10534  */
devlink_linecard_provision_clear(struct devlink_linecard * linecard)10535 void devlink_linecard_provision_clear(struct devlink_linecard *linecard)
10536 {
10537 	mutex_lock(&linecard->state_lock);
10538 	WARN_ON(linecard->nested_devlink);
10539 	linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
10540 	linecard->type = NULL;
10541 	devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10542 	mutex_unlock(&linecard->state_lock);
10543 }
10544 EXPORT_SYMBOL_GPL(devlink_linecard_provision_clear);
10545 
10546 /**
10547  *	devlink_linecard_provision_fail - Fail provisioning on linecard
10548  *
10549  *	@linecard: devlink linecard
10550  *
10551  *	This is either called directly from the provision() op call or
10552  *	as a result of the provision() op call asynchronously.
10553  */
devlink_linecard_provision_fail(struct devlink_linecard * linecard)10554 void devlink_linecard_provision_fail(struct devlink_linecard *linecard)
10555 {
10556 	mutex_lock(&linecard->state_lock);
10557 	WARN_ON(linecard->nested_devlink);
10558 	linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING_FAILED;
10559 	devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10560 	mutex_unlock(&linecard->state_lock);
10561 }
10562 EXPORT_SYMBOL_GPL(devlink_linecard_provision_fail);
10563 
10564 /**
10565  *	devlink_linecard_activate - Set linecard active
10566  *
10567  *	@linecard: devlink linecard
10568  */
devlink_linecard_activate(struct devlink_linecard * linecard)10569 void devlink_linecard_activate(struct devlink_linecard *linecard)
10570 {
10571 	mutex_lock(&linecard->state_lock);
10572 	WARN_ON(linecard->state != DEVLINK_LINECARD_STATE_PROVISIONED);
10573 	linecard->state = DEVLINK_LINECARD_STATE_ACTIVE;
10574 	devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10575 	mutex_unlock(&linecard->state_lock);
10576 }
10577 EXPORT_SYMBOL_GPL(devlink_linecard_activate);
10578 
10579 /**
10580  *	devlink_linecard_deactivate - Set linecard inactive
10581  *
10582  *	@linecard: devlink linecard
10583  */
devlink_linecard_deactivate(struct devlink_linecard * linecard)10584 void devlink_linecard_deactivate(struct devlink_linecard *linecard)
10585 {
10586 	mutex_lock(&linecard->state_lock);
10587 	switch (linecard->state) {
10588 	case DEVLINK_LINECARD_STATE_ACTIVE:
10589 		linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED;
10590 		devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10591 		break;
10592 	case DEVLINK_LINECARD_STATE_UNPROVISIONING:
10593 		/* Line card is being deactivated as part
10594 		 * of unprovisioning flow.
10595 		 */
10596 		break;
10597 	default:
10598 		WARN_ON(1);
10599 		break;
10600 	}
10601 	mutex_unlock(&linecard->state_lock);
10602 }
10603 EXPORT_SYMBOL_GPL(devlink_linecard_deactivate);
10604 
10605 /**
10606  *	devlink_linecard_nested_dl_set - Attach/detach nested devlink
10607  *					 instance to linecard.
10608  *
10609  *	@linecard: devlink linecard
10610  *	@nested_devlink: devlink instance to attach or NULL to detach
10611  */
devlink_linecard_nested_dl_set(struct devlink_linecard * linecard,struct devlink * nested_devlink)10612 void devlink_linecard_nested_dl_set(struct devlink_linecard *linecard,
10613 				    struct devlink *nested_devlink)
10614 {
10615 	mutex_lock(&linecard->state_lock);
10616 	linecard->nested_devlink = nested_devlink;
10617 	devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10618 	mutex_unlock(&linecard->state_lock);
10619 }
10620 EXPORT_SYMBOL_GPL(devlink_linecard_nested_dl_set);
10621 
devl_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)10622 int devl_sb_register(struct devlink *devlink, unsigned int sb_index,
10623 		     u32 size, u16 ingress_pools_count,
10624 		     u16 egress_pools_count, u16 ingress_tc_count,
10625 		     u16 egress_tc_count)
10626 {
10627 	struct devlink_sb *devlink_sb;
10628 
10629 	lockdep_assert_held(&devlink->lock);
10630 
10631 	if (devlink_sb_index_exists(devlink, sb_index))
10632 		return -EEXIST;
10633 
10634 	devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
10635 	if (!devlink_sb)
10636 		return -ENOMEM;
10637 	devlink_sb->index = sb_index;
10638 	devlink_sb->size = size;
10639 	devlink_sb->ingress_pools_count = ingress_pools_count;
10640 	devlink_sb->egress_pools_count = egress_pools_count;
10641 	devlink_sb->ingress_tc_count = ingress_tc_count;
10642 	devlink_sb->egress_tc_count = egress_tc_count;
10643 	list_add_tail(&devlink_sb->list, &devlink->sb_list);
10644 	return 0;
10645 }
10646 EXPORT_SYMBOL_GPL(devl_sb_register);
10647 
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)10648 int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
10649 			u32 size, u16 ingress_pools_count,
10650 			u16 egress_pools_count, u16 ingress_tc_count,
10651 			u16 egress_tc_count)
10652 {
10653 	int err;
10654 
10655 	devl_lock(devlink);
10656 	err = devl_sb_register(devlink, sb_index, size, ingress_pools_count,
10657 			       egress_pools_count, ingress_tc_count,
10658 			       egress_tc_count);
10659 	devl_unlock(devlink);
10660 	return err;
10661 }
10662 EXPORT_SYMBOL_GPL(devlink_sb_register);
10663 
devl_sb_unregister(struct devlink * devlink,unsigned int sb_index)10664 void devl_sb_unregister(struct devlink *devlink, unsigned int sb_index)
10665 {
10666 	struct devlink_sb *devlink_sb;
10667 
10668 	lockdep_assert_held(&devlink->lock);
10669 
10670 	devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
10671 	WARN_ON(!devlink_sb);
10672 	list_del(&devlink_sb->list);
10673 	kfree(devlink_sb);
10674 }
10675 EXPORT_SYMBOL_GPL(devl_sb_unregister);
10676 
devlink_sb_unregister(struct devlink * devlink,unsigned int sb_index)10677 void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
10678 {
10679 	devl_lock(devlink);
10680 	devl_sb_unregister(devlink, sb_index);
10681 	devl_unlock(devlink);
10682 }
10683 EXPORT_SYMBOL_GPL(devlink_sb_unregister);
10684 
10685 /**
10686  * devl_dpipe_headers_register - register dpipe headers
10687  *
10688  * @devlink: devlink
10689  * @dpipe_headers: dpipe header array
10690  *
10691  * Register the headers supported by hardware.
10692  */
devl_dpipe_headers_register(struct devlink * devlink,struct devlink_dpipe_headers * dpipe_headers)10693 void devl_dpipe_headers_register(struct devlink *devlink,
10694 				 struct devlink_dpipe_headers *dpipe_headers)
10695 {
10696 	lockdep_assert_held(&devlink->lock);
10697 
10698 	devlink->dpipe_headers = dpipe_headers;
10699 }
10700 EXPORT_SYMBOL_GPL(devl_dpipe_headers_register);
10701 
10702 /**
10703  * devl_dpipe_headers_unregister - unregister dpipe headers
10704  *
10705  * @devlink: devlink
10706  *
10707  * Unregister the headers supported by hardware.
10708  */
devl_dpipe_headers_unregister(struct devlink * devlink)10709 void devl_dpipe_headers_unregister(struct devlink *devlink)
10710 {
10711 	lockdep_assert_held(&devlink->lock);
10712 
10713 	devlink->dpipe_headers = NULL;
10714 }
10715 EXPORT_SYMBOL_GPL(devl_dpipe_headers_unregister);
10716 
10717 /**
10718  *	devlink_dpipe_table_counter_enabled - check if counter allocation
10719  *					      required
10720  *	@devlink: devlink
10721  *	@table_name: tables name
10722  *
10723  *	Used by driver to check if counter allocation is required.
10724  *	After counter allocation is turned on the table entries
10725  *	are updated to include counter statistics.
10726  *
10727  *	After that point on the driver must respect the counter
10728  *	state so that each entry added to the table is added
10729  *	with a counter.
10730  */
devlink_dpipe_table_counter_enabled(struct devlink * devlink,const char * table_name)10731 bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
10732 					 const char *table_name)
10733 {
10734 	struct devlink_dpipe_table *table;
10735 	bool enabled;
10736 
10737 	rcu_read_lock();
10738 	table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
10739 					 table_name, devlink);
10740 	enabled = false;
10741 	if (table)
10742 		enabled = table->counters_enabled;
10743 	rcu_read_unlock();
10744 	return enabled;
10745 }
10746 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled);
10747 
10748 /**
10749  * devl_dpipe_table_register - register dpipe table
10750  *
10751  * @devlink: devlink
10752  * @table_name: table name
10753  * @table_ops: table ops
10754  * @priv: priv
10755  * @counter_control_extern: external control for counters
10756  */
devl_dpipe_table_register(struct devlink * devlink,const char * table_name,struct devlink_dpipe_table_ops * table_ops,void * priv,bool counter_control_extern)10757 int devl_dpipe_table_register(struct devlink *devlink,
10758 			      const char *table_name,
10759 			      struct devlink_dpipe_table_ops *table_ops,
10760 			      void *priv, bool counter_control_extern)
10761 {
10762 	struct devlink_dpipe_table *table;
10763 
10764 	lockdep_assert_held(&devlink->lock);
10765 
10766 	if (WARN_ON(!table_ops->size_get))
10767 		return -EINVAL;
10768 
10769 	if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name,
10770 				     devlink))
10771 		return -EEXIST;
10772 
10773 	table = kzalloc(sizeof(*table), GFP_KERNEL);
10774 	if (!table)
10775 		return -ENOMEM;
10776 
10777 	table->name = table_name;
10778 	table->table_ops = table_ops;
10779 	table->priv = priv;
10780 	table->counter_control_extern = counter_control_extern;
10781 
10782 	list_add_tail_rcu(&table->list, &devlink->dpipe_table_list);
10783 
10784 	return 0;
10785 }
10786 EXPORT_SYMBOL_GPL(devl_dpipe_table_register);
10787 
10788 /**
10789  * devl_dpipe_table_unregister - unregister dpipe table
10790  *
10791  * @devlink: devlink
10792  * @table_name: table name
10793  */
devl_dpipe_table_unregister(struct devlink * devlink,const char * table_name)10794 void devl_dpipe_table_unregister(struct devlink *devlink,
10795 				 const char *table_name)
10796 {
10797 	struct devlink_dpipe_table *table;
10798 
10799 	lockdep_assert_held(&devlink->lock);
10800 
10801 	table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
10802 					 table_name, devlink);
10803 	if (!table)
10804 		return;
10805 	list_del_rcu(&table->list);
10806 	kfree_rcu(table, rcu);
10807 }
10808 EXPORT_SYMBOL_GPL(devl_dpipe_table_unregister);
10809 
10810 /**
10811  * devl_resource_register - devlink resource register
10812  *
10813  * @devlink: devlink
10814  * @resource_name: resource's name
10815  * @resource_size: resource's size
10816  * @resource_id: resource's id
10817  * @parent_resource_id: resource's parent id
10818  * @size_params: size parameters
10819  *
10820  * Generic resources should reuse the same names across drivers.
10821  * Please see the generic resources list at:
10822  * Documentation/networking/devlink/devlink-resource.rst
10823  */
devl_resource_register(struct devlink * devlink,const char * resource_name,u64 resource_size,u64 resource_id,u64 parent_resource_id,const struct devlink_resource_size_params * size_params)10824 int devl_resource_register(struct devlink *devlink,
10825 			   const char *resource_name,
10826 			   u64 resource_size,
10827 			   u64 resource_id,
10828 			   u64 parent_resource_id,
10829 			   const struct devlink_resource_size_params *size_params)
10830 {
10831 	struct devlink_resource *resource;
10832 	struct list_head *resource_list;
10833 	bool top_hierarchy;
10834 
10835 	lockdep_assert_held(&devlink->lock);
10836 
10837 	top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
10838 
10839 	resource = devlink_resource_find(devlink, NULL, resource_id);
10840 	if (resource)
10841 		return -EINVAL;
10842 
10843 	resource = kzalloc(sizeof(*resource), GFP_KERNEL);
10844 	if (!resource)
10845 		return -ENOMEM;
10846 
10847 	if (top_hierarchy) {
10848 		resource_list = &devlink->resource_list;
10849 	} else {
10850 		struct devlink_resource *parent_resource;
10851 
10852 		parent_resource = devlink_resource_find(devlink, NULL,
10853 							parent_resource_id);
10854 		if (parent_resource) {
10855 			resource_list = &parent_resource->resource_list;
10856 			resource->parent = parent_resource;
10857 		} else {
10858 			kfree(resource);
10859 			return -EINVAL;
10860 		}
10861 	}
10862 
10863 	resource->name = resource_name;
10864 	resource->size = resource_size;
10865 	resource->size_new = resource_size;
10866 	resource->id = resource_id;
10867 	resource->size_valid = true;
10868 	memcpy(&resource->size_params, size_params,
10869 	       sizeof(resource->size_params));
10870 	INIT_LIST_HEAD(&resource->resource_list);
10871 	list_add_tail(&resource->list, resource_list);
10872 
10873 	return 0;
10874 }
10875 EXPORT_SYMBOL_GPL(devl_resource_register);
10876 
10877 /**
10878  *	devlink_resource_register - devlink resource register
10879  *
10880  *	@devlink: devlink
10881  *	@resource_name: resource's name
10882  *	@resource_size: resource's size
10883  *	@resource_id: resource's id
10884  *	@parent_resource_id: resource's parent id
10885  *	@size_params: size parameters
10886  *
10887  *	Generic resources should reuse the same names across drivers.
10888  *	Please see the generic resources list at:
10889  *	Documentation/networking/devlink/devlink-resource.rst
10890  *
10891  *	Context: Takes and release devlink->lock <mutex>.
10892  */
devlink_resource_register(struct devlink * devlink,const char * resource_name,u64 resource_size,u64 resource_id,u64 parent_resource_id,const struct devlink_resource_size_params * size_params)10893 int devlink_resource_register(struct devlink *devlink,
10894 			      const char *resource_name,
10895 			      u64 resource_size,
10896 			      u64 resource_id,
10897 			      u64 parent_resource_id,
10898 			      const struct devlink_resource_size_params *size_params)
10899 {
10900 	int err;
10901 
10902 	devl_lock(devlink);
10903 	err = devl_resource_register(devlink, resource_name, resource_size,
10904 				     resource_id, parent_resource_id, size_params);
10905 	devl_unlock(devlink);
10906 	return err;
10907 }
10908 EXPORT_SYMBOL_GPL(devlink_resource_register);
10909 
devlink_resource_unregister(struct devlink * devlink,struct devlink_resource * resource)10910 static void devlink_resource_unregister(struct devlink *devlink,
10911 					struct devlink_resource *resource)
10912 {
10913 	struct devlink_resource *tmp, *child_resource;
10914 
10915 	list_for_each_entry_safe(child_resource, tmp, &resource->resource_list,
10916 				 list) {
10917 		devlink_resource_unregister(devlink, child_resource);
10918 		list_del(&child_resource->list);
10919 		kfree(child_resource);
10920 	}
10921 }
10922 
10923 /**
10924  * devl_resources_unregister - free all resources
10925  *
10926  * @devlink: devlink
10927  */
devl_resources_unregister(struct devlink * devlink)10928 void devl_resources_unregister(struct devlink *devlink)
10929 {
10930 	struct devlink_resource *tmp, *child_resource;
10931 
10932 	lockdep_assert_held(&devlink->lock);
10933 
10934 	list_for_each_entry_safe(child_resource, tmp, &devlink->resource_list,
10935 				 list) {
10936 		devlink_resource_unregister(devlink, child_resource);
10937 		list_del(&child_resource->list);
10938 		kfree(child_resource);
10939 	}
10940 }
10941 EXPORT_SYMBOL_GPL(devl_resources_unregister);
10942 
10943 /**
10944  *	devlink_resources_unregister - free all resources
10945  *
10946  *	@devlink: devlink
10947  *
10948  *	Context: Takes and release devlink->lock <mutex>.
10949  */
devlink_resources_unregister(struct devlink * devlink)10950 void devlink_resources_unregister(struct devlink *devlink)
10951 {
10952 	devl_lock(devlink);
10953 	devl_resources_unregister(devlink);
10954 	devl_unlock(devlink);
10955 }
10956 EXPORT_SYMBOL_GPL(devlink_resources_unregister);
10957 
10958 /**
10959  * devl_resource_size_get - get and update size
10960  *
10961  * @devlink: devlink
10962  * @resource_id: the requested resource id
10963  * @p_resource_size: ptr to update
10964  */
devl_resource_size_get(struct devlink * devlink,u64 resource_id,u64 * p_resource_size)10965 int devl_resource_size_get(struct devlink *devlink,
10966 			   u64 resource_id,
10967 			   u64 *p_resource_size)
10968 {
10969 	struct devlink_resource *resource;
10970 
10971 	lockdep_assert_held(&devlink->lock);
10972 
10973 	resource = devlink_resource_find(devlink, NULL, resource_id);
10974 	if (!resource)
10975 		return -EINVAL;
10976 	*p_resource_size = resource->size_new;
10977 	resource->size = resource->size_new;
10978 	return 0;
10979 }
10980 EXPORT_SYMBOL_GPL(devl_resource_size_get);
10981 
10982 /**
10983  * devl_dpipe_table_resource_set - set the resource id
10984  *
10985  * @devlink: devlink
10986  * @table_name: table name
10987  * @resource_id: resource id
10988  * @resource_units: number of resource's units consumed per table's entry
10989  */
devl_dpipe_table_resource_set(struct devlink * devlink,const char * table_name,u64 resource_id,u64 resource_units)10990 int devl_dpipe_table_resource_set(struct devlink *devlink,
10991 				  const char *table_name, u64 resource_id,
10992 				  u64 resource_units)
10993 {
10994 	struct devlink_dpipe_table *table;
10995 
10996 	table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
10997 					 table_name, devlink);
10998 	if (!table)
10999 		return -EINVAL;
11000 
11001 	table->resource_id = resource_id;
11002 	table->resource_units = resource_units;
11003 	table->resource_valid = true;
11004 	return 0;
11005 }
11006 EXPORT_SYMBOL_GPL(devl_dpipe_table_resource_set);
11007 
11008 /**
11009  * devl_resource_occ_get_register - register occupancy getter
11010  *
11011  * @devlink: devlink
11012  * @resource_id: resource id
11013  * @occ_get: occupancy getter callback
11014  * @occ_get_priv: occupancy getter callback priv
11015  */
devl_resource_occ_get_register(struct devlink * devlink,u64 resource_id,devlink_resource_occ_get_t * occ_get,void * occ_get_priv)11016 void devl_resource_occ_get_register(struct devlink *devlink,
11017 				    u64 resource_id,
11018 				    devlink_resource_occ_get_t *occ_get,
11019 				    void *occ_get_priv)
11020 {
11021 	struct devlink_resource *resource;
11022 
11023 	lockdep_assert_held(&devlink->lock);
11024 
11025 	resource = devlink_resource_find(devlink, NULL, resource_id);
11026 	if (WARN_ON(!resource))
11027 		return;
11028 	WARN_ON(resource->occ_get);
11029 
11030 	resource->occ_get = occ_get;
11031 	resource->occ_get_priv = occ_get_priv;
11032 }
11033 EXPORT_SYMBOL_GPL(devl_resource_occ_get_register);
11034 
11035 /**
11036  *	devlink_resource_occ_get_register - register occupancy getter
11037  *
11038  *	@devlink: devlink
11039  *	@resource_id: resource id
11040  *	@occ_get: occupancy getter callback
11041  *	@occ_get_priv: occupancy getter callback priv
11042  *
11043  *	Context: Takes and release devlink->lock <mutex>.
11044  */
devlink_resource_occ_get_register(struct devlink * devlink,u64 resource_id,devlink_resource_occ_get_t * occ_get,void * occ_get_priv)11045 void devlink_resource_occ_get_register(struct devlink *devlink,
11046 				       u64 resource_id,
11047 				       devlink_resource_occ_get_t *occ_get,
11048 				       void *occ_get_priv)
11049 {
11050 	devl_lock(devlink);
11051 	devl_resource_occ_get_register(devlink, resource_id,
11052 				       occ_get, occ_get_priv);
11053 	devl_unlock(devlink);
11054 }
11055 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register);
11056 
11057 /**
11058  * devl_resource_occ_get_unregister - unregister occupancy getter
11059  *
11060  * @devlink: devlink
11061  * @resource_id: resource id
11062  */
devl_resource_occ_get_unregister(struct devlink * devlink,u64 resource_id)11063 void devl_resource_occ_get_unregister(struct devlink *devlink,
11064 				      u64 resource_id)
11065 {
11066 	struct devlink_resource *resource;
11067 
11068 	lockdep_assert_held(&devlink->lock);
11069 
11070 	resource = devlink_resource_find(devlink, NULL, resource_id);
11071 	if (WARN_ON(!resource))
11072 		return;
11073 	WARN_ON(!resource->occ_get);
11074 
11075 	resource->occ_get = NULL;
11076 	resource->occ_get_priv = NULL;
11077 }
11078 EXPORT_SYMBOL_GPL(devl_resource_occ_get_unregister);
11079 
11080 /**
11081  *	devlink_resource_occ_get_unregister - unregister occupancy getter
11082  *
11083  *	@devlink: devlink
11084  *	@resource_id: resource id
11085  *
11086  *	Context: Takes and release devlink->lock <mutex>.
11087  */
devlink_resource_occ_get_unregister(struct devlink * devlink,u64 resource_id)11088 void devlink_resource_occ_get_unregister(struct devlink *devlink,
11089 					 u64 resource_id)
11090 {
11091 	devl_lock(devlink);
11092 	devl_resource_occ_get_unregister(devlink, resource_id);
11093 	devl_unlock(devlink);
11094 }
11095 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister);
11096 
devlink_param_verify(const struct devlink_param * param)11097 static int devlink_param_verify(const struct devlink_param *param)
11098 {
11099 	if (!param || !param->name || !param->supported_cmodes)
11100 		return -EINVAL;
11101 	if (param->generic)
11102 		return devlink_param_generic_verify(param);
11103 	else
11104 		return devlink_param_driver_verify(param);
11105 }
11106 
11107 /**
11108  *	devlink_params_register - register configuration parameters
11109  *
11110  *	@devlink: devlink
11111  *	@params: configuration parameters array
11112  *	@params_count: number of parameters provided
11113  *
11114  *	Register the configuration parameters supported by the driver.
11115  */
devlink_params_register(struct devlink * devlink,const struct devlink_param * params,size_t params_count)11116 int devlink_params_register(struct devlink *devlink,
11117 			    const struct devlink_param *params,
11118 			    size_t params_count)
11119 {
11120 	const struct devlink_param *param = params;
11121 	int i, err;
11122 
11123 	ASSERT_DEVLINK_NOT_REGISTERED(devlink);
11124 
11125 	for (i = 0; i < params_count; i++, param++) {
11126 		err = devlink_param_register(devlink, param);
11127 		if (err)
11128 			goto rollback;
11129 	}
11130 	return 0;
11131 
11132 rollback:
11133 	if (!i)
11134 		return err;
11135 
11136 	for (param--; i > 0; i--, param--)
11137 		devlink_param_unregister(devlink, param);
11138 	return err;
11139 }
11140 EXPORT_SYMBOL_GPL(devlink_params_register);
11141 
11142 /**
11143  *	devlink_params_unregister - unregister configuration parameters
11144  *	@devlink: devlink
11145  *	@params: configuration parameters to unregister
11146  *	@params_count: number of parameters provided
11147  */
devlink_params_unregister(struct devlink * devlink,const struct devlink_param * params,size_t params_count)11148 void devlink_params_unregister(struct devlink *devlink,
11149 			       const struct devlink_param *params,
11150 			       size_t params_count)
11151 {
11152 	const struct devlink_param *param = params;
11153 	int i;
11154 
11155 	ASSERT_DEVLINK_NOT_REGISTERED(devlink);
11156 
11157 	for (i = 0; i < params_count; i++, param++)
11158 		devlink_param_unregister(devlink, param);
11159 }
11160 EXPORT_SYMBOL_GPL(devlink_params_unregister);
11161 
11162 /**
11163  * devlink_param_register - register one configuration parameter
11164  *
11165  * @devlink: devlink
11166  * @param: one configuration parameter
11167  *
11168  * Register the configuration parameter supported by the driver.
11169  * Return: returns 0 on successful registration or error code otherwise.
11170  */
devlink_param_register(struct devlink * devlink,const struct devlink_param * param)11171 int devlink_param_register(struct devlink *devlink,
11172 			   const struct devlink_param *param)
11173 {
11174 	struct devlink_param_item *param_item;
11175 
11176 	ASSERT_DEVLINK_NOT_REGISTERED(devlink);
11177 
11178 	WARN_ON(devlink_param_verify(param));
11179 	WARN_ON(devlink_param_find_by_name(&devlink->param_list, param->name));
11180 
11181 	if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT))
11182 		WARN_ON(param->get || param->set);
11183 	else
11184 		WARN_ON(!param->get || !param->set);
11185 
11186 	param_item = kzalloc(sizeof(*param_item), GFP_KERNEL);
11187 	if (!param_item)
11188 		return -ENOMEM;
11189 
11190 	param_item->param = param;
11191 
11192 	list_add_tail(&param_item->list, &devlink->param_list);
11193 	return 0;
11194 }
11195 EXPORT_SYMBOL_GPL(devlink_param_register);
11196 
11197 /**
11198  * devlink_param_unregister - unregister one configuration parameter
11199  * @devlink: devlink
11200  * @param: configuration parameter to unregister
11201  */
devlink_param_unregister(struct devlink * devlink,const struct devlink_param * param)11202 void devlink_param_unregister(struct devlink *devlink,
11203 			      const struct devlink_param *param)
11204 {
11205 	struct devlink_param_item *param_item;
11206 
11207 	ASSERT_DEVLINK_NOT_REGISTERED(devlink);
11208 
11209 	param_item =
11210 		devlink_param_find_by_name(&devlink->param_list, param->name);
11211 	WARN_ON(!param_item);
11212 	list_del(&param_item->list);
11213 	kfree(param_item);
11214 }
11215 EXPORT_SYMBOL_GPL(devlink_param_unregister);
11216 
11217 /**
11218  *	devlink_param_driverinit_value_get - get configuration parameter
11219  *					     value for driver initializing
11220  *
11221  *	@devlink: devlink
11222  *	@param_id: parameter ID
11223  *	@init_val: value of parameter in driverinit configuration mode
11224  *
11225  *	This function should be used by the driver to get driverinit
11226  *	configuration for initialization after reload command.
11227  */
devlink_param_driverinit_value_get(struct devlink * devlink,u32 param_id,union devlink_param_value * init_val)11228 int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
11229 				       union devlink_param_value *init_val)
11230 {
11231 	struct devlink_param_item *param_item;
11232 
11233 	if (!devlink_reload_supported(devlink->ops))
11234 		return -EOPNOTSUPP;
11235 
11236 	param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
11237 	if (!param_item)
11238 		return -EINVAL;
11239 
11240 	if (!param_item->driverinit_value_valid ||
11241 	    !devlink_param_cmode_is_supported(param_item->param,
11242 					      DEVLINK_PARAM_CMODE_DRIVERINIT))
11243 		return -EOPNOTSUPP;
11244 
11245 	if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
11246 		strcpy(init_val->vstr, param_item->driverinit_value.vstr);
11247 	else
11248 		*init_val = param_item->driverinit_value;
11249 
11250 	return 0;
11251 }
11252 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_get);
11253 
11254 /**
11255  *	devlink_param_driverinit_value_set - set value of configuration
11256  *					     parameter for driverinit
11257  *					     configuration mode
11258  *
11259  *	@devlink: devlink
11260  *	@param_id: parameter ID
11261  *	@init_val: value of parameter to set for driverinit configuration mode
11262  *
11263  *	This function should be used by the driver to set driverinit
11264  *	configuration mode default value.
11265  */
devlink_param_driverinit_value_set(struct devlink * devlink,u32 param_id,union devlink_param_value init_val)11266 int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
11267 				       union devlink_param_value init_val)
11268 {
11269 	struct devlink_param_item *param_item;
11270 
11271 	ASSERT_DEVLINK_NOT_REGISTERED(devlink);
11272 
11273 	param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
11274 	if (!param_item)
11275 		return -EINVAL;
11276 
11277 	if (!devlink_param_cmode_is_supported(param_item->param,
11278 					      DEVLINK_PARAM_CMODE_DRIVERINIT))
11279 		return -EOPNOTSUPP;
11280 
11281 	if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
11282 		strcpy(param_item->driverinit_value.vstr, init_val.vstr);
11283 	else
11284 		param_item->driverinit_value = init_val;
11285 	param_item->driverinit_value_valid = true;
11286 	return 0;
11287 }
11288 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set);
11289 
11290 /**
11291  *	devlink_param_value_changed - notify devlink on a parameter's value
11292  *				      change. Should be called by the driver
11293  *				      right after the change.
11294  *
11295  *	@devlink: devlink
11296  *	@param_id: parameter ID
11297  *
11298  *	This function should be used by the driver to notify devlink on value
11299  *	change, excluding driverinit configuration mode.
11300  *	For driverinit configuration mode driver should use the function
11301  */
devlink_param_value_changed(struct devlink * devlink,u32 param_id)11302 void devlink_param_value_changed(struct devlink *devlink, u32 param_id)
11303 {
11304 	struct devlink_param_item *param_item;
11305 
11306 	param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
11307 	WARN_ON(!param_item);
11308 
11309 	devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
11310 }
11311 EXPORT_SYMBOL_GPL(devlink_param_value_changed);
11312 
11313 /**
11314  * devl_region_create - create a new address region
11315  *
11316  * @devlink: devlink
11317  * @ops: region operations and name
11318  * @region_max_snapshots: Maximum supported number of snapshots for region
11319  * @region_size: size of region
11320  */
devl_region_create(struct devlink * devlink,const struct devlink_region_ops * ops,u32 region_max_snapshots,u64 region_size)11321 struct devlink_region *devl_region_create(struct devlink *devlink,
11322 					  const struct devlink_region_ops *ops,
11323 					  u32 region_max_snapshots,
11324 					  u64 region_size)
11325 {
11326 	struct devlink_region *region;
11327 
11328 	devl_assert_locked(devlink);
11329 
11330 	if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
11331 		return ERR_PTR(-EINVAL);
11332 
11333 	if (devlink_region_get_by_name(devlink, ops->name))
11334 		return ERR_PTR(-EEXIST);
11335 
11336 	region = kzalloc(sizeof(*region), GFP_KERNEL);
11337 	if (!region)
11338 		return ERR_PTR(-ENOMEM);
11339 
11340 	region->devlink = devlink;
11341 	region->max_snapshots = region_max_snapshots;
11342 	region->ops = ops;
11343 	region->size = region_size;
11344 	INIT_LIST_HEAD(&region->snapshot_list);
11345 	mutex_init(&region->snapshot_lock);
11346 	list_add_tail(&region->list, &devlink->region_list);
11347 	devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
11348 
11349 	return region;
11350 }
11351 EXPORT_SYMBOL_GPL(devl_region_create);
11352 
11353 /**
11354  *	devlink_region_create - create a new address region
11355  *
11356  *	@devlink: devlink
11357  *	@ops: region operations and name
11358  *	@region_max_snapshots: Maximum supported number of snapshots for region
11359  *	@region_size: size of region
11360  *
11361  *	Context: Takes and release devlink->lock <mutex>.
11362  */
11363 struct devlink_region *
devlink_region_create(struct devlink * devlink,const struct devlink_region_ops * ops,u32 region_max_snapshots,u64 region_size)11364 devlink_region_create(struct devlink *devlink,
11365 		      const struct devlink_region_ops *ops,
11366 		      u32 region_max_snapshots, u64 region_size)
11367 {
11368 	struct devlink_region *region;
11369 
11370 	devl_lock(devlink);
11371 	region = devl_region_create(devlink, ops, region_max_snapshots,
11372 				    region_size);
11373 	devl_unlock(devlink);
11374 	return region;
11375 }
11376 EXPORT_SYMBOL_GPL(devlink_region_create);
11377 
11378 /**
11379  *	devlink_port_region_create - create a new address region for a port
11380  *
11381  *	@port: devlink port
11382  *	@ops: region operations and name
11383  *	@region_max_snapshots: Maximum supported number of snapshots for region
11384  *	@region_size: size of region
11385  *
11386  *	Context: Takes and release devlink->lock <mutex>.
11387  */
11388 struct devlink_region *
devlink_port_region_create(struct devlink_port * port,const struct devlink_port_region_ops * ops,u32 region_max_snapshots,u64 region_size)11389 devlink_port_region_create(struct devlink_port *port,
11390 			   const struct devlink_port_region_ops *ops,
11391 			   u32 region_max_snapshots, u64 region_size)
11392 {
11393 	struct devlink *devlink = port->devlink;
11394 	struct devlink_region *region;
11395 	int err = 0;
11396 
11397 	ASSERT_DEVLINK_PORT_INITIALIZED(port);
11398 
11399 	if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
11400 		return ERR_PTR(-EINVAL);
11401 
11402 	devl_lock(devlink);
11403 
11404 	if (devlink_port_region_get_by_name(port, ops->name)) {
11405 		err = -EEXIST;
11406 		goto unlock;
11407 	}
11408 
11409 	region = kzalloc(sizeof(*region), GFP_KERNEL);
11410 	if (!region) {
11411 		err = -ENOMEM;
11412 		goto unlock;
11413 	}
11414 
11415 	region->devlink = devlink;
11416 	region->port = port;
11417 	region->max_snapshots = region_max_snapshots;
11418 	region->port_ops = ops;
11419 	region->size = region_size;
11420 	INIT_LIST_HEAD(&region->snapshot_list);
11421 	mutex_init(&region->snapshot_lock);
11422 	list_add_tail(&region->list, &port->region_list);
11423 	devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
11424 
11425 	devl_unlock(devlink);
11426 	return region;
11427 
11428 unlock:
11429 	devl_unlock(devlink);
11430 	return ERR_PTR(err);
11431 }
11432 EXPORT_SYMBOL_GPL(devlink_port_region_create);
11433 
11434 /**
11435  * devl_region_destroy - destroy address region
11436  *
11437  * @region: devlink region to destroy
11438  */
devl_region_destroy(struct devlink_region * region)11439 void devl_region_destroy(struct devlink_region *region)
11440 {
11441 	struct devlink *devlink = region->devlink;
11442 	struct devlink_snapshot *snapshot, *ts;
11443 
11444 	devl_assert_locked(devlink);
11445 
11446 	/* Free all snapshots of region */
11447 	mutex_lock(&region->snapshot_lock);
11448 	list_for_each_entry_safe(snapshot, ts, &region->snapshot_list, list)
11449 		devlink_region_snapshot_del(region, snapshot);
11450 	mutex_unlock(&region->snapshot_lock);
11451 
11452 	list_del(&region->list);
11453 	mutex_destroy(&region->snapshot_lock);
11454 
11455 	devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
11456 	kfree(region);
11457 }
11458 EXPORT_SYMBOL_GPL(devl_region_destroy);
11459 
11460 /**
11461  *	devlink_region_destroy - destroy address region
11462  *
11463  *	@region: devlink region to destroy
11464  *
11465  *	Context: Takes and release devlink->lock <mutex>.
11466  */
devlink_region_destroy(struct devlink_region * region)11467 void devlink_region_destroy(struct devlink_region *region)
11468 {
11469 	struct devlink *devlink = region->devlink;
11470 
11471 	devl_lock(devlink);
11472 	devl_region_destroy(region);
11473 	devl_unlock(devlink);
11474 }
11475 EXPORT_SYMBOL_GPL(devlink_region_destroy);
11476 
11477 /**
11478  *	devlink_region_snapshot_id_get - get snapshot ID
11479  *
11480  *	This callback should be called when adding a new snapshot,
11481  *	Driver should use the same id for multiple snapshots taken
11482  *	on multiple regions at the same time/by the same trigger.
11483  *
11484  *	The caller of this function must use devlink_region_snapshot_id_put
11485  *	when finished creating regions using this id.
11486  *
11487  *	Returns zero on success, or a negative error code on failure.
11488  *
11489  *	@devlink: devlink
11490  *	@id: storage to return id
11491  */
devlink_region_snapshot_id_get(struct devlink * devlink,u32 * id)11492 int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
11493 {
11494 	return __devlink_region_snapshot_id_get(devlink, id);
11495 }
11496 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get);
11497 
11498 /**
11499  *	devlink_region_snapshot_id_put - put snapshot ID reference
11500  *
11501  *	This should be called by a driver after finishing creating snapshots
11502  *	with an id. Doing so ensures that the ID can later be released in the
11503  *	event that all snapshots using it have been destroyed.
11504  *
11505  *	@devlink: devlink
11506  *	@id: id to release reference on
11507  */
devlink_region_snapshot_id_put(struct devlink * devlink,u32 id)11508 void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id)
11509 {
11510 	__devlink_snapshot_id_decrement(devlink, id);
11511 }
11512 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put);
11513 
11514 /**
11515  *	devlink_region_snapshot_create - create a new snapshot
11516  *	This will add a new snapshot of a region. The snapshot
11517  *	will be stored on the region struct and can be accessed
11518  *	from devlink. This is useful for future analyses of snapshots.
11519  *	Multiple snapshots can be created on a region.
11520  *	The @snapshot_id should be obtained using the getter function.
11521  *
11522  *	@region: devlink region of the snapshot
11523  *	@data: snapshot data
11524  *	@snapshot_id: snapshot id to be created
11525  */
devlink_region_snapshot_create(struct devlink_region * region,u8 * data,u32 snapshot_id)11526 int devlink_region_snapshot_create(struct devlink_region *region,
11527 				   u8 *data, u32 snapshot_id)
11528 {
11529 	int err;
11530 
11531 	mutex_lock(&region->snapshot_lock);
11532 	err = __devlink_region_snapshot_create(region, data, snapshot_id);
11533 	mutex_unlock(&region->snapshot_lock);
11534 	return err;
11535 }
11536 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create);
11537 
11538 #define DEVLINK_TRAP(_id, _type)					      \
11539 	{								      \
11540 		.type = DEVLINK_TRAP_TYPE_##_type,			      \
11541 		.id = DEVLINK_TRAP_GENERIC_ID_##_id,			      \
11542 		.name = DEVLINK_TRAP_GENERIC_NAME_##_id,		      \
11543 	}
11544 
11545 static const struct devlink_trap devlink_trap_generic[] = {
11546 	DEVLINK_TRAP(SMAC_MC, DROP),
11547 	DEVLINK_TRAP(VLAN_TAG_MISMATCH, DROP),
11548 	DEVLINK_TRAP(INGRESS_VLAN_FILTER, DROP),
11549 	DEVLINK_TRAP(INGRESS_STP_FILTER, DROP),
11550 	DEVLINK_TRAP(EMPTY_TX_LIST, DROP),
11551 	DEVLINK_TRAP(PORT_LOOPBACK_FILTER, DROP),
11552 	DEVLINK_TRAP(BLACKHOLE_ROUTE, DROP),
11553 	DEVLINK_TRAP(TTL_ERROR, EXCEPTION),
11554 	DEVLINK_TRAP(TAIL_DROP, DROP),
11555 	DEVLINK_TRAP(NON_IP_PACKET, DROP),
11556 	DEVLINK_TRAP(UC_DIP_MC_DMAC, DROP),
11557 	DEVLINK_TRAP(DIP_LB, DROP),
11558 	DEVLINK_TRAP(SIP_MC, DROP),
11559 	DEVLINK_TRAP(SIP_LB, DROP),
11560 	DEVLINK_TRAP(CORRUPTED_IP_HDR, DROP),
11561 	DEVLINK_TRAP(IPV4_SIP_BC, DROP),
11562 	DEVLINK_TRAP(IPV6_MC_DIP_RESERVED_SCOPE, DROP),
11563 	DEVLINK_TRAP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE, DROP),
11564 	DEVLINK_TRAP(MTU_ERROR, EXCEPTION),
11565 	DEVLINK_TRAP(UNRESOLVED_NEIGH, EXCEPTION),
11566 	DEVLINK_TRAP(RPF, EXCEPTION),
11567 	DEVLINK_TRAP(REJECT_ROUTE, EXCEPTION),
11568 	DEVLINK_TRAP(IPV4_LPM_UNICAST_MISS, EXCEPTION),
11569 	DEVLINK_TRAP(IPV6_LPM_UNICAST_MISS, EXCEPTION),
11570 	DEVLINK_TRAP(NON_ROUTABLE, DROP),
11571 	DEVLINK_TRAP(DECAP_ERROR, EXCEPTION),
11572 	DEVLINK_TRAP(OVERLAY_SMAC_MC, DROP),
11573 	DEVLINK_TRAP(INGRESS_FLOW_ACTION_DROP, DROP),
11574 	DEVLINK_TRAP(EGRESS_FLOW_ACTION_DROP, DROP),
11575 	DEVLINK_TRAP(STP, CONTROL),
11576 	DEVLINK_TRAP(LACP, CONTROL),
11577 	DEVLINK_TRAP(LLDP, CONTROL),
11578 	DEVLINK_TRAP(IGMP_QUERY, CONTROL),
11579 	DEVLINK_TRAP(IGMP_V1_REPORT, CONTROL),
11580 	DEVLINK_TRAP(IGMP_V2_REPORT, CONTROL),
11581 	DEVLINK_TRAP(IGMP_V3_REPORT, CONTROL),
11582 	DEVLINK_TRAP(IGMP_V2_LEAVE, CONTROL),
11583 	DEVLINK_TRAP(MLD_QUERY, CONTROL),
11584 	DEVLINK_TRAP(MLD_V1_REPORT, CONTROL),
11585 	DEVLINK_TRAP(MLD_V2_REPORT, CONTROL),
11586 	DEVLINK_TRAP(MLD_V1_DONE, CONTROL),
11587 	DEVLINK_TRAP(IPV4_DHCP, CONTROL),
11588 	DEVLINK_TRAP(IPV6_DHCP, CONTROL),
11589 	DEVLINK_TRAP(ARP_REQUEST, CONTROL),
11590 	DEVLINK_TRAP(ARP_RESPONSE, CONTROL),
11591 	DEVLINK_TRAP(ARP_OVERLAY, CONTROL),
11592 	DEVLINK_TRAP(IPV6_NEIGH_SOLICIT, CONTROL),
11593 	DEVLINK_TRAP(IPV6_NEIGH_ADVERT, CONTROL),
11594 	DEVLINK_TRAP(IPV4_BFD, CONTROL),
11595 	DEVLINK_TRAP(IPV6_BFD, CONTROL),
11596 	DEVLINK_TRAP(IPV4_OSPF, CONTROL),
11597 	DEVLINK_TRAP(IPV6_OSPF, CONTROL),
11598 	DEVLINK_TRAP(IPV4_BGP, CONTROL),
11599 	DEVLINK_TRAP(IPV6_BGP, CONTROL),
11600 	DEVLINK_TRAP(IPV4_VRRP, CONTROL),
11601 	DEVLINK_TRAP(IPV6_VRRP, CONTROL),
11602 	DEVLINK_TRAP(IPV4_PIM, CONTROL),
11603 	DEVLINK_TRAP(IPV6_PIM, CONTROL),
11604 	DEVLINK_TRAP(UC_LB, CONTROL),
11605 	DEVLINK_TRAP(LOCAL_ROUTE, CONTROL),
11606 	DEVLINK_TRAP(EXTERNAL_ROUTE, CONTROL),
11607 	DEVLINK_TRAP(IPV6_UC_DIP_LINK_LOCAL_SCOPE, CONTROL),
11608 	DEVLINK_TRAP(IPV6_DIP_ALL_NODES, CONTROL),
11609 	DEVLINK_TRAP(IPV6_DIP_ALL_ROUTERS, CONTROL),
11610 	DEVLINK_TRAP(IPV6_ROUTER_SOLICIT, CONTROL),
11611 	DEVLINK_TRAP(IPV6_ROUTER_ADVERT, CONTROL),
11612 	DEVLINK_TRAP(IPV6_REDIRECT, CONTROL),
11613 	DEVLINK_TRAP(IPV4_ROUTER_ALERT, CONTROL),
11614 	DEVLINK_TRAP(IPV6_ROUTER_ALERT, CONTROL),
11615 	DEVLINK_TRAP(PTP_EVENT, CONTROL),
11616 	DEVLINK_TRAP(PTP_GENERAL, CONTROL),
11617 	DEVLINK_TRAP(FLOW_ACTION_SAMPLE, CONTROL),
11618 	DEVLINK_TRAP(FLOW_ACTION_TRAP, CONTROL),
11619 	DEVLINK_TRAP(EARLY_DROP, DROP),
11620 	DEVLINK_TRAP(VXLAN_PARSING, DROP),
11621 	DEVLINK_TRAP(LLC_SNAP_PARSING, DROP),
11622 	DEVLINK_TRAP(VLAN_PARSING, DROP),
11623 	DEVLINK_TRAP(PPPOE_PPP_PARSING, DROP),
11624 	DEVLINK_TRAP(MPLS_PARSING, DROP),
11625 	DEVLINK_TRAP(ARP_PARSING, DROP),
11626 	DEVLINK_TRAP(IP_1_PARSING, DROP),
11627 	DEVLINK_TRAP(IP_N_PARSING, DROP),
11628 	DEVLINK_TRAP(GRE_PARSING, DROP),
11629 	DEVLINK_TRAP(UDP_PARSING, DROP),
11630 	DEVLINK_TRAP(TCP_PARSING, DROP),
11631 	DEVLINK_TRAP(IPSEC_PARSING, DROP),
11632 	DEVLINK_TRAP(SCTP_PARSING, DROP),
11633 	DEVLINK_TRAP(DCCP_PARSING, DROP),
11634 	DEVLINK_TRAP(GTP_PARSING, DROP),
11635 	DEVLINK_TRAP(ESP_PARSING, DROP),
11636 	DEVLINK_TRAP(BLACKHOLE_NEXTHOP, DROP),
11637 	DEVLINK_TRAP(DMAC_FILTER, DROP),
11638 };
11639 
11640 #define DEVLINK_TRAP_GROUP(_id)						      \
11641 	{								      \
11642 		.id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id,		      \
11643 		.name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id,		      \
11644 	}
11645 
11646 static const struct devlink_trap_group devlink_trap_group_generic[] = {
11647 	DEVLINK_TRAP_GROUP(L2_DROPS),
11648 	DEVLINK_TRAP_GROUP(L3_DROPS),
11649 	DEVLINK_TRAP_GROUP(L3_EXCEPTIONS),
11650 	DEVLINK_TRAP_GROUP(BUFFER_DROPS),
11651 	DEVLINK_TRAP_GROUP(TUNNEL_DROPS),
11652 	DEVLINK_TRAP_GROUP(ACL_DROPS),
11653 	DEVLINK_TRAP_GROUP(STP),
11654 	DEVLINK_TRAP_GROUP(LACP),
11655 	DEVLINK_TRAP_GROUP(LLDP),
11656 	DEVLINK_TRAP_GROUP(MC_SNOOPING),
11657 	DEVLINK_TRAP_GROUP(DHCP),
11658 	DEVLINK_TRAP_GROUP(NEIGH_DISCOVERY),
11659 	DEVLINK_TRAP_GROUP(BFD),
11660 	DEVLINK_TRAP_GROUP(OSPF),
11661 	DEVLINK_TRAP_GROUP(BGP),
11662 	DEVLINK_TRAP_GROUP(VRRP),
11663 	DEVLINK_TRAP_GROUP(PIM),
11664 	DEVLINK_TRAP_GROUP(UC_LB),
11665 	DEVLINK_TRAP_GROUP(LOCAL_DELIVERY),
11666 	DEVLINK_TRAP_GROUP(EXTERNAL_DELIVERY),
11667 	DEVLINK_TRAP_GROUP(IPV6),
11668 	DEVLINK_TRAP_GROUP(PTP_EVENT),
11669 	DEVLINK_TRAP_GROUP(PTP_GENERAL),
11670 	DEVLINK_TRAP_GROUP(ACL_SAMPLE),
11671 	DEVLINK_TRAP_GROUP(ACL_TRAP),
11672 	DEVLINK_TRAP_GROUP(PARSER_ERROR_DROPS),
11673 };
11674 
devlink_trap_generic_verify(const struct devlink_trap * trap)11675 static int devlink_trap_generic_verify(const struct devlink_trap *trap)
11676 {
11677 	if (trap->id > DEVLINK_TRAP_GENERIC_ID_MAX)
11678 		return -EINVAL;
11679 
11680 	if (strcmp(trap->name, devlink_trap_generic[trap->id].name))
11681 		return -EINVAL;
11682 
11683 	if (trap->type != devlink_trap_generic[trap->id].type)
11684 		return -EINVAL;
11685 
11686 	return 0;
11687 }
11688 
devlink_trap_driver_verify(const struct devlink_trap * trap)11689 static int devlink_trap_driver_verify(const struct devlink_trap *trap)
11690 {
11691 	int i;
11692 
11693 	if (trap->id <= DEVLINK_TRAP_GENERIC_ID_MAX)
11694 		return -EINVAL;
11695 
11696 	for (i = 0; i < ARRAY_SIZE(devlink_trap_generic); i++) {
11697 		if (!strcmp(trap->name, devlink_trap_generic[i].name))
11698 			return -EEXIST;
11699 	}
11700 
11701 	return 0;
11702 }
11703 
devlink_trap_verify(const struct devlink_trap * trap)11704 static int devlink_trap_verify(const struct devlink_trap *trap)
11705 {
11706 	if (!trap || !trap->name)
11707 		return -EINVAL;
11708 
11709 	if (trap->generic)
11710 		return devlink_trap_generic_verify(trap);
11711 	else
11712 		return devlink_trap_driver_verify(trap);
11713 }
11714 
11715 static int
devlink_trap_group_generic_verify(const struct devlink_trap_group * group)11716 devlink_trap_group_generic_verify(const struct devlink_trap_group *group)
11717 {
11718 	if (group->id > DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
11719 		return -EINVAL;
11720 
11721 	if (strcmp(group->name, devlink_trap_group_generic[group->id].name))
11722 		return -EINVAL;
11723 
11724 	return 0;
11725 }
11726 
11727 static int
devlink_trap_group_driver_verify(const struct devlink_trap_group * group)11728 devlink_trap_group_driver_verify(const struct devlink_trap_group *group)
11729 {
11730 	int i;
11731 
11732 	if (group->id <= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
11733 		return -EINVAL;
11734 
11735 	for (i = 0; i < ARRAY_SIZE(devlink_trap_group_generic); i++) {
11736 		if (!strcmp(group->name, devlink_trap_group_generic[i].name))
11737 			return -EEXIST;
11738 	}
11739 
11740 	return 0;
11741 }
11742 
devlink_trap_group_verify(const struct devlink_trap_group * group)11743 static int devlink_trap_group_verify(const struct devlink_trap_group *group)
11744 {
11745 	if (group->generic)
11746 		return devlink_trap_group_generic_verify(group);
11747 	else
11748 		return devlink_trap_group_driver_verify(group);
11749 }
11750 
11751 static void
devlink_trap_group_notify(struct devlink * devlink,const struct devlink_trap_group_item * group_item,enum devlink_command cmd)11752 devlink_trap_group_notify(struct devlink *devlink,
11753 			  const struct devlink_trap_group_item *group_item,
11754 			  enum devlink_command cmd)
11755 {
11756 	struct sk_buff *msg;
11757 	int err;
11758 
11759 	WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_GROUP_NEW &&
11760 		     cmd != DEVLINK_CMD_TRAP_GROUP_DEL);
11761 	if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
11762 		return;
11763 
11764 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11765 	if (!msg)
11766 		return;
11767 
11768 	err = devlink_nl_trap_group_fill(msg, devlink, group_item, cmd, 0, 0,
11769 					 0);
11770 	if (err) {
11771 		nlmsg_free(msg);
11772 		return;
11773 	}
11774 
11775 	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
11776 				msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
11777 }
11778 
11779 static int
devlink_trap_item_group_link(struct devlink * devlink,struct devlink_trap_item * trap_item)11780 devlink_trap_item_group_link(struct devlink *devlink,
11781 			     struct devlink_trap_item *trap_item)
11782 {
11783 	u16 group_id = trap_item->trap->init_group_id;
11784 	struct devlink_trap_group_item *group_item;
11785 
11786 	group_item = devlink_trap_group_item_lookup_by_id(devlink, group_id);
11787 	if (WARN_ON_ONCE(!group_item))
11788 		return -EINVAL;
11789 
11790 	trap_item->group_item = group_item;
11791 
11792 	return 0;
11793 }
11794 
devlink_trap_notify(struct devlink * devlink,const struct devlink_trap_item * trap_item,enum devlink_command cmd)11795 static void devlink_trap_notify(struct devlink *devlink,
11796 				const struct devlink_trap_item *trap_item,
11797 				enum devlink_command cmd)
11798 {
11799 	struct sk_buff *msg;
11800 	int err;
11801 
11802 	WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_NEW &&
11803 		     cmd != DEVLINK_CMD_TRAP_DEL);
11804 	if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
11805 		return;
11806 
11807 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11808 	if (!msg)
11809 		return;
11810 
11811 	err = devlink_nl_trap_fill(msg, devlink, trap_item, cmd, 0, 0, 0);
11812 	if (err) {
11813 		nlmsg_free(msg);
11814 		return;
11815 	}
11816 
11817 	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
11818 				msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
11819 }
11820 
11821 static int
devlink_trap_register(struct devlink * devlink,const struct devlink_trap * trap,void * priv)11822 devlink_trap_register(struct devlink *devlink,
11823 		      const struct devlink_trap *trap, void *priv)
11824 {
11825 	struct devlink_trap_item *trap_item;
11826 	int err;
11827 
11828 	if (devlink_trap_item_lookup(devlink, trap->name))
11829 		return -EEXIST;
11830 
11831 	trap_item = kzalloc(sizeof(*trap_item), GFP_KERNEL);
11832 	if (!trap_item)
11833 		return -ENOMEM;
11834 
11835 	trap_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
11836 	if (!trap_item->stats) {
11837 		err = -ENOMEM;
11838 		goto err_stats_alloc;
11839 	}
11840 
11841 	trap_item->trap = trap;
11842 	trap_item->action = trap->init_action;
11843 	trap_item->priv = priv;
11844 
11845 	err = devlink_trap_item_group_link(devlink, trap_item);
11846 	if (err)
11847 		goto err_group_link;
11848 
11849 	err = devlink->ops->trap_init(devlink, trap, trap_item);
11850 	if (err)
11851 		goto err_trap_init;
11852 
11853 	list_add_tail(&trap_item->list, &devlink->trap_list);
11854 	devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
11855 
11856 	return 0;
11857 
11858 err_trap_init:
11859 err_group_link:
11860 	free_percpu(trap_item->stats);
11861 err_stats_alloc:
11862 	kfree(trap_item);
11863 	return err;
11864 }
11865 
devlink_trap_unregister(struct devlink * devlink,const struct devlink_trap * trap)11866 static void devlink_trap_unregister(struct devlink *devlink,
11867 				    const struct devlink_trap *trap)
11868 {
11869 	struct devlink_trap_item *trap_item;
11870 
11871 	trap_item = devlink_trap_item_lookup(devlink, trap->name);
11872 	if (WARN_ON_ONCE(!trap_item))
11873 		return;
11874 
11875 	devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL);
11876 	list_del(&trap_item->list);
11877 	if (devlink->ops->trap_fini)
11878 		devlink->ops->trap_fini(devlink, trap, trap_item);
11879 	free_percpu(trap_item->stats);
11880 	kfree(trap_item);
11881 }
11882 
devlink_trap_disable(struct devlink * devlink,const struct devlink_trap * trap)11883 static void devlink_trap_disable(struct devlink *devlink,
11884 				 const struct devlink_trap *trap)
11885 {
11886 	struct devlink_trap_item *trap_item;
11887 
11888 	trap_item = devlink_trap_item_lookup(devlink, trap->name);
11889 	if (WARN_ON_ONCE(!trap_item))
11890 		return;
11891 
11892 	devlink->ops->trap_action_set(devlink, trap, DEVLINK_TRAP_ACTION_DROP,
11893 				      NULL);
11894 	trap_item->action = DEVLINK_TRAP_ACTION_DROP;
11895 }
11896 
11897 /**
11898  * devl_traps_register - Register packet traps with devlink.
11899  * @devlink: devlink.
11900  * @traps: Packet traps.
11901  * @traps_count: Count of provided packet traps.
11902  * @priv: Driver private information.
11903  *
11904  * Return: Non-zero value on failure.
11905  */
devl_traps_register(struct devlink * devlink,const struct devlink_trap * traps,size_t traps_count,void * priv)11906 int devl_traps_register(struct devlink *devlink,
11907 			const struct devlink_trap *traps,
11908 			size_t traps_count, void *priv)
11909 {
11910 	int i, err;
11911 
11912 	if (!devlink->ops->trap_init || !devlink->ops->trap_action_set)
11913 		return -EINVAL;
11914 
11915 	devl_assert_locked(devlink);
11916 	for (i = 0; i < traps_count; i++) {
11917 		const struct devlink_trap *trap = &traps[i];
11918 
11919 		err = devlink_trap_verify(trap);
11920 		if (err)
11921 			goto err_trap_verify;
11922 
11923 		err = devlink_trap_register(devlink, trap, priv);
11924 		if (err)
11925 			goto err_trap_register;
11926 	}
11927 
11928 	return 0;
11929 
11930 err_trap_register:
11931 err_trap_verify:
11932 	for (i--; i >= 0; i--)
11933 		devlink_trap_unregister(devlink, &traps[i]);
11934 	return err;
11935 }
11936 EXPORT_SYMBOL_GPL(devl_traps_register);
11937 
11938 /**
11939  * devlink_traps_register - Register packet traps with devlink.
11940  * @devlink: devlink.
11941  * @traps: Packet traps.
11942  * @traps_count: Count of provided packet traps.
11943  * @priv: Driver private information.
11944  *
11945  * Context: Takes and release devlink->lock <mutex>.
11946  *
11947  * Return: Non-zero value on failure.
11948  */
devlink_traps_register(struct devlink * devlink,const struct devlink_trap * traps,size_t traps_count,void * priv)11949 int devlink_traps_register(struct devlink *devlink,
11950 			   const struct devlink_trap *traps,
11951 			   size_t traps_count, void *priv)
11952 {
11953 	int err;
11954 
11955 	devl_lock(devlink);
11956 	err = devl_traps_register(devlink, traps, traps_count, priv);
11957 	devl_unlock(devlink);
11958 	return err;
11959 }
11960 EXPORT_SYMBOL_GPL(devlink_traps_register);
11961 
11962 /**
11963  * devl_traps_unregister - Unregister packet traps from devlink.
11964  * @devlink: devlink.
11965  * @traps: Packet traps.
11966  * @traps_count: Count of provided packet traps.
11967  */
devl_traps_unregister(struct devlink * devlink,const struct devlink_trap * traps,size_t traps_count)11968 void devl_traps_unregister(struct devlink *devlink,
11969 			   const struct devlink_trap *traps,
11970 			   size_t traps_count)
11971 {
11972 	int i;
11973 
11974 	devl_assert_locked(devlink);
11975 	/* Make sure we do not have any packets in-flight while unregistering
11976 	 * traps by disabling all of them and waiting for a grace period.
11977 	 */
11978 	for (i = traps_count - 1; i >= 0; i--)
11979 		devlink_trap_disable(devlink, &traps[i]);
11980 	synchronize_rcu();
11981 	for (i = traps_count - 1; i >= 0; i--)
11982 		devlink_trap_unregister(devlink, &traps[i]);
11983 }
11984 EXPORT_SYMBOL_GPL(devl_traps_unregister);
11985 
11986 /**
11987  * devlink_traps_unregister - Unregister packet traps from devlink.
11988  * @devlink: devlink.
11989  * @traps: Packet traps.
11990  * @traps_count: Count of provided packet traps.
11991  *
11992  * Context: Takes and release devlink->lock <mutex>.
11993  */
devlink_traps_unregister(struct devlink * devlink,const struct devlink_trap * traps,size_t traps_count)11994 void devlink_traps_unregister(struct devlink *devlink,
11995 			      const struct devlink_trap *traps,
11996 			      size_t traps_count)
11997 {
11998 	devl_lock(devlink);
11999 	devl_traps_unregister(devlink, traps, traps_count);
12000 	devl_unlock(devlink);
12001 }
12002 EXPORT_SYMBOL_GPL(devlink_traps_unregister);
12003 
12004 static void
devlink_trap_stats_update(struct devlink_stats __percpu * trap_stats,size_t skb_len)12005 devlink_trap_stats_update(struct devlink_stats __percpu *trap_stats,
12006 			  size_t skb_len)
12007 {
12008 	struct devlink_stats *stats;
12009 
12010 	stats = this_cpu_ptr(trap_stats);
12011 	u64_stats_update_begin(&stats->syncp);
12012 	u64_stats_add(&stats->rx_bytes, skb_len);
12013 	u64_stats_inc(&stats->rx_packets);
12014 	u64_stats_update_end(&stats->syncp);
12015 }
12016 
12017 static void
devlink_trap_report_metadata_set(struct devlink_trap_metadata * metadata,const struct devlink_trap_item * trap_item,struct devlink_port * in_devlink_port,const struct flow_action_cookie * fa_cookie)12018 devlink_trap_report_metadata_set(struct devlink_trap_metadata *metadata,
12019 				 const struct devlink_trap_item *trap_item,
12020 				 struct devlink_port *in_devlink_port,
12021 				 const struct flow_action_cookie *fa_cookie)
12022 {
12023 	metadata->trap_name = trap_item->trap->name;
12024 	metadata->trap_group_name = trap_item->group_item->group->name;
12025 	metadata->fa_cookie = fa_cookie;
12026 	metadata->trap_type = trap_item->trap->type;
12027 
12028 	spin_lock(&in_devlink_port->type_lock);
12029 	if (in_devlink_port->type == DEVLINK_PORT_TYPE_ETH)
12030 		metadata->input_dev = in_devlink_port->type_dev;
12031 	spin_unlock(&in_devlink_port->type_lock);
12032 }
12033 
12034 /**
12035  * devlink_trap_report - Report trapped packet to drop monitor.
12036  * @devlink: devlink.
12037  * @skb: Trapped packet.
12038  * @trap_ctx: Trap context.
12039  * @in_devlink_port: Input devlink port.
12040  * @fa_cookie: Flow action cookie. Could be NULL.
12041  */
devlink_trap_report(struct devlink * devlink,struct sk_buff * skb,void * trap_ctx,struct devlink_port * in_devlink_port,const struct flow_action_cookie * fa_cookie)12042 void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb,
12043 			 void *trap_ctx, struct devlink_port *in_devlink_port,
12044 			 const struct flow_action_cookie *fa_cookie)
12045 
12046 {
12047 	struct devlink_trap_item *trap_item = trap_ctx;
12048 
12049 	devlink_trap_stats_update(trap_item->stats, skb->len);
12050 	devlink_trap_stats_update(trap_item->group_item->stats, skb->len);
12051 
12052 	if (trace_devlink_trap_report_enabled()) {
12053 		struct devlink_trap_metadata metadata = {};
12054 
12055 		devlink_trap_report_metadata_set(&metadata, trap_item,
12056 						 in_devlink_port, fa_cookie);
12057 		trace_devlink_trap_report(devlink, skb, &metadata);
12058 	}
12059 }
12060 EXPORT_SYMBOL_GPL(devlink_trap_report);
12061 
12062 /**
12063  * devlink_trap_ctx_priv - Trap context to driver private information.
12064  * @trap_ctx: Trap context.
12065  *
12066  * Return: Driver private information passed during registration.
12067  */
devlink_trap_ctx_priv(void * trap_ctx)12068 void *devlink_trap_ctx_priv(void *trap_ctx)
12069 {
12070 	struct devlink_trap_item *trap_item = trap_ctx;
12071 
12072 	return trap_item->priv;
12073 }
12074 EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv);
12075 
12076 static int
devlink_trap_group_item_policer_link(struct devlink * devlink,struct devlink_trap_group_item * group_item)12077 devlink_trap_group_item_policer_link(struct devlink *devlink,
12078 				     struct devlink_trap_group_item *group_item)
12079 {
12080 	u32 policer_id = group_item->group->init_policer_id;
12081 	struct devlink_trap_policer_item *policer_item;
12082 
12083 	if (policer_id == 0)
12084 		return 0;
12085 
12086 	policer_item = devlink_trap_policer_item_lookup(devlink, policer_id);
12087 	if (WARN_ON_ONCE(!policer_item))
12088 		return -EINVAL;
12089 
12090 	group_item->policer_item = policer_item;
12091 
12092 	return 0;
12093 }
12094 
12095 static int
devlink_trap_group_register(struct devlink * devlink,const struct devlink_trap_group * group)12096 devlink_trap_group_register(struct devlink *devlink,
12097 			    const struct devlink_trap_group *group)
12098 {
12099 	struct devlink_trap_group_item *group_item;
12100 	int err;
12101 
12102 	if (devlink_trap_group_item_lookup(devlink, group->name))
12103 		return -EEXIST;
12104 
12105 	group_item = kzalloc(sizeof(*group_item), GFP_KERNEL);
12106 	if (!group_item)
12107 		return -ENOMEM;
12108 
12109 	group_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
12110 	if (!group_item->stats) {
12111 		err = -ENOMEM;
12112 		goto err_stats_alloc;
12113 	}
12114 
12115 	group_item->group = group;
12116 
12117 	err = devlink_trap_group_item_policer_link(devlink, group_item);
12118 	if (err)
12119 		goto err_policer_link;
12120 
12121 	if (devlink->ops->trap_group_init) {
12122 		err = devlink->ops->trap_group_init(devlink, group);
12123 		if (err)
12124 			goto err_group_init;
12125 	}
12126 
12127 	list_add_tail(&group_item->list, &devlink->trap_group_list);
12128 	devlink_trap_group_notify(devlink, group_item,
12129 				  DEVLINK_CMD_TRAP_GROUP_NEW);
12130 
12131 	return 0;
12132 
12133 err_group_init:
12134 err_policer_link:
12135 	free_percpu(group_item->stats);
12136 err_stats_alloc:
12137 	kfree(group_item);
12138 	return err;
12139 }
12140 
12141 static void
devlink_trap_group_unregister(struct devlink * devlink,const struct devlink_trap_group * group)12142 devlink_trap_group_unregister(struct devlink *devlink,
12143 			      const struct devlink_trap_group *group)
12144 {
12145 	struct devlink_trap_group_item *group_item;
12146 
12147 	group_item = devlink_trap_group_item_lookup(devlink, group->name);
12148 	if (WARN_ON_ONCE(!group_item))
12149 		return;
12150 
12151 	devlink_trap_group_notify(devlink, group_item,
12152 				  DEVLINK_CMD_TRAP_GROUP_DEL);
12153 	list_del(&group_item->list);
12154 	free_percpu(group_item->stats);
12155 	kfree(group_item);
12156 }
12157 
12158 /**
12159  * devl_trap_groups_register - Register packet trap groups with devlink.
12160  * @devlink: devlink.
12161  * @groups: Packet trap groups.
12162  * @groups_count: Count of provided packet trap groups.
12163  *
12164  * Return: Non-zero value on failure.
12165  */
devl_trap_groups_register(struct devlink * devlink,const struct devlink_trap_group * groups,size_t groups_count)12166 int devl_trap_groups_register(struct devlink *devlink,
12167 			      const struct devlink_trap_group *groups,
12168 			      size_t groups_count)
12169 {
12170 	int i, err;
12171 
12172 	devl_assert_locked(devlink);
12173 	for (i = 0; i < groups_count; i++) {
12174 		const struct devlink_trap_group *group = &groups[i];
12175 
12176 		err = devlink_trap_group_verify(group);
12177 		if (err)
12178 			goto err_trap_group_verify;
12179 
12180 		err = devlink_trap_group_register(devlink, group);
12181 		if (err)
12182 			goto err_trap_group_register;
12183 	}
12184 
12185 	return 0;
12186 
12187 err_trap_group_register:
12188 err_trap_group_verify:
12189 	for (i--; i >= 0; i--)
12190 		devlink_trap_group_unregister(devlink, &groups[i]);
12191 	return err;
12192 }
12193 EXPORT_SYMBOL_GPL(devl_trap_groups_register);
12194 
12195 /**
12196  * devlink_trap_groups_register - Register packet trap groups with devlink.
12197  * @devlink: devlink.
12198  * @groups: Packet trap groups.
12199  * @groups_count: Count of provided packet trap groups.
12200  *
12201  * Context: Takes and release devlink->lock <mutex>.
12202  *
12203  * Return: Non-zero value on failure.
12204  */
devlink_trap_groups_register(struct devlink * devlink,const struct devlink_trap_group * groups,size_t groups_count)12205 int devlink_trap_groups_register(struct devlink *devlink,
12206 				 const struct devlink_trap_group *groups,
12207 				 size_t groups_count)
12208 {
12209 	int err;
12210 
12211 	devl_lock(devlink);
12212 	err = devl_trap_groups_register(devlink, groups, groups_count);
12213 	devl_unlock(devlink);
12214 	return err;
12215 }
12216 EXPORT_SYMBOL_GPL(devlink_trap_groups_register);
12217 
12218 /**
12219  * devl_trap_groups_unregister - Unregister packet trap groups from devlink.
12220  * @devlink: devlink.
12221  * @groups: Packet trap groups.
12222  * @groups_count: Count of provided packet trap groups.
12223  */
devl_trap_groups_unregister(struct devlink * devlink,const struct devlink_trap_group * groups,size_t groups_count)12224 void devl_trap_groups_unregister(struct devlink *devlink,
12225 				 const struct devlink_trap_group *groups,
12226 				 size_t groups_count)
12227 {
12228 	int i;
12229 
12230 	devl_assert_locked(devlink);
12231 	for (i = groups_count - 1; i >= 0; i--)
12232 		devlink_trap_group_unregister(devlink, &groups[i]);
12233 }
12234 EXPORT_SYMBOL_GPL(devl_trap_groups_unregister);
12235 
12236 /**
12237  * devlink_trap_groups_unregister - Unregister packet trap groups from devlink.
12238  * @devlink: devlink.
12239  * @groups: Packet trap groups.
12240  * @groups_count: Count of provided packet trap groups.
12241  *
12242  * Context: Takes and release devlink->lock <mutex>.
12243  */
devlink_trap_groups_unregister(struct devlink * devlink,const struct devlink_trap_group * groups,size_t groups_count)12244 void devlink_trap_groups_unregister(struct devlink *devlink,
12245 				    const struct devlink_trap_group *groups,
12246 				    size_t groups_count)
12247 {
12248 	devl_lock(devlink);
12249 	devl_trap_groups_unregister(devlink, groups, groups_count);
12250 	devl_unlock(devlink);
12251 }
12252 EXPORT_SYMBOL_GPL(devlink_trap_groups_unregister);
12253 
12254 static void
devlink_trap_policer_notify(struct devlink * devlink,const struct devlink_trap_policer_item * policer_item,enum devlink_command cmd)12255 devlink_trap_policer_notify(struct devlink *devlink,
12256 			    const struct devlink_trap_policer_item *policer_item,
12257 			    enum devlink_command cmd)
12258 {
12259 	struct sk_buff *msg;
12260 	int err;
12261 
12262 	WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_POLICER_NEW &&
12263 		     cmd != DEVLINK_CMD_TRAP_POLICER_DEL);
12264 	if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
12265 		return;
12266 
12267 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12268 	if (!msg)
12269 		return;
12270 
12271 	err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, cmd, 0,
12272 					   0, 0);
12273 	if (err) {
12274 		nlmsg_free(msg);
12275 		return;
12276 	}
12277 
12278 	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
12279 				msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
12280 }
12281 
12282 static int
devlink_trap_policer_register(struct devlink * devlink,const struct devlink_trap_policer * policer)12283 devlink_trap_policer_register(struct devlink *devlink,
12284 			      const struct devlink_trap_policer *policer)
12285 {
12286 	struct devlink_trap_policer_item *policer_item;
12287 	int err;
12288 
12289 	if (devlink_trap_policer_item_lookup(devlink, policer->id))
12290 		return -EEXIST;
12291 
12292 	policer_item = kzalloc(sizeof(*policer_item), GFP_KERNEL);
12293 	if (!policer_item)
12294 		return -ENOMEM;
12295 
12296 	policer_item->policer = policer;
12297 	policer_item->rate = policer->init_rate;
12298 	policer_item->burst = policer->init_burst;
12299 
12300 	if (devlink->ops->trap_policer_init) {
12301 		err = devlink->ops->trap_policer_init(devlink, policer);
12302 		if (err)
12303 			goto err_policer_init;
12304 	}
12305 
12306 	list_add_tail(&policer_item->list, &devlink->trap_policer_list);
12307 	devlink_trap_policer_notify(devlink, policer_item,
12308 				    DEVLINK_CMD_TRAP_POLICER_NEW);
12309 
12310 	return 0;
12311 
12312 err_policer_init:
12313 	kfree(policer_item);
12314 	return err;
12315 }
12316 
12317 static void
devlink_trap_policer_unregister(struct devlink * devlink,const struct devlink_trap_policer * policer)12318 devlink_trap_policer_unregister(struct devlink *devlink,
12319 				const struct devlink_trap_policer *policer)
12320 {
12321 	struct devlink_trap_policer_item *policer_item;
12322 
12323 	policer_item = devlink_trap_policer_item_lookup(devlink, policer->id);
12324 	if (WARN_ON_ONCE(!policer_item))
12325 		return;
12326 
12327 	devlink_trap_policer_notify(devlink, policer_item,
12328 				    DEVLINK_CMD_TRAP_POLICER_DEL);
12329 	list_del(&policer_item->list);
12330 	if (devlink->ops->trap_policer_fini)
12331 		devlink->ops->trap_policer_fini(devlink, policer);
12332 	kfree(policer_item);
12333 }
12334 
12335 /**
12336  * devl_trap_policers_register - Register packet trap policers with devlink.
12337  * @devlink: devlink.
12338  * @policers: Packet trap policers.
12339  * @policers_count: Count of provided packet trap policers.
12340  *
12341  * Return: Non-zero value on failure.
12342  */
12343 int
devl_trap_policers_register(struct devlink * devlink,const struct devlink_trap_policer * policers,size_t policers_count)12344 devl_trap_policers_register(struct devlink *devlink,
12345 			    const struct devlink_trap_policer *policers,
12346 			    size_t policers_count)
12347 {
12348 	int i, err;
12349 
12350 	devl_assert_locked(devlink);
12351 	for (i = 0; i < policers_count; i++) {
12352 		const struct devlink_trap_policer *policer = &policers[i];
12353 
12354 		if (WARN_ON(policer->id == 0 ||
12355 			    policer->max_rate < policer->min_rate ||
12356 			    policer->max_burst < policer->min_burst)) {
12357 			err = -EINVAL;
12358 			goto err_trap_policer_verify;
12359 		}
12360 
12361 		err = devlink_trap_policer_register(devlink, policer);
12362 		if (err)
12363 			goto err_trap_policer_register;
12364 	}
12365 	return 0;
12366 
12367 err_trap_policer_register:
12368 err_trap_policer_verify:
12369 	for (i--; i >= 0; i--)
12370 		devlink_trap_policer_unregister(devlink, &policers[i]);
12371 	return err;
12372 }
12373 EXPORT_SYMBOL_GPL(devl_trap_policers_register);
12374 
12375 /**
12376  * devl_trap_policers_unregister - Unregister packet trap policers from devlink.
12377  * @devlink: devlink.
12378  * @policers: Packet trap policers.
12379  * @policers_count: Count of provided packet trap policers.
12380  */
12381 void
devl_trap_policers_unregister(struct devlink * devlink,const struct devlink_trap_policer * policers,size_t policers_count)12382 devl_trap_policers_unregister(struct devlink *devlink,
12383 			      const struct devlink_trap_policer *policers,
12384 			      size_t policers_count)
12385 {
12386 	int i;
12387 
12388 	devl_assert_locked(devlink);
12389 	for (i = policers_count - 1; i >= 0; i--)
12390 		devlink_trap_policer_unregister(devlink, &policers[i]);
12391 }
12392 EXPORT_SYMBOL_GPL(devl_trap_policers_unregister);
12393 
__devlink_compat_running_version(struct devlink * devlink,char * buf,size_t len)12394 static void __devlink_compat_running_version(struct devlink *devlink,
12395 					     char *buf, size_t len)
12396 {
12397 	struct devlink_info_req req = {};
12398 	const struct nlattr *nlattr;
12399 	struct sk_buff *msg;
12400 	int rem, err;
12401 
12402 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12403 	if (!msg)
12404 		return;
12405 
12406 	req.msg = msg;
12407 	err = devlink->ops->info_get(devlink, &req, NULL);
12408 	if (err)
12409 		goto free_msg;
12410 
12411 	nla_for_each_attr(nlattr, (void *)msg->data, msg->len, rem) {
12412 		const struct nlattr *kv;
12413 		int rem_kv;
12414 
12415 		if (nla_type(nlattr) != DEVLINK_ATTR_INFO_VERSION_RUNNING)
12416 			continue;
12417 
12418 		nla_for_each_nested(kv, nlattr, rem_kv) {
12419 			if (nla_type(kv) != DEVLINK_ATTR_INFO_VERSION_VALUE)
12420 				continue;
12421 
12422 			strlcat(buf, nla_data(kv), len);
12423 			strlcat(buf, " ", len);
12424 		}
12425 	}
12426 free_msg:
12427 	nlmsg_free(msg);
12428 }
12429 
netdev_to_devlink_port(struct net_device * dev)12430 static struct devlink_port *netdev_to_devlink_port(struct net_device *dev)
12431 {
12432 	if (!dev->netdev_ops->ndo_get_devlink_port)
12433 		return NULL;
12434 
12435 	return dev->netdev_ops->ndo_get_devlink_port(dev);
12436 }
12437 
devlink_compat_running_version(struct devlink * devlink,char * buf,size_t len)12438 void devlink_compat_running_version(struct devlink *devlink,
12439 				    char *buf, size_t len)
12440 {
12441 	if (!devlink->ops->info_get)
12442 		return;
12443 
12444 	devl_lock(devlink);
12445 	__devlink_compat_running_version(devlink, buf, len);
12446 	devl_unlock(devlink);
12447 }
12448 
devlink_compat_flash_update(struct devlink * devlink,const char * file_name)12449 int devlink_compat_flash_update(struct devlink *devlink, const char *file_name)
12450 {
12451 	struct devlink_flash_update_params params = {};
12452 	int ret;
12453 
12454 	if (!devlink->ops->flash_update)
12455 		return -EOPNOTSUPP;
12456 
12457 	ret = request_firmware(&params.fw, file_name, devlink->dev);
12458 	if (ret)
12459 		return ret;
12460 
12461 	devl_lock(devlink);
12462 	devlink_flash_update_begin_notify(devlink);
12463 	ret = devlink->ops->flash_update(devlink, &params, NULL);
12464 	devlink_flash_update_end_notify(devlink);
12465 	devl_unlock(devlink);
12466 
12467 	release_firmware(params.fw);
12468 
12469 	return ret;
12470 }
12471 
devlink_compat_phys_port_name_get(struct net_device * dev,char * name,size_t len)12472 int devlink_compat_phys_port_name_get(struct net_device *dev,
12473 				      char *name, size_t len)
12474 {
12475 	struct devlink_port *devlink_port;
12476 
12477 	/* RTNL mutex is held here which ensures that devlink_port
12478 	 * instance cannot disappear in the middle. No need to take
12479 	 * any devlink lock as only permanent values are accessed.
12480 	 */
12481 	ASSERT_RTNL();
12482 
12483 	devlink_port = netdev_to_devlink_port(dev);
12484 	if (!devlink_port)
12485 		return -EOPNOTSUPP;
12486 
12487 	return __devlink_port_phys_port_name_get(devlink_port, name, len);
12488 }
12489 
devlink_compat_switch_id_get(struct net_device * dev,struct netdev_phys_item_id * ppid)12490 int devlink_compat_switch_id_get(struct net_device *dev,
12491 				 struct netdev_phys_item_id *ppid)
12492 {
12493 	struct devlink_port *devlink_port;
12494 
12495 	/* Caller must hold RTNL mutex or reference to dev, which ensures that
12496 	 * devlink_port instance cannot disappear in the middle. No need to take
12497 	 * any devlink lock as only permanent values are accessed.
12498 	 */
12499 	devlink_port = netdev_to_devlink_port(dev);
12500 	if (!devlink_port || !devlink_port->switch_port)
12501 		return -EOPNOTSUPP;
12502 
12503 	memcpy(ppid, &devlink_port->attrs.switch_id, sizeof(*ppid));
12504 
12505 	return 0;
12506 }
12507 
devlink_pernet_pre_exit(struct net * net)12508 static void __net_exit devlink_pernet_pre_exit(struct net *net)
12509 {
12510 	struct devlink *devlink;
12511 	u32 actions_performed;
12512 	unsigned long index;
12513 	int err;
12514 
12515 	/* In case network namespace is getting destroyed, reload
12516 	 * all devlink instances from this namespace into init_net.
12517 	 */
12518 	devlinks_xa_for_each_registered_get(net, index, devlink) {
12519 		WARN_ON(!(devlink->features & DEVLINK_F_RELOAD));
12520 		mutex_lock(&devlink->lock);
12521 		err = devlink_reload(devlink, &init_net,
12522 				     DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
12523 				     DEVLINK_RELOAD_LIMIT_UNSPEC,
12524 				     &actions_performed, NULL);
12525 		mutex_unlock(&devlink->lock);
12526 		if (err && err != -EOPNOTSUPP)
12527 			pr_warn("Failed to reload devlink instance into init_net\n");
12528 		devlink_put(devlink);
12529 	}
12530 }
12531 
12532 static struct pernet_operations devlink_pernet_ops __net_initdata = {
12533 	.pre_exit = devlink_pernet_pre_exit,
12534 };
12535 
devlink_init(void)12536 static int __init devlink_init(void)
12537 {
12538 	int err;
12539 
12540 	err = genl_register_family(&devlink_nl_family);
12541 	if (err)
12542 		goto out;
12543 	err = register_pernet_subsys(&devlink_pernet_ops);
12544 
12545 out:
12546 	WARN_ON(err);
12547 	return err;
12548 }
12549 
12550 subsys_initcall(devlink_init);
12551