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