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