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