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