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