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