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