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