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