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