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