EDAC/igen6: ecclog_llist can be static
[sfrench/cifs-2.6.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                 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
4218                                 region->port->index))
4219                         goto nla_put_failure;
4220
4221         err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->ops->name);
4222         if (err)
4223                 goto nla_put_failure;
4224
4225         err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
4226                                 region->size,
4227                                 DEVLINK_ATTR_PAD);
4228         if (err)
4229                 goto nla_put_failure;
4230
4231         err = devlink_nl_region_snapshots_id_put(msg, devlink, region);
4232         if (err)
4233                 goto nla_put_failure;
4234
4235         genlmsg_end(msg, hdr);
4236         return 0;
4237
4238 nla_put_failure:
4239         genlmsg_cancel(msg, hdr);
4240         return err;
4241 }
4242
4243 static struct sk_buff *
4244 devlink_nl_region_notify_build(struct devlink_region *region,
4245                                struct devlink_snapshot *snapshot,
4246                                enum devlink_command cmd, u32 portid, u32 seq)
4247 {
4248         struct devlink *devlink = region->devlink;
4249         struct sk_buff *msg;
4250         void *hdr;
4251         int err;
4252
4253
4254         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4255         if (!msg)
4256                 return ERR_PTR(-ENOMEM);
4257
4258         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, 0, cmd);
4259         if (!hdr) {
4260                 err = -EMSGSIZE;
4261                 goto out_free_msg;
4262         }
4263
4264         err = devlink_nl_put_handle(msg, devlink);
4265         if (err)
4266                 goto out_cancel_msg;
4267
4268         if (region->port)
4269                 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
4270                                 region->port->index))
4271                         goto out_cancel_msg;
4272
4273         err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME,
4274                              region->ops->name);
4275         if (err)
4276                 goto out_cancel_msg;
4277
4278         if (snapshot) {
4279                 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID,
4280                                   snapshot->id);
4281                 if (err)
4282                         goto out_cancel_msg;
4283         } else {
4284                 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
4285                                         region->size, DEVLINK_ATTR_PAD);
4286                 if (err)
4287                         goto out_cancel_msg;
4288         }
4289         genlmsg_end(msg, hdr);
4290
4291         return msg;
4292
4293 out_cancel_msg:
4294         genlmsg_cancel(msg, hdr);
4295 out_free_msg:
4296         nlmsg_free(msg);
4297         return ERR_PTR(err);
4298 }
4299
4300 static void devlink_nl_region_notify(struct devlink_region *region,
4301                                      struct devlink_snapshot *snapshot,
4302                                      enum devlink_command cmd)
4303 {
4304         struct devlink *devlink = region->devlink;
4305         struct sk_buff *msg;
4306
4307         WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL);
4308
4309         msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0);
4310         if (IS_ERR(msg))
4311                 return;
4312
4313         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
4314                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
4315 }
4316
4317 /**
4318  * __devlink_snapshot_id_increment - Increment number of snapshots using an id
4319  *      @devlink: devlink instance
4320  *      @id: the snapshot id
4321  *
4322  *      Track when a new snapshot begins using an id. Load the count for the
4323  *      given id from the snapshot xarray, increment it, and store it back.
4324  *
4325  *      Called when a new snapshot is created with the given id.
4326  *
4327  *      The id *must* have been previously allocated by
4328  *      devlink_region_snapshot_id_get().
4329  *
4330  *      Returns 0 on success, or an error on failure.
4331  */
4332 static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id)
4333 {
4334         unsigned long count;
4335         void *p;
4336
4337         lockdep_assert_held(&devlink->lock);
4338
4339         p = xa_load(&devlink->snapshot_ids, id);
4340         if (WARN_ON(!p))
4341                 return -EINVAL;
4342
4343         if (WARN_ON(!xa_is_value(p)))
4344                 return -EINVAL;
4345
4346         count = xa_to_value(p);
4347         count++;
4348
4349         return xa_err(xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
4350                                GFP_KERNEL));
4351 }
4352
4353 /**
4354  * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id
4355  *      @devlink: devlink instance
4356  *      @id: the snapshot id
4357  *
4358  *      Track when a snapshot is deleted and stops using an id. Load the count
4359  *      for the given id from the snapshot xarray, decrement it, and store it
4360  *      back.
4361  *
4362  *      If the count reaches zero, erase this id from the xarray, freeing it
4363  *      up for future re-use by devlink_region_snapshot_id_get().
4364  *
4365  *      Called when a snapshot using the given id is deleted, and when the
4366  *      initial allocator of the id is finished using it.
4367  */
4368 static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id)
4369 {
4370         unsigned long count;
4371         void *p;
4372
4373         lockdep_assert_held(&devlink->lock);
4374
4375         p = xa_load(&devlink->snapshot_ids, id);
4376         if (WARN_ON(!p))
4377                 return;
4378
4379         if (WARN_ON(!xa_is_value(p)))
4380                 return;
4381
4382         count = xa_to_value(p);
4383
4384         if (count > 1) {
4385                 count--;
4386                 xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
4387                          GFP_KERNEL);
4388         } else {
4389                 /* If this was the last user, we can erase this id */
4390                 xa_erase(&devlink->snapshot_ids, id);
4391         }
4392 }
4393
4394 /**
4395  *      __devlink_snapshot_id_insert - Insert a specific snapshot ID
4396  *      @devlink: devlink instance
4397  *      @id: the snapshot id
4398  *
4399  *      Mark the given snapshot id as used by inserting a zero value into the
4400  *      snapshot xarray.
4401  *
4402  *      This must be called while holding the devlink instance lock. Unlike
4403  *      devlink_snapshot_id_get, the initial reference count is zero, not one.
4404  *      It is expected that the id will immediately be used before
4405  *      releasing the devlink instance lock.
4406  *
4407  *      Returns zero on success, or an error code if the snapshot id could not
4408  *      be inserted.
4409  */
4410 static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id)
4411 {
4412         lockdep_assert_held(&devlink->lock);
4413
4414         if (xa_load(&devlink->snapshot_ids, id))
4415                 return -EEXIST;
4416
4417         return xa_err(xa_store(&devlink->snapshot_ids, id, xa_mk_value(0),
4418                                GFP_KERNEL));
4419 }
4420
4421 /**
4422  *      __devlink_region_snapshot_id_get - get snapshot ID
4423  *      @devlink: devlink instance
4424  *      @id: storage to return snapshot id
4425  *
4426  *      Allocates a new snapshot id. Returns zero on success, or a negative
4427  *      error on failure. Must be called while holding the devlink instance
4428  *      lock.
4429  *
4430  *      Snapshot IDs are tracked using an xarray which stores the number of
4431  *      users of the snapshot id.
4432  *
4433  *      Note that the caller of this function counts as a 'user', in order to
4434  *      avoid race conditions. The caller must release its hold on the
4435  *      snapshot by using devlink_region_snapshot_id_put.
4436  */
4437 static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
4438 {
4439         lockdep_assert_held(&devlink->lock);
4440
4441         return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1),
4442                         xa_limit_32b, GFP_KERNEL);
4443 }
4444
4445 /**
4446  *      __devlink_region_snapshot_create - create a new snapshot
4447  *      This will add a new snapshot of a region. The snapshot
4448  *      will be stored on the region struct and can be accessed
4449  *      from devlink. This is useful for future analyses of snapshots.
4450  *      Multiple snapshots can be created on a region.
4451  *      The @snapshot_id should be obtained using the getter function.
4452  *
4453  *      Must be called only while holding the devlink instance lock.
4454  *
4455  *      @region: devlink region of the snapshot
4456  *      @data: snapshot data
4457  *      @snapshot_id: snapshot id to be created
4458  */
4459 static int
4460 __devlink_region_snapshot_create(struct devlink_region *region,
4461                                  u8 *data, u32 snapshot_id)
4462 {
4463         struct devlink *devlink = region->devlink;
4464         struct devlink_snapshot *snapshot;
4465         int err;
4466
4467         lockdep_assert_held(&devlink->lock);
4468
4469         /* check if region can hold one more snapshot */
4470         if (region->cur_snapshots == region->max_snapshots)
4471                 return -ENOSPC;
4472
4473         if (devlink_region_snapshot_get_by_id(region, snapshot_id))
4474                 return -EEXIST;
4475
4476         snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL);
4477         if (!snapshot)
4478                 return -ENOMEM;
4479
4480         err = __devlink_snapshot_id_increment(devlink, snapshot_id);
4481         if (err)
4482                 goto err_snapshot_id_increment;
4483
4484         snapshot->id = snapshot_id;
4485         snapshot->region = region;
4486         snapshot->data = data;
4487
4488         list_add_tail(&snapshot->list, &region->snapshot_list);
4489
4490         region->cur_snapshots++;
4491
4492         devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW);
4493         return 0;
4494
4495 err_snapshot_id_increment:
4496         kfree(snapshot);
4497         return err;
4498 }
4499
4500 static void devlink_region_snapshot_del(struct devlink_region *region,
4501                                         struct devlink_snapshot *snapshot)
4502 {
4503         struct devlink *devlink = region->devlink;
4504
4505         lockdep_assert_held(&devlink->lock);
4506
4507         devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL);
4508         region->cur_snapshots--;
4509         list_del(&snapshot->list);
4510         region->ops->destructor(snapshot->data);
4511         __devlink_snapshot_id_decrement(devlink, snapshot->id);
4512         kfree(snapshot);
4513 }
4514
4515 static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb,
4516                                           struct genl_info *info)
4517 {
4518         struct devlink *devlink = info->user_ptr[0];
4519         struct devlink_port *port = NULL;
4520         struct devlink_region *region;
4521         const char *region_name;
4522         struct sk_buff *msg;
4523         unsigned int index;
4524         int err;
4525
4526         if (!info->attrs[DEVLINK_ATTR_REGION_NAME])
4527                 return -EINVAL;
4528
4529         if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
4530                 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
4531
4532                 port = devlink_port_get_by_index(devlink, index);
4533                 if (!port)
4534                         return -ENODEV;
4535         }
4536
4537         region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
4538         if (port)
4539                 region = devlink_port_region_get_by_name(port, region_name);
4540         else
4541                 region = devlink_region_get_by_name(devlink, region_name);
4542
4543         if (!region)
4544                 return -EINVAL;
4545
4546         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4547         if (!msg)
4548                 return -ENOMEM;
4549
4550         err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET,
4551                                      info->snd_portid, info->snd_seq, 0,
4552                                      region);
4553         if (err) {
4554                 nlmsg_free(msg);
4555                 return err;
4556         }
4557
4558         return genlmsg_reply(msg, info);
4559 }
4560
4561 static int devlink_nl_cmd_region_get_port_dumpit(struct sk_buff *msg,
4562                                                  struct netlink_callback *cb,
4563                                                  struct devlink_port *port,
4564                                                  int *idx,
4565                                                  int start)
4566 {
4567         struct devlink_region *region;
4568         int err = 0;
4569
4570         list_for_each_entry(region, &port->region_list, list) {
4571                 if (*idx < start) {
4572                         (*idx)++;
4573                         continue;
4574                 }
4575                 err = devlink_nl_region_fill(msg, port->devlink,
4576                                              DEVLINK_CMD_REGION_GET,
4577                                              NETLINK_CB(cb->skb).portid,
4578                                              cb->nlh->nlmsg_seq,
4579                                              NLM_F_MULTI, region);
4580                 if (err)
4581                         goto out;
4582                 (*idx)++;
4583         }
4584
4585 out:
4586         return err;
4587 }
4588
4589 static int devlink_nl_cmd_region_get_devlink_dumpit(struct sk_buff *msg,
4590                                                     struct netlink_callback *cb,
4591                                                     struct devlink *devlink,
4592                                                     int *idx,
4593                                                     int start)
4594 {
4595         struct devlink_region *region;
4596         struct devlink_port *port;
4597         int err = 0;
4598
4599         mutex_lock(&devlink->lock);
4600         list_for_each_entry(region, &devlink->region_list, list) {
4601                 if (*idx < start) {
4602                         (*idx)++;
4603                         continue;
4604                 }
4605                 err = devlink_nl_region_fill(msg, devlink,
4606                                              DEVLINK_CMD_REGION_GET,
4607                                              NETLINK_CB(cb->skb).portid,
4608                                              cb->nlh->nlmsg_seq,
4609                                              NLM_F_MULTI, region);
4610                 if (err)
4611                         goto out;
4612                 (*idx)++;
4613         }
4614
4615         list_for_each_entry(port, &devlink->port_list, list) {
4616                 err = devlink_nl_cmd_region_get_port_dumpit(msg, cb, port, idx,
4617                                                             start);
4618                 if (err)
4619                         goto out;
4620         }
4621
4622 out:
4623         mutex_unlock(&devlink->lock);
4624         return err;
4625 }
4626
4627 static int devlink_nl_cmd_region_get_dumpit(struct sk_buff *msg,
4628                                             struct netlink_callback *cb)
4629 {
4630         struct devlink *devlink;
4631         int start = cb->args[0];
4632         int idx = 0;
4633         int err;
4634
4635         mutex_lock(&devlink_mutex);
4636         list_for_each_entry(devlink, &devlink_list, list) {
4637                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
4638                         continue;
4639                 err = devlink_nl_cmd_region_get_devlink_dumpit(msg, cb, devlink,
4640                                                                &idx, start);
4641                 if (err)
4642                         goto out;
4643         }
4644 out:
4645         mutex_unlock(&devlink_mutex);
4646         cb->args[0] = idx;
4647         return msg->len;
4648 }
4649
4650 static int devlink_nl_cmd_region_del(struct sk_buff *skb,
4651                                      struct genl_info *info)
4652 {
4653         struct devlink *devlink = info->user_ptr[0];
4654         struct devlink_snapshot *snapshot;
4655         struct devlink_port *port = NULL;
4656         struct devlink_region *region;
4657         const char *region_name;
4658         unsigned int index;
4659         u32 snapshot_id;
4660
4661         if (!info->attrs[DEVLINK_ATTR_REGION_NAME] ||
4662             !info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID])
4663                 return -EINVAL;
4664
4665         region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
4666         snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
4667
4668         if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
4669                 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
4670
4671                 port = devlink_port_get_by_index(devlink, index);
4672                 if (!port)
4673                         return -ENODEV;
4674         }
4675
4676         if (port)
4677                 region = devlink_port_region_get_by_name(port, region_name);
4678         else
4679                 region = devlink_region_get_by_name(devlink, region_name);
4680
4681         if (!region)
4682                 return -EINVAL;
4683
4684         snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
4685         if (!snapshot)
4686                 return -EINVAL;
4687
4688         devlink_region_snapshot_del(region, snapshot);
4689         return 0;
4690 }
4691
4692 static int
4693 devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
4694 {
4695         struct devlink *devlink = info->user_ptr[0];
4696         struct devlink_snapshot *snapshot;
4697         struct devlink_port *port = NULL;
4698         struct nlattr *snapshot_id_attr;
4699         struct devlink_region *region;
4700         const char *region_name;
4701         unsigned int index;
4702         u32 snapshot_id;
4703         u8 *data;
4704         int err;
4705
4706         if (!info->attrs[DEVLINK_ATTR_REGION_NAME]) {
4707                 NL_SET_ERR_MSG_MOD(info->extack, "No region name provided");
4708                 return -EINVAL;
4709         }
4710
4711         region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
4712
4713         if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
4714                 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
4715
4716                 port = devlink_port_get_by_index(devlink, index);
4717                 if (!port)
4718                         return -ENODEV;
4719         }
4720
4721         if (port)
4722                 region = devlink_port_region_get_by_name(port, region_name);
4723         else
4724                 region = devlink_region_get_by_name(devlink, region_name);
4725
4726         if (!region) {
4727                 NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not exist");
4728                 return -EINVAL;
4729         }
4730
4731         if (!region->ops->snapshot) {
4732                 NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not support taking an immediate snapshot");
4733                 return -EOPNOTSUPP;
4734         }
4735
4736         if (region->cur_snapshots == region->max_snapshots) {
4737                 NL_SET_ERR_MSG_MOD(info->extack, "The region has reached the maximum number of stored snapshots");
4738                 return -ENOSPC;
4739         }
4740
4741         snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID];
4742         if (snapshot_id_attr) {
4743                 snapshot_id = nla_get_u32(snapshot_id_attr);
4744
4745                 if (devlink_region_snapshot_get_by_id(region, snapshot_id)) {
4746                         NL_SET_ERR_MSG_MOD(info->extack, "The requested snapshot id is already in use");
4747                         return -EEXIST;
4748                 }
4749
4750                 err = __devlink_snapshot_id_insert(devlink, snapshot_id);
4751                 if (err)
4752                         return err;
4753         } else {
4754                 err = __devlink_region_snapshot_id_get(devlink, &snapshot_id);
4755                 if (err) {
4756                         NL_SET_ERR_MSG_MOD(info->extack, "Failed to allocate a new snapshot id");
4757                         return err;
4758                 }
4759         }
4760
4761         if (port)
4762                 err = region->port_ops->snapshot(port, region->port_ops,
4763                                                  info->extack, &data);
4764         else
4765                 err = region->ops->snapshot(devlink, region->ops,
4766                                             info->extack, &data);
4767         if (err)
4768                 goto err_snapshot_capture;
4769
4770         err = __devlink_region_snapshot_create(region, data, snapshot_id);
4771         if (err)
4772                 goto err_snapshot_create;
4773
4774         if (!snapshot_id_attr) {
4775                 struct sk_buff *msg;
4776
4777                 snapshot = devlink_region_snapshot_get_by_id(region,
4778                                                              snapshot_id);
4779                 if (WARN_ON(!snapshot))
4780                         return -EINVAL;
4781
4782                 msg = devlink_nl_region_notify_build(region, snapshot,
4783                                                      DEVLINK_CMD_REGION_NEW,
4784                                                      info->snd_portid,
4785                                                      info->snd_seq);
4786                 err = PTR_ERR_OR_ZERO(msg);
4787                 if (err)
4788                         goto err_notify;
4789
4790                 err = genlmsg_reply(msg, info);
4791                 if (err)
4792                         goto err_notify;
4793         }
4794
4795         return 0;
4796
4797 err_snapshot_create:
4798         region->ops->destructor(data);
4799 err_snapshot_capture:
4800         __devlink_snapshot_id_decrement(devlink, snapshot_id);
4801         return err;
4802
4803 err_notify:
4804         devlink_region_snapshot_del(region, snapshot);
4805         return err;
4806 }
4807
4808 static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg,
4809                                                  struct devlink *devlink,
4810                                                  u8 *chunk, u32 chunk_size,
4811                                                  u64 addr)
4812 {
4813         struct nlattr *chunk_attr;
4814         int err;
4815
4816         chunk_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_CHUNK);
4817         if (!chunk_attr)
4818                 return -EINVAL;
4819
4820         err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk);
4821         if (err)
4822                 goto nla_put_failure;
4823
4824         err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr,
4825                                 DEVLINK_ATTR_PAD);
4826         if (err)
4827                 goto nla_put_failure;
4828
4829         nla_nest_end(msg, chunk_attr);
4830         return 0;
4831
4832 nla_put_failure:
4833         nla_nest_cancel(msg, chunk_attr);
4834         return err;
4835 }
4836
4837 #define DEVLINK_REGION_READ_CHUNK_SIZE 256
4838
4839 static int devlink_nl_region_read_snapshot_fill(struct sk_buff *skb,
4840                                                 struct devlink *devlink,
4841                                                 struct devlink_region *region,
4842                                                 struct nlattr **attrs,
4843                                                 u64 start_offset,
4844                                                 u64 end_offset,
4845                                                 u64 *new_offset)
4846 {
4847         struct devlink_snapshot *snapshot;
4848         u64 curr_offset = start_offset;
4849         u32 snapshot_id;
4850         int err = 0;
4851
4852         *new_offset = start_offset;
4853
4854         snapshot_id = nla_get_u32(attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
4855         snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
4856         if (!snapshot)
4857                 return -EINVAL;
4858
4859         while (curr_offset < end_offset) {
4860                 u32 data_size;
4861                 u8 *data;
4862
4863                 if (end_offset - curr_offset < DEVLINK_REGION_READ_CHUNK_SIZE)
4864                         data_size = end_offset - curr_offset;
4865                 else
4866                         data_size = DEVLINK_REGION_READ_CHUNK_SIZE;
4867
4868                 data = &snapshot->data[curr_offset];
4869                 err = devlink_nl_cmd_region_read_chunk_fill(skb, devlink,
4870                                                             data, data_size,
4871                                                             curr_offset);
4872                 if (err)
4873                         break;
4874
4875                 curr_offset += data_size;
4876         }
4877         *new_offset = curr_offset;
4878
4879         return err;
4880 }
4881
4882 static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
4883                                              struct netlink_callback *cb)
4884 {
4885         const struct genl_dumpit_info *info = genl_dumpit_info(cb);
4886         u64 ret_offset, start_offset, end_offset = U64_MAX;
4887         struct nlattr **attrs = info->attrs;
4888         struct devlink_port *port = NULL;
4889         struct devlink_region *region;
4890         struct nlattr *chunks_attr;
4891         const char *region_name;
4892         struct devlink *devlink;
4893         unsigned int index;
4894         void *hdr;
4895         int err;
4896
4897         start_offset = *((u64 *)&cb->args[0]);
4898
4899         mutex_lock(&devlink_mutex);
4900         devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs);
4901         if (IS_ERR(devlink)) {
4902                 err = PTR_ERR(devlink);
4903                 goto out_dev;
4904         }
4905
4906         mutex_lock(&devlink->lock);
4907
4908         if (!attrs[DEVLINK_ATTR_REGION_NAME] ||
4909             !attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]) {
4910                 err = -EINVAL;
4911                 goto out_unlock;
4912         }
4913
4914         if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
4915                 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
4916
4917                 port = devlink_port_get_by_index(devlink, index);
4918                 if (!port)
4919                         return -ENODEV;
4920         }
4921
4922         region_name = nla_data(attrs[DEVLINK_ATTR_REGION_NAME]);
4923
4924         if (port)
4925                 region = devlink_port_region_get_by_name(port, region_name);
4926         else
4927                 region = devlink_region_get_by_name(devlink, region_name);
4928
4929         if (!region) {
4930                 err = -EINVAL;
4931                 goto out_unlock;
4932         }
4933
4934         if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] &&
4935             attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) {
4936                 if (!start_offset)
4937                         start_offset =
4938                                 nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
4939
4940                 end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
4941                 end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]);
4942         }
4943
4944         if (end_offset > region->size)
4945                 end_offset = region->size;
4946
4947         /* return 0 if there is no further data to read */
4948         if (start_offset == end_offset) {
4949                 err = 0;
4950                 goto out_unlock;
4951         }
4952
4953         hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
4954                           &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI,
4955                           DEVLINK_CMD_REGION_READ);
4956         if (!hdr) {
4957                 err = -EMSGSIZE;
4958                 goto out_unlock;
4959         }
4960
4961         err = devlink_nl_put_handle(skb, devlink);
4962         if (err)
4963                 goto nla_put_failure;
4964
4965         if (region->port)
4966                 if (nla_put_u32(skb, DEVLINK_ATTR_PORT_INDEX,
4967                                 region->port->index))
4968                         goto nla_put_failure;
4969
4970         err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name);
4971         if (err)
4972                 goto nla_put_failure;
4973
4974         chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS);
4975         if (!chunks_attr) {
4976                 err = -EMSGSIZE;
4977                 goto nla_put_failure;
4978         }
4979
4980         err = devlink_nl_region_read_snapshot_fill(skb, devlink,
4981                                                    region, attrs,
4982                                                    start_offset,
4983                                                    end_offset, &ret_offset);
4984
4985         if (err && err != -EMSGSIZE)
4986                 goto nla_put_failure;
4987
4988         /* Check if there was any progress done to prevent infinite loop */
4989         if (ret_offset == start_offset) {
4990                 err = -EINVAL;
4991                 goto nla_put_failure;
4992         }
4993
4994         *((u64 *)&cb->args[0]) = ret_offset;
4995
4996         nla_nest_end(skb, chunks_attr);
4997         genlmsg_end(skb, hdr);
4998         mutex_unlock(&devlink->lock);
4999         mutex_unlock(&devlink_mutex);
5000
5001         return skb->len;
5002
5003 nla_put_failure:
5004         genlmsg_cancel(skb, hdr);
5005 out_unlock:
5006         mutex_unlock(&devlink->lock);
5007 out_dev:
5008         mutex_unlock(&devlink_mutex);
5009         return err;
5010 }
5011
5012 struct devlink_info_req {
5013         struct sk_buff *msg;
5014 };
5015
5016 int devlink_info_driver_name_put(struct devlink_info_req *req, const char *name)
5017 {
5018         return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME, name);
5019 }
5020 EXPORT_SYMBOL_GPL(devlink_info_driver_name_put);
5021
5022 int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn)
5023 {
5024         return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn);
5025 }
5026 EXPORT_SYMBOL_GPL(devlink_info_serial_number_put);
5027
5028 int devlink_info_board_serial_number_put(struct devlink_info_req *req,
5029                                          const char *bsn)
5030 {
5031         return nla_put_string(req->msg, DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER,
5032                               bsn);
5033 }
5034 EXPORT_SYMBOL_GPL(devlink_info_board_serial_number_put);
5035
5036 static int devlink_info_version_put(struct devlink_info_req *req, int attr,
5037                                     const char *version_name,
5038                                     const char *version_value)
5039 {
5040         struct nlattr *nest;
5041         int err;
5042
5043         nest = nla_nest_start_noflag(req->msg, attr);
5044         if (!nest)
5045                 return -EMSGSIZE;
5046
5047         err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME,
5048                              version_name);
5049         if (err)
5050                 goto nla_put_failure;
5051
5052         err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE,
5053                              version_value);
5054         if (err)
5055                 goto nla_put_failure;
5056
5057         nla_nest_end(req->msg, nest);
5058
5059         return 0;
5060
5061 nla_put_failure:
5062         nla_nest_cancel(req->msg, nest);
5063         return err;
5064 }
5065
5066 int devlink_info_version_fixed_put(struct devlink_info_req *req,
5067                                    const char *version_name,
5068                                    const char *version_value)
5069 {
5070         return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED,
5071                                         version_name, version_value);
5072 }
5073 EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put);
5074
5075 int devlink_info_version_stored_put(struct devlink_info_req *req,
5076                                     const char *version_name,
5077                                     const char *version_value)
5078 {
5079         return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED,
5080                                         version_name, version_value);
5081 }
5082 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put);
5083
5084 int devlink_info_version_running_put(struct devlink_info_req *req,
5085                                      const char *version_name,
5086                                      const char *version_value)
5087 {
5088         return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING,
5089                                         version_name, version_value);
5090 }
5091 EXPORT_SYMBOL_GPL(devlink_info_version_running_put);
5092
5093 static int
5094 devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
5095                      enum devlink_command cmd, u32 portid,
5096                      u32 seq, int flags, struct netlink_ext_ack *extack)
5097 {
5098         struct devlink_info_req req;
5099         void *hdr;
5100         int err;
5101
5102         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
5103         if (!hdr)
5104                 return -EMSGSIZE;
5105
5106         err = -EMSGSIZE;
5107         if (devlink_nl_put_handle(msg, devlink))
5108                 goto err_cancel_msg;
5109
5110         req.msg = msg;
5111         err = devlink->ops->info_get(devlink, &req, extack);
5112         if (err)
5113                 goto err_cancel_msg;
5114
5115         genlmsg_end(msg, hdr);
5116         return 0;
5117
5118 err_cancel_msg:
5119         genlmsg_cancel(msg, hdr);
5120         return err;
5121 }
5122
5123 static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb,
5124                                         struct genl_info *info)
5125 {
5126         struct devlink *devlink = info->user_ptr[0];
5127         struct sk_buff *msg;
5128         int err;
5129
5130         if (!devlink->ops->info_get)
5131                 return -EOPNOTSUPP;
5132
5133         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5134         if (!msg)
5135                 return -ENOMEM;
5136
5137         err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
5138                                    info->snd_portid, info->snd_seq, 0,
5139                                    info->extack);
5140         if (err) {
5141                 nlmsg_free(msg);
5142                 return err;
5143         }
5144
5145         return genlmsg_reply(msg, info);
5146 }
5147
5148 static int devlink_nl_cmd_info_get_dumpit(struct sk_buff *msg,
5149                                           struct netlink_callback *cb)
5150 {
5151         struct devlink *devlink;
5152         int start = cb->args[0];
5153         int idx = 0;
5154         int err = 0;
5155
5156         mutex_lock(&devlink_mutex);
5157         list_for_each_entry(devlink, &devlink_list, list) {
5158                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
5159                         continue;
5160                 if (idx < start) {
5161                         idx++;
5162                         continue;
5163                 }
5164
5165                 if (!devlink->ops->info_get) {
5166                         idx++;
5167                         continue;
5168                 }
5169
5170                 mutex_lock(&devlink->lock);
5171                 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
5172                                            NETLINK_CB(cb->skb).portid,
5173                                            cb->nlh->nlmsg_seq, NLM_F_MULTI,
5174                                            cb->extack);
5175                 mutex_unlock(&devlink->lock);
5176                 if (err == -EOPNOTSUPP)
5177                         err = 0;
5178                 else if (err)
5179                         break;
5180                 idx++;
5181         }
5182         mutex_unlock(&devlink_mutex);
5183
5184         if (err != -EMSGSIZE)
5185                 return err;
5186
5187         cb->args[0] = idx;
5188         return msg->len;
5189 }
5190
5191 struct devlink_fmsg_item {
5192         struct list_head list;
5193         int attrtype;
5194         u8 nla_type;
5195         u16 len;
5196         int value[];
5197 };
5198
5199 struct devlink_fmsg {
5200         struct list_head item_list;
5201         bool putting_binary; /* This flag forces enclosing of binary data
5202                               * in an array brackets. It forces using
5203                               * of designated API:
5204                               * devlink_fmsg_binary_pair_nest_start()
5205                               * devlink_fmsg_binary_pair_nest_end()
5206                               */
5207 };
5208
5209 static struct devlink_fmsg *devlink_fmsg_alloc(void)
5210 {
5211         struct devlink_fmsg *fmsg;
5212
5213         fmsg = kzalloc(sizeof(*fmsg), GFP_KERNEL);
5214         if (!fmsg)
5215                 return NULL;
5216
5217         INIT_LIST_HEAD(&fmsg->item_list);
5218
5219         return fmsg;
5220 }
5221
5222 static void devlink_fmsg_free(struct devlink_fmsg *fmsg)
5223 {
5224         struct devlink_fmsg_item *item, *tmp;
5225
5226         list_for_each_entry_safe(item, tmp, &fmsg->item_list, list) {
5227                 list_del(&item->list);
5228                 kfree(item);
5229         }
5230         kfree(fmsg);
5231 }
5232
5233 static int devlink_fmsg_nest_common(struct devlink_fmsg *fmsg,
5234                                     int attrtype)
5235 {
5236         struct devlink_fmsg_item *item;
5237
5238         item = kzalloc(sizeof(*item), GFP_KERNEL);
5239         if (!item)
5240                 return -ENOMEM;
5241
5242         item->attrtype = attrtype;
5243         list_add_tail(&item->list, &fmsg->item_list);
5244
5245         return 0;
5246 }
5247
5248 int devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg)
5249 {
5250         if (fmsg->putting_binary)
5251                 return -EINVAL;
5252
5253         return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_OBJ_NEST_START);
5254 }
5255 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start);
5256
5257 static int devlink_fmsg_nest_end(struct devlink_fmsg *fmsg)
5258 {
5259         if (fmsg->putting_binary)
5260                 return -EINVAL;
5261
5262         return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_NEST_END);
5263 }
5264
5265 int devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg)
5266 {
5267         if (fmsg->putting_binary)
5268                 return -EINVAL;
5269
5270         return devlink_fmsg_nest_end(fmsg);
5271 }
5272 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end);
5273
5274 #define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN)
5275
5276 static int devlink_fmsg_put_name(struct devlink_fmsg *fmsg, const char *name)
5277 {
5278         struct devlink_fmsg_item *item;
5279
5280         if (fmsg->putting_binary)
5281                 return -EINVAL;
5282
5283         if (strlen(name) + 1 > DEVLINK_FMSG_MAX_SIZE)
5284                 return -EMSGSIZE;
5285
5286         item = kzalloc(sizeof(*item) + strlen(name) + 1, GFP_KERNEL);
5287         if (!item)
5288                 return -ENOMEM;
5289
5290         item->nla_type = NLA_NUL_STRING;
5291         item->len = strlen(name) + 1;
5292         item->attrtype = DEVLINK_ATTR_FMSG_OBJ_NAME;
5293         memcpy(&item->value, name, item->len);
5294         list_add_tail(&item->list, &fmsg->item_list);
5295
5296         return 0;
5297 }
5298
5299 int devlink_fmsg_pair_nest_start(struct devlink_fmsg *fmsg, const char *name)
5300 {
5301         int err;
5302
5303         if (fmsg->putting_binary)
5304                 return -EINVAL;
5305
5306         err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_PAIR_NEST_START);
5307         if (err)
5308                 return err;
5309
5310         err = devlink_fmsg_put_name(fmsg, name);
5311         if (err)
5312                 return err;
5313
5314         return 0;
5315 }
5316 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start);
5317
5318 int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg)
5319 {
5320         if (fmsg->putting_binary)
5321                 return -EINVAL;
5322
5323         return devlink_fmsg_nest_end(fmsg);
5324 }
5325 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end);
5326
5327 int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg,
5328                                      const char *name)
5329 {
5330         int err;
5331
5332         if (fmsg->putting_binary)
5333                 return -EINVAL;
5334
5335         err = devlink_fmsg_pair_nest_start(fmsg, name);
5336         if (err)
5337                 return err;
5338
5339         err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_ARR_NEST_START);
5340         if (err)
5341                 return err;
5342
5343         return 0;
5344 }
5345 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start);
5346
5347 int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg)
5348 {
5349         int err;
5350
5351         if (fmsg->putting_binary)
5352                 return -EINVAL;
5353
5354         err = devlink_fmsg_nest_end(fmsg);
5355         if (err)
5356                 return err;
5357
5358         err = devlink_fmsg_nest_end(fmsg);
5359         if (err)
5360                 return err;
5361
5362         return 0;
5363 }
5364 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end);
5365
5366 int devlink_fmsg_binary_pair_nest_start(struct devlink_fmsg *fmsg,
5367                                         const char *name)
5368 {
5369         int err;
5370
5371         err = devlink_fmsg_arr_pair_nest_start(fmsg, name);
5372         if (err)
5373                 return err;
5374
5375         fmsg->putting_binary = true;
5376         return err;
5377 }
5378 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_start);
5379
5380 int devlink_fmsg_binary_pair_nest_end(struct devlink_fmsg *fmsg)
5381 {
5382         if (!fmsg->putting_binary)
5383                 return -EINVAL;
5384
5385         fmsg->putting_binary = false;
5386         return devlink_fmsg_arr_pair_nest_end(fmsg);
5387 }
5388 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_end);
5389
5390 static int devlink_fmsg_put_value(struct devlink_fmsg *fmsg,
5391                                   const void *value, u16 value_len,
5392                                   u8 value_nla_type)
5393 {
5394         struct devlink_fmsg_item *item;
5395
5396         if (value_len > DEVLINK_FMSG_MAX_SIZE)
5397                 return -EMSGSIZE;
5398
5399         item = kzalloc(sizeof(*item) + value_len, GFP_KERNEL);
5400         if (!item)
5401                 return -ENOMEM;
5402
5403         item->nla_type = value_nla_type;
5404         item->len = value_len;
5405         item->attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
5406         memcpy(&item->value, value, item->len);
5407         list_add_tail(&item->list, &fmsg->item_list);
5408
5409         return 0;
5410 }
5411
5412 int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value)
5413 {
5414         if (fmsg->putting_binary)
5415                 return -EINVAL;
5416
5417         return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_FLAG);
5418 }
5419 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_put);
5420
5421 int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value)
5422 {
5423         if (fmsg->putting_binary)
5424                 return -EINVAL;
5425
5426         return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U8);
5427 }
5428 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_put);
5429
5430 int devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value)
5431 {
5432         if (fmsg->putting_binary)
5433                 return -EINVAL;
5434
5435         return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U32);
5436 }
5437 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put);
5438
5439 int devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value)
5440 {
5441         if (fmsg->putting_binary)
5442                 return -EINVAL;
5443
5444         return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U64);
5445 }
5446 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_put);
5447
5448 int devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value)
5449 {
5450         if (fmsg->putting_binary)
5451                 return -EINVAL;
5452
5453         return devlink_fmsg_put_value(fmsg, value, strlen(value) + 1,
5454                                       NLA_NUL_STRING);
5455 }
5456 EXPORT_SYMBOL_GPL(devlink_fmsg_string_put);
5457
5458 int devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value,
5459                             u16 value_len)
5460 {
5461         if (!fmsg->putting_binary)
5462                 return -EINVAL;
5463
5464         return devlink_fmsg_put_value(fmsg, value, value_len, NLA_BINARY);
5465 }
5466 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put);
5467
5468 int devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name,
5469                                bool value)
5470 {
5471         int err;
5472
5473         err = devlink_fmsg_pair_nest_start(fmsg, name);
5474         if (err)
5475                 return err;
5476
5477         err = devlink_fmsg_bool_put(fmsg, value);
5478         if (err)
5479                 return err;
5480
5481         err = devlink_fmsg_pair_nest_end(fmsg);
5482         if (err)
5483                 return err;
5484
5485         return 0;
5486 }
5487 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put);
5488
5489 int devlink_fmsg_u8_pair_put(struct devlink_fmsg *fmsg, const char *name,
5490                              u8 value)
5491 {
5492         int err;
5493
5494         err = devlink_fmsg_pair_nest_start(fmsg, name);
5495         if (err)
5496                 return err;
5497
5498         err = devlink_fmsg_u8_put(fmsg, value);
5499         if (err)
5500                 return err;
5501
5502         err = devlink_fmsg_pair_nest_end(fmsg);
5503         if (err)
5504                 return err;
5505
5506         return 0;
5507 }
5508 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put);
5509
5510 int devlink_fmsg_u32_pair_put(struct devlink_fmsg *fmsg, const char *name,
5511                               u32 value)
5512 {
5513         int err;
5514
5515         err = devlink_fmsg_pair_nest_start(fmsg, name);
5516         if (err)
5517                 return err;
5518
5519         err = devlink_fmsg_u32_put(fmsg, value);
5520         if (err)
5521                 return err;
5522
5523         err = devlink_fmsg_pair_nest_end(fmsg);
5524         if (err)
5525                 return err;
5526
5527         return 0;
5528 }
5529 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put);
5530
5531 int devlink_fmsg_u64_pair_put(struct devlink_fmsg *fmsg, const char *name,
5532                               u64 value)
5533 {
5534         int err;
5535
5536         err = devlink_fmsg_pair_nest_start(fmsg, name);
5537         if (err)
5538                 return err;
5539
5540         err = devlink_fmsg_u64_put(fmsg, value);
5541         if (err)
5542                 return err;
5543
5544         err = devlink_fmsg_pair_nest_end(fmsg);
5545         if (err)
5546                 return err;
5547
5548         return 0;
5549 }
5550 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put);
5551
5552 int devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name,
5553                                  const char *value)
5554 {
5555         int err;
5556
5557         err = devlink_fmsg_pair_nest_start(fmsg, name);
5558         if (err)
5559                 return err;
5560
5561         err = devlink_fmsg_string_put(fmsg, value);
5562         if (err)
5563                 return err;
5564
5565         err = devlink_fmsg_pair_nest_end(fmsg);
5566         if (err)
5567                 return err;
5568
5569         return 0;
5570 }
5571 EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put);
5572
5573 int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name,
5574                                  const void *value, u32 value_len)
5575 {
5576         u32 data_size;
5577         int end_err;
5578         u32 offset;
5579         int err;
5580
5581         err = devlink_fmsg_binary_pair_nest_start(fmsg, name);
5582         if (err)
5583                 return err;
5584
5585         for (offset = 0; offset < value_len; offset += data_size) {
5586                 data_size = value_len - offset;
5587                 if (data_size > DEVLINK_FMSG_MAX_SIZE)
5588                         data_size = DEVLINK_FMSG_MAX_SIZE;
5589                 err = devlink_fmsg_binary_put(fmsg, value + offset, data_size);
5590                 if (err)
5591                         break;
5592                 /* Exit from loop with a break (instead of
5593                  * return) to make sure putting_binary is turned off in
5594                  * devlink_fmsg_binary_pair_nest_end
5595                  */
5596         }
5597
5598         end_err = devlink_fmsg_binary_pair_nest_end(fmsg);
5599         if (end_err)
5600                 err = end_err;
5601
5602         return err;
5603 }
5604 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put);
5605
5606 static int
5607 devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb)
5608 {
5609         switch (msg->nla_type) {
5610         case NLA_FLAG:
5611         case NLA_U8:
5612         case NLA_U32:
5613         case NLA_U64:
5614         case NLA_NUL_STRING:
5615         case NLA_BINARY:
5616                 return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE,
5617                                   msg->nla_type);
5618         default:
5619                 return -EINVAL;
5620         }
5621 }
5622
5623 static int
5624 devlink_fmsg_item_fill_data(struct devlink_fmsg_item *msg, struct sk_buff *skb)
5625 {
5626         int attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
5627         u8 tmp;
5628
5629         switch (msg->nla_type) {
5630         case NLA_FLAG:
5631                 /* Always provide flag data, regardless of its value */
5632                 tmp = *(bool *) msg->value;
5633
5634                 return nla_put_u8(skb, attrtype, tmp);
5635         case NLA_U8:
5636                 return nla_put_u8(skb, attrtype, *(u8 *) msg->value);
5637         case NLA_U32:
5638                 return nla_put_u32(skb, attrtype, *(u32 *) msg->value);
5639         case NLA_U64:
5640                 return nla_put_u64_64bit(skb, attrtype, *(u64 *) msg->value,
5641                                          DEVLINK_ATTR_PAD);
5642         case NLA_NUL_STRING:
5643                 return nla_put_string(skb, attrtype, (char *) &msg->value);
5644         case NLA_BINARY:
5645                 return nla_put(skb, attrtype, msg->len, (void *) &msg->value);
5646         default:
5647                 return -EINVAL;
5648         }
5649 }
5650
5651 static int
5652 devlink_fmsg_prepare_skb(struct devlink_fmsg *fmsg, struct sk_buff *skb,
5653                          int *start)
5654 {
5655         struct devlink_fmsg_item *item;
5656         struct nlattr *fmsg_nlattr;
5657         int i = 0;
5658         int err;
5659
5660         fmsg_nlattr = nla_nest_start_noflag(skb, DEVLINK_ATTR_FMSG);
5661         if (!fmsg_nlattr)
5662                 return -EMSGSIZE;
5663
5664         list_for_each_entry(item, &fmsg->item_list, list) {
5665                 if (i < *start) {
5666                         i++;
5667                         continue;
5668                 }
5669
5670                 switch (item->attrtype) {
5671                 case DEVLINK_ATTR_FMSG_OBJ_NEST_START:
5672                 case DEVLINK_ATTR_FMSG_PAIR_NEST_START:
5673                 case DEVLINK_ATTR_FMSG_ARR_NEST_START:
5674                 case DEVLINK_ATTR_FMSG_NEST_END:
5675                         err = nla_put_flag(skb, item->attrtype);
5676                         break;
5677                 case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA:
5678                         err = devlink_fmsg_item_fill_type(item, skb);
5679                         if (err)
5680                                 break;
5681                         err = devlink_fmsg_item_fill_data(item, skb);
5682                         break;
5683                 case DEVLINK_ATTR_FMSG_OBJ_NAME:
5684                         err = nla_put_string(skb, item->attrtype,
5685                                              (char *) &item->value);
5686                         break;
5687                 default:
5688                         err = -EINVAL;
5689                         break;
5690                 }
5691                 if (!err)
5692                         *start = ++i;
5693                 else
5694                         break;
5695         }
5696
5697         nla_nest_end(skb, fmsg_nlattr);
5698         return err;
5699 }
5700
5701 static int devlink_fmsg_snd(struct devlink_fmsg *fmsg,
5702                             struct genl_info *info,
5703                             enum devlink_command cmd, int flags)
5704 {
5705         struct nlmsghdr *nlh;
5706         struct sk_buff *skb;
5707         bool last = false;
5708         int index = 0;
5709         void *hdr;
5710         int err;
5711
5712         while (!last) {
5713                 int tmp_index = index;
5714
5715                 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
5716                 if (!skb)
5717                         return -ENOMEM;
5718
5719                 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
5720                                   &devlink_nl_family, flags | NLM_F_MULTI, cmd);
5721                 if (!hdr) {
5722                         err = -EMSGSIZE;
5723                         goto nla_put_failure;
5724                 }
5725
5726                 err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
5727                 if (!err)
5728                         last = true;
5729                 else if (err != -EMSGSIZE || tmp_index == index)
5730                         goto nla_put_failure;
5731
5732                 genlmsg_end(skb, hdr);
5733                 err = genlmsg_reply(skb, info);
5734                 if (err)
5735                         return err;
5736         }
5737
5738         skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
5739         if (!skb)
5740                 return -ENOMEM;
5741         nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
5742                         NLMSG_DONE, 0, flags | NLM_F_MULTI);
5743         if (!nlh) {
5744                 err = -EMSGSIZE;
5745                 goto nla_put_failure;
5746         }
5747
5748         return genlmsg_reply(skb, info);
5749
5750 nla_put_failure:
5751         nlmsg_free(skb);
5752         return err;
5753 }
5754
5755 static int devlink_fmsg_dumpit(struct devlink_fmsg *fmsg, struct sk_buff *skb,
5756                                struct netlink_callback *cb,
5757                                enum devlink_command cmd)
5758 {
5759         int index = cb->args[0];
5760         int tmp_index = index;
5761         void *hdr;
5762         int err;
5763
5764         hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
5765                           &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, cmd);
5766         if (!hdr) {
5767                 err = -EMSGSIZE;
5768                 goto nla_put_failure;
5769         }
5770
5771         err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
5772         if ((err && err != -EMSGSIZE) || tmp_index == index)
5773                 goto nla_put_failure;
5774
5775         cb->args[0] = index;
5776         genlmsg_end(skb, hdr);
5777         return skb->len;
5778
5779 nla_put_failure:
5780         genlmsg_cancel(skb, hdr);
5781         return err;
5782 }
5783
5784 struct devlink_health_reporter {
5785         struct list_head list;
5786         void *priv;
5787         const struct devlink_health_reporter_ops *ops;
5788         struct devlink *devlink;
5789         struct devlink_port *devlink_port;
5790         struct devlink_fmsg *dump_fmsg;
5791         struct mutex dump_lock; /* lock parallel read/write from dump buffers */
5792         u64 graceful_period;
5793         bool auto_recover;
5794         bool auto_dump;
5795         u8 health_state;
5796         u64 dump_ts;
5797         u64 dump_real_ts;
5798         u64 error_count;
5799         u64 recovery_count;
5800         u64 last_recovery_ts;
5801         refcount_t refcount;
5802 };
5803
5804 void *
5805 devlink_health_reporter_priv(struct devlink_health_reporter *reporter)
5806 {
5807         return reporter->priv;
5808 }
5809 EXPORT_SYMBOL_GPL(devlink_health_reporter_priv);
5810
5811 static struct devlink_health_reporter *
5812 __devlink_health_reporter_find_by_name(struct list_head *reporter_list,
5813                                        struct mutex *list_lock,
5814                                        const char *reporter_name)
5815 {
5816         struct devlink_health_reporter *reporter;
5817
5818         lockdep_assert_held(list_lock);
5819         list_for_each_entry(reporter, reporter_list, list)
5820                 if (!strcmp(reporter->ops->name, reporter_name))
5821                         return reporter;
5822         return NULL;
5823 }
5824
5825 static struct devlink_health_reporter *
5826 devlink_health_reporter_find_by_name(struct devlink *devlink,
5827                                      const char *reporter_name)
5828 {
5829         return __devlink_health_reporter_find_by_name(&devlink->reporter_list,
5830                                                       &devlink->reporters_lock,
5831                                                       reporter_name);
5832 }
5833
5834 static struct devlink_health_reporter *
5835 devlink_port_health_reporter_find_by_name(struct devlink_port *devlink_port,
5836                                           const char *reporter_name)
5837 {
5838         return __devlink_health_reporter_find_by_name(&devlink_port->reporter_list,
5839                                                       &devlink_port->reporters_lock,
5840                                                       reporter_name);
5841 }
5842
5843 static struct devlink_health_reporter *
5844 __devlink_health_reporter_create(struct devlink *devlink,
5845                                  const struct devlink_health_reporter_ops *ops,
5846                                  u64 graceful_period, void *priv)
5847 {
5848         struct devlink_health_reporter *reporter;
5849
5850         if (WARN_ON(graceful_period && !ops->recover))
5851                 return ERR_PTR(-EINVAL);
5852
5853         reporter = kzalloc(sizeof(*reporter), GFP_KERNEL);
5854         if (!reporter)
5855                 return ERR_PTR(-ENOMEM);
5856
5857         reporter->priv = priv;
5858         reporter->ops = ops;
5859         reporter->devlink = devlink;
5860         reporter->graceful_period = graceful_period;
5861         reporter->auto_recover = !!ops->recover;
5862         reporter->auto_dump = !!ops->dump;
5863         mutex_init(&reporter->dump_lock);
5864         refcount_set(&reporter->refcount, 1);
5865         return reporter;
5866 }
5867
5868 /**
5869  *      devlink_port_health_reporter_create - create devlink health reporter for
5870  *                                            specified port instance
5871  *
5872  *      @port: devlink_port which should contain the new reporter
5873  *      @ops: ops
5874  *      @graceful_period: to avoid recovery loops, in msecs
5875  *      @priv: priv
5876  */
5877 struct devlink_health_reporter *
5878 devlink_port_health_reporter_create(struct devlink_port *port,
5879                                     const struct devlink_health_reporter_ops *ops,
5880                                     u64 graceful_period, void *priv)
5881 {
5882         struct devlink_health_reporter *reporter;
5883
5884         mutex_lock(&port->reporters_lock);
5885         if (__devlink_health_reporter_find_by_name(&port->reporter_list,
5886                                                    &port->reporters_lock, ops->name)) {
5887                 reporter = ERR_PTR(-EEXIST);
5888                 goto unlock;
5889         }
5890
5891         reporter = __devlink_health_reporter_create(port->devlink, ops,
5892                                                     graceful_period, priv);
5893         if (IS_ERR(reporter))
5894                 goto unlock;
5895
5896         reporter->devlink_port = port;
5897         list_add_tail(&reporter->list, &port->reporter_list);
5898 unlock:
5899         mutex_unlock(&port->reporters_lock);
5900         return reporter;
5901 }
5902 EXPORT_SYMBOL_GPL(devlink_port_health_reporter_create);
5903
5904 /**
5905  *      devlink_health_reporter_create - create devlink health reporter
5906  *
5907  *      @devlink: devlink
5908  *      @ops: ops
5909  *      @graceful_period: to avoid recovery loops, in msecs
5910  *      @priv: priv
5911  */
5912 struct devlink_health_reporter *
5913 devlink_health_reporter_create(struct devlink *devlink,
5914                                const struct devlink_health_reporter_ops *ops,
5915                                u64 graceful_period, void *priv)
5916 {
5917         struct devlink_health_reporter *reporter;
5918
5919         mutex_lock(&devlink->reporters_lock);
5920         if (devlink_health_reporter_find_by_name(devlink, ops->name)) {
5921                 reporter = ERR_PTR(-EEXIST);
5922                 goto unlock;
5923         }
5924
5925         reporter = __devlink_health_reporter_create(devlink, ops,
5926                                                     graceful_period, priv);
5927         if (IS_ERR(reporter))
5928                 goto unlock;
5929
5930         list_add_tail(&reporter->list, &devlink->reporter_list);
5931 unlock:
5932         mutex_unlock(&devlink->reporters_lock);
5933         return reporter;
5934 }
5935 EXPORT_SYMBOL_GPL(devlink_health_reporter_create);
5936
5937 static void
5938 devlink_health_reporter_free(struct devlink_health_reporter *reporter)
5939 {
5940         mutex_destroy(&reporter->dump_lock);
5941         if (reporter->dump_fmsg)
5942                 devlink_fmsg_free(reporter->dump_fmsg);
5943         kfree(reporter);
5944 }
5945
5946 static void
5947 devlink_health_reporter_put(struct devlink_health_reporter *reporter)
5948 {
5949         if (refcount_dec_and_test(&reporter->refcount))
5950                 devlink_health_reporter_free(reporter);
5951 }
5952
5953 static void
5954 __devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
5955 {
5956         list_del(&reporter->list);
5957         devlink_health_reporter_put(reporter);
5958 }
5959
5960 /**
5961  *      devlink_health_reporter_destroy - destroy devlink health reporter
5962  *
5963  *      @reporter: devlink health reporter to destroy
5964  */
5965 void
5966 devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
5967 {
5968         struct mutex *lock = &reporter->devlink->reporters_lock;
5969
5970         mutex_lock(lock);
5971         __devlink_health_reporter_destroy(reporter);
5972         mutex_unlock(lock);
5973 }
5974 EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy);
5975
5976 /**
5977  *      devlink_port_health_reporter_destroy - destroy devlink port health reporter
5978  *
5979  *      @reporter: devlink health reporter to destroy
5980  */
5981 void
5982 devlink_port_health_reporter_destroy(struct devlink_health_reporter *reporter)
5983 {
5984         struct mutex *lock = &reporter->devlink_port->reporters_lock;
5985
5986         mutex_lock(lock);
5987         __devlink_health_reporter_destroy(reporter);
5988         mutex_unlock(lock);
5989 }
5990 EXPORT_SYMBOL_GPL(devlink_port_health_reporter_destroy);
5991
5992 static int
5993 devlink_nl_health_reporter_fill(struct sk_buff *msg,
5994                                 struct devlink *devlink,
5995                                 struct devlink_health_reporter *reporter,
5996                                 enum devlink_command cmd, u32 portid,
5997                                 u32 seq, int flags)
5998 {
5999         struct nlattr *reporter_attr;
6000         void *hdr;
6001
6002         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
6003         if (!hdr)
6004                 return -EMSGSIZE;
6005
6006         if (devlink_nl_put_handle(msg, devlink))
6007                 goto genlmsg_cancel;
6008
6009         if (reporter->devlink_port) {
6010                 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, reporter->devlink_port->index))
6011                         goto genlmsg_cancel;
6012         }
6013         reporter_attr = nla_nest_start_noflag(msg,
6014                                               DEVLINK_ATTR_HEALTH_REPORTER);
6015         if (!reporter_attr)
6016                 goto genlmsg_cancel;
6017         if (nla_put_string(msg, DEVLINK_ATTR_HEALTH_REPORTER_NAME,
6018                            reporter->ops->name))
6019                 goto reporter_nest_cancel;
6020         if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_STATE,
6021                        reporter->health_state))
6022                 goto reporter_nest_cancel;
6023         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT,
6024                               reporter->error_count, DEVLINK_ATTR_PAD))
6025                 goto reporter_nest_cancel;
6026         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT,
6027                               reporter->recovery_count, DEVLINK_ATTR_PAD))
6028                 goto reporter_nest_cancel;
6029         if (reporter->ops->recover &&
6030             nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD,
6031                               reporter->graceful_period,
6032                               DEVLINK_ATTR_PAD))
6033                 goto reporter_nest_cancel;
6034         if (reporter->ops->recover &&
6035             nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER,
6036                        reporter->auto_recover))
6037                 goto reporter_nest_cancel;
6038         if (reporter->dump_fmsg &&
6039             nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS,
6040                               jiffies_to_msecs(reporter->dump_ts),
6041                               DEVLINK_ATTR_PAD))
6042                 goto reporter_nest_cancel;
6043         if (reporter->dump_fmsg &&
6044             nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS,
6045                               reporter->dump_real_ts, DEVLINK_ATTR_PAD))
6046                 goto reporter_nest_cancel;
6047         if (reporter->ops->dump &&
6048             nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP,
6049                        reporter->auto_dump))
6050                 goto reporter_nest_cancel;
6051
6052         nla_nest_end(msg, reporter_attr);
6053         genlmsg_end(msg, hdr);
6054         return 0;
6055
6056 reporter_nest_cancel:
6057         nla_nest_end(msg, reporter_attr);
6058 genlmsg_cancel:
6059         genlmsg_cancel(msg, hdr);
6060         return -EMSGSIZE;
6061 }
6062
6063 static void devlink_recover_notify(struct devlink_health_reporter *reporter,
6064                                    enum devlink_command cmd)
6065 {
6066         struct sk_buff *msg;
6067         int err;
6068
6069         WARN_ON(cmd != DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
6070
6071         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6072         if (!msg)
6073                 return;
6074
6075         err = devlink_nl_health_reporter_fill(msg, reporter->devlink,
6076                                               reporter, cmd, 0, 0, 0);
6077         if (err) {
6078                 nlmsg_free(msg);
6079                 return;
6080         }
6081
6082         genlmsg_multicast_netns(&devlink_nl_family,
6083                                 devlink_net(reporter->devlink),
6084                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
6085 }
6086
6087 void
6088 devlink_health_reporter_recovery_done(struct devlink_health_reporter *reporter)
6089 {
6090         reporter->recovery_count++;
6091         reporter->last_recovery_ts = jiffies;
6092 }
6093 EXPORT_SYMBOL_GPL(devlink_health_reporter_recovery_done);
6094
6095 static int
6096 devlink_health_reporter_recover(struct devlink_health_reporter *reporter,
6097                                 void *priv_ctx, struct netlink_ext_ack *extack)
6098 {
6099         int err;
6100
6101         if (reporter->health_state == DEVLINK_HEALTH_REPORTER_STATE_HEALTHY)
6102                 return 0;
6103
6104         if (!reporter->ops->recover)
6105                 return -EOPNOTSUPP;
6106
6107         err = reporter->ops->recover(reporter, priv_ctx, extack);
6108         if (err)
6109                 return err;
6110
6111         devlink_health_reporter_recovery_done(reporter);
6112         reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY;
6113         devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
6114
6115         return 0;
6116 }
6117
6118 static void
6119 devlink_health_dump_clear(struct devlink_health_reporter *reporter)
6120 {
6121         if (!reporter->dump_fmsg)
6122                 return;
6123         devlink_fmsg_free(reporter->dump_fmsg);
6124         reporter->dump_fmsg = NULL;
6125 }
6126
6127 static int devlink_health_do_dump(struct devlink_health_reporter *reporter,
6128                                   void *priv_ctx,
6129                                   struct netlink_ext_ack *extack)
6130 {
6131         int err;
6132
6133         if (!reporter->ops->dump)
6134                 return 0;
6135
6136         if (reporter->dump_fmsg)
6137                 return 0;
6138
6139         reporter->dump_fmsg = devlink_fmsg_alloc();
6140         if (!reporter->dump_fmsg) {
6141                 err = -ENOMEM;
6142                 return err;
6143         }
6144
6145         err = devlink_fmsg_obj_nest_start(reporter->dump_fmsg);
6146         if (err)
6147                 goto dump_err;
6148
6149         err = reporter->ops->dump(reporter, reporter->dump_fmsg,
6150                                   priv_ctx, extack);
6151         if (err)
6152                 goto dump_err;
6153
6154         err = devlink_fmsg_obj_nest_end(reporter->dump_fmsg);
6155         if (err)
6156                 goto dump_err;
6157
6158         reporter->dump_ts = jiffies;
6159         reporter->dump_real_ts = ktime_get_real_ns();
6160
6161         return 0;
6162
6163 dump_err:
6164         devlink_health_dump_clear(reporter);
6165         return err;
6166 }
6167
6168 int devlink_health_report(struct devlink_health_reporter *reporter,
6169                           const char *msg, void *priv_ctx)
6170 {
6171         enum devlink_health_reporter_state prev_health_state;
6172         struct devlink *devlink = reporter->devlink;
6173         unsigned long recover_ts_threshold;
6174
6175         /* write a log message of the current error */
6176         WARN_ON(!msg);
6177         trace_devlink_health_report(devlink, reporter->ops->name, msg);
6178         reporter->error_count++;
6179         prev_health_state = reporter->health_state;
6180         reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
6181         devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
6182
6183         /* abort if the previous error wasn't recovered */
6184         recover_ts_threshold = reporter->last_recovery_ts +
6185                                msecs_to_jiffies(reporter->graceful_period);
6186         if (reporter->auto_recover &&
6187             (prev_health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY ||
6188              (reporter->last_recovery_ts && reporter->recovery_count &&
6189               time_is_after_jiffies(recover_ts_threshold)))) {
6190                 trace_devlink_health_recover_aborted(devlink,
6191                                                      reporter->ops->name,
6192                                                      reporter->health_state,
6193                                                      jiffies -
6194                                                      reporter->last_recovery_ts);
6195                 return -ECANCELED;
6196         }
6197
6198         reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
6199
6200         if (reporter->auto_dump) {
6201                 mutex_lock(&reporter->dump_lock);
6202                 /* store current dump of current error, for later analysis */
6203                 devlink_health_do_dump(reporter, priv_ctx, NULL);
6204                 mutex_unlock(&reporter->dump_lock);
6205         }
6206
6207         if (reporter->auto_recover)
6208                 return devlink_health_reporter_recover(reporter,
6209                                                        priv_ctx, NULL);
6210
6211         return 0;
6212 }
6213 EXPORT_SYMBOL_GPL(devlink_health_report);
6214
6215 static struct devlink_health_reporter *
6216 devlink_health_reporter_get_from_attrs(struct devlink *devlink,
6217                                        struct nlattr **attrs)
6218 {
6219         struct devlink_health_reporter *reporter;
6220         struct devlink_port *devlink_port;
6221         char *reporter_name;
6222
6223         if (!attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME])
6224                 return NULL;
6225
6226         reporter_name = nla_data(attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]);
6227         devlink_port = devlink_port_get_from_attrs(devlink, attrs);
6228         if (IS_ERR(devlink_port)) {
6229                 mutex_lock(&devlink->reporters_lock);
6230                 reporter = devlink_health_reporter_find_by_name(devlink, reporter_name);
6231                 if (reporter)
6232                         refcount_inc(&reporter->refcount);
6233                 mutex_unlock(&devlink->reporters_lock);
6234         } else {
6235                 mutex_lock(&devlink_port->reporters_lock);
6236                 reporter = devlink_port_health_reporter_find_by_name(devlink_port, reporter_name);
6237                 if (reporter)
6238                         refcount_inc(&reporter->refcount);
6239                 mutex_unlock(&devlink_port->reporters_lock);
6240         }
6241
6242         return reporter;
6243 }
6244
6245 static struct devlink_health_reporter *
6246 devlink_health_reporter_get_from_info(struct devlink *devlink,
6247                                       struct genl_info *info)
6248 {
6249         return devlink_health_reporter_get_from_attrs(devlink, info->attrs);
6250 }
6251
6252 static struct devlink_health_reporter *
6253 devlink_health_reporter_get_from_cb(struct netlink_callback *cb)
6254 {
6255         const struct genl_dumpit_info *info = genl_dumpit_info(cb);
6256         struct devlink_health_reporter *reporter;
6257         struct nlattr **attrs = info->attrs;
6258         struct devlink *devlink;
6259
6260         mutex_lock(&devlink_mutex);
6261         devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs);
6262         if (IS_ERR(devlink))
6263                 goto unlock;
6264
6265         reporter = devlink_health_reporter_get_from_attrs(devlink, attrs);
6266         mutex_unlock(&devlink_mutex);
6267         return reporter;
6268 unlock:
6269         mutex_unlock(&devlink_mutex);
6270         return NULL;
6271 }
6272
6273 void
6274 devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
6275                                      enum devlink_health_reporter_state state)
6276 {
6277         if (WARN_ON(state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY &&
6278                     state != DEVLINK_HEALTH_REPORTER_STATE_ERROR))
6279                 return;
6280
6281         if (reporter->health_state == state)
6282                 return;
6283
6284         reporter->health_state = state;
6285         trace_devlink_health_reporter_state_update(reporter->devlink,
6286                                                    reporter->ops->name, state);
6287         devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
6288 }
6289 EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update);
6290
6291 static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb,
6292                                                    struct genl_info *info)
6293 {
6294         struct devlink *devlink = info->user_ptr[0];
6295         struct devlink_health_reporter *reporter;
6296         struct sk_buff *msg;
6297         int err;
6298
6299         reporter = devlink_health_reporter_get_from_info(devlink, info);
6300         if (!reporter)
6301                 return -EINVAL;
6302
6303         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6304         if (!msg) {
6305                 err = -ENOMEM;
6306                 goto out;
6307         }
6308
6309         err = devlink_nl_health_reporter_fill(msg, devlink, reporter,
6310                                               DEVLINK_CMD_HEALTH_REPORTER_GET,
6311                                               info->snd_portid, info->snd_seq,
6312                                               0);
6313         if (err) {
6314                 nlmsg_free(msg);
6315                 goto out;
6316         }
6317
6318         err = genlmsg_reply(msg, info);
6319 out:
6320         devlink_health_reporter_put(reporter);
6321         return err;
6322 }
6323
6324 static int
6325 devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff *msg,
6326                                           struct netlink_callback *cb)
6327 {
6328         struct devlink_health_reporter *reporter;
6329         struct devlink_port *port;
6330         struct devlink *devlink;
6331         int start = cb->args[0];
6332         int idx = 0;
6333         int err;
6334
6335         mutex_lock(&devlink_mutex);
6336         list_for_each_entry(devlink, &devlink_list, list) {
6337                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
6338                         continue;
6339                 mutex_lock(&devlink->reporters_lock);
6340                 list_for_each_entry(reporter, &devlink->reporter_list,
6341                                     list) {
6342                         if (idx < start) {
6343                                 idx++;
6344                                 continue;
6345                         }
6346                         err = devlink_nl_health_reporter_fill(msg, devlink,
6347                                                               reporter,
6348                                                               DEVLINK_CMD_HEALTH_REPORTER_GET,
6349                                                               NETLINK_CB(cb->skb).portid,
6350                                                               cb->nlh->nlmsg_seq,
6351                                                               NLM_F_MULTI);
6352                         if (err) {
6353                                 mutex_unlock(&devlink->reporters_lock);
6354                                 goto out;
6355                         }
6356                         idx++;
6357                 }
6358                 mutex_unlock(&devlink->reporters_lock);
6359         }
6360
6361         list_for_each_entry(devlink, &devlink_list, list) {
6362                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
6363                         continue;
6364                 mutex_lock(&devlink->lock);
6365                 list_for_each_entry(port, &devlink->port_list, list) {
6366                         mutex_lock(&port->reporters_lock);
6367                         list_for_each_entry(reporter, &port->reporter_list, list) {
6368                                 if (idx < start) {
6369                                         idx++;
6370                                         continue;
6371                                 }
6372                                 err = devlink_nl_health_reporter_fill(msg, devlink, reporter,
6373                                                                       DEVLINK_CMD_HEALTH_REPORTER_GET,
6374                                                                       NETLINK_CB(cb->skb).portid,
6375                                                                       cb->nlh->nlmsg_seq,
6376                                                                       NLM_F_MULTI);
6377                                 if (err) {
6378                                         mutex_unlock(&port->reporters_lock);
6379                                         mutex_unlock(&devlink->lock);
6380                                         goto out;
6381                                 }
6382                                 idx++;
6383                         }
6384                         mutex_unlock(&port->reporters_lock);
6385                 }
6386                 mutex_unlock(&devlink->lock);
6387         }
6388 out:
6389         mutex_unlock(&devlink_mutex);
6390
6391         cb->args[0] = idx;
6392         return msg->len;
6393 }
6394
6395 static int
6396 devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb,
6397                                         struct genl_info *info)
6398 {
6399         struct devlink *devlink = info->user_ptr[0];
6400         struct devlink_health_reporter *reporter;
6401         int err;
6402
6403         reporter = devlink_health_reporter_get_from_info(devlink, info);
6404         if (!reporter)
6405                 return -EINVAL;
6406
6407         if (!reporter->ops->recover &&
6408             (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] ||
6409              info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])) {
6410                 err = -EOPNOTSUPP;
6411                 goto out;
6412         }
6413         if (!reporter->ops->dump &&
6414             info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]) {
6415                 err = -EOPNOTSUPP;
6416                 goto out;
6417         }
6418
6419         if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD])
6420                 reporter->graceful_period =
6421                         nla_get_u64(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]);
6422
6423         if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])
6424                 reporter->auto_recover =
6425                         nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]);
6426
6427         if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP])
6428                 reporter->auto_dump =
6429                 nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]);
6430
6431         devlink_health_reporter_put(reporter);
6432         return 0;
6433 out:
6434         devlink_health_reporter_put(reporter);
6435         return err;
6436 }
6437
6438 static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb,
6439                                                        struct genl_info *info)
6440 {
6441         struct devlink *devlink = info->user_ptr[0];
6442         struct devlink_health_reporter *reporter;
6443         int err;
6444
6445         reporter = devlink_health_reporter_get_from_info(devlink, info);
6446         if (!reporter)
6447                 return -EINVAL;
6448
6449         err = devlink_health_reporter_recover(reporter, NULL, info->extack);
6450
6451         devlink_health_reporter_put(reporter);
6452         return err;
6453 }
6454
6455 static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb,
6456                                                         struct genl_info *info)
6457 {
6458         struct devlink *devlink = info->user_ptr[0];
6459         struct devlink_health_reporter *reporter;
6460         struct devlink_fmsg *fmsg;
6461         int err;
6462
6463         reporter = devlink_health_reporter_get_from_info(devlink, info);
6464         if (!reporter)
6465                 return -EINVAL;
6466
6467         if (!reporter->ops->diagnose) {
6468                 devlink_health_reporter_put(reporter);
6469                 return -EOPNOTSUPP;
6470         }
6471
6472         fmsg = devlink_fmsg_alloc();
6473         if (!fmsg) {
6474                 devlink_health_reporter_put(reporter);
6475                 return -ENOMEM;
6476         }
6477
6478         err = devlink_fmsg_obj_nest_start(fmsg);
6479         if (err)
6480                 goto out;
6481
6482         err = reporter->ops->diagnose(reporter, fmsg, info->extack);
6483         if (err)
6484                 goto out;
6485
6486         err = devlink_fmsg_obj_nest_end(fmsg);
6487         if (err)
6488                 goto out;
6489
6490         err = devlink_fmsg_snd(fmsg, info,
6491                                DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 0);
6492
6493 out:
6494         devlink_fmsg_free(fmsg);
6495         devlink_health_reporter_put(reporter);
6496         return err;
6497 }
6498
6499 static int
6500 devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff *skb,
6501                                                struct netlink_callback *cb)
6502 {
6503         struct devlink_health_reporter *reporter;
6504         u64 start = cb->args[0];
6505         int err;
6506
6507         reporter = devlink_health_reporter_get_from_cb(cb);
6508         if (!reporter)
6509                 return -EINVAL;
6510
6511         if (!reporter->ops->dump) {
6512                 err = -EOPNOTSUPP;
6513                 goto out;
6514         }
6515         mutex_lock(&reporter->dump_lock);
6516         if (!start) {
6517                 err = devlink_health_do_dump(reporter, NULL, cb->extack);
6518                 if (err)
6519                         goto unlock;
6520                 cb->args[1] = reporter->dump_ts;
6521         }
6522         if (!reporter->dump_fmsg || cb->args[1] != reporter->dump_ts) {
6523                 NL_SET_ERR_MSG_MOD(cb->extack, "Dump trampled, please retry");
6524                 err = -EAGAIN;
6525                 goto unlock;
6526         }
6527
6528         err = devlink_fmsg_dumpit(reporter->dump_fmsg, skb, cb,
6529                                   DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET);
6530 unlock:
6531         mutex_unlock(&reporter->dump_lock);
6532 out:
6533         devlink_health_reporter_put(reporter);
6534         return err;
6535 }
6536
6537 static int
6538 devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb,
6539                                                struct genl_info *info)
6540 {
6541         struct devlink *devlink = info->user_ptr[0];
6542         struct devlink_health_reporter *reporter;
6543
6544         reporter = devlink_health_reporter_get_from_info(devlink, info);
6545         if (!reporter)
6546                 return -EINVAL;
6547
6548         if (!reporter->ops->dump) {
6549                 devlink_health_reporter_put(reporter);
6550                 return -EOPNOTSUPP;
6551         }
6552
6553         mutex_lock(&reporter->dump_lock);
6554         devlink_health_dump_clear(reporter);
6555         mutex_unlock(&reporter->dump_lock);
6556         devlink_health_reporter_put(reporter);
6557         return 0;
6558 }
6559
6560 static int devlink_nl_cmd_health_reporter_test_doit(struct sk_buff *skb,
6561                                                     struct genl_info *info)
6562 {
6563         struct devlink *devlink = info->user_ptr[0];
6564         struct devlink_health_reporter *reporter;
6565         int err;
6566
6567         reporter = devlink_health_reporter_get_from_info(devlink, info);
6568         if (!reporter)
6569                 return -EINVAL;
6570
6571         if (!reporter->ops->test) {
6572                 devlink_health_reporter_put(reporter);
6573                 return -EOPNOTSUPP;
6574         }
6575
6576         err = reporter->ops->test(reporter, info->extack);
6577
6578         devlink_health_reporter_put(reporter);
6579         return err;
6580 }
6581
6582 struct devlink_stats {
6583         u64 rx_bytes;
6584         u64 rx_packets;
6585         struct u64_stats_sync syncp;
6586 };
6587
6588 /**
6589  * struct devlink_trap_policer_item - Packet trap policer attributes.
6590  * @policer: Immutable packet trap policer attributes.
6591  * @rate: Rate in packets / sec.
6592  * @burst: Burst size in packets.
6593  * @list: trap_policer_list member.
6594  *
6595  * Describes packet trap policer attributes. Created by devlink during trap
6596  * policer registration.
6597  */
6598 struct devlink_trap_policer_item {
6599         const struct devlink_trap_policer *policer;
6600         u64 rate;
6601         u64 burst;
6602         struct list_head list;
6603 };
6604
6605 /**
6606  * struct devlink_trap_group_item - Packet trap group attributes.
6607  * @group: Immutable packet trap group attributes.
6608  * @policer_item: Associated policer item. Can be NULL.
6609  * @list: trap_group_list member.
6610  * @stats: Trap group statistics.
6611  *
6612  * Describes packet trap group attributes. Created by devlink during trap
6613  * group registration.
6614  */
6615 struct devlink_trap_group_item {
6616         const struct devlink_trap_group *group;
6617         struct devlink_trap_policer_item *policer_item;
6618         struct list_head list;
6619         struct devlink_stats __percpu *stats;
6620 };
6621
6622 /**
6623  * struct devlink_trap_item - Packet trap attributes.
6624  * @trap: Immutable packet trap attributes.
6625  * @group_item: Associated group item.
6626  * @list: trap_list member.
6627  * @action: Trap action.
6628  * @stats: Trap statistics.
6629  * @priv: Driver private information.
6630  *
6631  * Describes both mutable and immutable packet trap attributes. Created by
6632  * devlink during trap registration and used for all trap related operations.
6633  */
6634 struct devlink_trap_item {
6635         const struct devlink_trap *trap;
6636         struct devlink_trap_group_item *group_item;
6637         struct list_head list;
6638         enum devlink_trap_action action;
6639         struct devlink_stats __percpu *stats;
6640         void *priv;
6641 };
6642
6643 static struct devlink_trap_policer_item *
6644 devlink_trap_policer_item_lookup(struct devlink *devlink, u32 id)
6645 {
6646         struct devlink_trap_policer_item *policer_item;
6647
6648         list_for_each_entry(policer_item, &devlink->trap_policer_list, list) {
6649                 if (policer_item->policer->id == id)
6650                         return policer_item;
6651         }
6652
6653         return NULL;
6654 }
6655
6656 static struct devlink_trap_item *
6657 devlink_trap_item_lookup(struct devlink *devlink, const char *name)
6658 {
6659         struct devlink_trap_item *trap_item;
6660
6661         list_for_each_entry(trap_item, &devlink->trap_list, list) {
6662                 if (!strcmp(trap_item->trap->name, name))
6663                         return trap_item;
6664         }
6665
6666         return NULL;
6667 }
6668
6669 static struct devlink_trap_item *
6670 devlink_trap_item_get_from_info(struct devlink *devlink,
6671                                 struct genl_info *info)
6672 {
6673         struct nlattr *attr;
6674
6675         if (!info->attrs[DEVLINK_ATTR_TRAP_NAME])
6676                 return NULL;
6677         attr = info->attrs[DEVLINK_ATTR_TRAP_NAME];
6678
6679         return devlink_trap_item_lookup(devlink, nla_data(attr));
6680 }
6681
6682 static int
6683 devlink_trap_action_get_from_info(struct genl_info *info,
6684                                   enum devlink_trap_action *p_trap_action)
6685 {
6686         u8 val;
6687
6688         val = nla_get_u8(info->attrs[DEVLINK_ATTR_TRAP_ACTION]);
6689         switch (val) {
6690         case DEVLINK_TRAP_ACTION_DROP:
6691         case DEVLINK_TRAP_ACTION_TRAP:
6692         case DEVLINK_TRAP_ACTION_MIRROR:
6693                 *p_trap_action = val;
6694                 break;
6695         default:
6696                 return -EINVAL;
6697         }
6698
6699         return 0;
6700 }
6701
6702 static int devlink_trap_metadata_put(struct sk_buff *msg,
6703                                      const struct devlink_trap *trap)
6704 {
6705         struct nlattr *attr;
6706
6707         attr = nla_nest_start(msg, DEVLINK_ATTR_TRAP_METADATA);
6708         if (!attr)
6709                 return -EMSGSIZE;
6710
6711         if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT) &&
6712             nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT))
6713                 goto nla_put_failure;
6714         if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE) &&
6715             nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE))
6716                 goto nla_put_failure;
6717
6718         nla_nest_end(msg, attr);
6719
6720         return 0;
6721
6722 nla_put_failure:
6723         nla_nest_cancel(msg, attr);
6724         return -EMSGSIZE;
6725 }
6726
6727 static void devlink_trap_stats_read(struct devlink_stats __percpu *trap_stats,
6728                                     struct devlink_stats *stats)
6729 {
6730         int i;
6731
6732         memset(stats, 0, sizeof(*stats));
6733         for_each_possible_cpu(i) {
6734                 struct devlink_stats *cpu_stats;
6735                 u64 rx_packets, rx_bytes;
6736                 unsigned int start;
6737
6738                 cpu_stats = per_cpu_ptr(trap_stats, i);
6739                 do {
6740                         start = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
6741                         rx_packets = cpu_stats->rx_packets;
6742                         rx_bytes = cpu_stats->rx_bytes;
6743                 } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start));
6744
6745                 stats->rx_packets += rx_packets;
6746                 stats->rx_bytes += rx_bytes;
6747         }
6748 }
6749
6750 static int devlink_trap_stats_put(struct sk_buff *msg,
6751                                   struct devlink_stats __percpu *trap_stats)
6752 {
6753         struct devlink_stats stats;
6754         struct nlattr *attr;
6755
6756         devlink_trap_stats_read(trap_stats, &stats);
6757
6758         attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
6759         if (!attr)
6760                 return -EMSGSIZE;
6761
6762         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS,
6763                               stats.rx_packets, DEVLINK_ATTR_PAD))
6764                 goto nla_put_failure;
6765
6766         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES,
6767                               stats.rx_bytes, DEVLINK_ATTR_PAD))
6768                 goto nla_put_failure;
6769
6770         nla_nest_end(msg, attr);
6771
6772         return 0;
6773
6774 nla_put_failure:
6775         nla_nest_cancel(msg, attr);
6776         return -EMSGSIZE;
6777 }
6778
6779 static int devlink_nl_trap_fill(struct sk_buff *msg, struct devlink *devlink,
6780                                 const struct devlink_trap_item *trap_item,
6781                                 enum devlink_command cmd, u32 portid, u32 seq,
6782                                 int flags)
6783 {
6784         struct devlink_trap_group_item *group_item = trap_item->group_item;
6785         void *hdr;
6786         int err;
6787
6788         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
6789         if (!hdr)
6790                 return -EMSGSIZE;
6791
6792         if (devlink_nl_put_handle(msg, devlink))
6793                 goto nla_put_failure;
6794
6795         if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
6796                            group_item->group->name))
6797                 goto nla_put_failure;
6798
6799         if (nla_put_string(msg, DEVLINK_ATTR_TRAP_NAME, trap_item->trap->name))
6800                 goto nla_put_failure;
6801
6802         if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_TYPE, trap_item->trap->type))
6803                 goto nla_put_failure;
6804
6805         if (trap_item->trap->generic &&
6806             nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
6807                 goto nla_put_failure;
6808
6809         if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_ACTION, trap_item->action))
6810                 goto nla_put_failure;
6811
6812         err = devlink_trap_metadata_put(msg, trap_item->trap);
6813         if (err)
6814                 goto nla_put_failure;
6815
6816         err = devlink_trap_stats_put(msg, trap_item->stats);
6817         if (err)
6818                 goto nla_put_failure;
6819
6820         genlmsg_end(msg, hdr);
6821
6822         return 0;
6823
6824 nla_put_failure:
6825         genlmsg_cancel(msg, hdr);
6826         return -EMSGSIZE;
6827 }
6828
6829 static int devlink_nl_cmd_trap_get_doit(struct sk_buff *skb,
6830                                         struct genl_info *info)
6831 {
6832         struct netlink_ext_ack *extack = info->extack;
6833         struct devlink *devlink = info->user_ptr[0];
6834         struct devlink_trap_item *trap_item;
6835         struct sk_buff *msg;
6836         int err;
6837
6838         if (list_empty(&devlink->trap_list))
6839                 return -EOPNOTSUPP;
6840
6841         trap_item = devlink_trap_item_get_from_info(devlink, info);
6842         if (!trap_item) {
6843                 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
6844                 return -ENOENT;
6845         }
6846
6847         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6848         if (!msg)
6849                 return -ENOMEM;
6850
6851         err = devlink_nl_trap_fill(msg, devlink, trap_item,
6852                                    DEVLINK_CMD_TRAP_NEW, info->snd_portid,
6853                                    info->snd_seq, 0);
6854         if (err)
6855                 goto err_trap_fill;
6856
6857         return genlmsg_reply(msg, info);
6858
6859 err_trap_fill:
6860         nlmsg_free(msg);
6861         return err;
6862 }
6863
6864 static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff *msg,
6865                                           struct netlink_callback *cb)
6866 {
6867         struct devlink_trap_item *trap_item;
6868         struct devlink *devlink;
6869         int start = cb->args[0];
6870         int idx = 0;
6871         int err;
6872
6873         mutex_lock(&devlink_mutex);
6874         list_for_each_entry(devlink, &devlink_list, list) {
6875                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
6876                         continue;
6877                 mutex_lock(&devlink->lock);
6878                 list_for_each_entry(trap_item, &devlink->trap_list, list) {
6879                         if (idx < start) {
6880                                 idx++;
6881                                 continue;
6882                         }
6883                         err = devlink_nl_trap_fill(msg, devlink, trap_item,
6884                                                    DEVLINK_CMD_TRAP_NEW,
6885                                                    NETLINK_CB(cb->skb).portid,
6886                                                    cb->nlh->nlmsg_seq,
6887                                                    NLM_F_MULTI);
6888                         if (err) {
6889                                 mutex_unlock(&devlink->lock);
6890                                 goto out;
6891                         }
6892                         idx++;
6893                 }
6894                 mutex_unlock(&devlink->lock);
6895         }
6896 out:
6897         mutex_unlock(&devlink_mutex);
6898
6899         cb->args[0] = idx;
6900         return msg->len;
6901 }
6902
6903 static int __devlink_trap_action_set(struct devlink *devlink,
6904                                      struct devlink_trap_item *trap_item,
6905                                      enum devlink_trap_action trap_action,
6906                                      struct netlink_ext_ack *extack)
6907 {
6908         int err;
6909
6910         if (trap_item->action != trap_action &&
6911             trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) {
6912                 NL_SET_ERR_MSG_MOD(extack, "Cannot change action of non-drop traps. Skipping");
6913                 return 0;
6914         }
6915
6916         err = devlink->ops->trap_action_set(devlink, trap_item->trap,
6917                                             trap_action, extack);
6918         if (err)
6919                 return err;
6920
6921         trap_item->action = trap_action;
6922
6923         return 0;
6924 }
6925
6926 static int devlink_trap_action_set(struct devlink *devlink,
6927                                    struct devlink_trap_item *trap_item,
6928                                    struct genl_info *info)
6929 {
6930         enum devlink_trap_action trap_action;
6931         int err;
6932
6933         if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
6934                 return 0;
6935
6936         err = devlink_trap_action_get_from_info(info, &trap_action);
6937         if (err) {
6938                 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
6939                 return -EINVAL;
6940         }
6941
6942         return __devlink_trap_action_set(devlink, trap_item, trap_action,
6943                                          info->extack);
6944 }
6945
6946 static int devlink_nl_cmd_trap_set_doit(struct sk_buff *skb,
6947                                         struct genl_info *info)
6948 {
6949         struct netlink_ext_ack *extack = info->extack;
6950         struct devlink *devlink = info->user_ptr[0];
6951         struct devlink_trap_item *trap_item;
6952         int err;
6953
6954         if (list_empty(&devlink->trap_list))
6955                 return -EOPNOTSUPP;
6956
6957         trap_item = devlink_trap_item_get_from_info(devlink, info);
6958         if (!trap_item) {
6959                 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
6960                 return -ENOENT;
6961         }
6962
6963         err = devlink_trap_action_set(devlink, trap_item, info);
6964         if (err)
6965                 return err;
6966
6967         return 0;
6968 }
6969
6970 static struct devlink_trap_group_item *
6971 devlink_trap_group_item_lookup(struct devlink *devlink, const char *name)
6972 {
6973         struct devlink_trap_group_item *group_item;
6974
6975         list_for_each_entry(group_item, &devlink->trap_group_list, list) {
6976                 if (!strcmp(group_item->group->name, name))
6977                         return group_item;
6978         }
6979
6980         return NULL;
6981 }
6982
6983 static struct devlink_trap_group_item *
6984 devlink_trap_group_item_lookup_by_id(struct devlink *devlink, u16 id)
6985 {
6986         struct devlink_trap_group_item *group_item;
6987
6988         list_for_each_entry(group_item, &devlink->trap_group_list, list) {
6989                 if (group_item->group->id == id)
6990                         return group_item;
6991         }
6992
6993         return NULL;
6994 }
6995
6996 static struct devlink_trap_group_item *
6997 devlink_trap_group_item_get_from_info(struct devlink *devlink,
6998                                       struct genl_info *info)
6999 {
7000         char *name;
7001
7002         if (!info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME])
7003                 return NULL;
7004         name = nla_data(info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]);
7005
7006         return devlink_trap_group_item_lookup(devlink, name);
7007 }
7008
7009 static int
7010 devlink_nl_trap_group_fill(struct sk_buff *msg, struct devlink *devlink,
7011                            const struct devlink_trap_group_item *group_item,
7012                            enum devlink_command cmd, u32 portid, u32 seq,
7013                            int flags)
7014 {
7015         void *hdr;
7016         int err;
7017
7018         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
7019         if (!hdr)
7020                 return -EMSGSIZE;
7021
7022         if (devlink_nl_put_handle(msg, devlink))
7023                 goto nla_put_failure;
7024
7025         if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
7026                            group_item->group->name))
7027                 goto nla_put_failure;
7028
7029         if (group_item->group->generic &&
7030             nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
7031                 goto nla_put_failure;
7032
7033         if (group_item->policer_item &&
7034             nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
7035                         group_item->policer_item->policer->id))
7036                 goto nla_put_failure;
7037
7038         err = devlink_trap_stats_put(msg, group_item->stats);
7039         if (err)
7040                 goto nla_put_failure;
7041
7042         genlmsg_end(msg, hdr);
7043
7044         return 0;
7045
7046 nla_put_failure:
7047         genlmsg_cancel(msg, hdr);
7048         return -EMSGSIZE;
7049 }
7050
7051 static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff *skb,
7052                                               struct genl_info *info)
7053 {
7054         struct netlink_ext_ack *extack = info->extack;
7055         struct devlink *devlink = info->user_ptr[0];
7056         struct devlink_trap_group_item *group_item;
7057         struct sk_buff *msg;
7058         int err;
7059
7060         if (list_empty(&devlink->trap_group_list))
7061                 return -EOPNOTSUPP;
7062
7063         group_item = devlink_trap_group_item_get_from_info(devlink, info);
7064         if (!group_item) {
7065                 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
7066                 return -ENOENT;
7067         }
7068
7069         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7070         if (!msg)
7071                 return -ENOMEM;
7072
7073         err = devlink_nl_trap_group_fill(msg, devlink, group_item,
7074                                          DEVLINK_CMD_TRAP_GROUP_NEW,
7075                                          info->snd_portid, info->snd_seq, 0);
7076         if (err)
7077                 goto err_trap_group_fill;
7078
7079         return genlmsg_reply(msg, info);
7080
7081 err_trap_group_fill:
7082         nlmsg_free(msg);
7083         return err;
7084 }
7085
7086 static int devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff *msg,
7087                                                 struct netlink_callback *cb)
7088 {
7089         enum devlink_command cmd = DEVLINK_CMD_TRAP_GROUP_NEW;
7090         struct devlink_trap_group_item *group_item;
7091         u32 portid = NETLINK_CB(cb->skb).portid;
7092         struct devlink *devlink;
7093         int start = cb->args[0];
7094         int idx = 0;
7095         int err;
7096
7097         mutex_lock(&devlink_mutex);
7098         list_for_each_entry(devlink, &devlink_list, list) {
7099                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
7100                         continue;
7101                 mutex_lock(&devlink->lock);
7102                 list_for_each_entry(group_item, &devlink->trap_group_list,
7103                                     list) {
7104                         if (idx < start) {
7105                                 idx++;
7106                                 continue;
7107                         }
7108                         err = devlink_nl_trap_group_fill(msg, devlink,
7109                                                          group_item, cmd,
7110                                                          portid,
7111                                                          cb->nlh->nlmsg_seq,
7112                                                          NLM_F_MULTI);
7113                         if (err) {
7114                                 mutex_unlock(&devlink->lock);
7115                                 goto out;
7116                         }
7117                         idx++;
7118                 }
7119                 mutex_unlock(&devlink->lock);
7120         }
7121 out:
7122         mutex_unlock(&devlink_mutex);
7123
7124         cb->args[0] = idx;
7125         return msg->len;
7126 }
7127
7128 static int
7129 __devlink_trap_group_action_set(struct devlink *devlink,
7130                                 struct devlink_trap_group_item *group_item,
7131                                 enum devlink_trap_action trap_action,
7132                                 struct netlink_ext_ack *extack)
7133 {
7134         const char *group_name = group_item->group->name;
7135         struct devlink_trap_item *trap_item;
7136         int err;
7137
7138         if (devlink->ops->trap_group_action_set) {
7139                 err = devlink->ops->trap_group_action_set(devlink, group_item->group,
7140                                                           trap_action, extack);
7141                 if (err)
7142                         return err;
7143
7144                 list_for_each_entry(trap_item, &devlink->trap_list, list) {
7145                         if (strcmp(trap_item->group_item->group->name, group_name))
7146                                 continue;
7147                         if (trap_item->action != trap_action &&
7148                             trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP)
7149                                 continue;
7150                         trap_item->action = trap_action;
7151                 }
7152
7153                 return 0;
7154         }
7155
7156         list_for_each_entry(trap_item, &devlink->trap_list, list) {
7157                 if (strcmp(trap_item->group_item->group->name, group_name))
7158                         continue;
7159                 err = __devlink_trap_action_set(devlink, trap_item,
7160                                                 trap_action, extack);
7161                 if (err)
7162                         return err;
7163         }
7164
7165         return 0;
7166 }
7167
7168 static int
7169 devlink_trap_group_action_set(struct devlink *devlink,
7170                               struct devlink_trap_group_item *group_item,
7171                               struct genl_info *info, bool *p_modified)
7172 {
7173         enum devlink_trap_action trap_action;
7174         int err;
7175
7176         if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
7177                 return 0;
7178
7179         err = devlink_trap_action_get_from_info(info, &trap_action);
7180         if (err) {
7181                 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
7182                 return -EINVAL;
7183         }
7184
7185         err = __devlink_trap_group_action_set(devlink, group_item, trap_action,
7186                                               info->extack);
7187         if (err)
7188                 return err;
7189
7190         *p_modified = true;
7191
7192         return 0;
7193 }
7194
7195 static int devlink_trap_group_set(struct devlink *devlink,
7196                                   struct devlink_trap_group_item *group_item,
7197                                   struct genl_info *info)
7198 {
7199         struct devlink_trap_policer_item *policer_item;
7200         struct netlink_ext_ack *extack = info->extack;
7201         const struct devlink_trap_policer *policer;
7202         struct nlattr **attrs = info->attrs;
7203         int err;
7204
7205         if (!attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
7206                 return 0;
7207
7208         if (!devlink->ops->trap_group_set)
7209                 return -EOPNOTSUPP;
7210
7211         policer_item = group_item->policer_item;
7212         if (attrs[DEVLINK_ATTR_TRAP_POLICER_ID]) {
7213                 u32 policer_id;
7214
7215                 policer_id = nla_get_u32(attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
7216                 policer_item = devlink_trap_policer_item_lookup(devlink,
7217                                                                 policer_id);
7218                 if (policer_id && !policer_item) {
7219                         NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
7220                         return -ENOENT;
7221                 }
7222         }
7223         policer = policer_item ? policer_item->policer : NULL;
7224
7225         err = devlink->ops->trap_group_set(devlink, group_item->group, policer,
7226                                            extack);
7227         if (err)
7228                 return err;
7229
7230         group_item->policer_item = policer_item;
7231
7232         return 0;
7233 }
7234
7235 static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff *skb,
7236                                               struct genl_info *info)
7237 {
7238         struct netlink_ext_ack *extack = info->extack;
7239         struct devlink *devlink = info->user_ptr[0];
7240         struct devlink_trap_group_item *group_item;
7241         bool modified = false;
7242         int err;
7243
7244         if (list_empty(&devlink->trap_group_list))
7245                 return -EOPNOTSUPP;
7246
7247         group_item = devlink_trap_group_item_get_from_info(devlink, info);
7248         if (!group_item) {
7249                 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
7250                 return -ENOENT;
7251         }
7252
7253         err = devlink_trap_group_action_set(devlink, group_item, info,
7254                                             &modified);
7255         if (err)
7256                 return err;
7257
7258         err = devlink_trap_group_set(devlink, group_item, info);
7259         if (err)
7260                 goto err_trap_group_set;
7261
7262         return 0;
7263
7264 err_trap_group_set:
7265         if (modified)
7266                 NL_SET_ERR_MSG_MOD(extack, "Trap group set failed, but some changes were committed already");
7267         return err;
7268 }
7269
7270 static struct devlink_trap_policer_item *
7271 devlink_trap_policer_item_get_from_info(struct devlink *devlink,
7272                                         struct genl_info *info)
7273 {
7274         u32 id;
7275
7276         if (!info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
7277                 return NULL;
7278         id = nla_get_u32(info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
7279
7280         return devlink_trap_policer_item_lookup(devlink, id);
7281 }
7282
7283 static int
7284 devlink_trap_policer_stats_put(struct sk_buff *msg, struct devlink *devlink,
7285                                const struct devlink_trap_policer *policer)
7286 {
7287         struct nlattr *attr;
7288         u64 drops;
7289         int err;
7290
7291         if (!devlink->ops->trap_policer_counter_get)
7292                 return 0;
7293
7294         err = devlink->ops->trap_policer_counter_get(devlink, policer, &drops);
7295         if (err)
7296                 return err;
7297
7298         attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
7299         if (!attr)
7300                 return -EMSGSIZE;
7301
7302         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops,
7303                               DEVLINK_ATTR_PAD))
7304                 goto nla_put_failure;
7305
7306         nla_nest_end(msg, attr);
7307
7308         return 0;
7309
7310 nla_put_failure:
7311         nla_nest_cancel(msg, attr);
7312         return -EMSGSIZE;
7313 }
7314
7315 static int
7316 devlink_nl_trap_policer_fill(struct sk_buff *msg, struct devlink *devlink,
7317                              const struct devlink_trap_policer_item *policer_item,
7318                              enum devlink_command cmd, u32 portid, u32 seq,
7319                              int flags)
7320 {
7321         void *hdr;
7322         int err;
7323
7324         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
7325         if (!hdr)
7326                 return -EMSGSIZE;
7327
7328         if (devlink_nl_put_handle(msg, devlink))
7329                 goto nla_put_failure;
7330
7331         if (nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
7332                         policer_item->policer->id))
7333                 goto nla_put_failure;
7334
7335         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_RATE,
7336                               policer_item->rate, DEVLINK_ATTR_PAD))
7337                 goto nla_put_failure;
7338
7339         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_BURST,
7340                               policer_item->burst, DEVLINK_ATTR_PAD))
7341                 goto nla_put_failure;
7342
7343         err = devlink_trap_policer_stats_put(msg, devlink,
7344                                              policer_item->policer);
7345         if (err)
7346                 goto nla_put_failure;
7347
7348         genlmsg_end(msg, hdr);
7349
7350         return 0;
7351
7352 nla_put_failure:
7353         genlmsg_cancel(msg, hdr);
7354         return -EMSGSIZE;
7355 }
7356
7357 static int devlink_nl_cmd_trap_policer_get_doit(struct sk_buff *skb,
7358                                                 struct genl_info *info)
7359 {
7360         struct devlink_trap_policer_item *policer_item;
7361         struct netlink_ext_ack *extack = info->extack;
7362         struct devlink *devlink = info->user_ptr[0];
7363         struct sk_buff *msg;
7364         int err;
7365
7366         if (list_empty(&devlink->trap_policer_list))
7367                 return -EOPNOTSUPP;
7368
7369         policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
7370         if (!policer_item) {
7371                 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
7372                 return -ENOENT;
7373         }
7374
7375         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7376         if (!msg)
7377                 return -ENOMEM;
7378
7379         err = devlink_nl_trap_policer_fill(msg, devlink, policer_item,
7380                                            DEVLINK_CMD_TRAP_POLICER_NEW,
7381                                            info->snd_portid, info->snd_seq, 0);
7382         if (err)
7383                 goto err_trap_policer_fill;
7384
7385         return genlmsg_reply(msg, info);
7386
7387 err_trap_policer_fill:
7388         nlmsg_free(msg);
7389         return err;
7390 }
7391
7392 static int devlink_nl_cmd_trap_policer_get_dumpit(struct sk_buff *msg,
7393                                                   struct netlink_callback *cb)
7394 {
7395         enum devlink_command cmd = DEVLINK_CMD_TRAP_POLICER_NEW;
7396         struct devlink_trap_policer_item *policer_item;
7397         u32 portid = NETLINK_CB(cb->skb).portid;
7398         struct devlink *devlink;
7399         int start = cb->args[0];
7400         int idx = 0;
7401         int err;
7402
7403         mutex_lock(&devlink_mutex);
7404         list_for_each_entry(devlink, &devlink_list, list) {
7405                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
7406                         continue;
7407                 mutex_lock(&devlink->lock);
7408                 list_for_each_entry(policer_item, &devlink->trap_policer_list,
7409                                     list) {
7410                         if (idx < start) {
7411                                 idx++;
7412                                 continue;
7413                         }
7414                         err = devlink_nl_trap_policer_fill(msg, devlink,
7415                                                            policer_item, cmd,
7416                                                            portid,
7417                                                            cb->nlh->nlmsg_seq,
7418                                                            NLM_F_MULTI);
7419                         if (err) {
7420                                 mutex_unlock(&devlink->lock);
7421                                 goto out;
7422                         }
7423                         idx++;
7424                 }
7425                 mutex_unlock(&devlink->lock);
7426         }
7427 out:
7428         mutex_unlock(&devlink_mutex);
7429
7430         cb->args[0] = idx;
7431         return msg->len;
7432 }
7433
7434 static int
7435 devlink_trap_policer_set(struct devlink *devlink,
7436                          struct devlink_trap_policer_item *policer_item,
7437                          struct genl_info *info)
7438 {
7439         struct netlink_ext_ack *extack = info->extack;
7440         struct nlattr **attrs = info->attrs;
7441         u64 rate, burst;
7442         int err;
7443
7444         rate = policer_item->rate;
7445         burst = policer_item->burst;
7446
7447         if (attrs[DEVLINK_ATTR_TRAP_POLICER_RATE])
7448                 rate = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_RATE]);
7449
7450         if (attrs[DEVLINK_ATTR_TRAP_POLICER_BURST])
7451                 burst = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_BURST]);
7452
7453         if (rate < policer_item->policer->min_rate) {
7454                 NL_SET_ERR_MSG_MOD(extack, "Policer rate lower than limit");
7455                 return -EINVAL;
7456         }
7457
7458         if (rate > policer_item->policer->max_rate) {
7459                 NL_SET_ERR_MSG_MOD(extack, "Policer rate higher than limit");
7460                 return -EINVAL;
7461         }
7462
7463         if (burst < policer_item->policer->min_burst) {
7464                 NL_SET_ERR_MSG_MOD(extack, "Policer burst size lower than limit");
7465                 return -EINVAL;
7466         }
7467
7468         if (burst > policer_item->policer->max_burst) {
7469                 NL_SET_ERR_MSG_MOD(extack, "Policer burst size higher than limit");
7470                 return -EINVAL;
7471         }
7472
7473         err = devlink->ops->trap_policer_set(devlink, policer_item->policer,
7474                                              rate, burst, info->extack);
7475         if (err)
7476                 return err;
7477
7478         policer_item->rate = rate;
7479         policer_item->burst = burst;
7480
7481         return 0;
7482 }
7483
7484 static int devlink_nl_cmd_trap_policer_set_doit(struct sk_buff *skb,
7485                                                 struct genl_info *info)
7486 {
7487         struct devlink_trap_policer_item *policer_item;
7488         struct netlink_ext_ack *extack = info->extack;
7489         struct devlink *devlink = info->user_ptr[0];
7490
7491         if (list_empty(&devlink->trap_policer_list))
7492                 return -EOPNOTSUPP;
7493
7494         if (!devlink->ops->trap_policer_set)
7495                 return -EOPNOTSUPP;
7496
7497         policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
7498         if (!policer_item) {
7499                 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
7500                 return -ENOENT;
7501         }
7502
7503         return devlink_trap_policer_set(devlink, policer_item, info);
7504 }
7505
7506 static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
7507         [DEVLINK_ATTR_UNSPEC] = { .strict_start_type =
7508                 DEVLINK_ATTR_TRAP_POLICER_ID },
7509         [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
7510         [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
7511         [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 },
7512         [DEVLINK_ATTR_PORT_TYPE] = NLA_POLICY_RANGE(NLA_U16, DEVLINK_PORT_TYPE_AUTO,
7513                                                     DEVLINK_PORT_TYPE_IB),
7514         [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 },
7515         [DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 },
7516         [DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 },
7517         [DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 },
7518         [DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 },
7519         [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 },
7520         [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
7521         [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
7522         [DEVLINK_ATTR_ESWITCH_MODE] = NLA_POLICY_RANGE(NLA_U16, DEVLINK_ESWITCH_MODE_LEGACY,
7523                                                        DEVLINK_ESWITCH_MODE_SWITCHDEV),
7524         [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 },
7525         [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 },
7526         [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING },
7527         [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 },
7528         [DEVLINK_ATTR_RESOURCE_ID] = { .type = NLA_U64},
7529         [DEVLINK_ATTR_RESOURCE_SIZE] = { .type = NLA_U64},
7530         [DEVLINK_ATTR_PARAM_NAME] = { .type = NLA_NUL_STRING },
7531         [DEVLINK_ATTR_PARAM_TYPE] = { .type = NLA_U8 },
7532         [DEVLINK_ATTR_PARAM_VALUE_CMODE] = { .type = NLA_U8 },
7533         [DEVLINK_ATTR_REGION_NAME] = { .type = NLA_NUL_STRING },
7534         [DEVLINK_ATTR_REGION_SNAPSHOT_ID] = { .type = NLA_U32 },
7535         [DEVLINK_ATTR_REGION_CHUNK_ADDR] = { .type = NLA_U64 },
7536         [DEVLINK_ATTR_REGION_CHUNK_LEN] = { .type = NLA_U64 },
7537         [DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING },
7538         [DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] = { .type = NLA_U64 },
7539         [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER] = { .type = NLA_U8 },
7540         [DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME] = { .type = NLA_NUL_STRING },
7541         [DEVLINK_ATTR_FLASH_UPDATE_COMPONENT] = { .type = NLA_NUL_STRING },
7542         [DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK] =
7543                 NLA_POLICY_BITFIELD32(DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS),
7544         [DEVLINK_ATTR_TRAP_NAME] = { .type = NLA_NUL_STRING },
7545         [DEVLINK_ATTR_TRAP_ACTION] = { .type = NLA_U8 },
7546         [DEVLINK_ATTR_TRAP_GROUP_NAME] = { .type = NLA_NUL_STRING },
7547         [DEVLINK_ATTR_NETNS_PID] = { .type = NLA_U32 },
7548         [DEVLINK_ATTR_NETNS_FD] = { .type = NLA_U32 },
7549         [DEVLINK_ATTR_NETNS_ID] = { .type = NLA_U32 },
7550         [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP] = { .type = NLA_U8 },
7551         [DEVLINK_ATTR_TRAP_POLICER_ID] = { .type = NLA_U32 },
7552         [DEVLINK_ATTR_TRAP_POLICER_RATE] = { .type = NLA_U64 },
7553         [DEVLINK_ATTR_TRAP_POLICER_BURST] = { .type = NLA_U64 },
7554         [DEVLINK_ATTR_PORT_FUNCTION] = { .type = NLA_NESTED },
7555         [DEVLINK_ATTR_RELOAD_ACTION] = NLA_POLICY_RANGE(NLA_U8, DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
7556                                                         DEVLINK_RELOAD_ACTION_MAX),
7557         [DEVLINK_ATTR_RELOAD_LIMITS] = NLA_POLICY_BITFIELD32(DEVLINK_RELOAD_LIMITS_VALID_MASK),
7558 };
7559
7560 static const struct genl_small_ops devlink_nl_ops[] = {
7561         {
7562                 .cmd = DEVLINK_CMD_GET,
7563                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7564                 .doit = devlink_nl_cmd_get_doit,
7565                 .dumpit = devlink_nl_cmd_get_dumpit,
7566                 /* can be retrieved by unprivileged users */
7567         },
7568         {
7569                 .cmd = DEVLINK_CMD_PORT_GET,
7570                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7571                 .doit = devlink_nl_cmd_port_get_doit,
7572                 .dumpit = devlink_nl_cmd_port_get_dumpit,
7573                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7574                 /* can be retrieved by unprivileged users */
7575         },
7576         {
7577                 .cmd = DEVLINK_CMD_PORT_SET,
7578                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7579                 .doit = devlink_nl_cmd_port_set_doit,
7580                 .flags = GENL_ADMIN_PERM,
7581                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7582         },
7583         {
7584                 .cmd = DEVLINK_CMD_PORT_SPLIT,
7585                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7586                 .doit = devlink_nl_cmd_port_split_doit,
7587                 .flags = GENL_ADMIN_PERM,
7588                 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK,
7589         },
7590         {
7591                 .cmd = DEVLINK_CMD_PORT_UNSPLIT,
7592                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7593                 .doit = devlink_nl_cmd_port_unsplit_doit,
7594                 .flags = GENL_ADMIN_PERM,
7595                 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK,
7596         },
7597         {
7598                 .cmd = DEVLINK_CMD_SB_GET,
7599                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7600                 .doit = devlink_nl_cmd_sb_get_doit,
7601                 .dumpit = devlink_nl_cmd_sb_get_dumpit,
7602                 /* can be retrieved by unprivileged users */
7603         },
7604         {
7605                 .cmd = DEVLINK_CMD_SB_POOL_GET,
7606                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7607                 .doit = devlink_nl_cmd_sb_pool_get_doit,
7608                 .dumpit = devlink_nl_cmd_sb_pool_get_dumpit,
7609                 /* can be retrieved by unprivileged users */
7610         },
7611         {
7612                 .cmd = DEVLINK_CMD_SB_POOL_SET,
7613                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7614                 .doit = devlink_nl_cmd_sb_pool_set_doit,
7615                 .flags = GENL_ADMIN_PERM,
7616         },
7617         {
7618                 .cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
7619                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7620                 .doit = devlink_nl_cmd_sb_port_pool_get_doit,
7621                 .dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit,
7622                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7623                 /* can be retrieved by unprivileged users */
7624         },
7625         {
7626                 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
7627                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7628                 .doit = devlink_nl_cmd_sb_port_pool_set_doit,
7629                 .flags = GENL_ADMIN_PERM,
7630                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7631         },
7632         {
7633                 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
7634                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7635                 .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
7636                 .dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit,
7637                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7638                 /* can be retrieved by unprivileged users */
7639         },
7640         {
7641                 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
7642                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7643                 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
7644                 .flags = GENL_ADMIN_PERM,
7645                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7646         },
7647         {
7648                 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
7649                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7650                 .doit = devlink_nl_cmd_sb_occ_snapshot_doit,
7651                 .flags = GENL_ADMIN_PERM,
7652         },
7653         {
7654                 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
7655                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7656                 .doit = devlink_nl_cmd_sb_occ_max_clear_doit,
7657                 .flags = GENL_ADMIN_PERM,
7658         },
7659         {
7660                 .cmd = DEVLINK_CMD_ESWITCH_GET,
7661                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7662                 .doit = devlink_nl_cmd_eswitch_get_doit,
7663                 .flags = GENL_ADMIN_PERM,
7664                 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK,
7665         },
7666         {
7667                 .cmd = DEVLINK_CMD_ESWITCH_SET,
7668                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7669                 .doit = devlink_nl_cmd_eswitch_set_doit,
7670                 .flags = GENL_ADMIN_PERM,
7671                 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK,
7672         },
7673         {
7674                 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET,
7675                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7676                 .doit = devlink_nl_cmd_dpipe_table_get,
7677                 /* can be retrieved by unprivileged users */
7678         },
7679         {
7680                 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET,
7681                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7682                 .doit = devlink_nl_cmd_dpipe_entries_get,
7683                 /* can be retrieved by unprivileged users */
7684         },
7685         {
7686                 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET,
7687                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7688                 .doit = devlink_nl_cmd_dpipe_headers_get,
7689                 /* can be retrieved by unprivileged users */
7690         },
7691         {
7692                 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
7693                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7694                 .doit = devlink_nl_cmd_dpipe_table_counters_set,
7695                 .flags = GENL_ADMIN_PERM,
7696         },
7697         {
7698                 .cmd = DEVLINK_CMD_RESOURCE_SET,
7699                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7700                 .doit = devlink_nl_cmd_resource_set,
7701                 .flags = GENL_ADMIN_PERM,
7702         },
7703         {
7704                 .cmd = DEVLINK_CMD_RESOURCE_DUMP,
7705                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7706                 .doit = devlink_nl_cmd_resource_dump,
7707                 /* can be retrieved by unprivileged users */
7708         },
7709         {
7710                 .cmd = DEVLINK_CMD_RELOAD,
7711                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7712                 .doit = devlink_nl_cmd_reload,
7713                 .flags = GENL_ADMIN_PERM,
7714                 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK,
7715         },
7716         {
7717                 .cmd = DEVLINK_CMD_PARAM_GET,
7718                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7719                 .doit = devlink_nl_cmd_param_get_doit,
7720                 .dumpit = devlink_nl_cmd_param_get_dumpit,
7721                 /* can be retrieved by unprivileged users */
7722         },
7723         {
7724                 .cmd = DEVLINK_CMD_PARAM_SET,
7725                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7726                 .doit = devlink_nl_cmd_param_set_doit,
7727                 .flags = GENL_ADMIN_PERM,
7728         },
7729         {
7730                 .cmd = DEVLINK_CMD_PORT_PARAM_GET,
7731                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7732                 .doit = devlink_nl_cmd_port_param_get_doit,
7733                 .dumpit = devlink_nl_cmd_port_param_get_dumpit,
7734                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7735                 /* can be retrieved by unprivileged users */
7736         },
7737         {
7738                 .cmd = DEVLINK_CMD_PORT_PARAM_SET,
7739                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7740                 .doit = devlink_nl_cmd_port_param_set_doit,
7741                 .flags = GENL_ADMIN_PERM,
7742                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7743         },
7744         {
7745                 .cmd = DEVLINK_CMD_REGION_GET,
7746                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7747                 .doit = devlink_nl_cmd_region_get_doit,
7748                 .dumpit = devlink_nl_cmd_region_get_dumpit,
7749                 .flags = GENL_ADMIN_PERM,
7750         },
7751         {
7752                 .cmd = DEVLINK_CMD_REGION_NEW,
7753                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7754                 .doit = devlink_nl_cmd_region_new,
7755                 .flags = GENL_ADMIN_PERM,
7756         },
7757         {
7758                 .cmd = DEVLINK_CMD_REGION_DEL,
7759                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7760                 .doit = devlink_nl_cmd_region_del,
7761                 .flags = GENL_ADMIN_PERM,
7762         },
7763         {
7764                 .cmd = DEVLINK_CMD_REGION_READ,
7765                 .validate = GENL_DONT_VALIDATE_STRICT |
7766                             GENL_DONT_VALIDATE_DUMP_STRICT,
7767                 .dumpit = devlink_nl_cmd_region_read_dumpit,
7768                 .flags = GENL_ADMIN_PERM,
7769         },
7770         {
7771                 .cmd = DEVLINK_CMD_INFO_GET,
7772                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7773                 .doit = devlink_nl_cmd_info_get_doit,
7774                 .dumpit = devlink_nl_cmd_info_get_dumpit,
7775                 /* can be retrieved by unprivileged users */
7776         },
7777         {
7778                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_GET,
7779                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7780                 .doit = devlink_nl_cmd_health_reporter_get_doit,
7781                 .dumpit = devlink_nl_cmd_health_reporter_get_dumpit,
7782                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT |
7783                                   DEVLINK_NL_FLAG_NO_LOCK,
7784                 /* can be retrieved by unprivileged users */
7785         },
7786         {
7787                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_SET,
7788                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7789                 .doit = devlink_nl_cmd_health_reporter_set_doit,
7790                 .flags = GENL_ADMIN_PERM,
7791                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT |
7792                                   DEVLINK_NL_FLAG_NO_LOCK,
7793         },
7794         {
7795                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER,
7796                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7797                 .doit = devlink_nl_cmd_health_reporter_recover_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_DIAGNOSE,
7804                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7805                 .doit = devlink_nl_cmd_health_reporter_diagnose_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_DUMP_GET,
7812                 .validate = GENL_DONT_VALIDATE_STRICT |
7813                             GENL_DONT_VALIDATE_DUMP_STRICT,
7814                 .dumpit = devlink_nl_cmd_health_reporter_dump_get_dumpit,
7815                 .flags = GENL_ADMIN_PERM,
7816                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT |
7817                                   DEVLINK_NL_FLAG_NO_LOCK,
7818         },
7819         {
7820                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR,
7821                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7822                 .doit = devlink_nl_cmd_health_reporter_dump_clear_doit,
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_TEST,
7829                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7830                 .doit = devlink_nl_cmd_health_reporter_test_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_FLASH_UPDATE,
7837                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7838                 .doit = devlink_nl_cmd_flash_update,
7839                 .flags = GENL_ADMIN_PERM,
7840         },
7841         {
7842                 .cmd = DEVLINK_CMD_TRAP_GET,
7843                 .doit = devlink_nl_cmd_trap_get_doit,
7844                 .dumpit = devlink_nl_cmd_trap_get_dumpit,
7845                 /* can be retrieved by unprivileged users */
7846         },
7847         {
7848                 .cmd = DEVLINK_CMD_TRAP_SET,
7849                 .doit = devlink_nl_cmd_trap_set_doit,
7850                 .flags = GENL_ADMIN_PERM,
7851         },
7852         {
7853                 .cmd = DEVLINK_CMD_TRAP_GROUP_GET,
7854                 .doit = devlink_nl_cmd_trap_group_get_doit,
7855                 .dumpit = devlink_nl_cmd_trap_group_get_dumpit,
7856                 /* can be retrieved by unprivileged users */
7857         },
7858         {
7859                 .cmd = DEVLINK_CMD_TRAP_GROUP_SET,
7860                 .doit = devlink_nl_cmd_trap_group_set_doit,
7861                 .flags = GENL_ADMIN_PERM,
7862         },
7863         {
7864                 .cmd = DEVLINK_CMD_TRAP_POLICER_GET,
7865                 .doit = devlink_nl_cmd_trap_policer_get_doit,
7866                 .dumpit = devlink_nl_cmd_trap_policer_get_dumpit,
7867                 /* can be retrieved by unprivileged users */
7868         },
7869         {
7870                 .cmd = DEVLINK_CMD_TRAP_POLICER_SET,
7871                 .doit = devlink_nl_cmd_trap_policer_set_doit,
7872                 .flags = GENL_ADMIN_PERM,
7873         },
7874 };
7875
7876 static struct genl_family devlink_nl_family __ro_after_init = {
7877         .name           = DEVLINK_GENL_NAME,
7878         .version        = DEVLINK_GENL_VERSION,
7879         .maxattr        = DEVLINK_ATTR_MAX,
7880         .policy = devlink_nl_policy,
7881         .netnsok        = true,
7882         .pre_doit       = devlink_nl_pre_doit,
7883         .post_doit      = devlink_nl_post_doit,
7884         .module         = THIS_MODULE,
7885         .small_ops      = devlink_nl_ops,
7886         .n_small_ops    = ARRAY_SIZE(devlink_nl_ops),
7887         .mcgrps         = devlink_nl_mcgrps,
7888         .n_mcgrps       = ARRAY_SIZE(devlink_nl_mcgrps),
7889 };
7890
7891 static bool devlink_reload_actions_valid(const struct devlink_ops *ops)
7892 {
7893         const struct devlink_reload_combination *comb;
7894         int i;
7895
7896         if (!devlink_reload_supported(ops)) {
7897                 if (WARN_ON(ops->reload_actions))
7898                         return false;
7899                 return true;
7900         }
7901
7902         if (WARN_ON(!ops->reload_actions ||
7903                     ops->reload_actions & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) ||
7904                     ops->reload_actions >= BIT(__DEVLINK_RELOAD_ACTION_MAX)))
7905                 return false;
7906
7907         if (WARN_ON(ops->reload_limits & BIT(DEVLINK_RELOAD_LIMIT_UNSPEC) ||
7908                     ops->reload_limits >= BIT(__DEVLINK_RELOAD_LIMIT_MAX)))
7909                 return false;
7910
7911         for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++)  {
7912                 comb = &devlink_reload_invalid_combinations[i];
7913                 if (ops->reload_actions == BIT(comb->action) &&
7914                     ops->reload_limits == BIT(comb->limit))
7915                         return false;
7916         }
7917         return true;
7918 }
7919
7920 /**
7921  *      devlink_alloc - Allocate new devlink instance resources
7922  *
7923  *      @ops: ops
7924  *      @priv_size: size of user private data
7925  *
7926  *      Allocate new devlink instance resources, including devlink index
7927  *      and name.
7928  */
7929 struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
7930 {
7931         struct devlink *devlink;
7932
7933         if (WARN_ON(!ops))
7934                 return NULL;
7935
7936         if (!devlink_reload_actions_valid(ops))
7937                 return NULL;
7938
7939         devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
7940         if (!devlink)
7941                 return NULL;
7942         devlink->ops = ops;
7943         xa_init_flags(&devlink->snapshot_ids, XA_FLAGS_ALLOC);
7944         __devlink_net_set(devlink, &init_net);
7945         INIT_LIST_HEAD(&devlink->port_list);
7946         INIT_LIST_HEAD(&devlink->sb_list);
7947         INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list);
7948         INIT_LIST_HEAD(&devlink->resource_list);
7949         INIT_LIST_HEAD(&devlink->param_list);
7950         INIT_LIST_HEAD(&devlink->region_list);
7951         INIT_LIST_HEAD(&devlink->reporter_list);
7952         INIT_LIST_HEAD(&devlink->trap_list);
7953         INIT_LIST_HEAD(&devlink->trap_group_list);
7954         INIT_LIST_HEAD(&devlink->trap_policer_list);
7955         mutex_init(&devlink->lock);
7956         mutex_init(&devlink->reporters_lock);
7957         return devlink;
7958 }
7959 EXPORT_SYMBOL_GPL(devlink_alloc);
7960
7961 /**
7962  *      devlink_register - Register devlink instance
7963  *
7964  *      @devlink: devlink
7965  *      @dev: parent device
7966  */
7967 int devlink_register(struct devlink *devlink, struct device *dev)
7968 {
7969         devlink->dev = dev;
7970         devlink->registered = true;
7971         mutex_lock(&devlink_mutex);
7972         list_add_tail(&devlink->list, &devlink_list);
7973         devlink_notify(devlink, DEVLINK_CMD_NEW);
7974         mutex_unlock(&devlink_mutex);
7975         return 0;
7976 }
7977 EXPORT_SYMBOL_GPL(devlink_register);
7978
7979 /**
7980  *      devlink_unregister - Unregister devlink instance
7981  *
7982  *      @devlink: devlink
7983  */
7984 void devlink_unregister(struct devlink *devlink)
7985 {
7986         mutex_lock(&devlink_mutex);
7987         WARN_ON(devlink_reload_supported(devlink->ops) &&
7988                 devlink->reload_enabled);
7989         devlink_notify(devlink, DEVLINK_CMD_DEL);
7990         list_del(&devlink->list);
7991         mutex_unlock(&devlink_mutex);
7992 }
7993 EXPORT_SYMBOL_GPL(devlink_unregister);
7994
7995 /**
7996  *      devlink_reload_enable - Enable reload of devlink instance
7997  *
7998  *      @devlink: devlink
7999  *
8000  *      Should be called at end of device initialization
8001  *      process when reload operation is supported.
8002  */
8003 void devlink_reload_enable(struct devlink *devlink)
8004 {
8005         mutex_lock(&devlink_mutex);
8006         devlink->reload_enabled = true;
8007         mutex_unlock(&devlink_mutex);
8008 }
8009 EXPORT_SYMBOL_GPL(devlink_reload_enable);
8010
8011 /**
8012  *      devlink_reload_disable - Disable reload of devlink instance
8013  *
8014  *      @devlink: devlink
8015  *
8016  *      Should be called at the beginning of device cleanup
8017  *      process when reload operation is supported.
8018  */
8019 void devlink_reload_disable(struct devlink *devlink)
8020 {
8021         mutex_lock(&devlink_mutex);
8022         /* Mutex is taken which ensures that no reload operation is in
8023          * progress while setting up forbidded flag.
8024          */
8025         devlink->reload_enabled = false;
8026         mutex_unlock(&devlink_mutex);
8027 }
8028 EXPORT_SYMBOL_GPL(devlink_reload_disable);
8029
8030 /**
8031  *      devlink_free - Free devlink instance resources
8032  *
8033  *      @devlink: devlink
8034  */
8035 void devlink_free(struct devlink *devlink)
8036 {
8037         mutex_destroy(&devlink->reporters_lock);
8038         mutex_destroy(&devlink->lock);
8039         WARN_ON(!list_empty(&devlink->trap_policer_list));
8040         WARN_ON(!list_empty(&devlink->trap_group_list));
8041         WARN_ON(!list_empty(&devlink->trap_list));
8042         WARN_ON(!list_empty(&devlink->reporter_list));
8043         WARN_ON(!list_empty(&devlink->region_list));
8044         WARN_ON(!list_empty(&devlink->param_list));
8045         WARN_ON(!list_empty(&devlink->resource_list));
8046         WARN_ON(!list_empty(&devlink->dpipe_table_list));
8047         WARN_ON(!list_empty(&devlink->sb_list));
8048         WARN_ON(!list_empty(&devlink->port_list));
8049
8050         xa_destroy(&devlink->snapshot_ids);
8051
8052         kfree(devlink);
8053 }
8054 EXPORT_SYMBOL_GPL(devlink_free);
8055
8056 static void devlink_port_type_warn(struct work_struct *work)
8057 {
8058         WARN(true, "Type was not set for devlink port.");
8059 }
8060
8061 static bool devlink_port_type_should_warn(struct devlink_port *devlink_port)
8062 {
8063         /* Ignore CPU and DSA flavours. */
8064         return devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_CPU &&
8065                devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_DSA &&
8066                devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_UNUSED;
8067 }
8068
8069 #define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 3600)
8070
8071 static void devlink_port_type_warn_schedule(struct devlink_port *devlink_port)
8072 {
8073         if (!devlink_port_type_should_warn(devlink_port))
8074                 return;
8075         /* Schedule a work to WARN in case driver does not set port
8076          * type within timeout.
8077          */
8078         schedule_delayed_work(&devlink_port->type_warn_dw,
8079                               DEVLINK_PORT_TYPE_WARN_TIMEOUT);
8080 }
8081
8082 static void devlink_port_type_warn_cancel(struct devlink_port *devlink_port)
8083 {
8084         if (!devlink_port_type_should_warn(devlink_port))
8085                 return;
8086         cancel_delayed_work_sync(&devlink_port->type_warn_dw);
8087 }
8088
8089 /**
8090  *      devlink_port_register - Register devlink port
8091  *
8092  *      @devlink: devlink
8093  *      @devlink_port: devlink port
8094  *      @port_index: driver-specific numerical identifier of the port
8095  *
8096  *      Register devlink port with provided port index. User can use
8097  *      any indexing, even hw-related one. devlink_port structure
8098  *      is convenient to be embedded inside user driver private structure.
8099  *      Note that the caller should take care of zeroing the devlink_port
8100  *      structure.
8101  */
8102 int devlink_port_register(struct devlink *devlink,
8103                           struct devlink_port *devlink_port,
8104                           unsigned int port_index)
8105 {
8106         mutex_lock(&devlink->lock);
8107         if (devlink_port_index_exists(devlink, port_index)) {
8108                 mutex_unlock(&devlink->lock);
8109                 return -EEXIST;
8110         }
8111         devlink_port->devlink = devlink;
8112         devlink_port->index = port_index;
8113         devlink_port->registered = true;
8114         spin_lock_init(&devlink_port->type_lock);
8115         INIT_LIST_HEAD(&devlink_port->reporter_list);
8116         mutex_init(&devlink_port->reporters_lock);
8117         list_add_tail(&devlink_port->list, &devlink->port_list);
8118         INIT_LIST_HEAD(&devlink_port->param_list);
8119         INIT_LIST_HEAD(&devlink_port->region_list);
8120         mutex_unlock(&devlink->lock);
8121         INIT_DELAYED_WORK(&devlink_port->type_warn_dw, &devlink_port_type_warn);
8122         devlink_port_type_warn_schedule(devlink_port);
8123         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
8124         return 0;
8125 }
8126 EXPORT_SYMBOL_GPL(devlink_port_register);
8127
8128 /**
8129  *      devlink_port_unregister - Unregister devlink port
8130  *
8131  *      @devlink_port: devlink port
8132  */
8133 void devlink_port_unregister(struct devlink_port *devlink_port)
8134 {
8135         struct devlink *devlink = devlink_port->devlink;
8136
8137         devlink_port_type_warn_cancel(devlink_port);
8138         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
8139         mutex_lock(&devlink->lock);
8140         list_del(&devlink_port->list);
8141         mutex_unlock(&devlink->lock);
8142         WARN_ON(!list_empty(&devlink_port->reporter_list));
8143         WARN_ON(!list_empty(&devlink_port->region_list));
8144         mutex_destroy(&devlink_port->reporters_lock);
8145 }
8146 EXPORT_SYMBOL_GPL(devlink_port_unregister);
8147
8148 static void __devlink_port_type_set(struct devlink_port *devlink_port,
8149                                     enum devlink_port_type type,
8150                                     void *type_dev)
8151 {
8152         if (WARN_ON(!devlink_port->registered))
8153                 return;
8154         devlink_port_type_warn_cancel(devlink_port);
8155         spin_lock_bh(&devlink_port->type_lock);
8156         devlink_port->type = type;
8157         devlink_port->type_dev = type_dev;
8158         spin_unlock_bh(&devlink_port->type_lock);
8159         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
8160 }
8161
8162 static void devlink_port_type_netdev_checks(struct devlink_port *devlink_port,
8163                                             struct net_device *netdev)
8164 {
8165         const struct net_device_ops *ops = netdev->netdev_ops;
8166
8167         /* If driver registers devlink port, it should set devlink port
8168          * attributes accordingly so the compat functions are called
8169          * and the original ops are not used.
8170          */
8171         if (ops->ndo_get_phys_port_name) {
8172                 /* Some drivers use the same set of ndos for netdevs
8173                  * that have devlink_port registered and also for
8174                  * those who don't. Make sure that ndo_get_phys_port_name
8175                  * returns -EOPNOTSUPP here in case it is defined.
8176                  * Warn if not.
8177                  */
8178                 char name[IFNAMSIZ];
8179                 int err;
8180
8181                 err = ops->ndo_get_phys_port_name(netdev, name, sizeof(name));
8182                 WARN_ON(err != -EOPNOTSUPP);
8183         }
8184         if (ops->ndo_get_port_parent_id) {
8185                 /* Some drivers use the same set of ndos for netdevs
8186                  * that have devlink_port registered and also for
8187                  * those who don't. Make sure that ndo_get_port_parent_id
8188                  * returns -EOPNOTSUPP here in case it is defined.
8189                  * Warn if not.
8190                  */
8191                 struct netdev_phys_item_id ppid;
8192                 int err;
8193
8194                 err = ops->ndo_get_port_parent_id(netdev, &ppid);
8195                 WARN_ON(err != -EOPNOTSUPP);
8196         }
8197 }
8198
8199 /**
8200  *      devlink_port_type_eth_set - Set port type to Ethernet
8201  *
8202  *      @devlink_port: devlink port
8203  *      @netdev: related netdevice
8204  */
8205 void devlink_port_type_eth_set(struct devlink_port *devlink_port,
8206                                struct net_device *netdev)
8207 {
8208         if (netdev)
8209                 devlink_port_type_netdev_checks(devlink_port, netdev);
8210         else
8211                 dev_warn(devlink_port->devlink->dev,
8212                          "devlink port type for port %d set to Ethernet without a software interface reference, device type not supported by the kernel?\n",
8213                          devlink_port->index);
8214
8215         __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, netdev);
8216 }
8217 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
8218
8219 /**
8220  *      devlink_port_type_ib_set - Set port type to InfiniBand
8221  *
8222  *      @devlink_port: devlink port
8223  *      @ibdev: related IB device
8224  */
8225 void devlink_port_type_ib_set(struct devlink_port *devlink_port,
8226                               struct ib_device *ibdev)
8227 {
8228         __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_IB, ibdev);
8229 }
8230 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
8231
8232 /**
8233  *      devlink_port_type_clear - Clear port type
8234  *
8235  *      @devlink_port: devlink port
8236  */
8237 void devlink_port_type_clear(struct devlink_port *devlink_port)
8238 {
8239         __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, NULL);
8240         devlink_port_type_warn_schedule(devlink_port);
8241 }
8242 EXPORT_SYMBOL_GPL(devlink_port_type_clear);
8243
8244 static int __devlink_port_attrs_set(struct devlink_port *devlink_port,
8245                                     enum devlink_port_flavour flavour)
8246 {
8247         struct devlink_port_attrs *attrs = &devlink_port->attrs;
8248
8249         if (WARN_ON(devlink_port->registered))
8250                 return -EEXIST;
8251         devlink_port->attrs_set = true;
8252         attrs->flavour = flavour;
8253         if (attrs->switch_id.id_len) {
8254                 devlink_port->switch_port = true;
8255                 if (WARN_ON(attrs->switch_id.id_len > MAX_PHYS_ITEM_ID_LEN))
8256                         attrs->switch_id.id_len = MAX_PHYS_ITEM_ID_LEN;
8257         } else {
8258                 devlink_port->switch_port = false;
8259         }
8260         return 0;
8261 }
8262
8263 /**
8264  *      devlink_port_attrs_set - Set port attributes
8265  *
8266  *      @devlink_port: devlink port
8267  *      @attrs: devlink port attrs
8268  */
8269 void devlink_port_attrs_set(struct devlink_port *devlink_port,
8270                             struct devlink_port_attrs *attrs)
8271 {
8272         int ret;
8273
8274         devlink_port->attrs = *attrs;
8275         ret = __devlink_port_attrs_set(devlink_port, attrs->flavour);
8276         if (ret)
8277                 return;
8278         WARN_ON(attrs->splittable && attrs->split);
8279 }
8280 EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
8281
8282 /**
8283  *      devlink_port_attrs_pci_pf_set - Set PCI PF port attributes
8284  *
8285  *      @devlink_port: devlink port
8286  *      @controller: associated controller number for the devlink port instance
8287  *      @pf: associated PF for the devlink port instance
8288  *      @external: indicates if the port is for an external controller
8289  */
8290 void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u32 controller,
8291                                    u16 pf, bool external)
8292 {
8293         struct devlink_port_attrs *attrs = &devlink_port->attrs;
8294         int ret;
8295
8296         ret = __devlink_port_attrs_set(devlink_port,
8297                                        DEVLINK_PORT_FLAVOUR_PCI_PF);
8298         if (ret)
8299                 return;
8300         attrs->pci_pf.controller = controller;
8301         attrs->pci_pf.pf = pf;
8302         attrs->pci_pf.external = external;
8303 }
8304 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set);
8305
8306 /**
8307  *      devlink_port_attrs_pci_vf_set - Set PCI VF port attributes
8308  *
8309  *      @devlink_port: devlink port
8310  *      @controller: associated controller number for the devlink port instance
8311  *      @pf: associated PF for the devlink port instance
8312  *      @vf: associated VF of a PF for the devlink port instance
8313  *      @external: indicates if the port is for an external controller
8314  */
8315 void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port, u32 controller,
8316                                    u16 pf, u16 vf, bool external)
8317 {
8318         struct devlink_port_attrs *attrs = &devlink_port->attrs;
8319         int ret;
8320
8321         ret = __devlink_port_attrs_set(devlink_port,
8322                                        DEVLINK_PORT_FLAVOUR_PCI_VF);
8323         if (ret)
8324                 return;
8325         attrs->pci_vf.controller = controller;
8326         attrs->pci_vf.pf = pf;
8327         attrs->pci_vf.vf = vf;
8328         attrs->pci_vf.external = external;
8329 }
8330 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set);
8331
8332 static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
8333                                              char *name, size_t len)
8334 {
8335         struct devlink_port_attrs *attrs = &devlink_port->attrs;
8336         int n = 0;
8337
8338         if (!devlink_port->attrs_set)
8339                 return -EOPNOTSUPP;
8340
8341         switch (attrs->flavour) {
8342         case DEVLINK_PORT_FLAVOUR_PHYSICAL:
8343         case DEVLINK_PORT_FLAVOUR_VIRTUAL:
8344                 if (!attrs->split)
8345                         n = snprintf(name, len, "p%u", attrs->phys.port_number);
8346                 else
8347                         n = snprintf(name, len, "p%us%u",
8348                                      attrs->phys.port_number,
8349                                      attrs->phys.split_subport_number);
8350                 break;
8351         case DEVLINK_PORT_FLAVOUR_CPU:
8352         case DEVLINK_PORT_FLAVOUR_DSA:
8353         case DEVLINK_PORT_FLAVOUR_UNUSED:
8354                 /* As CPU and DSA ports do not have a netdevice associated
8355                  * case should not ever happen.
8356                  */
8357                 WARN_ON(1);
8358                 return -EINVAL;
8359         case DEVLINK_PORT_FLAVOUR_PCI_PF:
8360                 if (attrs->pci_pf.external) {
8361                         n = snprintf(name, len, "c%u", attrs->pci_pf.controller);
8362                         if (n >= len)
8363                                 return -EINVAL;
8364                         len -= n;
8365                         name += n;
8366                 }
8367                 n = snprintf(name, len, "pf%u", attrs->pci_pf.pf);
8368                 break;
8369         case DEVLINK_PORT_FLAVOUR_PCI_VF:
8370                 if (attrs->pci_vf.external) {
8371                         n = snprintf(name, len, "c%u", attrs->pci_vf.controller);
8372                         if (n >= len)
8373                                 return -EINVAL;
8374                         len -= n;
8375                         name += n;
8376                 }
8377                 n = snprintf(name, len, "pf%uvf%u",
8378                              attrs->pci_vf.pf, attrs->pci_vf.vf);
8379                 break;
8380         }
8381
8382         if (n >= len)
8383                 return -EINVAL;
8384
8385         return 0;
8386 }
8387
8388 int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
8389                         u32 size, u16 ingress_pools_count,
8390                         u16 egress_pools_count, u16 ingress_tc_count,
8391                         u16 egress_tc_count)
8392 {
8393         struct devlink_sb *devlink_sb;
8394         int err = 0;
8395
8396         mutex_lock(&devlink->lock);
8397         if (devlink_sb_index_exists(devlink, sb_index)) {
8398                 err = -EEXIST;
8399                 goto unlock;
8400         }
8401
8402         devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
8403         if (!devlink_sb) {
8404                 err = -ENOMEM;
8405                 goto unlock;
8406         }
8407         devlink_sb->index = sb_index;
8408         devlink_sb->size = size;
8409         devlink_sb->ingress_pools_count = ingress_pools_count;
8410         devlink_sb->egress_pools_count = egress_pools_count;
8411         devlink_sb->ingress_tc_count = ingress_tc_count;
8412         devlink_sb->egress_tc_count = egress_tc_count;
8413         list_add_tail(&devlink_sb->list, &devlink->sb_list);
8414 unlock:
8415         mutex_unlock(&devlink->lock);
8416         return err;
8417 }
8418 EXPORT_SYMBOL_GPL(devlink_sb_register);
8419
8420 void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
8421 {
8422         struct devlink_sb *devlink_sb;
8423
8424         mutex_lock(&devlink->lock);
8425         devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
8426         WARN_ON(!devlink_sb);
8427         list_del(&devlink_sb->list);
8428         mutex_unlock(&devlink->lock);
8429         kfree(devlink_sb);
8430 }
8431 EXPORT_SYMBOL_GPL(devlink_sb_unregister);
8432
8433 /**
8434  *      devlink_dpipe_headers_register - register dpipe headers
8435  *
8436  *      @devlink: devlink
8437  *      @dpipe_headers: dpipe header array
8438  *
8439  *      Register the headers supported by hardware.
8440  */
8441 int devlink_dpipe_headers_register(struct devlink *devlink,
8442                                    struct devlink_dpipe_headers *dpipe_headers)
8443 {
8444         mutex_lock(&devlink->lock);
8445         devlink->dpipe_headers = dpipe_headers;
8446         mutex_unlock(&devlink->lock);
8447         return 0;
8448 }
8449 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register);
8450
8451 /**
8452  *      devlink_dpipe_headers_unregister - unregister dpipe headers
8453  *
8454  *      @devlink: devlink
8455  *
8456  *      Unregister the headers supported by hardware.
8457  */
8458 void devlink_dpipe_headers_unregister(struct devlink *devlink)
8459 {
8460         mutex_lock(&devlink->lock);
8461         devlink->dpipe_headers = NULL;
8462         mutex_unlock(&devlink->lock);
8463 }
8464 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister);
8465
8466 /**
8467  *      devlink_dpipe_table_counter_enabled - check if counter allocation
8468  *                                            required
8469  *      @devlink: devlink
8470  *      @table_name: tables name
8471  *
8472  *      Used by driver to check if counter allocation is required.
8473  *      After counter allocation is turned on the table entries
8474  *      are updated to include counter statistics.
8475  *
8476  *      After that point on the driver must respect the counter
8477  *      state so that each entry added to the table is added
8478  *      with a counter.
8479  */
8480 bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
8481                                          const char *table_name)
8482 {
8483         struct devlink_dpipe_table *table;
8484         bool enabled;
8485
8486         rcu_read_lock();
8487         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
8488                                          table_name, devlink);
8489         enabled = false;
8490         if (table)
8491                 enabled = table->counters_enabled;
8492         rcu_read_unlock();
8493         return enabled;
8494 }
8495 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled);
8496
8497 /**
8498  *      devlink_dpipe_table_register - register dpipe table
8499  *
8500  *      @devlink: devlink
8501  *      @table_name: table name
8502  *      @table_ops: table ops
8503  *      @priv: priv
8504  *      @counter_control_extern: external control for counters
8505  */
8506 int devlink_dpipe_table_register(struct devlink *devlink,
8507                                  const char *table_name,
8508                                  struct devlink_dpipe_table_ops *table_ops,
8509                                  void *priv, bool counter_control_extern)
8510 {
8511         struct devlink_dpipe_table *table;
8512         int err = 0;
8513
8514         if (WARN_ON(!table_ops->size_get))
8515                 return -EINVAL;
8516
8517         mutex_lock(&devlink->lock);
8518
8519         if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name,
8520                                      devlink)) {
8521                 err = -EEXIST;
8522                 goto unlock;
8523         }
8524
8525         table = kzalloc(sizeof(*table), GFP_KERNEL);
8526         if (!table) {
8527                 err = -ENOMEM;
8528                 goto unlock;
8529         }
8530
8531         table->name = table_name;
8532         table->table_ops = table_ops;
8533         table->priv = priv;
8534         table->counter_control_extern = counter_control_extern;
8535
8536         list_add_tail_rcu(&table->list, &devlink->dpipe_table_list);
8537 unlock:
8538         mutex_unlock(&devlink->lock);
8539         return err;
8540 }
8541 EXPORT_SYMBOL_GPL(devlink_dpipe_table_register);
8542
8543 /**
8544  *      devlink_dpipe_table_unregister - unregister dpipe table
8545  *
8546  *      @devlink: devlink
8547  *      @table_name: table name
8548  */
8549 void devlink_dpipe_table_unregister(struct devlink *devlink,
8550                                     const char *table_name)
8551 {
8552         struct devlink_dpipe_table *table;
8553
8554         mutex_lock(&devlink->lock);
8555         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
8556                                          table_name, devlink);
8557         if (!table)
8558                 goto unlock;
8559         list_del_rcu(&table->list);
8560         mutex_unlock(&devlink->lock);
8561         kfree_rcu(table, rcu);
8562         return;
8563 unlock:
8564         mutex_unlock(&devlink->lock);
8565 }
8566 EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister);
8567
8568 /**
8569  *      devlink_resource_register - devlink resource register
8570  *
8571  *      @devlink: devlink
8572  *      @resource_name: resource's name
8573  *      @resource_size: resource's size
8574  *      @resource_id: resource's id
8575  *      @parent_resource_id: resource's parent id
8576  *      @size_params: size parameters
8577  */
8578 int devlink_resource_register(struct devlink *devlink,
8579                               const char *resource_name,
8580                               u64 resource_size,
8581                               u64 resource_id,
8582                               u64 parent_resource_id,
8583                               const struct devlink_resource_size_params *size_params)
8584 {
8585         struct devlink_resource *resource;
8586         struct list_head *resource_list;
8587         bool top_hierarchy;
8588         int err = 0;
8589
8590         top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
8591
8592         mutex_lock(&devlink->lock);
8593         resource = devlink_resource_find(devlink, NULL, resource_id);
8594         if (resource) {
8595                 err = -EINVAL;
8596                 goto out;
8597         }
8598
8599         resource = kzalloc(sizeof(*resource), GFP_KERNEL);
8600         if (!resource) {
8601                 err = -ENOMEM;
8602                 goto out;
8603         }
8604
8605         if (top_hierarchy) {
8606                 resource_list = &devlink->resource_list;
8607         } else {
8608                 struct devlink_resource *parent_resource;
8609
8610                 parent_resource = devlink_resource_find(devlink, NULL,
8611                                                         parent_resource_id);
8612                 if (parent_resource) {
8613                         resource_list = &parent_resource->resource_list;
8614                         resource->parent = parent_resource;
8615                 } else {
8616                         kfree(resource);
8617                         err = -EINVAL;
8618                         goto out;
8619                 }
8620         }
8621
8622         resource->name = resource_name;
8623         resource->size = resource_size;
8624         resource->size_new = resource_size;
8625         resource->id = resource_id;
8626         resource->size_valid = true;
8627         memcpy(&resource->size_params, size_params,
8628                sizeof(resource->size_params));
8629         INIT_LIST_HEAD(&resource->resource_list);
8630         list_add_tail(&resource->list, resource_list);
8631 out:
8632         mutex_unlock(&devlink->lock);
8633         return err;
8634 }
8635 EXPORT_SYMBOL_GPL(devlink_resource_register);
8636
8637 /**
8638  *      devlink_resources_unregister - free all resources
8639  *
8640  *      @devlink: devlink
8641  *      @resource: resource
8642  */
8643 void devlink_resources_unregister(struct devlink *devlink,
8644                                   struct devlink_resource *resource)
8645 {
8646         struct devlink_resource *tmp, *child_resource;
8647         struct list_head *resource_list;
8648
8649         if (resource)
8650                 resource_list = &resource->resource_list;
8651         else
8652                 resource_list = &devlink->resource_list;
8653
8654         if (!resource)
8655                 mutex_lock(&devlink->lock);
8656
8657         list_for_each_entry_safe(child_resource, tmp, resource_list, list) {
8658                 devlink_resources_unregister(devlink, child_resource);
8659                 list_del(&child_resource->list);
8660                 kfree(child_resource);
8661         }
8662
8663         if (!resource)
8664                 mutex_unlock(&devlink->lock);
8665 }
8666 EXPORT_SYMBOL_GPL(devlink_resources_unregister);
8667
8668 /**
8669  *      devlink_resource_size_get - get and update size
8670  *
8671  *      @devlink: devlink
8672  *      @resource_id: the requested resource id
8673  *      @p_resource_size: ptr to update
8674  */
8675 int devlink_resource_size_get(struct devlink *devlink,
8676                               u64 resource_id,
8677                               u64 *p_resource_size)
8678 {
8679         struct devlink_resource *resource;
8680         int err = 0;
8681
8682         mutex_lock(&devlink->lock);
8683         resource = devlink_resource_find(devlink, NULL, resource_id);
8684         if (!resource) {
8685                 err = -EINVAL;
8686                 goto out;
8687         }
8688         *p_resource_size = resource->size_new;
8689         resource->size = resource->size_new;
8690 out:
8691         mutex_unlock(&devlink->lock);
8692         return err;
8693 }
8694 EXPORT_SYMBOL_GPL(devlink_resource_size_get);
8695
8696 /**
8697  *      devlink_dpipe_table_resource_set - set the resource id
8698  *
8699  *      @devlink: devlink
8700  *      @table_name: table name
8701  *      @resource_id: resource id
8702  *      @resource_units: number of resource's units consumed per table's entry
8703  */
8704 int devlink_dpipe_table_resource_set(struct devlink *devlink,
8705                                      const char *table_name, u64 resource_id,
8706                                      u64 resource_units)
8707 {
8708         struct devlink_dpipe_table *table;
8709         int err = 0;
8710
8711         mutex_lock(&devlink->lock);
8712         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
8713                                          table_name, devlink);
8714         if (!table) {
8715                 err = -EINVAL;
8716                 goto out;
8717         }
8718         table->resource_id = resource_id;
8719         table->resource_units = resource_units;
8720         table->resource_valid = true;
8721 out:
8722         mutex_unlock(&devlink->lock);
8723         return err;
8724 }
8725 EXPORT_SYMBOL_GPL(devlink_dpipe_table_resource_set);
8726
8727 /**
8728  *      devlink_resource_occ_get_register - register occupancy getter
8729  *
8730  *      @devlink: devlink
8731  *      @resource_id: resource id
8732  *      @occ_get: occupancy getter callback
8733  *      @occ_get_priv: occupancy getter callback priv
8734  */
8735 void devlink_resource_occ_get_register(struct devlink *devlink,
8736                                        u64 resource_id,
8737                                        devlink_resource_occ_get_t *occ_get,
8738                                        void *occ_get_priv)
8739 {
8740         struct devlink_resource *resource;
8741
8742         mutex_lock(&devlink->lock);
8743         resource = devlink_resource_find(devlink, NULL, resource_id);
8744         if (WARN_ON(!resource))
8745                 goto out;
8746         WARN_ON(resource->occ_get);
8747
8748         resource->occ_get = occ_get;
8749         resource->occ_get_priv = occ_get_priv;
8750 out:
8751         mutex_unlock(&devlink->lock);
8752 }
8753 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register);
8754
8755 /**
8756  *      devlink_resource_occ_get_unregister - unregister occupancy getter
8757  *
8758  *      @devlink: devlink
8759  *      @resource_id: resource id
8760  */
8761 void devlink_resource_occ_get_unregister(struct devlink *devlink,
8762                                          u64 resource_id)
8763 {
8764         struct devlink_resource *resource;
8765
8766         mutex_lock(&devlink->lock);
8767         resource = devlink_resource_find(devlink, NULL, resource_id);
8768         if (WARN_ON(!resource))
8769                 goto out;
8770         WARN_ON(!resource->occ_get);
8771
8772         resource->occ_get = NULL;
8773         resource->occ_get_priv = NULL;
8774 out:
8775         mutex_unlock(&devlink->lock);
8776 }
8777 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister);
8778
8779 static int devlink_param_verify(const struct devlink_param *param)
8780 {
8781         if (!param || !param->name || !param->supported_cmodes)
8782                 return -EINVAL;
8783         if (param->generic)
8784                 return devlink_param_generic_verify(param);
8785         else
8786                 return devlink_param_driver_verify(param);
8787 }
8788
8789 static int __devlink_params_register(struct devlink *devlink,
8790                                      unsigned int port_index,
8791                                      struct list_head *param_list,
8792                                      const struct devlink_param *params,
8793                                      size_t params_count,
8794                                      enum devlink_command reg_cmd,
8795                                      enum devlink_command unreg_cmd)
8796 {
8797         const struct devlink_param *param = params;
8798         int i;
8799         int err;
8800
8801         mutex_lock(&devlink->lock);
8802         for (i = 0; i < params_count; i++, param++) {
8803                 err = devlink_param_verify(param);
8804                 if (err)
8805                         goto rollback;
8806
8807                 err = devlink_param_register_one(devlink, port_index,
8808                                                  param_list, param, reg_cmd);
8809                 if (err)
8810                         goto rollback;
8811         }
8812
8813         mutex_unlock(&devlink->lock);
8814         return 0;
8815
8816 rollback:
8817         if (!i)
8818                 goto unlock;
8819         for (param--; i > 0; i--, param--)
8820                 devlink_param_unregister_one(devlink, port_index, param_list,
8821                                              param, unreg_cmd);
8822 unlock:
8823         mutex_unlock(&devlink->lock);
8824         return err;
8825 }
8826
8827 static void __devlink_params_unregister(struct devlink *devlink,
8828                                         unsigned int port_index,
8829                                         struct list_head *param_list,
8830                                         const struct devlink_param *params,
8831                                         size_t params_count,
8832                                         enum devlink_command cmd)
8833 {
8834         const struct devlink_param *param = params;
8835         int i;
8836
8837         mutex_lock(&devlink->lock);
8838         for (i = 0; i < params_count; i++, param++)
8839                 devlink_param_unregister_one(devlink, 0, param_list, param,
8840                                              cmd);
8841         mutex_unlock(&devlink->lock);
8842 }
8843
8844 /**
8845  *      devlink_params_register - register configuration parameters
8846  *
8847  *      @devlink: devlink
8848  *      @params: configuration parameters array
8849  *      @params_count: number of parameters provided
8850  *
8851  *      Register the configuration parameters supported by the driver.
8852  */
8853 int devlink_params_register(struct devlink *devlink,
8854                             const struct devlink_param *params,
8855                             size_t params_count)
8856 {
8857         return __devlink_params_register(devlink, 0, &devlink->param_list,
8858                                          params, params_count,
8859                                          DEVLINK_CMD_PARAM_NEW,
8860                                          DEVLINK_CMD_PARAM_DEL);
8861 }
8862 EXPORT_SYMBOL_GPL(devlink_params_register);
8863
8864 /**
8865  *      devlink_params_unregister - unregister configuration parameters
8866  *      @devlink: devlink
8867  *      @params: configuration parameters to unregister
8868  *      @params_count: number of parameters provided
8869  */
8870 void devlink_params_unregister(struct devlink *devlink,
8871                                const struct devlink_param *params,
8872                                size_t params_count)
8873 {
8874         return __devlink_params_unregister(devlink, 0, &devlink->param_list,
8875                                            params, params_count,
8876                                            DEVLINK_CMD_PARAM_DEL);
8877 }
8878 EXPORT_SYMBOL_GPL(devlink_params_unregister);
8879
8880 /**
8881  *      devlink_params_publish - publish configuration parameters
8882  *
8883  *      @devlink: devlink
8884  *
8885  *      Publish previously registered configuration parameters.
8886  */
8887 void devlink_params_publish(struct devlink *devlink)
8888 {
8889         struct devlink_param_item *param_item;
8890
8891         list_for_each_entry(param_item, &devlink->param_list, list) {
8892                 if (param_item->published)
8893                         continue;
8894                 param_item->published = true;
8895                 devlink_param_notify(devlink, 0, param_item,
8896                                      DEVLINK_CMD_PARAM_NEW);
8897         }
8898 }
8899 EXPORT_SYMBOL_GPL(devlink_params_publish);
8900
8901 /**
8902  *      devlink_params_unpublish - unpublish configuration parameters
8903  *
8904  *      @devlink: devlink
8905  *
8906  *      Unpublish previously registered configuration parameters.
8907  */
8908 void devlink_params_unpublish(struct devlink *devlink)
8909 {
8910         struct devlink_param_item *param_item;
8911
8912         list_for_each_entry(param_item, &devlink->param_list, list) {
8913                 if (!param_item->published)
8914                         continue;
8915                 param_item->published = false;
8916                 devlink_param_notify(devlink, 0, param_item,
8917                                      DEVLINK_CMD_PARAM_DEL);
8918         }
8919 }
8920 EXPORT_SYMBOL_GPL(devlink_params_unpublish);
8921
8922 /**
8923  *      devlink_port_params_register - register port configuration parameters
8924  *
8925  *      @devlink_port: devlink port
8926  *      @params: configuration parameters array
8927  *      @params_count: number of parameters provided
8928  *
8929  *      Register the configuration parameters supported by the port.
8930  */
8931 int devlink_port_params_register(struct devlink_port *devlink_port,
8932                                  const struct devlink_param *params,
8933                                  size_t params_count)
8934 {
8935         return __devlink_params_register(devlink_port->devlink,
8936                                          devlink_port->index,
8937                                          &devlink_port->param_list, params,
8938                                          params_count,
8939                                          DEVLINK_CMD_PORT_PARAM_NEW,
8940                                          DEVLINK_CMD_PORT_PARAM_DEL);
8941 }
8942 EXPORT_SYMBOL_GPL(devlink_port_params_register);
8943
8944 /**
8945  *      devlink_port_params_unregister - unregister port configuration
8946  *      parameters
8947  *
8948  *      @devlink_port: devlink port
8949  *      @params: configuration parameters array
8950  *      @params_count: number of parameters provided
8951  */
8952 void devlink_port_params_unregister(struct devlink_port *devlink_port,
8953                                     const struct devlink_param *params,
8954                                     size_t params_count)
8955 {
8956         return __devlink_params_unregister(devlink_port->devlink,
8957                                            devlink_port->index,
8958                                            &devlink_port->param_list,
8959                                            params, params_count,
8960                                            DEVLINK_CMD_PORT_PARAM_DEL);
8961 }
8962 EXPORT_SYMBOL_GPL(devlink_port_params_unregister);
8963
8964 static int
8965 __devlink_param_driverinit_value_get(struct list_head *param_list, u32 param_id,
8966                                      union devlink_param_value *init_val)
8967 {
8968         struct devlink_param_item *param_item;
8969
8970         param_item = devlink_param_find_by_id(param_list, param_id);
8971         if (!param_item)
8972                 return -EINVAL;
8973
8974         if (!param_item->driverinit_value_valid ||
8975             !devlink_param_cmode_is_supported(param_item->param,
8976                                               DEVLINK_PARAM_CMODE_DRIVERINIT))
8977                 return -EOPNOTSUPP;
8978
8979         if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
8980                 strcpy(init_val->vstr, param_item->driverinit_value.vstr);
8981         else
8982                 *init_val = param_item->driverinit_value;
8983
8984         return 0;
8985 }
8986
8987 static int
8988 __devlink_param_driverinit_value_set(struct devlink *devlink,
8989                                      unsigned int port_index,
8990                                      struct list_head *param_list, u32 param_id,
8991                                      union devlink_param_value init_val,
8992                                      enum devlink_command cmd)
8993 {
8994         struct devlink_param_item *param_item;
8995
8996         param_item = devlink_param_find_by_id(param_list, param_id);
8997         if (!param_item)
8998                 return -EINVAL;
8999
9000         if (!devlink_param_cmode_is_supported(param_item->param,
9001                                               DEVLINK_PARAM_CMODE_DRIVERINIT))
9002                 return -EOPNOTSUPP;
9003
9004         if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
9005                 strcpy(param_item->driverinit_value.vstr, init_val.vstr);
9006         else
9007                 param_item->driverinit_value = init_val;
9008         param_item->driverinit_value_valid = true;
9009
9010         devlink_param_notify(devlink, port_index, param_item, cmd);
9011         return 0;
9012 }
9013
9014 /**
9015  *      devlink_param_driverinit_value_get - get configuration parameter
9016  *                                           value for driver initializing
9017  *
9018  *      @devlink: devlink
9019  *      @param_id: parameter ID
9020  *      @init_val: value of parameter in driverinit configuration mode
9021  *
9022  *      This function should be used by the driver to get driverinit
9023  *      configuration for initialization after reload command.
9024  */
9025 int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
9026                                        union devlink_param_value *init_val)
9027 {
9028         if (!devlink_reload_supported(devlink->ops))
9029                 return -EOPNOTSUPP;
9030
9031         return __devlink_param_driverinit_value_get(&devlink->param_list,
9032                                                     param_id, init_val);
9033 }
9034 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_get);
9035
9036 /**
9037  *      devlink_param_driverinit_value_set - set value of configuration
9038  *                                           parameter for driverinit
9039  *                                           configuration mode
9040  *
9041  *      @devlink: devlink
9042  *      @param_id: parameter ID
9043  *      @init_val: value of parameter to set for driverinit configuration mode
9044  *
9045  *      This function should be used by the driver to set driverinit
9046  *      configuration mode default value.
9047  */
9048 int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
9049                                        union devlink_param_value init_val)
9050 {
9051         return __devlink_param_driverinit_value_set(devlink, 0,
9052                                                     &devlink->param_list,
9053                                                     param_id, init_val,
9054                                                     DEVLINK_CMD_PARAM_NEW);
9055 }
9056 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set);
9057
9058 /**
9059  *      devlink_port_param_driverinit_value_get - get configuration parameter
9060  *                                              value for driver initializing
9061  *
9062  *      @devlink_port: devlink_port
9063  *      @param_id: parameter ID
9064  *      @init_val: value of parameter in driverinit configuration mode
9065  *
9066  *      This function should be used by the driver to get driverinit
9067  *      configuration for initialization after reload command.
9068  */
9069 int devlink_port_param_driverinit_value_get(struct devlink_port *devlink_port,
9070                                             u32 param_id,
9071                                             union devlink_param_value *init_val)
9072 {
9073         struct devlink *devlink = devlink_port->devlink;
9074
9075         if (!devlink_reload_supported(devlink->ops))
9076                 return -EOPNOTSUPP;
9077
9078         return __devlink_param_driverinit_value_get(&devlink_port->param_list,
9079                                                     param_id, init_val);
9080 }
9081 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_get);
9082
9083 /**
9084  *     devlink_port_param_driverinit_value_set - set value of configuration
9085  *                                               parameter for driverinit
9086  *                                               configuration mode
9087  *
9088  *     @devlink_port: devlink_port
9089  *     @param_id: parameter ID
9090  *     @init_val: value of parameter to set for driverinit configuration mode
9091  *
9092  *     This function should be used by the driver to set driverinit
9093  *     configuration mode default value.
9094  */
9095 int devlink_port_param_driverinit_value_set(struct devlink_port *devlink_port,
9096                                             u32 param_id,
9097                                             union devlink_param_value init_val)
9098 {
9099         return __devlink_param_driverinit_value_set(devlink_port->devlink,
9100                                                     devlink_port->index,
9101                                                     &devlink_port->param_list,
9102                                                     param_id, init_val,
9103                                                     DEVLINK_CMD_PORT_PARAM_NEW);
9104 }
9105 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_set);
9106
9107 /**
9108  *      devlink_param_value_changed - notify devlink on a parameter's value
9109  *                                    change. Should be called by the driver
9110  *                                    right after the change.
9111  *
9112  *      @devlink: devlink
9113  *      @param_id: parameter ID
9114  *
9115  *      This function should be used by the driver to notify devlink on value
9116  *      change, excluding driverinit configuration mode.
9117  *      For driverinit configuration mode driver should use the function
9118  */
9119 void devlink_param_value_changed(struct devlink *devlink, u32 param_id)
9120 {
9121         struct devlink_param_item *param_item;
9122
9123         param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
9124         WARN_ON(!param_item);
9125
9126         devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
9127 }
9128 EXPORT_SYMBOL_GPL(devlink_param_value_changed);
9129
9130 /**
9131  *     devlink_port_param_value_changed - notify devlink on a parameter's value
9132  *                                      change. Should be called by the driver
9133  *                                      right after the change.
9134  *
9135  *     @devlink_port: devlink_port
9136  *     @param_id: parameter ID
9137  *
9138  *     This function should be used by the driver to notify devlink on value
9139  *     change, excluding driverinit configuration mode.
9140  *     For driverinit configuration mode driver should use the function
9141  *     devlink_port_param_driverinit_value_set() instead.
9142  */
9143 void devlink_port_param_value_changed(struct devlink_port *devlink_port,
9144                                       u32 param_id)
9145 {
9146         struct devlink_param_item *param_item;
9147
9148         param_item = devlink_param_find_by_id(&devlink_port->param_list,
9149                                               param_id);
9150         WARN_ON(!param_item);
9151
9152         devlink_param_notify(devlink_port->devlink, devlink_port->index,
9153                              param_item, DEVLINK_CMD_PORT_PARAM_NEW);
9154 }
9155 EXPORT_SYMBOL_GPL(devlink_port_param_value_changed);
9156
9157 /**
9158  *      devlink_param_value_str_fill - Safely fill-up the string preventing
9159  *                                     from overflow of the preallocated buffer
9160  *
9161  *      @dst_val: destination devlink_param_value
9162  *      @src: source buffer
9163  */
9164 void devlink_param_value_str_fill(union devlink_param_value *dst_val,
9165                                   const char *src)
9166 {
9167         size_t len;
9168
9169         len = strlcpy(dst_val->vstr, src, __DEVLINK_PARAM_MAX_STRING_VALUE);
9170         WARN_ON(len >= __DEVLINK_PARAM_MAX_STRING_VALUE);
9171 }
9172 EXPORT_SYMBOL_GPL(devlink_param_value_str_fill);
9173
9174 /**
9175  *      devlink_region_create - create a new address region
9176  *
9177  *      @devlink: devlink
9178  *      @ops: region operations and name
9179  *      @region_max_snapshots: Maximum supported number of snapshots for region
9180  *      @region_size: size of region
9181  */
9182 struct devlink_region *
9183 devlink_region_create(struct devlink *devlink,
9184                       const struct devlink_region_ops *ops,
9185                       u32 region_max_snapshots, u64 region_size)
9186 {
9187         struct devlink_region *region;
9188         int err = 0;
9189
9190         if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
9191                 return ERR_PTR(-EINVAL);
9192
9193         mutex_lock(&devlink->lock);
9194
9195         if (devlink_region_get_by_name(devlink, ops->name)) {
9196                 err = -EEXIST;
9197                 goto unlock;
9198         }
9199
9200         region = kzalloc(sizeof(*region), GFP_KERNEL);
9201         if (!region) {
9202                 err = -ENOMEM;
9203                 goto unlock;
9204         }
9205
9206         region->devlink = devlink;
9207         region->max_snapshots = region_max_snapshots;
9208         region->ops = ops;
9209         region->size = region_size;
9210         INIT_LIST_HEAD(&region->snapshot_list);
9211         list_add_tail(&region->list, &devlink->region_list);
9212         devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
9213
9214         mutex_unlock(&devlink->lock);
9215         return region;
9216
9217 unlock:
9218         mutex_unlock(&devlink->lock);
9219         return ERR_PTR(err);
9220 }
9221 EXPORT_SYMBOL_GPL(devlink_region_create);
9222
9223 /**
9224  *      devlink_port_region_create - create a new address region for a port
9225  *
9226  *      @port: devlink port
9227  *      @ops: region operations and name
9228  *      @region_max_snapshots: Maximum supported number of snapshots for region
9229  *      @region_size: size of region
9230  */
9231 struct devlink_region *
9232 devlink_port_region_create(struct devlink_port *port,
9233                            const struct devlink_port_region_ops *ops,
9234                            u32 region_max_snapshots, u64 region_size)
9235 {
9236         struct devlink *devlink = port->devlink;
9237         struct devlink_region *region;
9238         int err = 0;
9239
9240         if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
9241                 return ERR_PTR(-EINVAL);
9242
9243         mutex_lock(&devlink->lock);
9244
9245         if (devlink_port_region_get_by_name(port, ops->name)) {
9246                 err = -EEXIST;
9247                 goto unlock;
9248         }
9249
9250         region = kzalloc(sizeof(*region), GFP_KERNEL);
9251         if (!region) {
9252                 err = -ENOMEM;
9253                 goto unlock;
9254         }
9255
9256         region->devlink = devlink;
9257         region->port = port;
9258         region->max_snapshots = region_max_snapshots;
9259         region->port_ops = ops;
9260         region->size = region_size;
9261         INIT_LIST_HEAD(&region->snapshot_list);
9262         list_add_tail(&region->list, &port->region_list);
9263         devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
9264
9265         mutex_unlock(&devlink->lock);
9266         return region;
9267
9268 unlock:
9269         mutex_unlock(&devlink->lock);
9270         return ERR_PTR(err);
9271 }
9272 EXPORT_SYMBOL_GPL(devlink_port_region_create);
9273
9274 /**
9275  *      devlink_region_destroy - destroy address region
9276  *
9277  *      @region: devlink region to destroy
9278  */
9279 void devlink_region_destroy(struct devlink_region *region)
9280 {
9281         struct devlink *devlink = region->devlink;
9282         struct devlink_snapshot *snapshot, *ts;
9283
9284         mutex_lock(&devlink->lock);
9285
9286         /* Free all snapshots of region */
9287         list_for_each_entry_safe(snapshot, ts, &region->snapshot_list, list)
9288                 devlink_region_snapshot_del(region, snapshot);
9289
9290         list_del(&region->list);
9291
9292         devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
9293         mutex_unlock(&devlink->lock);
9294         kfree(region);
9295 }
9296 EXPORT_SYMBOL_GPL(devlink_region_destroy);
9297
9298 /**
9299  *      devlink_region_snapshot_id_get - get snapshot ID
9300  *
9301  *      This callback should be called when adding a new snapshot,
9302  *      Driver should use the same id for multiple snapshots taken
9303  *      on multiple regions at the same time/by the same trigger.
9304  *
9305  *      The caller of this function must use devlink_region_snapshot_id_put
9306  *      when finished creating regions using this id.
9307  *
9308  *      Returns zero on success, or a negative error code on failure.
9309  *
9310  *      @devlink: devlink
9311  *      @id: storage to return id
9312  */
9313 int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
9314 {
9315         int err;
9316
9317         mutex_lock(&devlink->lock);
9318         err = __devlink_region_snapshot_id_get(devlink, id);
9319         mutex_unlock(&devlink->lock);
9320
9321         return err;
9322 }
9323 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get);
9324
9325 /**
9326  *      devlink_region_snapshot_id_put - put snapshot ID reference
9327  *
9328  *      This should be called by a driver after finishing creating snapshots
9329  *      with an id. Doing so ensures that the ID can later be released in the
9330  *      event that all snapshots using it have been destroyed.
9331  *
9332  *      @devlink: devlink
9333  *      @id: id to release reference on
9334  */
9335 void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id)
9336 {
9337         mutex_lock(&devlink->lock);
9338         __devlink_snapshot_id_decrement(devlink, id);
9339         mutex_unlock(&devlink->lock);
9340 }
9341 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put);
9342
9343 /**
9344  *      devlink_region_snapshot_create - create a new snapshot
9345  *      This will add a new snapshot of a region. The snapshot
9346  *      will be stored on the region struct and can be accessed
9347  *      from devlink. This is useful for future analyses of snapshots.
9348  *      Multiple snapshots can be created on a region.
9349  *      The @snapshot_id should be obtained using the getter function.
9350  *
9351  *      @region: devlink region of the snapshot
9352  *      @data: snapshot data
9353  *      @snapshot_id: snapshot id to be created
9354  */
9355 int devlink_region_snapshot_create(struct devlink_region *region,
9356                                    u8 *data, u32 snapshot_id)
9357 {
9358         struct devlink *devlink = region->devlink;
9359         int err;
9360
9361         mutex_lock(&devlink->lock);
9362         err = __devlink_region_snapshot_create(region, data, snapshot_id);
9363         mutex_unlock(&devlink->lock);
9364
9365         return err;
9366 }
9367 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create);
9368
9369 #define DEVLINK_TRAP(_id, _type)                                              \
9370         {                                                                     \
9371                 .type = DEVLINK_TRAP_TYPE_##_type,                            \
9372                 .id = DEVLINK_TRAP_GENERIC_ID_##_id,                          \
9373                 .name = DEVLINK_TRAP_GENERIC_NAME_##_id,                      \
9374         }
9375
9376 static const struct devlink_trap devlink_trap_generic[] = {
9377         DEVLINK_TRAP(SMAC_MC, DROP),
9378         DEVLINK_TRAP(VLAN_TAG_MISMATCH, DROP),
9379         DEVLINK_TRAP(INGRESS_VLAN_FILTER, DROP),
9380         DEVLINK_TRAP(INGRESS_STP_FILTER, DROP),
9381         DEVLINK_TRAP(EMPTY_TX_LIST, DROP),
9382         DEVLINK_TRAP(PORT_LOOPBACK_FILTER, DROP),
9383         DEVLINK_TRAP(BLACKHOLE_ROUTE, DROP),
9384         DEVLINK_TRAP(TTL_ERROR, EXCEPTION),
9385         DEVLINK_TRAP(TAIL_DROP, DROP),
9386         DEVLINK_TRAP(NON_IP_PACKET, DROP),
9387         DEVLINK_TRAP(UC_DIP_MC_DMAC, DROP),
9388         DEVLINK_TRAP(DIP_LB, DROP),
9389         DEVLINK_TRAP(SIP_MC, DROP),
9390         DEVLINK_TRAP(SIP_LB, DROP),
9391         DEVLINK_TRAP(CORRUPTED_IP_HDR, DROP),
9392         DEVLINK_TRAP(IPV4_SIP_BC, DROP),
9393         DEVLINK_TRAP(IPV6_MC_DIP_RESERVED_SCOPE, DROP),
9394         DEVLINK_TRAP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE, DROP),
9395         DEVLINK_TRAP(MTU_ERROR, EXCEPTION),
9396         DEVLINK_TRAP(UNRESOLVED_NEIGH, EXCEPTION),
9397         DEVLINK_TRAP(RPF, EXCEPTION),
9398         DEVLINK_TRAP(REJECT_ROUTE, EXCEPTION),
9399         DEVLINK_TRAP(IPV4_LPM_UNICAST_MISS, EXCEPTION),
9400         DEVLINK_TRAP(IPV6_LPM_UNICAST_MISS, EXCEPTION),
9401         DEVLINK_TRAP(NON_ROUTABLE, DROP),
9402         DEVLINK_TRAP(DECAP_ERROR, EXCEPTION),
9403         DEVLINK_TRAP(OVERLAY_SMAC_MC, DROP),
9404         DEVLINK_TRAP(INGRESS_FLOW_ACTION_DROP, DROP),
9405         DEVLINK_TRAP(EGRESS_FLOW_ACTION_DROP, DROP),
9406         DEVLINK_TRAP(STP, CONTROL),
9407         DEVLINK_TRAP(LACP, CONTROL),
9408         DEVLINK_TRAP(LLDP, CONTROL),
9409         DEVLINK_TRAP(IGMP_QUERY, CONTROL),
9410         DEVLINK_TRAP(IGMP_V1_REPORT, CONTROL),
9411         DEVLINK_TRAP(IGMP_V2_REPORT, CONTROL),
9412         DEVLINK_TRAP(IGMP_V3_REPORT, CONTROL),
9413         DEVLINK_TRAP(IGMP_V2_LEAVE, CONTROL),
9414         DEVLINK_TRAP(MLD_QUERY, CONTROL),
9415         DEVLINK_TRAP(MLD_V1_REPORT, CONTROL),
9416         DEVLINK_TRAP(MLD_V2_REPORT, CONTROL),
9417         DEVLINK_TRAP(MLD_V1_DONE, CONTROL),
9418         DEVLINK_TRAP(IPV4_DHCP, CONTROL),
9419         DEVLINK_TRAP(IPV6_DHCP, CONTROL),
9420         DEVLINK_TRAP(ARP_REQUEST, CONTROL),
9421         DEVLINK_TRAP(ARP_RESPONSE, CONTROL),
9422         DEVLINK_TRAP(ARP_OVERLAY, CONTROL),
9423         DEVLINK_TRAP(IPV6_NEIGH_SOLICIT, CONTROL),
9424         DEVLINK_TRAP(IPV6_NEIGH_ADVERT, CONTROL),
9425         DEVLINK_TRAP(IPV4_BFD, CONTROL),
9426         DEVLINK_TRAP(IPV6_BFD, CONTROL),
9427         DEVLINK_TRAP(IPV4_OSPF, CONTROL),
9428         DEVLINK_TRAP(IPV6_OSPF, CONTROL),
9429         DEVLINK_TRAP(IPV4_BGP, CONTROL),
9430         DEVLINK_TRAP(IPV6_BGP, CONTROL),
9431         DEVLINK_TRAP(IPV4_VRRP, CONTROL),
9432         DEVLINK_TRAP(IPV6_VRRP, CONTROL),
9433         DEVLINK_TRAP(IPV4_PIM, CONTROL),
9434         DEVLINK_TRAP(IPV6_PIM, CONTROL),
9435         DEVLINK_TRAP(UC_LB, CONTROL),
9436         DEVLINK_TRAP(LOCAL_ROUTE, CONTROL),
9437         DEVLINK_TRAP(EXTERNAL_ROUTE, CONTROL),
9438         DEVLINK_TRAP(IPV6_UC_DIP_LINK_LOCAL_SCOPE, CONTROL),
9439         DEVLINK_TRAP(IPV6_DIP_ALL_NODES, CONTROL),
9440         DEVLINK_TRAP(IPV6_DIP_ALL_ROUTERS, CONTROL),
9441         DEVLINK_TRAP(IPV6_ROUTER_SOLICIT, CONTROL),
9442         DEVLINK_TRAP(IPV6_ROUTER_ADVERT, CONTROL),
9443         DEVLINK_TRAP(IPV6_REDIRECT, CONTROL),
9444         DEVLINK_TRAP(IPV4_ROUTER_ALERT, CONTROL),
9445         DEVLINK_TRAP(IPV6_ROUTER_ALERT, CONTROL),
9446         DEVLINK_TRAP(PTP_EVENT, CONTROL),
9447         DEVLINK_TRAP(PTP_GENERAL, CONTROL),
9448         DEVLINK_TRAP(FLOW_ACTION_SAMPLE, CONTROL),
9449         DEVLINK_TRAP(FLOW_ACTION_TRAP, CONTROL),
9450         DEVLINK_TRAP(EARLY_DROP, DROP),
9451         DEVLINK_TRAP(VXLAN_PARSING, DROP),
9452         DEVLINK_TRAP(LLC_SNAP_PARSING, DROP),
9453         DEVLINK_TRAP(VLAN_PARSING, DROP),
9454         DEVLINK_TRAP(PPPOE_PPP_PARSING, DROP),
9455         DEVLINK_TRAP(MPLS_PARSING, DROP),
9456         DEVLINK_TRAP(ARP_PARSING, DROP),
9457         DEVLINK_TRAP(IP_1_PARSING, DROP),
9458         DEVLINK_TRAP(IP_N_PARSING, DROP),
9459         DEVLINK_TRAP(GRE_PARSING, DROP),
9460         DEVLINK_TRAP(UDP_PARSING, DROP),
9461         DEVLINK_TRAP(TCP_PARSING, DROP),
9462         DEVLINK_TRAP(IPSEC_PARSING, DROP),
9463         DEVLINK_TRAP(SCTP_PARSING, DROP),
9464         DEVLINK_TRAP(DCCP_PARSING, DROP),
9465         DEVLINK_TRAP(GTP_PARSING, DROP),
9466         DEVLINK_TRAP(ESP_PARSING, DROP),
9467 };
9468
9469 #define DEVLINK_TRAP_GROUP(_id)                                               \
9470         {                                                                     \
9471                 .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id,                    \
9472                 .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id,                \
9473         }
9474
9475 static const struct devlink_trap_group devlink_trap_group_generic[] = {
9476         DEVLINK_TRAP_GROUP(L2_DROPS),
9477         DEVLINK_TRAP_GROUP(L3_DROPS),
9478         DEVLINK_TRAP_GROUP(L3_EXCEPTIONS),
9479         DEVLINK_TRAP_GROUP(BUFFER_DROPS),
9480         DEVLINK_TRAP_GROUP(TUNNEL_DROPS),
9481         DEVLINK_TRAP_GROUP(ACL_DROPS),
9482         DEVLINK_TRAP_GROUP(STP),
9483         DEVLINK_TRAP_GROUP(LACP),
9484         DEVLINK_TRAP_GROUP(LLDP),
9485         DEVLINK_TRAP_GROUP(MC_SNOOPING),
9486         DEVLINK_TRAP_GROUP(DHCP),
9487         DEVLINK_TRAP_GROUP(NEIGH_DISCOVERY),
9488         DEVLINK_TRAP_GROUP(BFD),
9489         DEVLINK_TRAP_GROUP(OSPF),
9490         DEVLINK_TRAP_GROUP(BGP),
9491         DEVLINK_TRAP_GROUP(VRRP),
9492         DEVLINK_TRAP_GROUP(PIM),
9493         DEVLINK_TRAP_GROUP(UC_LB),
9494         DEVLINK_TRAP_GROUP(LOCAL_DELIVERY),
9495         DEVLINK_TRAP_GROUP(EXTERNAL_DELIVERY),
9496         DEVLINK_TRAP_GROUP(IPV6),
9497         DEVLINK_TRAP_GROUP(PTP_EVENT),
9498         DEVLINK_TRAP_GROUP(PTP_GENERAL),
9499         DEVLINK_TRAP_GROUP(ACL_SAMPLE),
9500         DEVLINK_TRAP_GROUP(ACL_TRAP),
9501         DEVLINK_TRAP_GROUP(PARSER_ERROR_DROPS),
9502 };
9503
9504 static int devlink_trap_generic_verify(const struct devlink_trap *trap)
9505 {
9506         if (trap->id > DEVLINK_TRAP_GENERIC_ID_MAX)
9507                 return -EINVAL;
9508
9509         if (strcmp(trap->name, devlink_trap_generic[trap->id].name))
9510                 return -EINVAL;
9511
9512         if (trap->type != devlink_trap_generic[trap->id].type)
9513                 return -EINVAL;
9514
9515         return 0;
9516 }
9517
9518 static int devlink_trap_driver_verify(const struct devlink_trap *trap)
9519 {
9520         int i;
9521
9522         if (trap->id <= DEVLINK_TRAP_GENERIC_ID_MAX)
9523                 return -EINVAL;
9524
9525         for (i = 0; i < ARRAY_SIZE(devlink_trap_generic); i++) {
9526                 if (!strcmp(trap->name, devlink_trap_generic[i].name))
9527                         return -EEXIST;
9528         }
9529
9530         return 0;
9531 }
9532
9533 static int devlink_trap_verify(const struct devlink_trap *trap)
9534 {
9535         if (!trap || !trap->name)
9536                 return -EINVAL;
9537
9538         if (trap->generic)
9539                 return devlink_trap_generic_verify(trap);
9540         else
9541                 return devlink_trap_driver_verify(trap);
9542 }
9543
9544 static int
9545 devlink_trap_group_generic_verify(const struct devlink_trap_group *group)
9546 {
9547         if (group->id > DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
9548                 return -EINVAL;
9549
9550         if (strcmp(group->name, devlink_trap_group_generic[group->id].name))
9551                 return -EINVAL;
9552
9553         return 0;
9554 }
9555
9556 static int
9557 devlink_trap_group_driver_verify(const struct devlink_trap_group *group)
9558 {
9559         int i;
9560
9561         if (group->id <= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
9562                 return -EINVAL;
9563
9564         for (i = 0; i < ARRAY_SIZE(devlink_trap_group_generic); i++) {
9565                 if (!strcmp(group->name, devlink_trap_group_generic[i].name))
9566                         return -EEXIST;
9567         }
9568
9569         return 0;
9570 }
9571
9572 static int devlink_trap_group_verify(const struct devlink_trap_group *group)
9573 {
9574         if (group->generic)
9575                 return devlink_trap_group_generic_verify(group);
9576         else
9577                 return devlink_trap_group_driver_verify(group);
9578 }
9579
9580 static void
9581 devlink_trap_group_notify(struct devlink *devlink,
9582                           const struct devlink_trap_group_item *group_item,
9583                           enum devlink_command cmd)
9584 {
9585         struct sk_buff *msg;
9586         int err;
9587
9588         WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_GROUP_NEW &&
9589                      cmd != DEVLINK_CMD_TRAP_GROUP_DEL);
9590
9591         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
9592         if (!msg)
9593                 return;
9594
9595         err = devlink_nl_trap_group_fill(msg, devlink, group_item, cmd, 0, 0,
9596                                          0);
9597         if (err) {
9598                 nlmsg_free(msg);
9599                 return;
9600         }
9601
9602         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
9603                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
9604 }
9605
9606 static int
9607 devlink_trap_item_group_link(struct devlink *devlink,
9608                              struct devlink_trap_item *trap_item)
9609 {
9610         u16 group_id = trap_item->trap->init_group_id;
9611         struct devlink_trap_group_item *group_item;
9612
9613         group_item = devlink_trap_group_item_lookup_by_id(devlink, group_id);
9614         if (WARN_ON_ONCE(!group_item))
9615                 return -EINVAL;
9616
9617         trap_item->group_item = group_item;
9618
9619         return 0;
9620 }
9621
9622 static void devlink_trap_notify(struct devlink *devlink,
9623                                 const struct devlink_trap_item *trap_item,
9624                                 enum devlink_command cmd)
9625 {
9626         struct sk_buff *msg;
9627         int err;
9628
9629         WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_NEW &&
9630                      cmd != DEVLINK_CMD_TRAP_DEL);
9631
9632         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
9633         if (!msg)
9634                 return;
9635
9636         err = devlink_nl_trap_fill(msg, devlink, trap_item, cmd, 0, 0, 0);
9637         if (err) {
9638                 nlmsg_free(msg);
9639                 return;
9640         }
9641
9642         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
9643                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
9644 }
9645
9646 static int
9647 devlink_trap_register(struct devlink *devlink,
9648                       const struct devlink_trap *trap, void *priv)
9649 {
9650         struct devlink_trap_item *trap_item;
9651         int err;
9652
9653         if (devlink_trap_item_lookup(devlink, trap->name))
9654                 return -EEXIST;
9655
9656         trap_item = kzalloc(sizeof(*trap_item), GFP_KERNEL);
9657         if (!trap_item)
9658                 return -ENOMEM;
9659
9660         trap_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
9661         if (!trap_item->stats) {
9662                 err = -ENOMEM;
9663                 goto err_stats_alloc;
9664         }
9665
9666         trap_item->trap = trap;
9667         trap_item->action = trap->init_action;
9668         trap_item->priv = priv;
9669
9670         err = devlink_trap_item_group_link(devlink, trap_item);
9671         if (err)
9672                 goto err_group_link;
9673
9674         err = devlink->ops->trap_init(devlink, trap, trap_item);
9675         if (err)
9676                 goto err_trap_init;
9677
9678         list_add_tail(&trap_item->list, &devlink->trap_list);
9679         devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
9680
9681         return 0;
9682
9683 err_trap_init:
9684 err_group_link:
9685         free_percpu(trap_item->stats);
9686 err_stats_alloc:
9687         kfree(trap_item);
9688         return err;
9689 }
9690
9691 static void devlink_trap_unregister(struct devlink *devlink,
9692                                     const struct devlink_trap *trap)
9693 {
9694         struct devlink_trap_item *trap_item;
9695
9696         trap_item = devlink_trap_item_lookup(devlink, trap->name);
9697         if (WARN_ON_ONCE(!trap_item))
9698                 return;
9699
9700         devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL);
9701         list_del(&trap_item->list);
9702         if (devlink->ops->trap_fini)
9703                 devlink->ops->trap_fini(devlink, trap, trap_item);
9704         free_percpu(trap_item->stats);
9705         kfree(trap_item);
9706 }
9707
9708 static void devlink_trap_disable(struct devlink *devlink,
9709                                  const struct devlink_trap *trap)
9710 {
9711         struct devlink_trap_item *trap_item;
9712
9713         trap_item = devlink_trap_item_lookup(devlink, trap->name);
9714         if (WARN_ON_ONCE(!trap_item))
9715                 return;
9716
9717         devlink->ops->trap_action_set(devlink, trap, DEVLINK_TRAP_ACTION_DROP,
9718                                       NULL);
9719         trap_item->action = DEVLINK_TRAP_ACTION_DROP;
9720 }
9721
9722 /**
9723  * devlink_traps_register - Register packet traps with devlink.
9724  * @devlink: devlink.
9725  * @traps: Packet traps.
9726  * @traps_count: Count of provided packet traps.
9727  * @priv: Driver private information.
9728  *
9729  * Return: Non-zero value on failure.
9730  */
9731 int devlink_traps_register(struct devlink *devlink,
9732                            const struct devlink_trap *traps,
9733                            size_t traps_count, void *priv)
9734 {
9735         int i, err;
9736
9737         if (!devlink->ops->trap_init || !devlink->ops->trap_action_set)
9738                 return -EINVAL;
9739
9740         mutex_lock(&devlink->lock);
9741         for (i = 0; i < traps_count; i++) {
9742                 const struct devlink_trap *trap = &traps[i];
9743
9744                 err = devlink_trap_verify(trap);
9745                 if (err)
9746                         goto err_trap_verify;
9747
9748                 err = devlink_trap_register(devlink, trap, priv);
9749                 if (err)
9750                         goto err_trap_register;
9751         }
9752         mutex_unlock(&devlink->lock);
9753
9754         return 0;
9755
9756 err_trap_register:
9757 err_trap_verify:
9758         for (i--; i >= 0; i--)
9759                 devlink_trap_unregister(devlink, &traps[i]);
9760         mutex_unlock(&devlink->lock);
9761         return err;
9762 }
9763 EXPORT_SYMBOL_GPL(devlink_traps_register);
9764
9765 /**
9766  * devlink_traps_unregister - Unregister packet traps from devlink.
9767  * @devlink: devlink.
9768  * @traps: Packet traps.
9769  * @traps_count: Count of provided packet traps.
9770  */
9771 void devlink_traps_unregister(struct devlink *devlink,
9772                               const struct devlink_trap *traps,
9773                               size_t traps_count)
9774 {
9775         int i;
9776
9777         mutex_lock(&devlink->lock);
9778         /* Make sure we do not have any packets in-flight while unregistering
9779          * traps by disabling all of them and waiting for a grace period.
9780          */
9781         for (i = traps_count - 1; i >= 0; i--)
9782                 devlink_trap_disable(devlink, &traps[i]);
9783         synchronize_rcu();
9784         for (i = traps_count - 1; i >= 0; i--)
9785                 devlink_trap_unregister(devlink, &traps[i]);
9786         mutex_unlock(&devlink->lock);
9787 }
9788 EXPORT_SYMBOL_GPL(devlink_traps_unregister);
9789
9790 static void
9791 devlink_trap_stats_update(struct devlink_stats __percpu *trap_stats,
9792                           size_t skb_len)
9793 {
9794         struct devlink_stats *stats;
9795
9796         stats = this_cpu_ptr(trap_stats);
9797         u64_stats_update_begin(&stats->syncp);
9798         stats->rx_bytes += skb_len;
9799         stats->rx_packets++;
9800         u64_stats_update_end(&stats->syncp);
9801 }
9802
9803 static void
9804 devlink_trap_report_metadata_set(struct devlink_trap_metadata *metadata,
9805                                  const struct devlink_trap_item *trap_item,
9806                                  struct devlink_port *in_devlink_port,
9807                                  const struct flow_action_cookie *fa_cookie)
9808 {
9809         metadata->trap_name = trap_item->trap->name;
9810         metadata->trap_group_name = trap_item->group_item->group->name;
9811         metadata->fa_cookie = fa_cookie;
9812         metadata->trap_type = trap_item->trap->type;
9813
9814         spin_lock(&in_devlink_port->type_lock);
9815         if (in_devlink_port->type == DEVLINK_PORT_TYPE_ETH)
9816                 metadata->input_dev = in_devlink_port->type_dev;
9817         spin_unlock(&in_devlink_port->type_lock);
9818 }
9819
9820 /**
9821  * devlink_trap_report - Report trapped packet to drop monitor.
9822  * @devlink: devlink.
9823  * @skb: Trapped packet.
9824  * @trap_ctx: Trap context.
9825  * @in_devlink_port: Input devlink port.
9826  * @fa_cookie: Flow action cookie. Could be NULL.
9827  */
9828 void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb,
9829                          void *trap_ctx, struct devlink_port *in_devlink_port,
9830                          const struct flow_action_cookie *fa_cookie)
9831
9832 {
9833         struct devlink_trap_item *trap_item = trap_ctx;
9834
9835         devlink_trap_stats_update(trap_item->stats, skb->len);
9836         devlink_trap_stats_update(trap_item->group_item->stats, skb->len);
9837
9838         if (trace_devlink_trap_report_enabled()) {
9839                 struct devlink_trap_metadata metadata = {};
9840
9841                 devlink_trap_report_metadata_set(&metadata, trap_item,
9842                                                  in_devlink_port, fa_cookie);
9843                 trace_devlink_trap_report(devlink, skb, &metadata);
9844         }
9845 }
9846 EXPORT_SYMBOL_GPL(devlink_trap_report);
9847
9848 /**
9849  * devlink_trap_ctx_priv - Trap context to driver private information.
9850  * @trap_ctx: Trap context.
9851  *
9852  * Return: Driver private information passed during registration.
9853  */
9854 void *devlink_trap_ctx_priv(void *trap_ctx)
9855 {
9856         struct devlink_trap_item *trap_item = trap_ctx;
9857
9858         return trap_item->priv;
9859 }
9860 EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv);
9861
9862 static int
9863 devlink_trap_group_item_policer_link(struct devlink *devlink,
9864                                      struct devlink_trap_group_item *group_item)
9865 {
9866         u32 policer_id = group_item->group->init_policer_id;
9867         struct devlink_trap_policer_item *policer_item;
9868
9869         if (policer_id == 0)
9870                 return 0;
9871
9872         policer_item = devlink_trap_policer_item_lookup(devlink, policer_id);
9873         if (WARN_ON_ONCE(!policer_item))
9874                 return -EINVAL;
9875
9876         group_item->policer_item = policer_item;
9877
9878         return 0;
9879 }
9880
9881 static int
9882 devlink_trap_group_register(struct devlink *devlink,
9883                             const struct devlink_trap_group *group)
9884 {
9885         struct devlink_trap_group_item *group_item;
9886         int err;
9887
9888         if (devlink_trap_group_item_lookup(devlink, group->name))
9889                 return -EEXIST;
9890
9891         group_item = kzalloc(sizeof(*group_item), GFP_KERNEL);
9892         if (!group_item)
9893                 return -ENOMEM;
9894
9895         group_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
9896         if (!group_item->stats) {
9897                 err = -ENOMEM;
9898                 goto err_stats_alloc;
9899         }
9900
9901         group_item->group = group;
9902
9903         err = devlink_trap_group_item_policer_link(devlink, group_item);
9904         if (err)
9905                 goto err_policer_link;
9906
9907         if (devlink->ops->trap_group_init) {
9908                 err = devlink->ops->trap_group_init(devlink, group);
9909                 if (err)
9910                         goto err_group_init;
9911         }
9912
9913         list_add_tail(&group_item->list, &devlink->trap_group_list);
9914         devlink_trap_group_notify(devlink, group_item,
9915                                   DEVLINK_CMD_TRAP_GROUP_NEW);
9916
9917         return 0;
9918
9919 err_group_init:
9920 err_policer_link:
9921         free_percpu(group_item->stats);
9922 err_stats_alloc:
9923         kfree(group_item);
9924         return err;
9925 }
9926
9927 static void
9928 devlink_trap_group_unregister(struct devlink *devlink,
9929                               const struct devlink_trap_group *group)
9930 {
9931         struct devlink_trap_group_item *group_item;
9932
9933         group_item = devlink_trap_group_item_lookup(devlink, group->name);
9934         if (WARN_ON_ONCE(!group_item))
9935                 return;
9936
9937         devlink_trap_group_notify(devlink, group_item,
9938                                   DEVLINK_CMD_TRAP_GROUP_DEL);
9939         list_del(&group_item->list);
9940         free_percpu(group_item->stats);
9941         kfree(group_item);
9942 }
9943
9944 /**
9945  * devlink_trap_groups_register - Register packet trap groups with devlink.
9946  * @devlink: devlink.
9947  * @groups: Packet trap groups.
9948  * @groups_count: Count of provided packet trap groups.
9949  *
9950  * Return: Non-zero value on failure.
9951  */
9952 int devlink_trap_groups_register(struct devlink *devlink,
9953                                  const struct devlink_trap_group *groups,
9954                                  size_t groups_count)
9955 {
9956         int i, err;
9957
9958         mutex_lock(&devlink->lock);
9959         for (i = 0; i < groups_count; i++) {
9960                 const struct devlink_trap_group *group = &groups[i];
9961
9962                 err = devlink_trap_group_verify(group);
9963                 if (err)
9964                         goto err_trap_group_verify;
9965
9966                 err = devlink_trap_group_register(devlink, group);
9967                 if (err)
9968                         goto err_trap_group_register;
9969         }
9970         mutex_unlock(&devlink->lock);
9971
9972         return 0;
9973
9974 err_trap_group_register:
9975 err_trap_group_verify:
9976         for (i--; i >= 0; i--)
9977                 devlink_trap_group_unregister(devlink, &groups[i]);
9978         mutex_unlock(&devlink->lock);
9979         return err;
9980 }
9981 EXPORT_SYMBOL_GPL(devlink_trap_groups_register);
9982
9983 /**
9984  * devlink_trap_groups_unregister - Unregister packet trap groups from devlink.
9985  * @devlink: devlink.
9986  * @groups: Packet trap groups.
9987  * @groups_count: Count of provided packet trap groups.
9988  */
9989 void devlink_trap_groups_unregister(struct devlink *devlink,
9990                                     const struct devlink_trap_group *groups,
9991                                     size_t groups_count)
9992 {
9993         int i;
9994
9995         mutex_lock(&devlink->lock);
9996         for (i = groups_count - 1; i >= 0; i--)
9997                 devlink_trap_group_unregister(devlink, &groups[i]);
9998         mutex_unlock(&devlink->lock);
9999 }
10000 EXPORT_SYMBOL_GPL(devlink_trap_groups_unregister);
10001
10002 static void
10003 devlink_trap_policer_notify(struct devlink *devlink,
10004                             const struct devlink_trap_policer_item *policer_item,
10005                             enum devlink_command cmd)
10006 {
10007         struct sk_buff *msg;
10008         int err;
10009
10010         WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_POLICER_NEW &&
10011                      cmd != DEVLINK_CMD_TRAP_POLICER_DEL);
10012
10013         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
10014         if (!msg)
10015                 return;
10016
10017         err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, cmd, 0,
10018                                            0, 0);
10019         if (err) {
10020                 nlmsg_free(msg);
10021                 return;
10022         }
10023
10024         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
10025                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
10026 }
10027
10028 static int
10029 devlink_trap_policer_register(struct devlink *devlink,
10030                               const struct devlink_trap_policer *policer)
10031 {
10032         struct devlink_trap_policer_item *policer_item;
10033         int err;
10034
10035         if (devlink_trap_policer_item_lookup(devlink, policer->id))
10036                 return -EEXIST;
10037
10038         policer_item = kzalloc(sizeof(*policer_item), GFP_KERNEL);
10039         if (!policer_item)
10040                 return -ENOMEM;
10041
10042         policer_item->policer = policer;
10043         policer_item->rate = policer->init_rate;
10044         policer_item->burst = policer->init_burst;
10045
10046         if (devlink->ops->trap_policer_init) {
10047                 err = devlink->ops->trap_policer_init(devlink, policer);
10048                 if (err)
10049                         goto err_policer_init;
10050         }
10051
10052         list_add_tail(&policer_item->list, &devlink->trap_policer_list);
10053         devlink_trap_policer_notify(devlink, policer_item,
10054                                     DEVLINK_CMD_TRAP_POLICER_NEW);
10055
10056         return 0;
10057
10058 err_policer_init:
10059         kfree(policer_item);
10060         return err;
10061 }
10062
10063 static void
10064 devlink_trap_policer_unregister(struct devlink *devlink,
10065                                 const struct devlink_trap_policer *policer)
10066 {
10067         struct devlink_trap_policer_item *policer_item;
10068
10069         policer_item = devlink_trap_policer_item_lookup(devlink, policer->id);
10070         if (WARN_ON_ONCE(!policer_item))
10071                 return;
10072
10073         devlink_trap_policer_notify(devlink, policer_item,
10074                                     DEVLINK_CMD_TRAP_POLICER_DEL);
10075         list_del(&policer_item->list);
10076         if (devlink->ops->trap_policer_fini)
10077                 devlink->ops->trap_policer_fini(devlink, policer);
10078         kfree(policer_item);
10079 }
10080
10081 /**
10082  * devlink_trap_policers_register - Register packet trap policers with devlink.
10083  * @devlink: devlink.
10084  * @policers: Packet trap policers.
10085  * @policers_count: Count of provided packet trap policers.
10086  *
10087  * Return: Non-zero value on failure.
10088  */
10089 int
10090 devlink_trap_policers_register(struct devlink *devlink,
10091                                const struct devlink_trap_policer *policers,
10092                                size_t policers_count)
10093 {
10094         int i, err;
10095
10096         mutex_lock(&devlink->lock);
10097         for (i = 0; i < policers_count; i++) {
10098                 const struct devlink_trap_policer *policer = &policers[i];
10099
10100                 if (WARN_ON(policer->id == 0 ||
10101                             policer->max_rate < policer->min_rate ||
10102                             policer->max_burst < policer->min_burst)) {
10103                         err = -EINVAL;
10104                         goto err_trap_policer_verify;
10105                 }
10106
10107                 err = devlink_trap_policer_register(devlink, policer);
10108                 if (err)
10109                         goto err_trap_policer_register;
10110         }
10111         mutex_unlock(&devlink->lock);
10112
10113         return 0;
10114
10115 err_trap_policer_register:
10116 err_trap_policer_verify:
10117         for (i--; i >= 0; i--)
10118                 devlink_trap_policer_unregister(devlink, &policers[i]);
10119         mutex_unlock(&devlink->lock);
10120         return err;
10121 }
10122 EXPORT_SYMBOL_GPL(devlink_trap_policers_register);
10123
10124 /**
10125  * devlink_trap_policers_unregister - Unregister packet trap policers from devlink.
10126  * @devlink: devlink.
10127  * @policers: Packet trap policers.
10128  * @policers_count: Count of provided packet trap policers.
10129  */
10130 void
10131 devlink_trap_policers_unregister(struct devlink *devlink,
10132                                  const struct devlink_trap_policer *policers,
10133                                  size_t policers_count)
10134 {
10135         int i;
10136
10137         mutex_lock(&devlink->lock);
10138         for (i = policers_count - 1; i >= 0; i--)
10139                 devlink_trap_policer_unregister(devlink, &policers[i]);
10140         mutex_unlock(&devlink->lock);
10141 }
10142 EXPORT_SYMBOL_GPL(devlink_trap_policers_unregister);
10143
10144 static void __devlink_compat_running_version(struct devlink *devlink,
10145                                              char *buf, size_t len)
10146 {
10147         const struct nlattr *nlattr;
10148         struct devlink_info_req req;
10149         struct sk_buff *msg;
10150         int rem, err;
10151
10152         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
10153         if (!msg)
10154                 return;
10155
10156         req.msg = msg;
10157         err = devlink->ops->info_get(devlink, &req, NULL);
10158         if (err)
10159                 goto free_msg;
10160
10161         nla_for_each_attr(nlattr, (void *)msg->data, msg->len, rem) {
10162                 const struct nlattr *kv;
10163                 int rem_kv;
10164
10165                 if (nla_type(nlattr) != DEVLINK_ATTR_INFO_VERSION_RUNNING)
10166                         continue;
10167
10168                 nla_for_each_nested(kv, nlattr, rem_kv) {
10169                         if (nla_type(kv) != DEVLINK_ATTR_INFO_VERSION_VALUE)
10170                                 continue;
10171
10172                         strlcat(buf, nla_data(kv), len);
10173                         strlcat(buf, " ", len);
10174                 }
10175         }
10176 free_msg:
10177         nlmsg_free(msg);
10178 }
10179
10180 void devlink_compat_running_version(struct net_device *dev,
10181                                     char *buf, size_t len)
10182 {
10183         struct devlink *devlink;
10184
10185         dev_hold(dev);
10186         rtnl_unlock();
10187
10188         devlink = netdev_to_devlink(dev);
10189         if (!devlink || !devlink->ops->info_get)
10190                 goto out;
10191
10192         mutex_lock(&devlink->lock);
10193         __devlink_compat_running_version(devlink, buf, len);
10194         mutex_unlock(&devlink->lock);
10195
10196 out:
10197         rtnl_lock();
10198         dev_put(dev);
10199 }
10200
10201 int devlink_compat_flash_update(struct net_device *dev, const char *file_name)
10202 {
10203         struct devlink_flash_update_params params = {};
10204         struct devlink *devlink;
10205         int ret;
10206
10207         dev_hold(dev);
10208         rtnl_unlock();
10209
10210         devlink = netdev_to_devlink(dev);
10211         if (!devlink || !devlink->ops->flash_update) {
10212                 ret = -EOPNOTSUPP;
10213                 goto out;
10214         }
10215
10216         params.file_name = file_name;
10217
10218         mutex_lock(&devlink->lock);
10219         ret = devlink->ops->flash_update(devlink, &params, NULL);
10220         mutex_unlock(&devlink->lock);
10221
10222 out:
10223         rtnl_lock();
10224         dev_put(dev);
10225
10226         return ret;
10227 }
10228
10229 int devlink_compat_phys_port_name_get(struct net_device *dev,
10230                                       char *name, size_t len)
10231 {
10232         struct devlink_port *devlink_port;
10233
10234         /* RTNL mutex is held here which ensures that devlink_port
10235          * instance cannot disappear in the middle. No need to take
10236          * any devlink lock as only permanent values are accessed.
10237          */
10238         ASSERT_RTNL();
10239
10240         devlink_port = netdev_to_devlink_port(dev);
10241         if (!devlink_port)
10242                 return -EOPNOTSUPP;
10243
10244         return __devlink_port_phys_port_name_get(devlink_port, name, len);
10245 }
10246
10247 int devlink_compat_switch_id_get(struct net_device *dev,
10248                                  struct netdev_phys_item_id *ppid)
10249 {
10250         struct devlink_port *devlink_port;
10251
10252         /* Caller must hold RTNL mutex or reference to dev, which ensures that
10253          * devlink_port instance cannot disappear in the middle. No need to take
10254          * any devlink lock as only permanent values are accessed.
10255          */
10256         devlink_port = netdev_to_devlink_port(dev);
10257         if (!devlink_port || !devlink_port->switch_port)
10258                 return -EOPNOTSUPP;
10259
10260         memcpy(ppid, &devlink_port->attrs.switch_id, sizeof(*ppid));
10261
10262         return 0;
10263 }
10264
10265 static void __net_exit devlink_pernet_pre_exit(struct net *net)
10266 {
10267         struct devlink *devlink;
10268         u32 actions_performed;
10269         int err;
10270
10271         /* In case network namespace is getting destroyed, reload
10272          * all devlink instances from this namespace into init_net.
10273          */
10274         mutex_lock(&devlink_mutex);
10275         list_for_each_entry(devlink, &devlink_list, list) {
10276                 if (net_eq(devlink_net(devlink), net)) {
10277                         if (WARN_ON(!devlink_reload_supported(devlink->ops)))
10278                                 continue;
10279                         err = devlink_reload(devlink, &init_net,
10280                                              DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
10281                                              DEVLINK_RELOAD_LIMIT_UNSPEC,
10282                                              &actions_performed, NULL);
10283                         if (err && err != -EOPNOTSUPP)
10284                                 pr_warn("Failed to reload devlink instance into init_net\n");
10285                 }
10286         }
10287         mutex_unlock(&devlink_mutex);
10288 }
10289
10290 static struct pernet_operations devlink_pernet_ops __net_initdata = {
10291         .pre_exit = devlink_pernet_pre_exit,
10292 };
10293
10294 static int __init devlink_init(void)
10295 {
10296         int err;
10297
10298         err = genl_register_family(&devlink_nl_family);
10299         if (err)
10300                 goto out;
10301         err = register_pernet_subsys(&devlink_pernet_ops);
10302
10303 out:
10304         WARN_ON(err);
10305         return err;
10306 }
10307
10308 subsys_initcall(devlink_init);