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