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