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