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