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