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