1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * net/core/devlink.c - Network physical/parent device Netlink interface
5 * Heavily inspired by net/wireless/
6 * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
7 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
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>
30 #include <net/devlink.h>
31 #define CREATE_TRACE_POINTS
32 #include <trace/events/devlink.h>
34 #define DEVLINK_RELOAD_STATS_ARRAY_SIZE \
35 (__DEVLINK_RELOAD_LIMIT_MAX * __DEVLINK_RELOAD_ACTION_MAX)
37 struct devlink_dev_stats {
38 u32 reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE];
39 u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE];
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;
61 struct xarray snapshot_ids;
62 struct devlink_dev_stats stats;
65 /* Serializes access to devlink instance specific objects such as
66 * port, sb, dpipe, resource, params, region, traps and more.
69 struct lock_class_key lock_key;
72 struct completion comp;
74 char priv[] __aligned(NETDEV_ALIGN);
77 struct devlink_linecard_ops;
78 struct devlink_linecard_type;
80 struct devlink_linecard {
81 struct list_head list;
82 struct devlink *devlink;
85 const struct devlink_linecard_ops *ops;
87 enum devlink_linecard_state state;
88 struct mutex state_lock; /* Protects state */
90 struct devlink_linecard_type *types;
91 unsigned int types_count;
92 struct devlink *nested_devlink;
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
106 * @resource_list: list of child resources
107 * @occ_get: occupancy getter callback
108 * @occ_get_priv: occupancy getter callback priv
110 struct devlink_resource {
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;
124 void *devlink_priv(struct devlink *devlink)
126 return &devlink->priv;
128 EXPORT_SYMBOL_GPL(devlink_priv);
130 struct devlink *priv_to_devlink(void *priv)
132 return container_of(priv, struct devlink, priv);
134 EXPORT_SYMBOL_GPL(priv_to_devlink);
136 struct device *devlink_to_dev(const struct devlink *devlink)
140 EXPORT_SYMBOL_GPL(devlink_to_dev);
142 static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = {
144 .name = "destination mac",
145 .id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
150 struct devlink_dpipe_header devlink_dpipe_header_ethernet = {
152 .id = DEVLINK_DPIPE_HEADER_ETHERNET,
153 .fields = devlink_dpipe_fields_ethernet,
154 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet),
157 EXPORT_SYMBOL_GPL(devlink_dpipe_header_ethernet);
159 static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = {
161 .name = "destination ip",
162 .id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP,
167 struct devlink_dpipe_header devlink_dpipe_header_ipv4 = {
169 .id = DEVLINK_DPIPE_HEADER_IPV4,
170 .fields = devlink_dpipe_fields_ipv4,
171 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4),
174 EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv4);
176 static struct devlink_dpipe_field devlink_dpipe_fields_ipv6[] = {
178 .name = "destination ip",
179 .id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP,
184 struct devlink_dpipe_header devlink_dpipe_header_ipv6 = {
186 .id = DEVLINK_DPIPE_HEADER_IPV6,
187 .fields = devlink_dpipe_fields_ipv6,
188 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv6),
191 EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv6);
193 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg);
194 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwerr);
195 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_trap_report);
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),
204 static DEFINE_XARRAY_FLAGS(devlinks, XA_FLAGS_ALLOC);
205 #define DEVLINK_REGISTERED XA_MARK_1
207 /* devlink instances are open to the access from the user space after
208 * devlink_register() call. Such logical barrier allows us to have certain
209 * expectations related to locking.
211 * Before *_register() - we are in initialization stage and no parallel
212 * access possible to the devlink instance. All drivers perform that phase
213 * by implicitly holding device_lock.
215 * After *_register() - users and driver can access devlink instance at
218 #define ASSERT_DEVLINK_REGISTERED(d) \
219 WARN_ON_ONCE(!xa_get_mark(&devlinks, (d)->index, DEVLINK_REGISTERED))
220 #define ASSERT_DEVLINK_NOT_REGISTERED(d) \
221 WARN_ON_ONCE(xa_get_mark(&devlinks, (d)->index, DEVLINK_REGISTERED))
225 * An overall lock guarding every operation coming from userspace.
227 static DEFINE_MUTEX(devlink_mutex);
229 struct net *devlink_net(const struct devlink *devlink)
231 return read_pnet(&devlink->_net);
233 EXPORT_SYMBOL_GPL(devlink_net);
235 static void __devlink_put_rcu(struct rcu_head *head)
237 struct devlink *devlink = container_of(head, struct devlink, rcu);
239 complete(&devlink->comp);
242 void devlink_put(struct devlink *devlink)
244 if (refcount_dec_and_test(&devlink->refcount))
245 /* Make sure unregister operation that may await the completion
246 * is unblocked only after all users are after the end of
249 call_rcu(&devlink->rcu, __devlink_put_rcu);
252 struct devlink *__must_check devlink_try_get(struct devlink *devlink)
254 if (refcount_inc_not_zero(&devlink->refcount))
259 void devl_assert_locked(struct devlink *devlink)
261 lockdep_assert_held(&devlink->lock);
263 EXPORT_SYMBOL_GPL(devl_assert_locked);
265 #ifdef CONFIG_LOCKDEP
266 /* For use in conjunction with LOCKDEP only e.g. rcu_dereference_protected() */
267 bool devl_lock_is_held(struct devlink *devlink)
269 return lockdep_is_held(&devlink->lock);
271 EXPORT_SYMBOL_GPL(devl_lock_is_held);
274 void devl_lock(struct devlink *devlink)
276 mutex_lock(&devlink->lock);
278 EXPORT_SYMBOL_GPL(devl_lock);
280 int devl_trylock(struct devlink *devlink)
282 return mutex_trylock(&devlink->lock);
284 EXPORT_SYMBOL_GPL(devl_trylock);
286 void devl_unlock(struct devlink *devlink)
288 mutex_unlock(&devlink->lock);
290 EXPORT_SYMBOL_GPL(devl_unlock);
292 static struct devlink *
293 devlinks_xa_find_get(struct net *net, unsigned long *indexp, xa_mark_t filter,
294 void * (*xa_find_fn)(struct xarray *, unsigned long *,
295 unsigned long, xa_mark_t))
297 struct devlink *devlink;
301 devlink = xa_find_fn(&devlinks, indexp, ULONG_MAX, DEVLINK_REGISTERED);
304 /* For a possible retry, the xa_find_after() should be always used */
305 xa_find_fn = xa_find_after;
306 if (!devlink_try_get(devlink))
308 if (!net_eq(devlink_net(devlink), net)) {
309 devlink_put(devlink);
317 static struct devlink *devlinks_xa_find_get_first(struct net *net,
318 unsigned long *indexp,
321 return devlinks_xa_find_get(net, indexp, filter, xa_find);
324 static struct devlink *devlinks_xa_find_get_next(struct net *net,
325 unsigned long *indexp,
328 return devlinks_xa_find_get(net, indexp, filter, xa_find_after);
331 /* Iterate over devlink pointers which were possible to get reference to.
332 * devlink_put() needs to be called for each iterated devlink pointer
333 * in loop body in order to release the reference.
335 #define devlinks_xa_for_each_get(net, index, devlink, filter) \
337 devlink = devlinks_xa_find_get_first(net, &index, filter); \
338 devlink; devlink = devlinks_xa_find_get_next(net, &index, filter))
340 #define devlinks_xa_for_each_registered_get(net, index, devlink) \
341 devlinks_xa_for_each_get(net, index, devlink, DEVLINK_REGISTERED)
343 static struct devlink *devlink_get_from_attrs(struct net *net,
344 struct nlattr **attrs)
346 struct devlink *devlink;
351 if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME])
352 return ERR_PTR(-EINVAL);
354 busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]);
355 devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
357 devlinks_xa_for_each_registered_get(net, index, devlink) {
358 if (strcmp(devlink->dev->bus->name, busname) == 0 &&
359 strcmp(dev_name(devlink->dev), devname) == 0)
361 devlink_put(devlink);
364 return ERR_PTR(-ENODEV);
367 static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
368 unsigned int port_index)
370 struct devlink_port *devlink_port;
372 list_for_each_entry(devlink_port, &devlink->port_list, list) {
373 if (devlink_port->index == port_index)
379 static bool devlink_port_index_exists(struct devlink *devlink,
380 unsigned int port_index)
382 return devlink_port_get_by_index(devlink, port_index);
385 static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
386 struct nlattr **attrs)
388 if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
389 u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
390 struct devlink_port *devlink_port;
392 devlink_port = devlink_port_get_by_index(devlink, port_index);
394 return ERR_PTR(-ENODEV);
397 return ERR_PTR(-EINVAL);
400 static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
401 struct genl_info *info)
403 return devlink_port_get_from_attrs(devlink, info->attrs);
407 devlink_rate_is_leaf(struct devlink_rate *devlink_rate)
409 return devlink_rate->type == DEVLINK_RATE_TYPE_LEAF;
413 devlink_rate_is_node(struct devlink_rate *devlink_rate)
415 return devlink_rate->type == DEVLINK_RATE_TYPE_NODE;
418 static struct devlink_rate *
419 devlink_rate_leaf_get_from_info(struct devlink *devlink, struct genl_info *info)
421 struct devlink_rate *devlink_rate;
422 struct devlink_port *devlink_port;
424 devlink_port = devlink_port_get_from_attrs(devlink, info->attrs);
425 if (IS_ERR(devlink_port))
426 return ERR_CAST(devlink_port);
427 devlink_rate = devlink_port->devlink_rate;
428 return devlink_rate ?: ERR_PTR(-ENODEV);
431 static struct devlink_rate *
432 devlink_rate_node_get_by_name(struct devlink *devlink, const char *node_name)
434 static struct devlink_rate *devlink_rate;
436 list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
437 if (devlink_rate_is_node(devlink_rate) &&
438 !strcmp(node_name, devlink_rate->name))
441 return ERR_PTR(-ENODEV);
444 static struct devlink_rate *
445 devlink_rate_node_get_from_attrs(struct devlink *devlink, struct nlattr **attrs)
447 const char *rate_node_name;
450 if (!attrs[DEVLINK_ATTR_RATE_NODE_NAME])
451 return ERR_PTR(-EINVAL);
452 rate_node_name = nla_data(attrs[DEVLINK_ATTR_RATE_NODE_NAME]);
453 len = strlen(rate_node_name);
454 /* Name cannot be empty or decimal number */
455 if (!len || strspn(rate_node_name, "0123456789") == len)
456 return ERR_PTR(-EINVAL);
458 return devlink_rate_node_get_by_name(devlink, rate_node_name);
461 static struct devlink_rate *
462 devlink_rate_node_get_from_info(struct devlink *devlink, struct genl_info *info)
464 return devlink_rate_node_get_from_attrs(devlink, info->attrs);
467 static struct devlink_rate *
468 devlink_rate_get_from_info(struct devlink *devlink, struct genl_info *info)
470 struct nlattr **attrs = info->attrs;
472 if (attrs[DEVLINK_ATTR_PORT_INDEX])
473 return devlink_rate_leaf_get_from_info(devlink, info);
474 else if (attrs[DEVLINK_ATTR_RATE_NODE_NAME])
475 return devlink_rate_node_get_from_info(devlink, info);
477 return ERR_PTR(-EINVAL);
480 static struct devlink_linecard *
481 devlink_linecard_get_by_index(struct devlink *devlink,
482 unsigned int linecard_index)
484 struct devlink_linecard *devlink_linecard;
486 list_for_each_entry(devlink_linecard, &devlink->linecard_list, list) {
487 if (devlink_linecard->index == linecard_index)
488 return devlink_linecard;
493 static bool devlink_linecard_index_exists(struct devlink *devlink,
494 unsigned int linecard_index)
496 return devlink_linecard_get_by_index(devlink, linecard_index);
499 static struct devlink_linecard *
500 devlink_linecard_get_from_attrs(struct devlink *devlink, struct nlattr **attrs)
502 if (attrs[DEVLINK_ATTR_LINECARD_INDEX]) {
503 u32 linecard_index = nla_get_u32(attrs[DEVLINK_ATTR_LINECARD_INDEX]);
504 struct devlink_linecard *linecard;
506 mutex_lock(&devlink->linecards_lock);
507 linecard = devlink_linecard_get_by_index(devlink, linecard_index);
509 refcount_inc(&linecard->refcount);
510 mutex_unlock(&devlink->linecards_lock);
512 return ERR_PTR(-ENODEV);
515 return ERR_PTR(-EINVAL);
518 static struct devlink_linecard *
519 devlink_linecard_get_from_info(struct devlink *devlink, struct genl_info *info)
521 return devlink_linecard_get_from_attrs(devlink, info->attrs);
524 static void devlink_linecard_put(struct devlink_linecard *linecard)
526 if (refcount_dec_and_test(&linecard->refcount)) {
527 mutex_destroy(&linecard->state_lock);
533 struct list_head list;
536 u16 ingress_pools_count;
537 u16 egress_pools_count;
538 u16 ingress_tc_count;
542 static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb)
544 return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count;
547 static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink,
548 unsigned int sb_index)
550 struct devlink_sb *devlink_sb;
552 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
553 if (devlink_sb->index == sb_index)
559 static bool devlink_sb_index_exists(struct devlink *devlink,
560 unsigned int sb_index)
562 return devlink_sb_get_by_index(devlink, sb_index);
565 static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink,
566 struct nlattr **attrs)
568 if (attrs[DEVLINK_ATTR_SB_INDEX]) {
569 u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]);
570 struct devlink_sb *devlink_sb;
572 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
574 return ERR_PTR(-ENODEV);
577 return ERR_PTR(-EINVAL);
580 static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink,
581 struct genl_info *info)
583 return devlink_sb_get_from_attrs(devlink, info->attrs);
586 static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb,
587 struct nlattr **attrs,
592 if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX])
595 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]);
596 if (val >= devlink_sb_pool_count(devlink_sb))
602 static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb,
603 struct genl_info *info,
606 return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs,
611 devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs,
612 enum devlink_sb_pool_type *p_pool_type)
616 if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE])
619 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]);
620 if (val != DEVLINK_SB_POOL_TYPE_INGRESS &&
621 val != DEVLINK_SB_POOL_TYPE_EGRESS)
628 devlink_sb_pool_type_get_from_info(struct genl_info *info,
629 enum devlink_sb_pool_type *p_pool_type)
631 return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type);
635 devlink_sb_th_type_get_from_attrs(struct nlattr **attrs,
636 enum devlink_sb_threshold_type *p_th_type)
640 if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])
643 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]);
644 if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC &&
645 val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC)
652 devlink_sb_th_type_get_from_info(struct genl_info *info,
653 enum devlink_sb_threshold_type *p_th_type)
655 return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type);
659 devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb,
660 struct nlattr **attrs,
661 enum devlink_sb_pool_type pool_type,
666 if (!attrs[DEVLINK_ATTR_SB_TC_INDEX])
669 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]);
670 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS &&
671 val >= devlink_sb->ingress_tc_count)
673 if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS &&
674 val >= devlink_sb->egress_tc_count)
681 devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
682 struct genl_info *info,
683 enum devlink_sb_pool_type pool_type,
686 return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs,
687 pool_type, p_tc_index);
690 struct devlink_region {
691 struct devlink *devlink;
692 struct devlink_port *port;
693 struct list_head list;
695 const struct devlink_region_ops *ops;
696 const struct devlink_port_region_ops *port_ops;
698 struct list_head snapshot_list;
704 struct devlink_snapshot {
705 struct list_head list;
706 struct devlink_region *region;
711 static struct devlink_region *
712 devlink_region_get_by_name(struct devlink *devlink, const char *region_name)
714 struct devlink_region *region;
716 list_for_each_entry(region, &devlink->region_list, list)
717 if (!strcmp(region->ops->name, region_name))
723 static struct devlink_region *
724 devlink_port_region_get_by_name(struct devlink_port *port,
725 const char *region_name)
727 struct devlink_region *region;
729 list_for_each_entry(region, &port->region_list, list)
730 if (!strcmp(region->ops->name, region_name))
736 static struct devlink_snapshot *
737 devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id)
739 struct devlink_snapshot *snapshot;
741 list_for_each_entry(snapshot, ®ion->snapshot_list, list)
742 if (snapshot->id == id)
748 #define DEVLINK_NL_FLAG_NEED_PORT BIT(0)
749 #define DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT BIT(1)
750 #define DEVLINK_NL_FLAG_NEED_RATE BIT(2)
751 #define DEVLINK_NL_FLAG_NEED_RATE_NODE BIT(3)
752 #define DEVLINK_NL_FLAG_NEED_LINECARD BIT(4)
754 /* The per devlink instance lock is taken by default in the pre-doit
755 * operation, yet several commands do not require this. The global
756 * devlink lock is taken and protects from disruption by user-calls.
758 #define DEVLINK_NL_FLAG_NO_LOCK BIT(5)
760 static int devlink_nl_pre_doit(const struct genl_ops *ops,
761 struct sk_buff *skb, struct genl_info *info)
763 struct devlink_linecard *linecard;
764 struct devlink_port *devlink_port;
765 struct devlink *devlink;
768 mutex_lock(&devlink_mutex);
769 devlink = devlink_get_from_attrs(genl_info_net(info), info->attrs);
770 if (IS_ERR(devlink)) {
771 mutex_unlock(&devlink_mutex);
772 return PTR_ERR(devlink);
774 if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
776 info->user_ptr[0] = devlink;
777 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) {
778 devlink_port = devlink_port_get_from_info(devlink, info);
779 if (IS_ERR(devlink_port)) {
780 err = PTR_ERR(devlink_port);
783 info->user_ptr[1] = devlink_port;
784 } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT) {
785 devlink_port = devlink_port_get_from_info(devlink, info);
786 if (!IS_ERR(devlink_port))
787 info->user_ptr[1] = devlink_port;
788 } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_RATE) {
789 struct devlink_rate *devlink_rate;
791 devlink_rate = devlink_rate_get_from_info(devlink, info);
792 if (IS_ERR(devlink_rate)) {
793 err = PTR_ERR(devlink_rate);
796 info->user_ptr[1] = devlink_rate;
797 } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_RATE_NODE) {
798 struct devlink_rate *rate_node;
800 rate_node = devlink_rate_node_get_from_info(devlink, info);
801 if (IS_ERR(rate_node)) {
802 err = PTR_ERR(rate_node);
805 info->user_ptr[1] = rate_node;
806 } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_LINECARD) {
807 linecard = devlink_linecard_get_from_info(devlink, info);
808 if (IS_ERR(linecard)) {
809 err = PTR_ERR(linecard);
812 info->user_ptr[1] = linecard;
817 if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
818 devl_unlock(devlink);
819 devlink_put(devlink);
820 mutex_unlock(&devlink_mutex);
824 static void devlink_nl_post_doit(const struct genl_ops *ops,
825 struct sk_buff *skb, struct genl_info *info)
827 struct devlink_linecard *linecard;
828 struct devlink *devlink;
830 devlink = info->user_ptr[0];
831 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_LINECARD) {
832 linecard = info->user_ptr[1];
833 devlink_linecard_put(linecard);
835 if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
836 devl_unlock(devlink);
837 devlink_put(devlink);
838 mutex_unlock(&devlink_mutex);
841 static struct genl_family devlink_nl_family;
843 enum devlink_multicast_groups {
844 DEVLINK_MCGRP_CONFIG,
847 static const struct genl_multicast_group devlink_nl_mcgrps[] = {
848 [DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME },
851 static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
853 if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name))
855 if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev)))
860 static int devlink_nl_put_nested_handle(struct sk_buff *msg, struct devlink *devlink)
862 struct nlattr *nested_attr;
864 nested_attr = nla_nest_start(msg, DEVLINK_ATTR_NESTED_DEVLINK);
867 if (devlink_nl_put_handle(msg, devlink))
868 goto nla_put_failure;
870 nla_nest_end(msg, nested_attr);
874 nla_nest_cancel(msg, nested_attr);
878 struct devlink_reload_combination {
879 enum devlink_reload_action action;
880 enum devlink_reload_limit limit;
883 static const struct devlink_reload_combination devlink_reload_invalid_combinations[] = {
885 /* can't reinitialize driver with no down time */
886 .action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
887 .limit = DEVLINK_RELOAD_LIMIT_NO_RESET,
892 devlink_reload_combination_is_invalid(enum devlink_reload_action action,
893 enum devlink_reload_limit limit)
897 for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++)
898 if (devlink_reload_invalid_combinations[i].action == action &&
899 devlink_reload_invalid_combinations[i].limit == limit)
905 devlink_reload_action_is_supported(struct devlink *devlink, enum devlink_reload_action action)
907 return test_bit(action, &devlink->ops->reload_actions);
911 devlink_reload_limit_is_supported(struct devlink *devlink, enum devlink_reload_limit limit)
913 return test_bit(limit, &devlink->ops->reload_limits);
916 static int devlink_reload_stat_put(struct sk_buff *msg,
917 enum devlink_reload_limit limit, u32 value)
919 struct nlattr *reload_stats_entry;
921 reload_stats_entry = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS_ENTRY);
922 if (!reload_stats_entry)
925 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_STATS_LIMIT, limit) ||
926 nla_put_u32(msg, DEVLINK_ATTR_RELOAD_STATS_VALUE, value))
927 goto nla_put_failure;
928 nla_nest_end(msg, reload_stats_entry);
932 nla_nest_cancel(msg, reload_stats_entry);
936 static int devlink_reload_stats_put(struct sk_buff *msg, struct devlink *devlink, bool is_remote)
938 struct nlattr *reload_stats_attr, *act_info, *act_stats;
943 reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS);
945 reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_REMOTE_RELOAD_STATS);
947 if (!reload_stats_attr)
950 for (i = 0; i <= DEVLINK_RELOAD_ACTION_MAX; i++) {
952 !devlink_reload_action_is_supported(devlink, i)) ||
953 i == DEVLINK_RELOAD_ACTION_UNSPEC)
955 act_info = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_INFO);
957 goto nla_put_failure;
959 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_ACTION, i))
960 goto action_info_nest_cancel;
961 act_stats = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_STATS);
963 goto action_info_nest_cancel;
965 for (j = 0; j <= DEVLINK_RELOAD_LIMIT_MAX; j++) {
966 /* Remote stats are shown even if not locally supported.
967 * Stats of actions with unspecified limit are shown
968 * though drivers don't need to register unspecified
971 if ((!is_remote && j != DEVLINK_RELOAD_LIMIT_UNSPEC &&
972 !devlink_reload_limit_is_supported(devlink, j)) ||
973 devlink_reload_combination_is_invalid(i, j))
976 stat_idx = j * __DEVLINK_RELOAD_ACTION_MAX + i;
978 value = devlink->stats.reload_stats[stat_idx];
980 value = devlink->stats.remote_reload_stats[stat_idx];
981 if (devlink_reload_stat_put(msg, j, value))
982 goto action_stats_nest_cancel;
984 nla_nest_end(msg, act_stats);
985 nla_nest_end(msg, act_info);
987 nla_nest_end(msg, reload_stats_attr);
990 action_stats_nest_cancel:
991 nla_nest_cancel(msg, act_stats);
992 action_info_nest_cancel:
993 nla_nest_cancel(msg, act_info);
995 nla_nest_cancel(msg, reload_stats_attr);
999 static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
1000 enum devlink_command cmd, u32 portid,
1003 struct nlattr *dev_stats;
1006 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1010 if (devlink_nl_put_handle(msg, devlink))
1011 goto nla_put_failure;
1012 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_FAILED, devlink->reload_failed))
1013 goto nla_put_failure;
1015 dev_stats = nla_nest_start(msg, DEVLINK_ATTR_DEV_STATS);
1017 goto nla_put_failure;
1019 if (devlink_reload_stats_put(msg, devlink, false))
1020 goto dev_stats_nest_cancel;
1021 if (devlink_reload_stats_put(msg, devlink, true))
1022 goto dev_stats_nest_cancel;
1024 nla_nest_end(msg, dev_stats);
1025 genlmsg_end(msg, hdr);
1028 dev_stats_nest_cancel:
1029 nla_nest_cancel(msg, dev_stats);
1031 genlmsg_cancel(msg, hdr);
1035 static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
1037 struct sk_buff *msg;
1040 WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
1041 WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED));
1043 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1047 err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0);
1053 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
1054 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
1057 static int devlink_nl_port_attrs_put(struct sk_buff *msg,
1058 struct devlink_port *devlink_port)
1060 struct devlink_port_attrs *attrs = &devlink_port->attrs;
1062 if (!devlink_port->attrs_set)
1065 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_LANES, attrs->lanes))
1068 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_SPLITTABLE, attrs->splittable))
1070 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour))
1072 switch (devlink_port->attrs.flavour) {
1073 case DEVLINK_PORT_FLAVOUR_PCI_PF:
1074 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
1075 attrs->pci_pf.controller) ||
1076 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_pf.pf))
1078 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_pf.external))
1081 case DEVLINK_PORT_FLAVOUR_PCI_VF:
1082 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
1083 attrs->pci_vf.controller) ||
1084 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_vf.pf) ||
1085 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_VF_NUMBER, attrs->pci_vf.vf))
1087 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_vf.external))
1090 case DEVLINK_PORT_FLAVOUR_PCI_SF:
1091 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
1092 attrs->pci_sf.controller) ||
1093 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER,
1094 attrs->pci_sf.pf) ||
1095 nla_put_u32(msg, DEVLINK_ATTR_PORT_PCI_SF_NUMBER,
1099 case DEVLINK_PORT_FLAVOUR_PHYSICAL:
1100 case DEVLINK_PORT_FLAVOUR_CPU:
1101 case DEVLINK_PORT_FLAVOUR_DSA:
1102 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER,
1103 attrs->phys.port_number))
1107 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
1108 attrs->phys.port_number))
1110 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER,
1111 attrs->phys.split_subport_number))
1120 static int devlink_port_fn_hw_addr_fill(const struct devlink_ops *ops,
1121 struct devlink_port *port,
1122 struct sk_buff *msg,
1123 struct netlink_ext_ack *extack,
1126 u8 hw_addr[MAX_ADDR_LEN];
1130 if (!ops->port_function_hw_addr_get)
1133 err = ops->port_function_hw_addr_get(port, hw_addr, &hw_addr_len,
1136 if (err == -EOPNOTSUPP)
1140 err = nla_put(msg, DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR, hw_addr_len, hw_addr);
1143 *msg_updated = true;
1147 static int devlink_nl_rate_fill(struct sk_buff *msg,
1148 struct devlink_rate *devlink_rate,
1149 enum devlink_command cmd, u32 portid, u32 seq,
1150 int flags, struct netlink_ext_ack *extack)
1152 struct devlink *devlink = devlink_rate->devlink;
1155 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1159 if (devlink_nl_put_handle(msg, devlink))
1160 goto nla_put_failure;
1162 if (nla_put_u16(msg, DEVLINK_ATTR_RATE_TYPE, devlink_rate->type))
1163 goto nla_put_failure;
1165 if (devlink_rate_is_leaf(devlink_rate)) {
1166 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
1167 devlink_rate->devlink_port->index))
1168 goto nla_put_failure;
1169 } else if (devlink_rate_is_node(devlink_rate)) {
1170 if (nla_put_string(msg, DEVLINK_ATTR_RATE_NODE_NAME,
1171 devlink_rate->name))
1172 goto nla_put_failure;
1175 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_RATE_TX_SHARE,
1176 devlink_rate->tx_share, DEVLINK_ATTR_PAD))
1177 goto nla_put_failure;
1179 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_RATE_TX_MAX,
1180 devlink_rate->tx_max, DEVLINK_ATTR_PAD))
1181 goto nla_put_failure;
1183 if (devlink_rate->parent)
1184 if (nla_put_string(msg, DEVLINK_ATTR_RATE_PARENT_NODE_NAME,
1185 devlink_rate->parent->name))
1186 goto nla_put_failure;
1188 genlmsg_end(msg, hdr);
1192 genlmsg_cancel(msg, hdr);
1197 devlink_port_fn_state_valid(enum devlink_port_fn_state state)
1199 return state == DEVLINK_PORT_FN_STATE_INACTIVE ||
1200 state == DEVLINK_PORT_FN_STATE_ACTIVE;
1204 devlink_port_fn_opstate_valid(enum devlink_port_fn_opstate opstate)
1206 return opstate == DEVLINK_PORT_FN_OPSTATE_DETACHED ||
1207 opstate == DEVLINK_PORT_FN_OPSTATE_ATTACHED;
1210 static int devlink_port_fn_state_fill(const struct devlink_ops *ops,
1211 struct devlink_port *port,
1212 struct sk_buff *msg,
1213 struct netlink_ext_ack *extack,
1216 enum devlink_port_fn_opstate opstate;
1217 enum devlink_port_fn_state state;
1220 if (!ops->port_fn_state_get)
1223 err = ops->port_fn_state_get(port, &state, &opstate, extack);
1225 if (err == -EOPNOTSUPP)
1229 if (!devlink_port_fn_state_valid(state)) {
1231 NL_SET_ERR_MSG_MOD(extack, "Invalid state read from driver");
1234 if (!devlink_port_fn_opstate_valid(opstate)) {
1236 NL_SET_ERR_MSG_MOD(extack,
1237 "Invalid operational state read from driver");
1240 if (nla_put_u8(msg, DEVLINK_PORT_FN_ATTR_STATE, state) ||
1241 nla_put_u8(msg, DEVLINK_PORT_FN_ATTR_OPSTATE, opstate))
1243 *msg_updated = true;
1248 devlink_nl_port_function_attrs_put(struct sk_buff *msg, struct devlink_port *port,
1249 struct netlink_ext_ack *extack)
1251 const struct devlink_ops *ops;
1252 struct nlattr *function_attr;
1253 bool msg_updated = false;
1256 function_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PORT_FUNCTION);
1260 ops = port->devlink->ops;
1261 err = devlink_port_fn_hw_addr_fill(ops, port, msg, extack,
1265 err = devlink_port_fn_state_fill(ops, port, msg, extack, &msg_updated);
1267 if (err || !msg_updated)
1268 nla_nest_cancel(msg, function_attr);
1270 nla_nest_end(msg, function_attr);
1274 static int devlink_nl_port_fill(struct sk_buff *msg,
1275 struct devlink_port *devlink_port,
1276 enum devlink_command cmd, u32 portid, u32 seq,
1277 int flags, struct netlink_ext_ack *extack)
1279 struct devlink *devlink = devlink_port->devlink;
1282 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1286 if (devlink_nl_put_handle(msg, devlink))
1287 goto nla_put_failure;
1288 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1289 goto nla_put_failure;
1291 /* Hold rtnl lock while accessing port's netdev attributes. */
1293 spin_lock_bh(&devlink_port->type_lock);
1294 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
1295 goto nla_put_failure_type_locked;
1296 if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
1297 nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
1298 devlink_port->desired_type))
1299 goto nla_put_failure_type_locked;
1300 if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
1301 struct net *net = devlink_net(devlink_port->devlink);
1302 struct net_device *netdev = devlink_port->type_dev;
1304 if (netdev && net_eq(net, dev_net(netdev)) &&
1305 (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
1307 nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
1309 goto nla_put_failure_type_locked;
1311 if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
1312 struct ib_device *ibdev = devlink_port->type_dev;
1315 nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
1317 goto nla_put_failure_type_locked;
1319 spin_unlock_bh(&devlink_port->type_lock);
1321 if (devlink_nl_port_attrs_put(msg, devlink_port))
1322 goto nla_put_failure;
1323 if (devlink_nl_port_function_attrs_put(msg, devlink_port, extack))
1324 goto nla_put_failure;
1325 if (devlink_port->linecard &&
1326 nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX,
1327 devlink_port->linecard->index))
1328 goto nla_put_failure;
1330 genlmsg_end(msg, hdr);
1333 nla_put_failure_type_locked:
1334 spin_unlock_bh(&devlink_port->type_lock);
1337 genlmsg_cancel(msg, hdr);
1341 static void devlink_port_notify(struct devlink_port *devlink_port,
1342 enum devlink_command cmd)
1344 struct devlink *devlink = devlink_port->devlink;
1345 struct sk_buff *msg;
1348 WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
1350 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
1353 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1357 err = devlink_nl_port_fill(msg, devlink_port, cmd, 0, 0, 0, NULL);
1363 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
1364 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
1367 static void devlink_rate_notify(struct devlink_rate *devlink_rate,
1368 enum devlink_command cmd)
1370 struct devlink *devlink = devlink_rate->devlink;
1371 struct sk_buff *msg;
1374 WARN_ON(cmd != DEVLINK_CMD_RATE_NEW && cmd != DEVLINK_CMD_RATE_DEL);
1376 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
1379 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1383 err = devlink_nl_rate_fill(msg, devlink_rate, cmd, 0, 0, 0, NULL);
1389 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
1390 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
1393 static int devlink_nl_cmd_rate_get_dumpit(struct sk_buff *msg,
1394 struct netlink_callback *cb)
1396 struct devlink_rate *devlink_rate;
1397 struct devlink *devlink;
1398 int start = cb->args[0];
1399 unsigned long index;
1403 mutex_lock(&devlink_mutex);
1404 devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
1406 list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
1407 enum devlink_command cmd = DEVLINK_CMD_RATE_NEW;
1408 u32 id = NETLINK_CB(cb->skb).portid;
1414 err = devlink_nl_rate_fill(msg, devlink_rate, cmd, id,
1418 devl_unlock(devlink);
1419 devlink_put(devlink);
1424 devl_unlock(devlink);
1425 devlink_put(devlink);
1428 mutex_unlock(&devlink_mutex);
1429 if (err != -EMSGSIZE)
1436 static int devlink_nl_cmd_rate_get_doit(struct sk_buff *skb,
1437 struct genl_info *info)
1439 struct devlink_rate *devlink_rate = info->user_ptr[1];
1440 struct sk_buff *msg;
1443 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1447 err = devlink_nl_rate_fill(msg, devlink_rate, DEVLINK_CMD_RATE_NEW,
1448 info->snd_portid, info->snd_seq, 0,
1455 return genlmsg_reply(msg, info);
1459 devlink_rate_is_parent_node(struct devlink_rate *devlink_rate,
1460 struct devlink_rate *parent)
1463 if (parent == devlink_rate)
1465 parent = parent->parent;
1470 static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
1472 struct devlink *devlink = info->user_ptr[0];
1473 struct sk_buff *msg;
1476 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1480 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
1481 info->snd_portid, info->snd_seq, 0);
1487 return genlmsg_reply(msg, info);
1490 static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
1491 struct netlink_callback *cb)
1493 struct devlink *devlink;
1494 int start = cb->args[0];
1495 unsigned long index;
1499 mutex_lock(&devlink_mutex);
1500 devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
1503 devlink_put(devlink);
1507 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
1508 NETLINK_CB(cb->skb).portid,
1509 cb->nlh->nlmsg_seq, NLM_F_MULTI);
1510 devlink_put(devlink);
1516 mutex_unlock(&devlink_mutex);
1522 static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
1523 struct genl_info *info)
1525 struct devlink_port *devlink_port = info->user_ptr[1];
1526 struct sk_buff *msg;
1529 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1533 err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_PORT_NEW,
1534 info->snd_portid, info->snd_seq, 0,
1541 return genlmsg_reply(msg, info);
1544 static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
1545 struct netlink_callback *cb)
1547 struct devlink *devlink;
1548 struct devlink_port *devlink_port;
1549 int start = cb->args[0];
1550 unsigned long index;
1554 mutex_lock(&devlink_mutex);
1555 devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
1557 list_for_each_entry(devlink_port, &devlink->port_list, list) {
1562 err = devlink_nl_port_fill(msg, devlink_port,
1564 NETLINK_CB(cb->skb).portid,
1566 NLM_F_MULTI, cb->extack);
1568 devl_unlock(devlink);
1569 devlink_put(devlink);
1574 devl_unlock(devlink);
1575 devlink_put(devlink);
1578 mutex_unlock(&devlink_mutex);
1584 static int devlink_port_type_set(struct devlink_port *devlink_port,
1585 enum devlink_port_type port_type)
1590 if (!devlink_port->devlink->ops->port_type_set)
1593 if (port_type == devlink_port->type)
1596 err = devlink_port->devlink->ops->port_type_set(devlink_port,
1601 devlink_port->desired_type = port_type;
1602 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
1606 static int devlink_port_function_hw_addr_set(struct devlink_port *port,
1607 const struct nlattr *attr,
1608 struct netlink_ext_ack *extack)
1610 const struct devlink_ops *ops = port->devlink->ops;
1614 hw_addr = nla_data(attr);
1615 hw_addr_len = nla_len(attr);
1616 if (hw_addr_len > MAX_ADDR_LEN) {
1617 NL_SET_ERR_MSG_MOD(extack, "Port function hardware address too long");
1620 if (port->type == DEVLINK_PORT_TYPE_ETH) {
1621 if (hw_addr_len != ETH_ALEN) {
1622 NL_SET_ERR_MSG_MOD(extack, "Address must be 6 bytes for Ethernet device");
1625 if (!is_unicast_ether_addr(hw_addr)) {
1626 NL_SET_ERR_MSG_MOD(extack, "Non-unicast hardware address unsupported");
1631 if (!ops->port_function_hw_addr_set) {
1632 NL_SET_ERR_MSG_MOD(extack, "Port doesn't support function attributes");
1636 return ops->port_function_hw_addr_set(port, hw_addr, hw_addr_len,
1640 static int devlink_port_fn_state_set(struct devlink_port *port,
1641 const struct nlattr *attr,
1642 struct netlink_ext_ack *extack)
1644 enum devlink_port_fn_state state;
1645 const struct devlink_ops *ops;
1647 state = nla_get_u8(attr);
1648 ops = port->devlink->ops;
1649 if (!ops->port_fn_state_set) {
1650 NL_SET_ERR_MSG_MOD(extack,
1651 "Function does not support state setting");
1654 return ops->port_fn_state_set(port, state, extack);
1657 static int devlink_port_function_set(struct devlink_port *port,
1658 const struct nlattr *attr,
1659 struct netlink_ext_ack *extack)
1661 struct nlattr *tb[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1];
1664 err = nla_parse_nested(tb, DEVLINK_PORT_FUNCTION_ATTR_MAX, attr,
1665 devlink_function_nl_policy, extack);
1667 NL_SET_ERR_MSG_MOD(extack, "Fail to parse port function attributes");
1671 attr = tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR];
1673 err = devlink_port_function_hw_addr_set(port, attr, extack);
1677 /* Keep this as the last function attribute set, so that when
1678 * multiple port function attributes are set along with state,
1679 * Those can be applied first before activating the state.
1681 attr = tb[DEVLINK_PORT_FN_ATTR_STATE];
1683 err = devlink_port_fn_state_set(port, attr, extack);
1686 devlink_port_notify(port, DEVLINK_CMD_PORT_NEW);
1690 static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
1691 struct genl_info *info)
1693 struct devlink_port *devlink_port = info->user_ptr[1];
1696 if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
1697 enum devlink_port_type port_type;
1699 port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
1700 err = devlink_port_type_set(devlink_port, port_type);
1705 if (info->attrs[DEVLINK_ATTR_PORT_FUNCTION]) {
1706 struct nlattr *attr = info->attrs[DEVLINK_ATTR_PORT_FUNCTION];
1707 struct netlink_ext_ack *extack = info->extack;
1709 err = devlink_port_function_set(devlink_port, attr, extack);
1717 static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
1718 struct genl_info *info)
1720 struct devlink_port *devlink_port = info->user_ptr[1];
1721 struct devlink *devlink = info->user_ptr[0];
1724 if (!info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT])
1726 if (!devlink->ops->port_split)
1729 count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
1731 if (!devlink_port->attrs.splittable) {
1732 /* Split ports cannot be split. */
1733 if (devlink_port->attrs.split)
1734 NL_SET_ERR_MSG_MOD(info->extack, "Port cannot be split further");
1736 NL_SET_ERR_MSG_MOD(info->extack, "Port cannot be split");
1740 if (count < 2 || !is_power_of_2(count) || count > devlink_port->attrs.lanes) {
1741 NL_SET_ERR_MSG_MOD(info->extack, "Invalid split count");
1745 return devlink->ops->port_split(devlink, devlink_port, count,
1749 static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
1750 struct genl_info *info)
1752 struct devlink_port *devlink_port = info->user_ptr[1];
1753 struct devlink *devlink = info->user_ptr[0];
1755 if (!devlink->ops->port_unsplit)
1757 return devlink->ops->port_unsplit(devlink, devlink_port, info->extack);
1760 static int devlink_port_new_notify(struct devlink *devlink,
1761 unsigned int port_index,
1762 struct genl_info *info)
1764 struct devlink_port *devlink_port;
1765 struct sk_buff *msg;
1768 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1772 lockdep_assert_held(&devlink->lock);
1773 devlink_port = devlink_port_get_by_index(devlink, port_index);
1774 if (!devlink_port) {
1779 err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_NEW,
1780 info->snd_portid, info->snd_seq, 0, NULL);
1784 return genlmsg_reply(msg, info);
1791 static int devlink_nl_cmd_port_new_doit(struct sk_buff *skb,
1792 struct genl_info *info)
1794 struct netlink_ext_ack *extack = info->extack;
1795 struct devlink_port_new_attrs new_attrs = {};
1796 struct devlink *devlink = info->user_ptr[0];
1797 unsigned int new_port_index;
1800 if (!devlink->ops->port_new || !devlink->ops->port_del)
1803 if (!info->attrs[DEVLINK_ATTR_PORT_FLAVOUR] ||
1804 !info->attrs[DEVLINK_ATTR_PORT_PCI_PF_NUMBER]) {
1805 NL_SET_ERR_MSG_MOD(extack, "Port flavour or PCI PF are not specified");
1808 new_attrs.flavour = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_FLAVOUR]);
1810 nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_PCI_PF_NUMBER]);
1812 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
1813 /* Port index of the new port being created by driver. */
1814 new_attrs.port_index =
1815 nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
1816 new_attrs.port_index_valid = true;
1818 if (info->attrs[DEVLINK_ATTR_PORT_CONTROLLER_NUMBER]) {
1819 new_attrs.controller =
1820 nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_CONTROLLER_NUMBER]);
1821 new_attrs.controller_valid = true;
1823 if (new_attrs.flavour == DEVLINK_PORT_FLAVOUR_PCI_SF &&
1824 info->attrs[DEVLINK_ATTR_PORT_PCI_SF_NUMBER]) {
1825 new_attrs.sfnum = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_PCI_SF_NUMBER]);
1826 new_attrs.sfnum_valid = true;
1829 err = devlink->ops->port_new(devlink, &new_attrs, extack,
1834 err = devlink_port_new_notify(devlink, new_port_index, info);
1835 if (err && err != -ENODEV) {
1836 /* Fail to send the response; destroy newly created port. */
1837 devlink->ops->port_del(devlink, new_port_index, extack);
1842 static int devlink_nl_cmd_port_del_doit(struct sk_buff *skb,
1843 struct genl_info *info)
1845 struct netlink_ext_ack *extack = info->extack;
1846 struct devlink *devlink = info->user_ptr[0];
1847 unsigned int port_index;
1849 if (!devlink->ops->port_del)
1852 if (!info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
1853 NL_SET_ERR_MSG_MOD(extack, "Port index is not specified");
1856 port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
1858 return devlink->ops->port_del(devlink, port_index, extack);
1862 devlink_nl_rate_parent_node_set(struct devlink_rate *devlink_rate,
1863 struct genl_info *info,
1864 struct nlattr *nla_parent)
1866 struct devlink *devlink = devlink_rate->devlink;
1867 const char *parent_name = nla_data(nla_parent);
1868 const struct devlink_ops *ops = devlink->ops;
1869 size_t len = strlen(parent_name);
1870 struct devlink_rate *parent;
1871 int err = -EOPNOTSUPP;
1873 parent = devlink_rate->parent;
1874 if (parent && len) {
1875 NL_SET_ERR_MSG_MOD(info->extack, "Rate object already has parent.");
1877 } else if (parent && !len) {
1878 if (devlink_rate_is_leaf(devlink_rate))
1879 err = ops->rate_leaf_parent_set(devlink_rate, NULL,
1880 devlink_rate->priv, NULL,
1882 else if (devlink_rate_is_node(devlink_rate))
1883 err = ops->rate_node_parent_set(devlink_rate, NULL,
1884 devlink_rate->priv, NULL,
1889 refcount_dec(&parent->refcnt);
1890 devlink_rate->parent = NULL;
1891 } else if (!parent && len) {
1892 parent = devlink_rate_node_get_by_name(devlink, parent_name);
1896 if (parent == devlink_rate) {
1897 NL_SET_ERR_MSG_MOD(info->extack, "Parent to self is not allowed");
1901 if (devlink_rate_is_node(devlink_rate) &&
1902 devlink_rate_is_parent_node(devlink_rate, parent->parent)) {
1903 NL_SET_ERR_MSG_MOD(info->extack, "Node is already a parent of parent node.");
1907 if (devlink_rate_is_leaf(devlink_rate))
1908 err = ops->rate_leaf_parent_set(devlink_rate, parent,
1909 devlink_rate->priv, parent->priv,
1911 else if (devlink_rate_is_node(devlink_rate))
1912 err = ops->rate_node_parent_set(devlink_rate, parent,
1913 devlink_rate->priv, parent->priv,
1918 refcount_inc(&parent->refcnt);
1919 devlink_rate->parent = parent;
1925 static int devlink_nl_rate_set(struct devlink_rate *devlink_rate,
1926 const struct devlink_ops *ops,
1927 struct genl_info *info)
1929 struct nlattr *nla_parent, **attrs = info->attrs;
1930 int err = -EOPNOTSUPP;
1933 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE]) {
1934 rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_SHARE]);
1935 if (devlink_rate_is_leaf(devlink_rate))
1936 err = ops->rate_leaf_tx_share_set(devlink_rate, devlink_rate->priv,
1937 rate, info->extack);
1938 else if (devlink_rate_is_node(devlink_rate))
1939 err = ops->rate_node_tx_share_set(devlink_rate, devlink_rate->priv,
1940 rate, info->extack);
1943 devlink_rate->tx_share = rate;
1946 if (attrs[DEVLINK_ATTR_RATE_TX_MAX]) {
1947 rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_MAX]);
1948 if (devlink_rate_is_leaf(devlink_rate))
1949 err = ops->rate_leaf_tx_max_set(devlink_rate, devlink_rate->priv,
1950 rate, info->extack);
1951 else if (devlink_rate_is_node(devlink_rate))
1952 err = ops->rate_node_tx_max_set(devlink_rate, devlink_rate->priv,
1953 rate, info->extack);
1956 devlink_rate->tx_max = rate;
1959 nla_parent = attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME];
1961 err = devlink_nl_rate_parent_node_set(devlink_rate, info,
1970 static bool devlink_rate_set_ops_supported(const struct devlink_ops *ops,
1971 struct genl_info *info,
1972 enum devlink_rate_type type)
1974 struct nlattr **attrs = info->attrs;
1976 if (type == DEVLINK_RATE_TYPE_LEAF) {
1977 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_leaf_tx_share_set) {
1978 NL_SET_ERR_MSG_MOD(info->extack, "TX share set isn't supported for the leafs");
1981 if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_leaf_tx_max_set) {
1982 NL_SET_ERR_MSG_MOD(info->extack, "TX max set isn't supported for the leafs");
1985 if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] &&
1986 !ops->rate_leaf_parent_set) {
1987 NL_SET_ERR_MSG_MOD(info->extack, "Parent set isn't supported for the leafs");
1990 } else if (type == DEVLINK_RATE_TYPE_NODE) {
1991 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_node_tx_share_set) {
1992 NL_SET_ERR_MSG_MOD(info->extack, "TX share set isn't supported for the nodes");
1995 if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_node_tx_max_set) {
1996 NL_SET_ERR_MSG_MOD(info->extack, "TX max set isn't supported for the nodes");
1999 if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] &&
2000 !ops->rate_node_parent_set) {
2001 NL_SET_ERR_MSG_MOD(info->extack, "Parent set isn't supported for the nodes");
2005 WARN(1, "Unknown type of rate object");
2012 static int devlink_nl_cmd_rate_set_doit(struct sk_buff *skb,
2013 struct genl_info *info)
2015 struct devlink_rate *devlink_rate = info->user_ptr[1];
2016 struct devlink *devlink = devlink_rate->devlink;
2017 const struct devlink_ops *ops = devlink->ops;
2020 if (!ops || !devlink_rate_set_ops_supported(ops, info, devlink_rate->type))
2023 err = devlink_nl_rate_set(devlink_rate, ops, info);
2026 devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW);
2030 static int devlink_nl_cmd_rate_new_doit(struct sk_buff *skb,
2031 struct genl_info *info)
2033 struct devlink *devlink = info->user_ptr[0];
2034 struct devlink_rate *rate_node;
2035 const struct devlink_ops *ops;
2039 if (!ops || !ops->rate_node_new || !ops->rate_node_del) {
2040 NL_SET_ERR_MSG_MOD(info->extack, "Rate nodes aren't supported");
2044 if (!devlink_rate_set_ops_supported(ops, info, DEVLINK_RATE_TYPE_NODE))
2047 rate_node = devlink_rate_node_get_from_attrs(devlink, info->attrs);
2048 if (!IS_ERR(rate_node))
2050 else if (rate_node == ERR_PTR(-EINVAL))
2053 rate_node = kzalloc(sizeof(*rate_node), GFP_KERNEL);
2057 rate_node->devlink = devlink;
2058 rate_node->type = DEVLINK_RATE_TYPE_NODE;
2059 rate_node->name = nla_strdup(info->attrs[DEVLINK_ATTR_RATE_NODE_NAME], GFP_KERNEL);
2060 if (!rate_node->name) {
2065 err = ops->rate_node_new(rate_node, &rate_node->priv, info->extack);
2069 err = devlink_nl_rate_set(rate_node, ops, info);
2073 refcount_set(&rate_node->refcnt, 1);
2074 list_add(&rate_node->list, &devlink->rate_list);
2075 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
2079 ops->rate_node_del(rate_node, rate_node->priv, info->extack);
2081 kfree(rate_node->name);
2087 static int devlink_nl_cmd_rate_del_doit(struct sk_buff *skb,
2088 struct genl_info *info)
2090 struct devlink_rate *rate_node = info->user_ptr[1];
2091 struct devlink *devlink = rate_node->devlink;
2092 const struct devlink_ops *ops = devlink->ops;
2095 if (refcount_read(&rate_node->refcnt) > 1) {
2096 NL_SET_ERR_MSG_MOD(info->extack, "Node has children. Cannot delete node.");
2100 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL);
2101 err = ops->rate_node_del(rate_node, rate_node->priv, info->extack);
2102 if (rate_node->parent)
2103 refcount_dec(&rate_node->parent->refcnt);
2104 list_del(&rate_node->list);
2105 kfree(rate_node->name);
2110 struct devlink_linecard_type {
2115 static int devlink_nl_linecard_fill(struct sk_buff *msg,
2116 struct devlink *devlink,
2117 struct devlink_linecard *linecard,
2118 enum devlink_command cmd, u32 portid,
2120 struct netlink_ext_ack *extack)
2122 struct devlink_linecard_type *linecard_type;
2123 struct nlattr *attr;
2127 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2131 if (devlink_nl_put_handle(msg, devlink))
2132 goto nla_put_failure;
2133 if (nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX, linecard->index))
2134 goto nla_put_failure;
2135 if (nla_put_u8(msg, DEVLINK_ATTR_LINECARD_STATE, linecard->state))
2136 goto nla_put_failure;
2137 if (linecard->type &&
2138 nla_put_string(msg, DEVLINK_ATTR_LINECARD_TYPE, linecard->type))
2139 goto nla_put_failure;
2141 if (linecard->types_count) {
2142 attr = nla_nest_start(msg,
2143 DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES);
2145 goto nla_put_failure;
2146 for (i = 0; i < linecard->types_count; i++) {
2147 linecard_type = &linecard->types[i];
2148 if (nla_put_string(msg, DEVLINK_ATTR_LINECARD_TYPE,
2149 linecard_type->type)) {
2150 nla_nest_cancel(msg, attr);
2151 goto nla_put_failure;
2154 nla_nest_end(msg, attr);
2157 if (linecard->nested_devlink &&
2158 devlink_nl_put_nested_handle(msg, linecard->nested_devlink))
2159 goto nla_put_failure;
2161 genlmsg_end(msg, hdr);
2165 genlmsg_cancel(msg, hdr);
2169 static void devlink_linecard_notify(struct devlink_linecard *linecard,
2170 enum devlink_command cmd)
2172 struct devlink *devlink = linecard->devlink;
2173 struct sk_buff *msg;
2176 WARN_ON(cmd != DEVLINK_CMD_LINECARD_NEW &&
2177 cmd != DEVLINK_CMD_LINECARD_DEL);
2179 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
2182 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2186 err = devlink_nl_linecard_fill(msg, devlink, linecard, cmd, 0, 0, 0,
2193 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
2194 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
2197 static int devlink_nl_cmd_linecard_get_doit(struct sk_buff *skb,
2198 struct genl_info *info)
2200 struct devlink_linecard *linecard = info->user_ptr[1];
2201 struct devlink *devlink = linecard->devlink;
2202 struct sk_buff *msg;
2205 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2209 mutex_lock(&linecard->state_lock);
2210 err = devlink_nl_linecard_fill(msg, devlink, linecard,
2211 DEVLINK_CMD_LINECARD_NEW,
2212 info->snd_portid, info->snd_seq, 0,
2214 mutex_unlock(&linecard->state_lock);
2220 return genlmsg_reply(msg, info);
2223 static int devlink_nl_cmd_linecard_get_dumpit(struct sk_buff *msg,
2224 struct netlink_callback *cb)
2226 struct devlink_linecard *linecard;
2227 struct devlink *devlink;
2228 int start = cb->args[0];
2229 unsigned long index;
2233 mutex_lock(&devlink_mutex);
2234 devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
2235 mutex_lock(&devlink->linecards_lock);
2236 list_for_each_entry(linecard, &devlink->linecard_list, list) {
2241 mutex_lock(&linecard->state_lock);
2242 err = devlink_nl_linecard_fill(msg, devlink, linecard,
2243 DEVLINK_CMD_LINECARD_NEW,
2244 NETLINK_CB(cb->skb).portid,
2248 mutex_unlock(&linecard->state_lock);
2250 mutex_unlock(&devlink->linecards_lock);
2251 devlink_put(devlink);
2256 mutex_unlock(&devlink->linecards_lock);
2257 devlink_put(devlink);
2260 mutex_unlock(&devlink_mutex);
2266 static struct devlink_linecard_type *
2267 devlink_linecard_type_lookup(struct devlink_linecard *linecard,
2270 struct devlink_linecard_type *linecard_type;
2273 for (i = 0; i < linecard->types_count; i++) {
2274 linecard_type = &linecard->types[i];
2275 if (!strcmp(type, linecard_type->type))
2276 return linecard_type;
2281 static int devlink_linecard_type_set(struct devlink_linecard *linecard,
2283 struct netlink_ext_ack *extack)
2285 const struct devlink_linecard_ops *ops = linecard->ops;
2286 struct devlink_linecard_type *linecard_type;
2289 mutex_lock(&linecard->state_lock);
2290 if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING) {
2291 NL_SET_ERR_MSG_MOD(extack, "Line card is currently being provisioned");
2295 if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONING) {
2296 NL_SET_ERR_MSG_MOD(extack, "Line card is currently being unprovisioned");
2301 linecard_type = devlink_linecard_type_lookup(linecard, type);
2302 if (!linecard_type) {
2303 NL_SET_ERR_MSG_MOD(extack, "Unsupported line card type provided");
2308 if (linecard->state != DEVLINK_LINECARD_STATE_UNPROVISIONED &&
2309 linecard->state != DEVLINK_LINECARD_STATE_PROVISIONING_FAILED) {
2310 NL_SET_ERR_MSG_MOD(extack, "Line card already provisioned");
2312 /* Check if the line card is provisioned in the same
2313 * way the user asks. In case it is, make the operation
2314 * to return success.
2316 if (ops->same_provision &&
2317 ops->same_provision(linecard, linecard->priv,
2318 linecard_type->type,
2319 linecard_type->priv))
2324 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING;
2325 linecard->type = linecard_type->type;
2326 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
2327 mutex_unlock(&linecard->state_lock);
2328 err = ops->provision(linecard, linecard->priv, linecard_type->type,
2329 linecard_type->priv, extack);
2331 /* Provisioning failed. Assume the linecard is unprovisioned
2332 * for future operations.
2334 mutex_lock(&linecard->state_lock);
2335 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
2336 linecard->type = NULL;
2337 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
2338 mutex_unlock(&linecard->state_lock);
2343 mutex_unlock(&linecard->state_lock);
2347 static int devlink_linecard_type_unset(struct devlink_linecard *linecard,
2348 struct netlink_ext_ack *extack)
2352 mutex_lock(&linecard->state_lock);
2353 if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING) {
2354 NL_SET_ERR_MSG_MOD(extack, "Line card is currently being provisioned");
2358 if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONING) {
2359 NL_SET_ERR_MSG_MOD(extack, "Line card is currently being unprovisioned");
2363 if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING_FAILED) {
2364 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
2365 linecard->type = NULL;
2366 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
2371 if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONED) {
2372 NL_SET_ERR_MSG_MOD(extack, "Line card is not provisioned");
2376 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONING;
2377 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
2378 mutex_unlock(&linecard->state_lock);
2379 err = linecard->ops->unprovision(linecard, linecard->priv,
2382 /* Unprovisioning failed. Assume the linecard is unprovisioned
2383 * for future operations.
2385 mutex_lock(&linecard->state_lock);
2386 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
2387 linecard->type = NULL;
2388 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
2389 mutex_unlock(&linecard->state_lock);
2394 mutex_unlock(&linecard->state_lock);
2398 static int devlink_nl_cmd_linecard_set_doit(struct sk_buff *skb,
2399 struct genl_info *info)
2401 struct devlink_linecard *linecard = info->user_ptr[1];
2402 struct netlink_ext_ack *extack = info->extack;
2405 if (info->attrs[DEVLINK_ATTR_LINECARD_TYPE]) {
2408 type = nla_data(info->attrs[DEVLINK_ATTR_LINECARD_TYPE]);
2409 if (strcmp(type, "")) {
2410 err = devlink_linecard_type_set(linecard, type, extack);
2414 err = devlink_linecard_type_unset(linecard, extack);
2423 static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
2424 struct devlink_sb *devlink_sb,
2425 enum devlink_command cmd, u32 portid,
2430 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2434 if (devlink_nl_put_handle(msg, devlink))
2435 goto nla_put_failure;
2436 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
2437 goto nla_put_failure;
2438 if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size))
2439 goto nla_put_failure;
2440 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT,
2441 devlink_sb->ingress_pools_count))
2442 goto nla_put_failure;
2443 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT,
2444 devlink_sb->egress_pools_count))
2445 goto nla_put_failure;
2446 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT,
2447 devlink_sb->ingress_tc_count))
2448 goto nla_put_failure;
2449 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT,
2450 devlink_sb->egress_tc_count))
2451 goto nla_put_failure;
2453 genlmsg_end(msg, hdr);
2457 genlmsg_cancel(msg, hdr);
2461 static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb,
2462 struct genl_info *info)
2464 struct devlink *devlink = info->user_ptr[0];
2465 struct devlink_sb *devlink_sb;
2466 struct sk_buff *msg;
2469 devlink_sb = devlink_sb_get_from_info(devlink, info);
2470 if (IS_ERR(devlink_sb))
2471 return PTR_ERR(devlink_sb);
2473 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2477 err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
2479 info->snd_portid, info->snd_seq, 0);
2485 return genlmsg_reply(msg, info);
2488 static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg,
2489 struct netlink_callback *cb)
2491 struct devlink *devlink;
2492 struct devlink_sb *devlink_sb;
2493 int start = cb->args[0];
2494 unsigned long index;
2498 mutex_lock(&devlink_mutex);
2499 devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
2501 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
2506 err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
2508 NETLINK_CB(cb->skb).portid,
2512 devl_unlock(devlink);
2513 devlink_put(devlink);
2518 devl_unlock(devlink);
2519 devlink_put(devlink);
2522 mutex_unlock(&devlink_mutex);
2528 static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink,
2529 struct devlink_sb *devlink_sb,
2530 u16 pool_index, enum devlink_command cmd,
2531 u32 portid, u32 seq, int flags)
2533 struct devlink_sb_pool_info pool_info;
2537 err = devlink->ops->sb_pool_get(devlink, devlink_sb->index,
2538 pool_index, &pool_info);
2542 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2546 if (devlink_nl_put_handle(msg, devlink))
2547 goto nla_put_failure;
2548 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
2549 goto nla_put_failure;
2550 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
2551 goto nla_put_failure;
2552 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type))
2553 goto nla_put_failure;
2554 if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size))
2555 goto nla_put_failure;
2556 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE,
2557 pool_info.threshold_type))
2558 goto nla_put_failure;
2559 if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_CELL_SIZE,
2560 pool_info.cell_size))
2561 goto nla_put_failure;
2563 genlmsg_end(msg, hdr);
2567 genlmsg_cancel(msg, hdr);
2571 static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb,
2572 struct genl_info *info)
2574 struct devlink *devlink = info->user_ptr[0];
2575 struct devlink_sb *devlink_sb;
2576 struct sk_buff *msg;
2580 devlink_sb = devlink_sb_get_from_info(devlink, info);
2581 if (IS_ERR(devlink_sb))
2582 return PTR_ERR(devlink_sb);
2584 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2589 if (!devlink->ops->sb_pool_get)
2592 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2596 err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index,
2597 DEVLINK_CMD_SB_POOL_NEW,
2598 info->snd_portid, info->snd_seq, 0);
2604 return genlmsg_reply(msg, info);
2607 static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
2608 struct devlink *devlink,
2609 struct devlink_sb *devlink_sb,
2610 u32 portid, u32 seq)
2612 u16 pool_count = devlink_sb_pool_count(devlink_sb);
2616 for (pool_index = 0; pool_index < pool_count; pool_index++) {
2617 if (*p_idx < start) {
2621 err = devlink_nl_sb_pool_fill(msg, devlink,
2624 DEVLINK_CMD_SB_POOL_NEW,
2625 portid, seq, NLM_F_MULTI);
2633 static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg,
2634 struct netlink_callback *cb)
2636 struct devlink *devlink;
2637 struct devlink_sb *devlink_sb;
2638 int start = cb->args[0];
2639 unsigned long index;
2643 mutex_lock(&devlink_mutex);
2644 devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
2645 if (!devlink->ops->sb_pool_get)
2649 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
2650 err = __sb_pool_get_dumpit(msg, start, &idx, devlink,
2652 NETLINK_CB(cb->skb).portid,
2653 cb->nlh->nlmsg_seq);
2654 if (err == -EOPNOTSUPP) {
2657 devl_unlock(devlink);
2658 devlink_put(devlink);
2662 devl_unlock(devlink);
2664 devlink_put(devlink);
2667 mutex_unlock(&devlink_mutex);
2669 if (err != -EMSGSIZE)
2676 static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
2677 u16 pool_index, u32 size,
2678 enum devlink_sb_threshold_type threshold_type,
2679 struct netlink_ext_ack *extack)
2682 const struct devlink_ops *ops = devlink->ops;
2684 if (ops->sb_pool_set)
2685 return ops->sb_pool_set(devlink, sb_index, pool_index,
2686 size, threshold_type, extack);
2690 static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb,
2691 struct genl_info *info)
2693 struct devlink *devlink = info->user_ptr[0];
2694 enum devlink_sb_threshold_type threshold_type;
2695 struct devlink_sb *devlink_sb;
2700 devlink_sb = devlink_sb_get_from_info(devlink, info);
2701 if (IS_ERR(devlink_sb))
2702 return PTR_ERR(devlink_sb);
2704 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2709 err = devlink_sb_th_type_get_from_info(info, &threshold_type);
2713 if (!info->attrs[DEVLINK_ATTR_SB_POOL_SIZE])
2716 size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]);
2717 return devlink_sb_pool_set(devlink, devlink_sb->index,
2718 pool_index, size, threshold_type,
2722 static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg,
2723 struct devlink *devlink,
2724 struct devlink_port *devlink_port,
2725 struct devlink_sb *devlink_sb,
2727 enum devlink_command cmd,
2728 u32 portid, u32 seq, int flags)
2730 const struct devlink_ops *ops = devlink->ops;
2735 err = ops->sb_port_pool_get(devlink_port, devlink_sb->index,
2736 pool_index, &threshold);
2740 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2744 if (devlink_nl_put_handle(msg, devlink))
2745 goto nla_put_failure;
2746 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
2747 goto nla_put_failure;
2748 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
2749 goto nla_put_failure;
2750 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
2751 goto nla_put_failure;
2752 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
2753 goto nla_put_failure;
2755 if (ops->sb_occ_port_pool_get) {
2759 err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index,
2760 pool_index, &cur, &max);
2761 if (err && err != -EOPNOTSUPP)
2762 goto sb_occ_get_failure;
2764 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
2765 goto nla_put_failure;
2766 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
2767 goto nla_put_failure;
2771 genlmsg_end(msg, hdr);
2777 genlmsg_cancel(msg, hdr);
2781 static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,
2782 struct genl_info *info)
2784 struct devlink_port *devlink_port = info->user_ptr[1];
2785 struct devlink *devlink = devlink_port->devlink;
2786 struct devlink_sb *devlink_sb;
2787 struct sk_buff *msg;
2791 devlink_sb = devlink_sb_get_from_info(devlink, info);
2792 if (IS_ERR(devlink_sb))
2793 return PTR_ERR(devlink_sb);
2795 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2800 if (!devlink->ops->sb_port_pool_get)
2803 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2807 err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port,
2808 devlink_sb, pool_index,
2809 DEVLINK_CMD_SB_PORT_POOL_NEW,
2810 info->snd_portid, info->snd_seq, 0);
2816 return genlmsg_reply(msg, info);
2819 static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
2820 struct devlink *devlink,
2821 struct devlink_sb *devlink_sb,
2822 u32 portid, u32 seq)
2824 struct devlink_port *devlink_port;
2825 u16 pool_count = devlink_sb_pool_count(devlink_sb);
2829 list_for_each_entry(devlink_port, &devlink->port_list, list) {
2830 for (pool_index = 0; pool_index < pool_count; pool_index++) {
2831 if (*p_idx < start) {
2835 err = devlink_nl_sb_port_pool_fill(msg, devlink,
2839 DEVLINK_CMD_SB_PORT_POOL_NEW,
2850 static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg,
2851 struct netlink_callback *cb)
2853 struct devlink *devlink;
2854 struct devlink_sb *devlink_sb;
2855 int start = cb->args[0];
2856 unsigned long index;
2860 mutex_lock(&devlink_mutex);
2861 devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
2862 if (!devlink->ops->sb_port_pool_get)
2866 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
2867 err = __sb_port_pool_get_dumpit(msg, start, &idx,
2868 devlink, devlink_sb,
2869 NETLINK_CB(cb->skb).portid,
2870 cb->nlh->nlmsg_seq);
2871 if (err == -EOPNOTSUPP) {
2874 devl_unlock(devlink);
2875 devlink_put(devlink);
2879 devl_unlock(devlink);
2881 devlink_put(devlink);
2884 mutex_unlock(&devlink_mutex);
2886 if (err != -EMSGSIZE)
2893 static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
2894 unsigned int sb_index, u16 pool_index,
2896 struct netlink_ext_ack *extack)
2899 const struct devlink_ops *ops = devlink_port->devlink->ops;
2901 if (ops->sb_port_pool_set)
2902 return ops->sb_port_pool_set(devlink_port, sb_index,
2903 pool_index, threshold, extack);
2907 static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb,
2908 struct genl_info *info)
2910 struct devlink_port *devlink_port = info->user_ptr[1];
2911 struct devlink *devlink = info->user_ptr[0];
2912 struct devlink_sb *devlink_sb;
2917 devlink_sb = devlink_sb_get_from_info(devlink, info);
2918 if (IS_ERR(devlink_sb))
2919 return PTR_ERR(devlink_sb);
2921 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2926 if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
2929 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
2930 return devlink_sb_port_pool_set(devlink_port, devlink_sb->index,
2931 pool_index, threshold, info->extack);
2935 devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink,
2936 struct devlink_port *devlink_port,
2937 struct devlink_sb *devlink_sb, u16 tc_index,
2938 enum devlink_sb_pool_type pool_type,
2939 enum devlink_command cmd,
2940 u32 portid, u32 seq, int flags)
2942 const struct devlink_ops *ops = devlink->ops;
2948 err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index,
2949 tc_index, pool_type,
2950 &pool_index, &threshold);
2954 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2958 if (devlink_nl_put_handle(msg, devlink))
2959 goto nla_put_failure;
2960 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
2961 goto nla_put_failure;
2962 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
2963 goto nla_put_failure;
2964 if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index))
2965 goto nla_put_failure;
2966 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type))
2967 goto nla_put_failure;
2968 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
2969 goto nla_put_failure;
2970 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
2971 goto nla_put_failure;
2973 if (ops->sb_occ_tc_port_bind_get) {
2977 err = ops->sb_occ_tc_port_bind_get(devlink_port,
2979 tc_index, pool_type,
2981 if (err && err != -EOPNOTSUPP)
2984 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
2985 goto nla_put_failure;
2986 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
2987 goto nla_put_failure;
2991 genlmsg_end(msg, hdr);
2995 genlmsg_cancel(msg, hdr);
2999 static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,
3000 struct genl_info *info)
3002 struct devlink_port *devlink_port = info->user_ptr[1];
3003 struct devlink *devlink = devlink_port->devlink;
3004 struct devlink_sb *devlink_sb;
3005 struct sk_buff *msg;
3006 enum devlink_sb_pool_type pool_type;
3010 devlink_sb = devlink_sb_get_from_info(devlink, info);
3011 if (IS_ERR(devlink_sb))
3012 return PTR_ERR(devlink_sb);
3014 err = devlink_sb_pool_type_get_from_info(info, &pool_type);
3018 err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
3019 pool_type, &tc_index);
3023 if (!devlink->ops->sb_tc_pool_bind_get)
3026 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3030 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port,
3031 devlink_sb, tc_index, pool_type,
3032 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
3040 return genlmsg_reply(msg, info);
3043 static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
3044 int start, int *p_idx,
3045 struct devlink *devlink,
3046 struct devlink_sb *devlink_sb,
3047 u32 portid, u32 seq)
3049 struct devlink_port *devlink_port;
3053 list_for_each_entry(devlink_port, &devlink->port_list, list) {
3055 tc_index < devlink_sb->ingress_tc_count; tc_index++) {
3056 if (*p_idx < start) {
3060 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
3064 DEVLINK_SB_POOL_TYPE_INGRESS,
3065 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
3073 tc_index < devlink_sb->egress_tc_count; tc_index++) {
3074 if (*p_idx < start) {
3078 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
3082 DEVLINK_SB_POOL_TYPE_EGRESS,
3083 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
3095 devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
3096 struct netlink_callback *cb)
3098 struct devlink *devlink;
3099 struct devlink_sb *devlink_sb;
3100 int start = cb->args[0];
3101 unsigned long index;
3105 mutex_lock(&devlink_mutex);
3106 devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
3107 if (!devlink->ops->sb_tc_pool_bind_get)
3111 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
3112 err = __sb_tc_pool_bind_get_dumpit(msg, start, &idx,
3115 NETLINK_CB(cb->skb).portid,
3116 cb->nlh->nlmsg_seq);
3117 if (err == -EOPNOTSUPP) {
3120 devl_unlock(devlink);
3121 devlink_put(devlink);
3125 devl_unlock(devlink);
3127 devlink_put(devlink);
3130 mutex_unlock(&devlink_mutex);
3132 if (err != -EMSGSIZE)
3139 static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port,
3140 unsigned int sb_index, u16 tc_index,
3141 enum devlink_sb_pool_type pool_type,
3142 u16 pool_index, u32 threshold,
3143 struct netlink_ext_ack *extack)
3146 const struct devlink_ops *ops = devlink_port->devlink->ops;
3148 if (ops->sb_tc_pool_bind_set)
3149 return ops->sb_tc_pool_bind_set(devlink_port, sb_index,
3150 tc_index, pool_type,
3151 pool_index, threshold, extack);
3155 static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb,
3156 struct genl_info *info)
3158 struct devlink_port *devlink_port = info->user_ptr[1];
3159 struct devlink *devlink = info->user_ptr[0];
3160 enum devlink_sb_pool_type pool_type;
3161 struct devlink_sb *devlink_sb;
3167 devlink_sb = devlink_sb_get_from_info(devlink, info);
3168 if (IS_ERR(devlink_sb))
3169 return PTR_ERR(devlink_sb);
3171 err = devlink_sb_pool_type_get_from_info(info, &pool_type);
3175 err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
3176 pool_type, &tc_index);
3180 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
3185 if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
3188 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
3189 return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index,
3190 tc_index, pool_type,
3191 pool_index, threshold, info->extack);
3194 static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
3195 struct genl_info *info)
3197 struct devlink *devlink = info->user_ptr[0];
3198 const struct devlink_ops *ops = devlink->ops;
3199 struct devlink_sb *devlink_sb;
3201 devlink_sb = devlink_sb_get_from_info(devlink, info);
3202 if (IS_ERR(devlink_sb))
3203 return PTR_ERR(devlink_sb);
3205 if (ops->sb_occ_snapshot)
3206 return ops->sb_occ_snapshot(devlink, devlink_sb->index);
3210 static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
3211 struct genl_info *info)
3213 struct devlink *devlink = info->user_ptr[0];
3214 const struct devlink_ops *ops = devlink->ops;
3215 struct devlink_sb *devlink_sb;
3217 devlink_sb = devlink_sb_get_from_info(devlink, info);
3218 if (IS_ERR(devlink_sb))
3219 return PTR_ERR(devlink_sb);
3221 if (ops->sb_occ_max_clear)
3222 return ops->sb_occ_max_clear(devlink, devlink_sb->index);
3226 static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
3227 enum devlink_command cmd, u32 portid,
3230 const struct devlink_ops *ops = devlink->ops;
3231 enum devlink_eswitch_encap_mode encap_mode;
3237 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
3241 err = devlink_nl_put_handle(msg, devlink);
3243 goto nla_put_failure;
3245 if (ops->eswitch_mode_get) {
3246 err = ops->eswitch_mode_get(devlink, &mode);
3248 goto nla_put_failure;
3249 err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode);
3251 goto nla_put_failure;
3254 if (ops->eswitch_inline_mode_get) {
3255 err = ops->eswitch_inline_mode_get(devlink, &inline_mode);
3257 goto nla_put_failure;
3258 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE,
3261 goto nla_put_failure;
3264 if (ops->eswitch_encap_mode_get) {
3265 err = ops->eswitch_encap_mode_get(devlink, &encap_mode);
3267 goto nla_put_failure;
3268 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode);
3270 goto nla_put_failure;
3273 genlmsg_end(msg, hdr);
3277 genlmsg_cancel(msg, hdr);
3281 static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb,
3282 struct genl_info *info)
3284 struct devlink *devlink = info->user_ptr[0];
3285 struct sk_buff *msg;
3288 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3292 err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET,
3293 info->snd_portid, info->snd_seq, 0);
3300 return genlmsg_reply(msg, info);
3303 static int devlink_rate_nodes_check(struct devlink *devlink, u16 mode,
3304 struct netlink_ext_ack *extack)
3306 struct devlink_rate *devlink_rate;
3308 list_for_each_entry(devlink_rate, &devlink->rate_list, list)
3309 if (devlink_rate_is_node(devlink_rate)) {
3310 NL_SET_ERR_MSG_MOD(extack, "Rate node(s) exists.");
3316 static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb,
3317 struct genl_info *info)
3319 struct devlink *devlink = info->user_ptr[0];
3320 const struct devlink_ops *ops = devlink->ops;
3321 enum devlink_eswitch_encap_mode encap_mode;
3326 if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) {
3327 if (!ops->eswitch_mode_set)
3329 mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
3330 err = devlink_rate_nodes_check(devlink, mode, info->extack);
3333 err = ops->eswitch_mode_set(devlink, mode, info->extack);
3338 if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) {
3339 if (!ops->eswitch_inline_mode_set)
3341 inline_mode = nla_get_u8(
3342 info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]);
3343 err = ops->eswitch_inline_mode_set(devlink, inline_mode,
3349 if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) {
3350 if (!ops->eswitch_encap_mode_set)
3352 encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]);
3353 err = ops->eswitch_encap_mode_set(devlink, encap_mode,
3362 int devlink_dpipe_match_put(struct sk_buff *skb,
3363 struct devlink_dpipe_match *match)
3365 struct devlink_dpipe_header *header = match->header;
3366 struct devlink_dpipe_field *field = &header->fields[match->field_id];
3367 struct nlattr *match_attr;
3369 match_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_MATCH);
3373 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) ||
3374 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) ||
3375 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
3376 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
3377 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
3378 goto nla_put_failure;
3380 nla_nest_end(skb, match_attr);
3384 nla_nest_cancel(skb, match_attr);
3387 EXPORT_SYMBOL_GPL(devlink_dpipe_match_put);
3389 static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table,
3390 struct sk_buff *skb)
3392 struct nlattr *matches_attr;
3394 matches_attr = nla_nest_start_noflag(skb,
3395 DEVLINK_ATTR_DPIPE_TABLE_MATCHES);
3399 if (table->table_ops->matches_dump(table->priv, skb))
3400 goto nla_put_failure;
3402 nla_nest_end(skb, matches_attr);
3406 nla_nest_cancel(skb, matches_attr);
3410 int devlink_dpipe_action_put(struct sk_buff *skb,
3411 struct devlink_dpipe_action *action)
3413 struct devlink_dpipe_header *header = action->header;
3414 struct devlink_dpipe_field *field = &header->fields[action->field_id];
3415 struct nlattr *action_attr;
3417 action_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ACTION);
3421 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) ||
3422 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) ||
3423 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
3424 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
3425 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
3426 goto nla_put_failure;
3428 nla_nest_end(skb, action_attr);
3432 nla_nest_cancel(skb, action_attr);
3435 EXPORT_SYMBOL_GPL(devlink_dpipe_action_put);
3437 static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table,
3438 struct sk_buff *skb)
3440 struct nlattr *actions_attr;
3442 actions_attr = nla_nest_start_noflag(skb,
3443 DEVLINK_ATTR_DPIPE_TABLE_ACTIONS);
3447 if (table->table_ops->actions_dump(table->priv, skb))
3448 goto nla_put_failure;
3450 nla_nest_end(skb, actions_attr);
3454 nla_nest_cancel(skb, actions_attr);
3458 static int devlink_dpipe_table_put(struct sk_buff *skb,
3459 struct devlink_dpipe_table *table)
3461 struct nlattr *table_attr;
3464 table_size = table->table_ops->size_get(table->priv);
3465 table_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLE);
3469 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) ||
3470 nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size,
3472 goto nla_put_failure;
3473 if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
3474 table->counters_enabled))
3475 goto nla_put_failure;
3477 if (table->resource_valid) {
3478 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID,
3479 table->resource_id, DEVLINK_ATTR_PAD) ||
3480 nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS,
3481 table->resource_units, DEVLINK_ATTR_PAD))
3482 goto nla_put_failure;
3484 if (devlink_dpipe_matches_put(table, skb))
3485 goto nla_put_failure;
3487 if (devlink_dpipe_actions_put(table, skb))
3488 goto nla_put_failure;
3490 nla_nest_end(skb, table_attr);
3494 nla_nest_cancel(skb, table_attr);
3498 static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb,
3499 struct genl_info *info)
3504 err = genlmsg_reply(*pskb, info);
3508 *pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
3514 static int devlink_dpipe_tables_fill(struct genl_info *info,
3515 enum devlink_command cmd, int flags,
3516 struct list_head *dpipe_tables,
3517 const char *table_name)
3519 struct devlink *devlink = info->user_ptr[0];
3520 struct devlink_dpipe_table *table;
3521 struct nlattr *tables_attr;
3522 struct sk_buff *skb = NULL;
3523 struct nlmsghdr *nlh;
3529 table = list_first_entry(dpipe_tables,
3530 struct devlink_dpipe_table, list);
3532 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3536 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
3537 &devlink_nl_family, NLM_F_MULTI, cmd);
3543 if (devlink_nl_put_handle(skb, devlink))
3544 goto nla_put_failure;
3545 tables_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLES);
3547 goto nla_put_failure;
3551 list_for_each_entry_from(table, dpipe_tables, list) {
3553 err = devlink_dpipe_table_put(skb, table);
3561 if (!strcmp(table->name, table_name)) {
3562 err = devlink_dpipe_table_put(skb, table);
3570 nla_nest_end(skb, tables_attr);
3571 genlmsg_end(skb, hdr);
3576 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
3577 NLMSG_DONE, 0, flags | NLM_F_MULTI);
3579 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3585 return genlmsg_reply(skb, info);
3594 static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb,
3595 struct genl_info *info)
3597 struct devlink *devlink = info->user_ptr[0];
3598 const char *table_name = NULL;
3600 if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
3601 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
3603 return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0,
3604 &devlink->dpipe_table_list,
3608 static int devlink_dpipe_value_put(struct sk_buff *skb,
3609 struct devlink_dpipe_value *value)
3611 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE,
3612 value->value_size, value->value))
3615 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK,
3616 value->value_size, value->mask))
3618 if (value->mapping_valid)
3619 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING,
3620 value->mapping_value))
3625 static int devlink_dpipe_action_value_put(struct sk_buff *skb,
3626 struct devlink_dpipe_value *value)
3630 if (devlink_dpipe_action_put(skb, value->action))
3632 if (devlink_dpipe_value_put(skb, value))
3637 static int devlink_dpipe_action_values_put(struct sk_buff *skb,
3638 struct devlink_dpipe_value *values,
3639 unsigned int values_count)
3641 struct nlattr *action_attr;
3645 for (i = 0; i < values_count; i++) {
3646 action_attr = nla_nest_start_noflag(skb,
3647 DEVLINK_ATTR_DPIPE_ACTION_VALUE);
3650 err = devlink_dpipe_action_value_put(skb, &values[i]);
3652 goto err_action_value_put;
3653 nla_nest_end(skb, action_attr);
3657 err_action_value_put:
3658 nla_nest_cancel(skb, action_attr);
3662 static int devlink_dpipe_match_value_put(struct sk_buff *skb,
3663 struct devlink_dpipe_value *value)
3667 if (devlink_dpipe_match_put(skb, value->match))
3669 if (devlink_dpipe_value_put(skb, value))
3674 static int devlink_dpipe_match_values_put(struct sk_buff *skb,
3675 struct devlink_dpipe_value *values,
3676 unsigned int values_count)
3678 struct nlattr *match_attr;
3682 for (i = 0; i < values_count; i++) {
3683 match_attr = nla_nest_start_noflag(skb,
3684 DEVLINK_ATTR_DPIPE_MATCH_VALUE);
3687 err = devlink_dpipe_match_value_put(skb, &values[i]);
3689 goto err_match_value_put;
3690 nla_nest_end(skb, match_attr);
3694 err_match_value_put:
3695 nla_nest_cancel(skb, match_attr);
3699 static int devlink_dpipe_entry_put(struct sk_buff *skb,
3700 struct devlink_dpipe_entry *entry)
3702 struct nlattr *entry_attr, *matches_attr, *actions_attr;
3705 entry_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ENTRY);
3709 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index,
3711 goto nla_put_failure;
3712 if (entry->counter_valid)
3713 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER,
3714 entry->counter, DEVLINK_ATTR_PAD))
3715 goto nla_put_failure;
3717 matches_attr = nla_nest_start_noflag(skb,
3718 DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES);
3720 goto nla_put_failure;
3722 err = devlink_dpipe_match_values_put(skb, entry->match_values,
3723 entry->match_values_count);
3725 nla_nest_cancel(skb, matches_attr);
3726 goto err_match_values_put;
3728 nla_nest_end(skb, matches_attr);
3730 actions_attr = nla_nest_start_noflag(skb,
3731 DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES);
3733 goto nla_put_failure;
3735 err = devlink_dpipe_action_values_put(skb, entry->action_values,
3736 entry->action_values_count);
3738 nla_nest_cancel(skb, actions_attr);
3739 goto err_action_values_put;
3741 nla_nest_end(skb, actions_attr);
3743 nla_nest_end(skb, entry_attr);
3748 err_match_values_put:
3749 err_action_values_put:
3750 nla_nest_cancel(skb, entry_attr);
3754 static struct devlink_dpipe_table *
3755 devlink_dpipe_table_find(struct list_head *dpipe_tables,
3756 const char *table_name, struct devlink *devlink)
3758 struct devlink_dpipe_table *table;
3759 list_for_each_entry_rcu(table, dpipe_tables, list,
3760 lockdep_is_held(&devlink->lock)) {
3761 if (!strcmp(table->name, table_name))
3767 int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx)
3769 struct devlink *devlink;
3772 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb,
3777 dump_ctx->hdr = genlmsg_put(dump_ctx->skb,
3778 dump_ctx->info->snd_portid,
3779 dump_ctx->info->snd_seq,
3780 &devlink_nl_family, NLM_F_MULTI,
3783 goto nla_put_failure;
3785 devlink = dump_ctx->info->user_ptr[0];
3786 if (devlink_nl_put_handle(dump_ctx->skb, devlink))
3787 goto nla_put_failure;
3788 dump_ctx->nest = nla_nest_start_noflag(dump_ctx->skb,
3789 DEVLINK_ATTR_DPIPE_ENTRIES);
3790 if (!dump_ctx->nest)
3791 goto nla_put_failure;
3795 nlmsg_free(dump_ctx->skb);
3798 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare);
3800 int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx,
3801 struct devlink_dpipe_entry *entry)
3803 return devlink_dpipe_entry_put(dump_ctx->skb, entry);
3805 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append);
3807 int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx)
3809 nla_nest_end(dump_ctx->skb, dump_ctx->nest);
3810 genlmsg_end(dump_ctx->skb, dump_ctx->hdr);
3813 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close);
3815 void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry)
3818 unsigned int value_count, value_index;
3819 struct devlink_dpipe_value *value;
3821 value = entry->action_values;
3822 value_count = entry->action_values_count;
3823 for (value_index = 0; value_index < value_count; value_index++) {
3824 kfree(value[value_index].value);
3825 kfree(value[value_index].mask);
3828 value = entry->match_values;
3829 value_count = entry->match_values_count;
3830 for (value_index = 0; value_index < value_count; value_index++) {
3831 kfree(value[value_index].value);
3832 kfree(value[value_index].mask);
3835 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_clear);
3837 static int devlink_dpipe_entries_fill(struct genl_info *info,
3838 enum devlink_command cmd, int flags,
3839 struct devlink_dpipe_table *table)
3841 struct devlink_dpipe_dump_ctx dump_ctx;
3842 struct nlmsghdr *nlh;
3845 dump_ctx.skb = NULL;
3847 dump_ctx.info = info;
3849 err = table->table_ops->entries_dump(table->priv,
3850 table->counters_enabled,
3856 nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq,
3857 NLMSG_DONE, 0, flags | NLM_F_MULTI);
3859 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info);
3864 return genlmsg_reply(dump_ctx.skb, info);
3867 static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
3868 struct genl_info *info)
3870 struct devlink *devlink = info->user_ptr[0];
3871 struct devlink_dpipe_table *table;
3872 const char *table_name;
3874 if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
3877 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
3878 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
3879 table_name, devlink);
3883 if (!table->table_ops->entries_dump)
3886 return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET,
3890 static int devlink_dpipe_fields_put(struct sk_buff *skb,
3891 const struct devlink_dpipe_header *header)
3893 struct devlink_dpipe_field *field;
3894 struct nlattr *field_attr;
3897 for (i = 0; i < header->fields_count; i++) {
3898 field = &header->fields[i];
3899 field_attr = nla_nest_start_noflag(skb,
3900 DEVLINK_ATTR_DPIPE_FIELD);
3903 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) ||
3904 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
3905 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) ||
3906 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type))
3907 goto nla_put_failure;
3908 nla_nest_end(skb, field_attr);
3913 nla_nest_cancel(skb, field_attr);
3917 static int devlink_dpipe_header_put(struct sk_buff *skb,
3918 struct devlink_dpipe_header *header)
3920 struct nlattr *fields_attr, *header_attr;
3923 header_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADER);
3927 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) ||
3928 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
3929 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
3930 goto nla_put_failure;
3932 fields_attr = nla_nest_start_noflag(skb,
3933 DEVLINK_ATTR_DPIPE_HEADER_FIELDS);
3935 goto nla_put_failure;
3937 err = devlink_dpipe_fields_put(skb, header);
3939 nla_nest_cancel(skb, fields_attr);
3940 goto nla_put_failure;
3942 nla_nest_end(skb, fields_attr);
3943 nla_nest_end(skb, header_attr);
3948 nla_nest_cancel(skb, header_attr);
3952 static int devlink_dpipe_headers_fill(struct genl_info *info,
3953 enum devlink_command cmd, int flags,
3954 struct devlink_dpipe_headers *
3957 struct devlink *devlink = info->user_ptr[0];
3958 struct nlattr *headers_attr;
3959 struct sk_buff *skb = NULL;
3960 struct nlmsghdr *nlh;
3967 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3971 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
3972 &devlink_nl_family, NLM_F_MULTI, cmd);
3978 if (devlink_nl_put_handle(skb, devlink))
3979 goto nla_put_failure;
3980 headers_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADERS);
3982 goto nla_put_failure;
3985 for (; i < dpipe_headers->headers_count; i++) {
3986 err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]);
3994 nla_nest_end(skb, headers_attr);
3995 genlmsg_end(skb, hdr);
3996 if (i != dpipe_headers->headers_count)
4000 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
4001 NLMSG_DONE, 0, flags | NLM_F_MULTI);
4003 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
4008 return genlmsg_reply(skb, info);
4017 static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb,
4018 struct genl_info *info)
4020 struct devlink *devlink = info->user_ptr[0];
4022 if (!devlink->dpipe_headers)
4024 return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET,
4025 0, devlink->dpipe_headers);
4028 static int devlink_dpipe_table_counters_set(struct devlink *devlink,
4029 const char *table_name,
4032 struct devlink_dpipe_table *table;
4034 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
4035 table_name, devlink);
4039 if (table->counter_control_extern)
4042 if (!(table->counters_enabled ^ enable))
4045 table->counters_enabled = enable;
4046 if (table->table_ops->counters_set_update)
4047 table->table_ops->counters_set_update(table->priv, enable);
4051 static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb,
4052 struct genl_info *info)
4054 struct devlink *devlink = info->user_ptr[0];
4055 const char *table_name;
4056 bool counters_enable;
4058 if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME] ||
4059 !info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED])
4062 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
4063 counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]);
4065 return devlink_dpipe_table_counters_set(devlink, table_name,
4069 static struct devlink_resource *
4070 devlink_resource_find(struct devlink *devlink,
4071 struct devlink_resource *resource, u64 resource_id)
4073 struct list_head *resource_list;
4076 resource_list = &resource->resource_list;
4078 resource_list = &devlink->resource_list;
4080 list_for_each_entry(resource, resource_list, list) {
4081 struct devlink_resource *child_resource;
4083 if (resource->id == resource_id)
4086 child_resource = devlink_resource_find(devlink, resource,
4089 return child_resource;
4095 devlink_resource_validate_children(struct devlink_resource *resource)
4097 struct devlink_resource *child_resource;
4098 bool size_valid = true;
4101 if (list_empty(&resource->resource_list))
4104 list_for_each_entry(child_resource, &resource->resource_list, list)
4105 parts_size += child_resource->size_new;
4107 if (parts_size > resource->size_new)
4110 resource->size_valid = size_valid;
4114 devlink_resource_validate_size(struct devlink_resource *resource, u64 size,
4115 struct netlink_ext_ack *extack)
4120 if (size > resource->size_params.size_max) {
4121 NL_SET_ERR_MSG_MOD(extack, "Size larger than maximum");
4125 if (size < resource->size_params.size_min) {
4126 NL_SET_ERR_MSG_MOD(extack, "Size smaller than minimum");
4130 div64_u64_rem(size, resource->size_params.size_granularity, &reminder);
4132 NL_SET_ERR_MSG_MOD(extack, "Wrong granularity");
4139 static int devlink_nl_cmd_resource_set(struct sk_buff *skb,
4140 struct genl_info *info)
4142 struct devlink *devlink = info->user_ptr[0];
4143 struct devlink_resource *resource;
4148 if (!info->attrs[DEVLINK_ATTR_RESOURCE_ID] ||
4149 !info->attrs[DEVLINK_ATTR_RESOURCE_SIZE])
4151 resource_id = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_ID]);
4153 resource = devlink_resource_find(devlink, NULL, resource_id);
4157 size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]);
4158 err = devlink_resource_validate_size(resource, size, info->extack);
4162 resource->size_new = size;
4163 devlink_resource_validate_children(resource);
4164 if (resource->parent)
4165 devlink_resource_validate_children(resource->parent);
4170 devlink_resource_size_params_put(struct devlink_resource *resource,
4171 struct sk_buff *skb)
4173 struct devlink_resource_size_params *size_params;
4175 size_params = &resource->size_params;
4176 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_GRAN,
4177 size_params->size_granularity, DEVLINK_ATTR_PAD) ||
4178 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MAX,
4179 size_params->size_max, DEVLINK_ATTR_PAD) ||
4180 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MIN,
4181 size_params->size_min, DEVLINK_ATTR_PAD) ||
4182 nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_UNIT, size_params->unit))
4187 static int devlink_resource_occ_put(struct devlink_resource *resource,
4188 struct sk_buff *skb)
4190 if (!resource->occ_get)
4192 return nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_OCC,
4193 resource->occ_get(resource->occ_get_priv),
4197 static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb,
4198 struct devlink_resource *resource)
4200 struct devlink_resource *child_resource;
4201 struct nlattr *child_resource_attr;
4202 struct nlattr *resource_attr;
4204 resource_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_RESOURCE);
4208 if (nla_put_string(skb, DEVLINK_ATTR_RESOURCE_NAME, resource->name) ||
4209 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE, resource->size,
4210 DEVLINK_ATTR_PAD) ||
4211 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_ID, resource->id,
4213 goto nla_put_failure;
4214 if (resource->size != resource->size_new)
4215 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_NEW,
4216 resource->size_new, DEVLINK_ATTR_PAD);
4217 if (devlink_resource_occ_put(resource, skb))
4218 goto nla_put_failure;
4219 if (devlink_resource_size_params_put(resource, skb))
4220 goto nla_put_failure;
4221 if (list_empty(&resource->resource_list))
4224 if (nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_SIZE_VALID,
4225 resource->size_valid))
4226 goto nla_put_failure;
4228 child_resource_attr = nla_nest_start_noflag(skb,
4229 DEVLINK_ATTR_RESOURCE_LIST);
4230 if (!child_resource_attr)
4231 goto nla_put_failure;
4233 list_for_each_entry(child_resource, &resource->resource_list, list) {
4234 if (devlink_resource_put(devlink, skb, child_resource))
4235 goto resource_put_failure;
4238 nla_nest_end(skb, child_resource_attr);
4240 nla_nest_end(skb, resource_attr);
4243 resource_put_failure:
4244 nla_nest_cancel(skb, child_resource_attr);
4246 nla_nest_cancel(skb, resource_attr);
4250 static int devlink_resource_fill(struct genl_info *info,
4251 enum devlink_command cmd, int flags)
4253 struct devlink *devlink = info->user_ptr[0];
4254 struct devlink_resource *resource;
4255 struct nlattr *resources_attr;
4256 struct sk_buff *skb = NULL;
4257 struct nlmsghdr *nlh;
4263 resource = list_first_entry(&devlink->resource_list,
4264 struct devlink_resource, list);
4266 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
4270 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
4271 &devlink_nl_family, NLM_F_MULTI, cmd);
4277 if (devlink_nl_put_handle(skb, devlink))
4278 goto nla_put_failure;
4280 resources_attr = nla_nest_start_noflag(skb,
4281 DEVLINK_ATTR_RESOURCE_LIST);
4282 if (!resources_attr)
4283 goto nla_put_failure;
4287 list_for_each_entry_from(resource, &devlink->resource_list, list) {
4288 err = devlink_resource_put(devlink, skb, resource);
4291 goto err_resource_put;
4297 nla_nest_end(skb, resources_attr);
4298 genlmsg_end(skb, hdr);
4302 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
4303 NLMSG_DONE, 0, flags | NLM_F_MULTI);
4305 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
4310 return genlmsg_reply(skb, info);
4319 static int devlink_nl_cmd_resource_dump(struct sk_buff *skb,
4320 struct genl_info *info)
4322 struct devlink *devlink = info->user_ptr[0];
4324 if (list_empty(&devlink->resource_list))
4327 return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0);
4331 devlink_resources_validate(struct devlink *devlink,
4332 struct devlink_resource *resource,
4333 struct genl_info *info)
4335 struct list_head *resource_list;
4339 resource_list = &resource->resource_list;
4341 resource_list = &devlink->resource_list;
4343 list_for_each_entry(resource, resource_list, list) {
4344 if (!resource->size_valid)
4346 err = devlink_resources_validate(devlink, resource, info);
4353 static struct net *devlink_netns_get(struct sk_buff *skb,
4354 struct genl_info *info)
4356 struct nlattr *netns_pid_attr = info->attrs[DEVLINK_ATTR_NETNS_PID];
4357 struct nlattr *netns_fd_attr = info->attrs[DEVLINK_ATTR_NETNS_FD];
4358 struct nlattr *netns_id_attr = info->attrs[DEVLINK_ATTR_NETNS_ID];
4361 if (!!netns_pid_attr + !!netns_fd_attr + !!netns_id_attr > 1) {
4362 NL_SET_ERR_MSG_MOD(info->extack, "multiple netns identifying attributes specified");
4363 return ERR_PTR(-EINVAL);
4366 if (netns_pid_attr) {
4367 net = get_net_ns_by_pid(nla_get_u32(netns_pid_attr));
4368 } else if (netns_fd_attr) {
4369 net = get_net_ns_by_fd(nla_get_u32(netns_fd_attr));
4370 } else if (netns_id_attr) {
4371 net = get_net_ns_by_id(sock_net(skb->sk),
4372 nla_get_u32(netns_id_attr));
4374 net = ERR_PTR(-EINVAL);
4377 net = ERR_PTR(-EINVAL);
4380 NL_SET_ERR_MSG_MOD(info->extack, "Unknown network namespace");
4381 return ERR_PTR(-EINVAL);
4383 if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) {
4385 return ERR_PTR(-EPERM);
4390 static void devlink_param_notify(struct devlink *devlink,
4391 unsigned int port_index,
4392 struct devlink_param_item *param_item,
4393 enum devlink_command cmd);
4395 static void devlink_ns_change_notify(struct devlink *devlink,
4396 struct net *dest_net, struct net *curr_net,
4399 struct devlink_param_item *param_item;
4400 enum devlink_command cmd;
4402 /* Userspace needs to be notified about devlink objects
4403 * removed from original and entering new network namespace.
4404 * The rest of the devlink objects are re-created during
4405 * reload process so the notifications are generated separatelly.
4408 if (!dest_net || net_eq(dest_net, curr_net))
4412 devlink_notify(devlink, DEVLINK_CMD_NEW);
4414 cmd = new ? DEVLINK_CMD_PARAM_NEW : DEVLINK_CMD_PARAM_DEL;
4415 list_for_each_entry(param_item, &devlink->param_list, list)
4416 devlink_param_notify(devlink, 0, param_item, cmd);
4419 devlink_notify(devlink, DEVLINK_CMD_DEL);
4422 static bool devlink_reload_supported(const struct devlink_ops *ops)
4424 return ops->reload_down && ops->reload_up;
4427 static void devlink_reload_failed_set(struct devlink *devlink,
4430 if (devlink->reload_failed == reload_failed)
4432 devlink->reload_failed = reload_failed;
4433 devlink_notify(devlink, DEVLINK_CMD_NEW);
4436 bool devlink_is_reload_failed(const struct devlink *devlink)
4438 return devlink->reload_failed;
4440 EXPORT_SYMBOL_GPL(devlink_is_reload_failed);
4443 __devlink_reload_stats_update(struct devlink *devlink, u32 *reload_stats,
4444 enum devlink_reload_limit limit, u32 actions_performed)
4446 unsigned long actions = actions_performed;
4450 for_each_set_bit(action, &actions, __DEVLINK_RELOAD_ACTION_MAX) {
4451 stat_idx = limit * __DEVLINK_RELOAD_ACTION_MAX + action;
4452 reload_stats[stat_idx]++;
4454 devlink_notify(devlink, DEVLINK_CMD_NEW);
4458 devlink_reload_stats_update(struct devlink *devlink, enum devlink_reload_limit limit,
4459 u32 actions_performed)
4461 __devlink_reload_stats_update(devlink, devlink->stats.reload_stats, limit,
4466 * devlink_remote_reload_actions_performed - Update devlink on reload actions
4467 * performed which are not a direct result of devlink reload call.
4469 * This should be called by a driver after performing reload actions in case it was not
4470 * a result of devlink reload call. For example fw_activate was performed as a result
4471 * of devlink reload triggered fw_activate on another host.
4472 * The motivation for this function is to keep data on reload actions performed on this
4473 * function whether it was done due to direct devlink reload call or not.
4476 * @limit: reload limit
4477 * @actions_performed: bitmask of actions performed
4479 void devlink_remote_reload_actions_performed(struct devlink *devlink,
4480 enum devlink_reload_limit limit,
4481 u32 actions_performed)
4483 if (WARN_ON(!actions_performed ||
4484 actions_performed & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) ||
4485 actions_performed >= BIT(__DEVLINK_RELOAD_ACTION_MAX) ||
4486 limit > DEVLINK_RELOAD_LIMIT_MAX))
4489 __devlink_reload_stats_update(devlink, devlink->stats.remote_reload_stats, limit,
4492 EXPORT_SYMBOL_GPL(devlink_remote_reload_actions_performed);
4494 static int devlink_reload(struct devlink *devlink, struct net *dest_net,
4495 enum devlink_reload_action action, enum devlink_reload_limit limit,
4496 u32 *actions_performed, struct netlink_ext_ack *extack)
4498 u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE];
4499 struct net *curr_net;
4502 memcpy(remote_reload_stats, devlink->stats.remote_reload_stats,
4503 sizeof(remote_reload_stats));
4505 curr_net = devlink_net(devlink);
4506 devlink_ns_change_notify(devlink, dest_net, curr_net, false);
4507 err = devlink->ops->reload_down(devlink, !!dest_net, action, limit, extack);
4511 if (dest_net && !net_eq(dest_net, curr_net))
4512 write_pnet(&devlink->_net, dest_net);
4514 err = devlink->ops->reload_up(devlink, action, limit, actions_performed, extack);
4515 devlink_reload_failed_set(devlink, !!err);
4519 devlink_ns_change_notify(devlink, dest_net, curr_net, true);
4520 WARN_ON(!(*actions_performed & BIT(action)));
4521 /* Catch driver on updating the remote action within devlink reload */
4522 WARN_ON(memcmp(remote_reload_stats, devlink->stats.remote_reload_stats,
4523 sizeof(remote_reload_stats)));
4524 devlink_reload_stats_update(devlink, limit, *actions_performed);
4529 devlink_nl_reload_actions_performed_snd(struct devlink *devlink, u32 actions_performed,
4530 enum devlink_command cmd, struct genl_info *info)
4532 struct sk_buff *msg;
4535 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4539 hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, &devlink_nl_family, 0, cmd);
4543 if (devlink_nl_put_handle(msg, devlink))
4544 goto nla_put_failure;
4546 if (nla_put_bitfield32(msg, DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED, actions_performed,
4548 goto nla_put_failure;
4549 genlmsg_end(msg, hdr);
4551 return genlmsg_reply(msg, info);
4554 genlmsg_cancel(msg, hdr);
4560 static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
4562 struct devlink *devlink = info->user_ptr[0];
4563 enum devlink_reload_action action;
4564 enum devlink_reload_limit limit;
4565 struct net *dest_net = NULL;
4566 u32 actions_performed;
4569 if (!(devlink->features & DEVLINK_F_RELOAD))
4572 err = devlink_resources_validate(devlink, NULL, info);
4574 NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed");
4578 if (info->attrs[DEVLINK_ATTR_RELOAD_ACTION])
4579 action = nla_get_u8(info->attrs[DEVLINK_ATTR_RELOAD_ACTION]);
4581 action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT;
4583 if (!devlink_reload_action_is_supported(devlink, action)) {
4584 NL_SET_ERR_MSG_MOD(info->extack,
4585 "Requested reload action is not supported by the driver");
4589 limit = DEVLINK_RELOAD_LIMIT_UNSPEC;
4590 if (info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]) {
4591 struct nla_bitfield32 limits;
4592 u32 limits_selected;
4594 limits = nla_get_bitfield32(info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]);
4595 limits_selected = limits.value & limits.selector;
4596 if (!limits_selected) {
4597 NL_SET_ERR_MSG_MOD(info->extack, "Invalid limit selected");
4600 for (limit = 0 ; limit <= DEVLINK_RELOAD_LIMIT_MAX ; limit++)
4601 if (limits_selected & BIT(limit))
4603 /* UAPI enables multiselection, but currently it is not used */
4604 if (limits_selected != BIT(limit)) {
4605 NL_SET_ERR_MSG_MOD(info->extack,
4606 "Multiselection of limit is not supported");
4609 if (!devlink_reload_limit_is_supported(devlink, limit)) {
4610 NL_SET_ERR_MSG_MOD(info->extack,
4611 "Requested limit is not supported by the driver");
4614 if (devlink_reload_combination_is_invalid(action, limit)) {
4615 NL_SET_ERR_MSG_MOD(info->extack,
4616 "Requested limit is invalid for this action");
4620 if (info->attrs[DEVLINK_ATTR_NETNS_PID] ||
4621 info->attrs[DEVLINK_ATTR_NETNS_FD] ||
4622 info->attrs[DEVLINK_ATTR_NETNS_ID]) {
4623 dest_net = devlink_netns_get(skb, info);
4624 if (IS_ERR(dest_net))
4625 return PTR_ERR(dest_net);
4628 err = devlink_reload(devlink, dest_net, action, limit, &actions_performed, info->extack);
4635 /* For backward compatibility generate reply only if attributes used by user */
4636 if (!info->attrs[DEVLINK_ATTR_RELOAD_ACTION] && !info->attrs[DEVLINK_ATTR_RELOAD_LIMITS])
4639 return devlink_nl_reload_actions_performed_snd(devlink, actions_performed,
4640 DEVLINK_CMD_RELOAD, info);
4643 static int devlink_nl_flash_update_fill(struct sk_buff *msg,
4644 struct devlink *devlink,
4645 enum devlink_command cmd,
4646 struct devlink_flash_notify *params)
4650 hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd);
4654 if (devlink_nl_put_handle(msg, devlink))
4655 goto nla_put_failure;
4657 if (cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS)
4660 if (params->status_msg &&
4661 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG,
4662 params->status_msg))
4663 goto nla_put_failure;
4664 if (params->component &&
4665 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT,
4667 goto nla_put_failure;
4668 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE,
4669 params->done, DEVLINK_ATTR_PAD))
4670 goto nla_put_failure;
4671 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL,
4672 params->total, DEVLINK_ATTR_PAD))
4673 goto nla_put_failure;
4674 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TIMEOUT,
4675 params->timeout, DEVLINK_ATTR_PAD))
4676 goto nla_put_failure;
4679 genlmsg_end(msg, hdr);
4683 genlmsg_cancel(msg, hdr);
4687 static void __devlink_flash_update_notify(struct devlink *devlink,
4688 enum devlink_command cmd,
4689 struct devlink_flash_notify *params)
4691 struct sk_buff *msg;
4694 WARN_ON(cmd != DEVLINK_CMD_FLASH_UPDATE &&
4695 cmd != DEVLINK_CMD_FLASH_UPDATE_END &&
4696 cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS);
4698 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
4701 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4705 err = devlink_nl_flash_update_fill(msg, devlink, cmd, params);
4709 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
4710 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
4717 static void devlink_flash_update_begin_notify(struct devlink *devlink)
4719 struct devlink_flash_notify params = {};
4721 __devlink_flash_update_notify(devlink,
4722 DEVLINK_CMD_FLASH_UPDATE,
4726 static void devlink_flash_update_end_notify(struct devlink *devlink)
4728 struct devlink_flash_notify params = {};
4730 __devlink_flash_update_notify(devlink,
4731 DEVLINK_CMD_FLASH_UPDATE_END,
4735 void devlink_flash_update_status_notify(struct devlink *devlink,
4736 const char *status_msg,
4737 const char *component,
4739 unsigned long total)
4741 struct devlink_flash_notify params = {
4742 .status_msg = status_msg,
4743 .component = component,
4748 __devlink_flash_update_notify(devlink,
4749 DEVLINK_CMD_FLASH_UPDATE_STATUS,
4752 EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify);
4754 void devlink_flash_update_timeout_notify(struct devlink *devlink,
4755 const char *status_msg,
4756 const char *component,
4757 unsigned long timeout)
4759 struct devlink_flash_notify params = {
4760 .status_msg = status_msg,
4761 .component = component,
4765 __devlink_flash_update_notify(devlink,
4766 DEVLINK_CMD_FLASH_UPDATE_STATUS,
4769 EXPORT_SYMBOL_GPL(devlink_flash_update_timeout_notify);
4771 static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
4772 struct genl_info *info)
4774 struct nlattr *nla_component, *nla_overwrite_mask, *nla_file_name;
4775 struct devlink_flash_update_params params = {};
4776 struct devlink *devlink = info->user_ptr[0];
4777 const char *file_name;
4778 u32 supported_params;
4781 if (!devlink->ops->flash_update)
4784 if (!info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME])
4787 supported_params = devlink->ops->supported_flash_update_params;
4789 nla_component = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT];
4790 if (nla_component) {
4791 if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT)) {
4792 NL_SET_ERR_MSG_ATTR(info->extack, nla_component,
4793 "component update is not supported by this device");
4796 params.component = nla_data(nla_component);
4799 nla_overwrite_mask = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK];
4800 if (nla_overwrite_mask) {
4801 struct nla_bitfield32 sections;
4803 if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK)) {
4804 NL_SET_ERR_MSG_ATTR(info->extack, nla_overwrite_mask,
4805 "overwrite settings are not supported by this device");
4808 sections = nla_get_bitfield32(nla_overwrite_mask);
4809 params.overwrite_mask = sections.value & sections.selector;
4812 nla_file_name = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME];
4813 file_name = nla_data(nla_file_name);
4814 ret = request_firmware(¶ms.fw, file_name, devlink->dev);
4816 NL_SET_ERR_MSG_ATTR(info->extack, nla_file_name, "failed to locate the requested firmware file");
4820 devlink_flash_update_begin_notify(devlink);
4821 ret = devlink->ops->flash_update(devlink, ¶ms, info->extack);
4822 devlink_flash_update_end_notify(devlink);
4824 release_firmware(params.fw);
4829 static const struct devlink_param devlink_param_generic[] = {
4831 .id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET,
4832 .name = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME,
4833 .type = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE,
4836 .id = DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
4837 .name = DEVLINK_PARAM_GENERIC_MAX_MACS_NAME,
4838 .type = DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE,
4841 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV,
4842 .name = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME,
4843 .type = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE,
4846 .id = DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT,
4847 .name = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME,
4848 .type = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE,
4851 .id = DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI,
4852 .name = DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME,
4853 .type = DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE,
4856 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX,
4857 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME,
4858 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE,
4861 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN,
4862 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME,
4863 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE,
4866 .id = DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY,
4867 .name = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME,
4868 .type = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE,
4871 .id = DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE,
4872 .name = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME,
4873 .type = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE,
4876 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE,
4877 .name = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_NAME,
4878 .type = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_TYPE,
4881 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_REMOTE_DEV_RESET,
4882 .name = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_NAME,
4883 .type = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_TYPE,
4886 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ETH,
4887 .name = DEVLINK_PARAM_GENERIC_ENABLE_ETH_NAME,
4888 .type = DEVLINK_PARAM_GENERIC_ENABLE_ETH_TYPE,
4891 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_RDMA,
4892 .name = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_NAME,
4893 .type = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_TYPE,
4896 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_VNET,
4897 .name = DEVLINK_PARAM_GENERIC_ENABLE_VNET_NAME,
4898 .type = DEVLINK_PARAM_GENERIC_ENABLE_VNET_TYPE,
4901 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_IWARP,
4902 .name = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_NAME,
4903 .type = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_TYPE,
4906 .id = DEVLINK_PARAM_GENERIC_ID_IO_EQ_SIZE,
4907 .name = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_NAME,
4908 .type = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_TYPE,
4911 .id = DEVLINK_PARAM_GENERIC_ID_EVENT_EQ_SIZE,
4912 .name = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_NAME,
4913 .type = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_TYPE,
4917 static int devlink_param_generic_verify(const struct devlink_param *param)
4919 /* verify it match generic parameter by id and name */
4920 if (param->id > DEVLINK_PARAM_GENERIC_ID_MAX)
4922 if (strcmp(param->name, devlink_param_generic[param->id].name))
4925 WARN_ON(param->type != devlink_param_generic[param->id].type);
4930 static int devlink_param_driver_verify(const struct devlink_param *param)
4934 if (param->id <= DEVLINK_PARAM_GENERIC_ID_MAX)
4936 /* verify no such name in generic params */
4937 for (i = 0; i <= DEVLINK_PARAM_GENERIC_ID_MAX; i++)
4938 if (!strcmp(param->name, devlink_param_generic[i].name))
4944 static struct devlink_param_item *
4945 devlink_param_find_by_name(struct list_head *param_list,
4946 const char *param_name)
4948 struct devlink_param_item *param_item;
4950 list_for_each_entry(param_item, param_list, list)
4951 if (!strcmp(param_item->param->name, param_name))
4956 static struct devlink_param_item *
4957 devlink_param_find_by_id(struct list_head *param_list, u32 param_id)
4959 struct devlink_param_item *param_item;
4961 list_for_each_entry(param_item, param_list, list)
4962 if (param_item->param->id == param_id)
4968 devlink_param_cmode_is_supported(const struct devlink_param *param,
4969 enum devlink_param_cmode cmode)
4971 return test_bit(cmode, ¶m->supported_cmodes);
4974 static int devlink_param_get(struct devlink *devlink,
4975 const struct devlink_param *param,
4976 struct devlink_param_gset_ctx *ctx)
4980 return param->get(devlink, param->id, ctx);
4983 static int devlink_param_set(struct devlink *devlink,
4984 const struct devlink_param *param,
4985 struct devlink_param_gset_ctx *ctx)
4989 return param->set(devlink, param->id, ctx);
4993 devlink_param_type_to_nla_type(enum devlink_param_type param_type)
4995 switch (param_type) {
4996 case DEVLINK_PARAM_TYPE_U8:
4998 case DEVLINK_PARAM_TYPE_U16:
5000 case DEVLINK_PARAM_TYPE_U32:
5002 case DEVLINK_PARAM_TYPE_STRING:
5004 case DEVLINK_PARAM_TYPE_BOOL:
5012 devlink_nl_param_value_fill_one(struct sk_buff *msg,
5013 enum devlink_param_type type,
5014 enum devlink_param_cmode cmode,
5015 union devlink_param_value val)
5017 struct nlattr *param_value_attr;
5019 param_value_attr = nla_nest_start_noflag(msg,
5020 DEVLINK_ATTR_PARAM_VALUE);
5021 if (!param_value_attr)
5022 goto nla_put_failure;
5024 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode))
5025 goto value_nest_cancel;
5028 case DEVLINK_PARAM_TYPE_U8:
5029 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu8))
5030 goto value_nest_cancel;
5032 case DEVLINK_PARAM_TYPE_U16:
5033 if (nla_put_u16(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu16))
5034 goto value_nest_cancel;
5036 case DEVLINK_PARAM_TYPE_U32:
5037 if (nla_put_u32(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu32))
5038 goto value_nest_cancel;
5040 case DEVLINK_PARAM_TYPE_STRING:
5041 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_VALUE_DATA,
5043 goto value_nest_cancel;
5045 case DEVLINK_PARAM_TYPE_BOOL:
5047 nla_put_flag(msg, DEVLINK_ATTR_PARAM_VALUE_DATA))
5048 goto value_nest_cancel;
5052 nla_nest_end(msg, param_value_attr);
5056 nla_nest_cancel(msg, param_value_attr);
5061 static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
5062 unsigned int port_index,
5063 struct devlink_param_item *param_item,
5064 enum devlink_command cmd,
5065 u32 portid, u32 seq, int flags)
5067 union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1];
5068 bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {};
5069 const struct devlink_param *param = param_item->param;
5070 struct devlink_param_gset_ctx ctx;
5071 struct nlattr *param_values_list;
5072 struct nlattr *param_attr;
5078 /* Get value from driver part to driverinit configuration mode */
5079 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
5080 if (!devlink_param_cmode_is_supported(param, i))
5082 if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) {
5083 if (!param_item->driverinit_value_valid)
5085 param_value[i] = param_item->driverinit_value;
5088 err = devlink_param_get(devlink, param, &ctx);
5091 param_value[i] = ctx.val;
5093 param_value_set[i] = true;
5096 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
5100 if (devlink_nl_put_handle(msg, devlink))
5101 goto genlmsg_cancel;
5103 if (cmd == DEVLINK_CMD_PORT_PARAM_GET ||
5104 cmd == DEVLINK_CMD_PORT_PARAM_NEW ||
5105 cmd == DEVLINK_CMD_PORT_PARAM_DEL)
5106 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index))
5107 goto genlmsg_cancel;
5109 param_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PARAM);
5111 goto genlmsg_cancel;
5112 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_NAME, param->name))
5113 goto param_nest_cancel;
5114 if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC))
5115 goto param_nest_cancel;
5117 nla_type = devlink_param_type_to_nla_type(param->type);
5119 goto param_nest_cancel;
5120 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, nla_type))
5121 goto param_nest_cancel;
5123 param_values_list = nla_nest_start_noflag(msg,
5124 DEVLINK_ATTR_PARAM_VALUES_LIST);
5125 if (!param_values_list)
5126 goto param_nest_cancel;
5128 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
5129 if (!param_value_set[i])
5131 err = devlink_nl_param_value_fill_one(msg, param->type,
5134 goto values_list_nest_cancel;
5137 nla_nest_end(msg, param_values_list);
5138 nla_nest_end(msg, param_attr);
5139 genlmsg_end(msg, hdr);
5142 values_list_nest_cancel:
5143 nla_nest_end(msg, param_values_list);
5145 nla_nest_cancel(msg, param_attr);
5147 genlmsg_cancel(msg, hdr);
5151 static void devlink_param_notify(struct devlink *devlink,
5152 unsigned int port_index,
5153 struct devlink_param_item *param_item,
5154 enum devlink_command cmd)
5156 struct sk_buff *msg;
5159 WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL &&
5160 cmd != DEVLINK_CMD_PORT_PARAM_NEW &&
5161 cmd != DEVLINK_CMD_PORT_PARAM_DEL);
5162 ASSERT_DEVLINK_REGISTERED(devlink);
5164 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5167 err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd,
5174 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
5175 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
5178 static int devlink_nl_cmd_param_get_dumpit(struct sk_buff *msg,
5179 struct netlink_callback *cb)
5181 struct devlink_param_item *param_item;
5182 struct devlink *devlink;
5183 int start = cb->args[0];
5184 unsigned long index;
5188 mutex_lock(&devlink_mutex);
5189 devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
5191 list_for_each_entry(param_item, &devlink->param_list, list) {
5196 err = devlink_nl_param_fill(msg, devlink, 0, param_item,
5197 DEVLINK_CMD_PARAM_GET,
5198 NETLINK_CB(cb->skb).portid,
5201 if (err == -EOPNOTSUPP) {
5204 devl_unlock(devlink);
5205 devlink_put(devlink);
5210 devl_unlock(devlink);
5211 devlink_put(devlink);
5214 mutex_unlock(&devlink_mutex);
5216 if (err != -EMSGSIZE)
5224 devlink_param_type_get_from_info(struct genl_info *info,
5225 enum devlink_param_type *param_type)
5227 if (!info->attrs[DEVLINK_ATTR_PARAM_TYPE])
5230 switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) {
5232 *param_type = DEVLINK_PARAM_TYPE_U8;
5235 *param_type = DEVLINK_PARAM_TYPE_U16;
5238 *param_type = DEVLINK_PARAM_TYPE_U32;
5241 *param_type = DEVLINK_PARAM_TYPE_STRING;
5244 *param_type = DEVLINK_PARAM_TYPE_BOOL;
5254 devlink_param_value_get_from_info(const struct devlink_param *param,
5255 struct genl_info *info,
5256 union devlink_param_value *value)
5258 struct nlattr *param_data;
5261 param_data = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA];
5263 if (param->type != DEVLINK_PARAM_TYPE_BOOL && !param_data)
5266 switch (param->type) {
5267 case DEVLINK_PARAM_TYPE_U8:
5268 if (nla_len(param_data) != sizeof(u8))
5270 value->vu8 = nla_get_u8(param_data);
5272 case DEVLINK_PARAM_TYPE_U16:
5273 if (nla_len(param_data) != sizeof(u16))
5275 value->vu16 = nla_get_u16(param_data);
5277 case DEVLINK_PARAM_TYPE_U32:
5278 if (nla_len(param_data) != sizeof(u32))
5280 value->vu32 = nla_get_u32(param_data);
5282 case DEVLINK_PARAM_TYPE_STRING:
5283 len = strnlen(nla_data(param_data), nla_len(param_data));
5284 if (len == nla_len(param_data) ||
5285 len >= __DEVLINK_PARAM_MAX_STRING_VALUE)
5287 strcpy(value->vstr, nla_data(param_data));
5289 case DEVLINK_PARAM_TYPE_BOOL:
5290 if (param_data && nla_len(param_data))
5292 value->vbool = nla_get_flag(param_data);
5298 static struct devlink_param_item *
5299 devlink_param_get_from_info(struct list_head *param_list,
5300 struct genl_info *info)
5304 if (!info->attrs[DEVLINK_ATTR_PARAM_NAME])
5307 param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]);
5308 return devlink_param_find_by_name(param_list, param_name);
5311 static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb,
5312 struct genl_info *info)
5314 struct devlink *devlink = info->user_ptr[0];
5315 struct devlink_param_item *param_item;
5316 struct sk_buff *msg;
5319 param_item = devlink_param_get_from_info(&devlink->param_list, info);
5323 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5327 err = devlink_nl_param_fill(msg, devlink, 0, param_item,
5328 DEVLINK_CMD_PARAM_GET,
5329 info->snd_portid, info->snd_seq, 0);
5335 return genlmsg_reply(msg, info);
5338 static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink,
5339 unsigned int port_index,
5340 struct list_head *param_list,
5341 struct genl_info *info,
5342 enum devlink_command cmd)
5344 enum devlink_param_type param_type;
5345 struct devlink_param_gset_ctx ctx;
5346 enum devlink_param_cmode cmode;
5347 struct devlink_param_item *param_item;
5348 const struct devlink_param *param;
5349 union devlink_param_value value;
5352 param_item = devlink_param_get_from_info(param_list, info);
5355 param = param_item->param;
5356 err = devlink_param_type_get_from_info(info, ¶m_type);
5359 if (param_type != param->type)
5361 err = devlink_param_value_get_from_info(param, info, &value);
5364 if (param->validate) {
5365 err = param->validate(devlink, param->id, value, info->extack);
5370 if (!info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE])
5372 cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]);
5373 if (!devlink_param_cmode_is_supported(param, cmode))
5376 if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) {
5377 if (param->type == DEVLINK_PARAM_TYPE_STRING)
5378 strcpy(param_item->driverinit_value.vstr, value.vstr);
5380 param_item->driverinit_value = value;
5381 param_item->driverinit_value_valid = true;
5387 err = devlink_param_set(devlink, param, &ctx);
5392 devlink_param_notify(devlink, port_index, param_item, cmd);
5396 static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb,
5397 struct genl_info *info)
5399 struct devlink *devlink = info->user_ptr[0];
5401 return __devlink_nl_cmd_param_set_doit(devlink, 0, &devlink->param_list,
5402 info, DEVLINK_CMD_PARAM_NEW);
5405 static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg,
5406 struct netlink_callback *cb)
5408 struct devlink_param_item *param_item;
5409 struct devlink_port *devlink_port;
5410 struct devlink *devlink;
5411 int start = cb->args[0];
5412 unsigned long index;
5416 mutex_lock(&devlink_mutex);
5417 devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
5419 list_for_each_entry(devlink_port, &devlink->port_list, list) {
5420 list_for_each_entry(param_item,
5421 &devlink_port->param_list, list) {
5426 err = devlink_nl_param_fill(msg,
5427 devlink_port->devlink,
5428 devlink_port->index, param_item,
5429 DEVLINK_CMD_PORT_PARAM_GET,
5430 NETLINK_CB(cb->skb).portid,
5433 if (err == -EOPNOTSUPP) {
5436 devl_unlock(devlink);
5437 devlink_put(devlink);
5443 devl_unlock(devlink);
5444 devlink_put(devlink);
5447 mutex_unlock(&devlink_mutex);
5449 if (err != -EMSGSIZE)
5456 static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb,
5457 struct genl_info *info)
5459 struct devlink_port *devlink_port = info->user_ptr[1];
5460 struct devlink_param_item *param_item;
5461 struct sk_buff *msg;
5464 param_item = devlink_param_get_from_info(&devlink_port->param_list,
5469 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5473 err = devlink_nl_param_fill(msg, devlink_port->devlink,
5474 devlink_port->index, param_item,
5475 DEVLINK_CMD_PORT_PARAM_GET,
5476 info->snd_portid, info->snd_seq, 0);
5482 return genlmsg_reply(msg, info);
5485 static int devlink_nl_cmd_port_param_set_doit(struct sk_buff *skb,
5486 struct genl_info *info)
5488 struct devlink_port *devlink_port = info->user_ptr[1];
5490 return __devlink_nl_cmd_param_set_doit(devlink_port->devlink,
5491 devlink_port->index,
5492 &devlink_port->param_list, info,
5493 DEVLINK_CMD_PORT_PARAM_NEW);
5496 static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg,
5497 struct devlink *devlink,
5498 struct devlink_snapshot *snapshot)
5500 struct nlattr *snap_attr;
5503 snap_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_SNAPSHOT);
5507 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, snapshot->id);
5509 goto nla_put_failure;
5511 nla_nest_end(msg, snap_attr);
5515 nla_nest_cancel(msg, snap_attr);
5519 static int devlink_nl_region_snapshots_id_put(struct sk_buff *msg,
5520 struct devlink *devlink,
5521 struct devlink_region *region)
5523 struct devlink_snapshot *snapshot;
5524 struct nlattr *snapshots_attr;
5527 snapshots_attr = nla_nest_start_noflag(msg,
5528 DEVLINK_ATTR_REGION_SNAPSHOTS);
5529 if (!snapshots_attr)
5532 list_for_each_entry(snapshot, ®ion->snapshot_list, list) {
5533 err = devlink_nl_region_snapshot_id_put(msg, devlink, snapshot);
5535 goto nla_put_failure;
5538 nla_nest_end(msg, snapshots_attr);
5542 nla_nest_cancel(msg, snapshots_attr);
5546 static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink,
5547 enum devlink_command cmd, u32 portid,
5549 struct devlink_region *region)
5554 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
5558 err = devlink_nl_put_handle(msg, devlink);
5560 goto nla_put_failure;
5563 err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
5564 region->port->index);
5566 goto nla_put_failure;
5569 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->ops->name);
5571 goto nla_put_failure;
5573 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
5577 goto nla_put_failure;
5579 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_MAX_SNAPSHOTS,
5580 region->max_snapshots);
5582 goto nla_put_failure;
5584 err = devlink_nl_region_snapshots_id_put(msg, devlink, region);
5586 goto nla_put_failure;
5588 genlmsg_end(msg, hdr);
5592 genlmsg_cancel(msg, hdr);
5596 static struct sk_buff *
5597 devlink_nl_region_notify_build(struct devlink_region *region,
5598 struct devlink_snapshot *snapshot,
5599 enum devlink_command cmd, u32 portid, u32 seq)
5601 struct devlink *devlink = region->devlink;
5602 struct sk_buff *msg;
5607 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5609 return ERR_PTR(-ENOMEM);
5611 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, 0, cmd);
5617 err = devlink_nl_put_handle(msg, devlink);
5619 goto out_cancel_msg;
5622 err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
5623 region->port->index);
5625 goto out_cancel_msg;
5628 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME,
5631 goto out_cancel_msg;
5634 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID,
5637 goto out_cancel_msg;
5639 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
5640 region->size, DEVLINK_ATTR_PAD);
5642 goto out_cancel_msg;
5644 genlmsg_end(msg, hdr);
5649 genlmsg_cancel(msg, hdr);
5652 return ERR_PTR(err);
5655 static void devlink_nl_region_notify(struct devlink_region *region,
5656 struct devlink_snapshot *snapshot,
5657 enum devlink_command cmd)
5659 struct devlink *devlink = region->devlink;
5660 struct sk_buff *msg;
5662 WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL);
5663 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
5666 msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0);
5670 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
5671 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
5675 * __devlink_snapshot_id_increment - Increment number of snapshots using an id
5676 * @devlink: devlink instance
5677 * @id: the snapshot id
5679 * Track when a new snapshot begins using an id. Load the count for the
5680 * given id from the snapshot xarray, increment it, and store it back.
5682 * Called when a new snapshot is created with the given id.
5684 * The id *must* have been previously allocated by
5685 * devlink_region_snapshot_id_get().
5687 * Returns 0 on success, or an error on failure.
5689 static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id)
5691 unsigned long count;
5694 devl_assert_locked(devlink);
5696 p = xa_load(&devlink->snapshot_ids, id);
5700 if (WARN_ON(!xa_is_value(p)))
5703 count = xa_to_value(p);
5706 return xa_err(xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
5711 * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id
5712 * @devlink: devlink instance
5713 * @id: the snapshot id
5715 * Track when a snapshot is deleted and stops using an id. Load the count
5716 * for the given id from the snapshot xarray, decrement it, and store it
5719 * If the count reaches zero, erase this id from the xarray, freeing it
5720 * up for future re-use by devlink_region_snapshot_id_get().
5722 * Called when a snapshot using the given id is deleted, and when the
5723 * initial allocator of the id is finished using it.
5725 static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id)
5727 unsigned long count;
5730 devl_assert_locked(devlink);
5732 p = xa_load(&devlink->snapshot_ids, id);
5736 if (WARN_ON(!xa_is_value(p)))
5739 count = xa_to_value(p);
5743 xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
5746 /* If this was the last user, we can erase this id */
5747 xa_erase(&devlink->snapshot_ids, id);
5752 * __devlink_snapshot_id_insert - Insert a specific snapshot ID
5753 * @devlink: devlink instance
5754 * @id: the snapshot id
5756 * Mark the given snapshot id as used by inserting a zero value into the
5759 * This must be called while holding the devlink instance lock. Unlike
5760 * devlink_snapshot_id_get, the initial reference count is zero, not one.
5761 * It is expected that the id will immediately be used before
5762 * releasing the devlink instance lock.
5764 * Returns zero on success, or an error code if the snapshot id could not
5767 static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id)
5769 devl_assert_locked(devlink);
5771 if (xa_load(&devlink->snapshot_ids, id))
5774 return xa_err(xa_store(&devlink->snapshot_ids, id, xa_mk_value(0),
5779 * __devlink_region_snapshot_id_get - get snapshot ID
5780 * @devlink: devlink instance
5781 * @id: storage to return snapshot id
5783 * Allocates a new snapshot id. Returns zero on success, or a negative
5784 * error on failure. Must be called while holding the devlink instance
5787 * Snapshot IDs are tracked using an xarray which stores the number of
5788 * users of the snapshot id.
5790 * Note that the caller of this function counts as a 'user', in order to
5791 * avoid race conditions. The caller must release its hold on the
5792 * snapshot by using devlink_region_snapshot_id_put.
5794 static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
5796 devl_assert_locked(devlink);
5798 return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1),
5799 xa_limit_32b, GFP_KERNEL);
5803 * __devlink_region_snapshot_create - create a new snapshot
5804 * This will add a new snapshot of a region. The snapshot
5805 * will be stored on the region struct and can be accessed
5806 * from devlink. This is useful for future analyses of snapshots.
5807 * Multiple snapshots can be created on a region.
5808 * The @snapshot_id should be obtained using the getter function.
5810 * Must be called only while holding the devlink instance lock.
5812 * @region: devlink region of the snapshot
5813 * @data: snapshot data
5814 * @snapshot_id: snapshot id to be created
5817 __devlink_region_snapshot_create(struct devlink_region *region,
5818 u8 *data, u32 snapshot_id)
5820 struct devlink *devlink = region->devlink;
5821 struct devlink_snapshot *snapshot;
5824 devl_assert_locked(devlink);
5826 /* check if region can hold one more snapshot */
5827 if (region->cur_snapshots == region->max_snapshots)
5830 if (devlink_region_snapshot_get_by_id(region, snapshot_id))
5833 snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL);
5837 err = __devlink_snapshot_id_increment(devlink, snapshot_id);
5839 goto err_snapshot_id_increment;
5841 snapshot->id = snapshot_id;
5842 snapshot->region = region;
5843 snapshot->data = data;
5845 list_add_tail(&snapshot->list, ®ion->snapshot_list);
5847 region->cur_snapshots++;
5849 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW);
5852 err_snapshot_id_increment:
5857 static void devlink_region_snapshot_del(struct devlink_region *region,
5858 struct devlink_snapshot *snapshot)
5860 struct devlink *devlink = region->devlink;
5862 devl_assert_locked(devlink);
5864 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL);
5865 region->cur_snapshots--;
5866 list_del(&snapshot->list);
5867 region->ops->destructor(snapshot->data);
5868 __devlink_snapshot_id_decrement(devlink, snapshot->id);
5872 static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb,
5873 struct genl_info *info)
5875 struct devlink *devlink = info->user_ptr[0];
5876 struct devlink_port *port = NULL;
5877 struct devlink_region *region;
5878 const char *region_name;
5879 struct sk_buff *msg;
5883 if (!info->attrs[DEVLINK_ATTR_REGION_NAME])
5886 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
5887 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
5889 port = devlink_port_get_by_index(devlink, index);
5894 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
5896 region = devlink_port_region_get_by_name(port, region_name);
5898 region = devlink_region_get_by_name(devlink, region_name);
5903 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5907 err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET,
5908 info->snd_portid, info->snd_seq, 0,
5915 return genlmsg_reply(msg, info);
5918 static int devlink_nl_cmd_region_get_port_dumpit(struct sk_buff *msg,
5919 struct netlink_callback *cb,
5920 struct devlink_port *port,
5924 struct devlink_region *region;
5927 list_for_each_entry(region, &port->region_list, list) {
5932 err = devlink_nl_region_fill(msg, port->devlink,
5933 DEVLINK_CMD_REGION_GET,
5934 NETLINK_CB(cb->skb).portid,
5936 NLM_F_MULTI, region);
5946 static int devlink_nl_cmd_region_get_devlink_dumpit(struct sk_buff *msg,
5947 struct netlink_callback *cb,
5948 struct devlink *devlink,
5952 struct devlink_region *region;
5953 struct devlink_port *port;
5957 list_for_each_entry(region, &devlink->region_list, list) {
5962 err = devlink_nl_region_fill(msg, devlink,
5963 DEVLINK_CMD_REGION_GET,
5964 NETLINK_CB(cb->skb).portid,
5966 NLM_F_MULTI, region);
5972 list_for_each_entry(port, &devlink->port_list, list) {
5973 err = devlink_nl_cmd_region_get_port_dumpit(msg, cb, port, idx,
5980 devl_unlock(devlink);
5984 static int devlink_nl_cmd_region_get_dumpit(struct sk_buff *msg,
5985 struct netlink_callback *cb)
5987 struct devlink *devlink;
5988 int start = cb->args[0];
5989 unsigned long index;
5993 mutex_lock(&devlink_mutex);
5994 devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
5995 err = devlink_nl_cmd_region_get_devlink_dumpit(msg, cb, devlink,
5997 devlink_put(devlink);
6002 mutex_unlock(&devlink_mutex);
6007 static int devlink_nl_cmd_region_del(struct sk_buff *skb,
6008 struct genl_info *info)
6010 struct devlink *devlink = info->user_ptr[0];
6011 struct devlink_snapshot *snapshot;
6012 struct devlink_port *port = NULL;
6013 struct devlink_region *region;
6014 const char *region_name;
6018 if (!info->attrs[DEVLINK_ATTR_REGION_NAME] ||
6019 !info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID])
6022 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
6023 snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
6025 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
6026 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
6028 port = devlink_port_get_by_index(devlink, index);
6034 region = devlink_port_region_get_by_name(port, region_name);
6036 region = devlink_region_get_by_name(devlink, region_name);
6041 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
6045 devlink_region_snapshot_del(region, snapshot);
6050 devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
6052 struct devlink *devlink = info->user_ptr[0];
6053 struct devlink_snapshot *snapshot;
6054 struct devlink_port *port = NULL;
6055 struct nlattr *snapshot_id_attr;
6056 struct devlink_region *region;
6057 const char *region_name;
6063 if (!info->attrs[DEVLINK_ATTR_REGION_NAME]) {
6064 NL_SET_ERR_MSG_MOD(info->extack, "No region name provided");
6068 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
6070 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
6071 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
6073 port = devlink_port_get_by_index(devlink, index);
6079 region = devlink_port_region_get_by_name(port, region_name);
6081 region = devlink_region_get_by_name(devlink, region_name);
6084 NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not exist");
6088 if (!region->ops->snapshot) {
6089 NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not support taking an immediate snapshot");
6093 if (region->cur_snapshots == region->max_snapshots) {
6094 NL_SET_ERR_MSG_MOD(info->extack, "The region has reached the maximum number of stored snapshots");
6098 snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID];
6099 if (snapshot_id_attr) {
6100 snapshot_id = nla_get_u32(snapshot_id_attr);
6102 if (devlink_region_snapshot_get_by_id(region, snapshot_id)) {
6103 NL_SET_ERR_MSG_MOD(info->extack, "The requested snapshot id is already in use");
6107 err = __devlink_snapshot_id_insert(devlink, snapshot_id);
6111 err = __devlink_region_snapshot_id_get(devlink, &snapshot_id);
6113 NL_SET_ERR_MSG_MOD(info->extack, "Failed to allocate a new snapshot id");
6119 err = region->port_ops->snapshot(port, region->port_ops,
6120 info->extack, &data);
6122 err = region->ops->snapshot(devlink, region->ops,
6123 info->extack, &data);
6125 goto err_snapshot_capture;
6127 err = __devlink_region_snapshot_create(region, data, snapshot_id);
6129 goto err_snapshot_create;
6131 if (!snapshot_id_attr) {
6132 struct sk_buff *msg;
6134 snapshot = devlink_region_snapshot_get_by_id(region,
6136 if (WARN_ON(!snapshot))
6139 msg = devlink_nl_region_notify_build(region, snapshot,
6140 DEVLINK_CMD_REGION_NEW,
6143 err = PTR_ERR_OR_ZERO(msg);
6147 err = genlmsg_reply(msg, info);
6154 err_snapshot_create:
6155 region->ops->destructor(data);
6156 err_snapshot_capture:
6157 __devlink_snapshot_id_decrement(devlink, snapshot_id);
6161 devlink_region_snapshot_del(region, snapshot);
6165 static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg,
6166 struct devlink *devlink,
6167 u8 *chunk, u32 chunk_size,
6170 struct nlattr *chunk_attr;
6173 chunk_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_CHUNK);
6177 err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk);
6179 goto nla_put_failure;
6181 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr,
6184 goto nla_put_failure;
6186 nla_nest_end(msg, chunk_attr);
6190 nla_nest_cancel(msg, chunk_attr);
6194 #define DEVLINK_REGION_READ_CHUNK_SIZE 256
6196 static int devlink_nl_region_read_snapshot_fill(struct sk_buff *skb,
6197 struct devlink *devlink,
6198 struct devlink_region *region,
6199 struct nlattr **attrs,
6204 struct devlink_snapshot *snapshot;
6205 u64 curr_offset = start_offset;
6209 *new_offset = start_offset;
6211 snapshot_id = nla_get_u32(attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
6212 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
6216 while (curr_offset < end_offset) {
6220 if (end_offset - curr_offset < DEVLINK_REGION_READ_CHUNK_SIZE)
6221 data_size = end_offset - curr_offset;
6223 data_size = DEVLINK_REGION_READ_CHUNK_SIZE;
6225 data = &snapshot->data[curr_offset];
6226 err = devlink_nl_cmd_region_read_chunk_fill(skb, devlink,
6232 curr_offset += data_size;
6234 *new_offset = curr_offset;
6239 static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
6240 struct netlink_callback *cb)
6242 const struct genl_dumpit_info *info = genl_dumpit_info(cb);
6243 u64 ret_offset, start_offset, end_offset = U64_MAX;
6244 struct nlattr **attrs = info->attrs;
6245 struct devlink_port *port = NULL;
6246 struct devlink_region *region;
6247 struct nlattr *chunks_attr;
6248 const char *region_name;
6249 struct devlink *devlink;
6254 start_offset = *((u64 *)&cb->args[0]);
6256 mutex_lock(&devlink_mutex);
6257 devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs);
6258 if (IS_ERR(devlink)) {
6259 err = PTR_ERR(devlink);
6265 if (!attrs[DEVLINK_ATTR_REGION_NAME] ||
6266 !attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]) {
6271 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
6272 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
6274 port = devlink_port_get_by_index(devlink, index);
6281 region_name = nla_data(attrs[DEVLINK_ATTR_REGION_NAME]);
6284 region = devlink_port_region_get_by_name(port, region_name);
6286 region = devlink_region_get_by_name(devlink, region_name);
6293 if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] &&
6294 attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) {
6297 nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
6299 end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
6300 end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]);
6303 if (end_offset > region->size)
6304 end_offset = region->size;
6306 /* return 0 if there is no further data to read */
6307 if (start_offset == end_offset) {
6312 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
6313 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI,
6314 DEVLINK_CMD_REGION_READ);
6320 err = devlink_nl_put_handle(skb, devlink);
6322 goto nla_put_failure;
6325 err = nla_put_u32(skb, DEVLINK_ATTR_PORT_INDEX,
6326 region->port->index);
6328 goto nla_put_failure;
6331 err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name);
6333 goto nla_put_failure;
6335 chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS);
6338 goto nla_put_failure;
6341 err = devlink_nl_region_read_snapshot_fill(skb, devlink,
6344 end_offset, &ret_offset);
6346 if (err && err != -EMSGSIZE)
6347 goto nla_put_failure;
6349 /* Check if there was any progress done to prevent infinite loop */
6350 if (ret_offset == start_offset) {
6352 goto nla_put_failure;
6355 *((u64 *)&cb->args[0]) = ret_offset;
6357 nla_nest_end(skb, chunks_attr);
6358 genlmsg_end(skb, hdr);
6359 devl_unlock(devlink);
6360 devlink_put(devlink);
6361 mutex_unlock(&devlink_mutex);
6366 genlmsg_cancel(skb, hdr);
6368 devl_unlock(devlink);
6369 devlink_put(devlink);
6371 mutex_unlock(&devlink_mutex);
6375 struct devlink_info_req {
6376 struct sk_buff *msg;
6379 int devlink_info_driver_name_put(struct devlink_info_req *req, const char *name)
6381 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME, name);
6383 EXPORT_SYMBOL_GPL(devlink_info_driver_name_put);
6385 int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn)
6387 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn);
6389 EXPORT_SYMBOL_GPL(devlink_info_serial_number_put);
6391 int devlink_info_board_serial_number_put(struct devlink_info_req *req,
6394 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER,
6397 EXPORT_SYMBOL_GPL(devlink_info_board_serial_number_put);
6399 static int devlink_info_version_put(struct devlink_info_req *req, int attr,
6400 const char *version_name,
6401 const char *version_value)
6403 struct nlattr *nest;
6406 nest = nla_nest_start_noflag(req->msg, attr);
6410 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME,
6413 goto nla_put_failure;
6415 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE,
6418 goto nla_put_failure;
6420 nla_nest_end(req->msg, nest);
6425 nla_nest_cancel(req->msg, nest);
6429 int devlink_info_version_fixed_put(struct devlink_info_req *req,
6430 const char *version_name,
6431 const char *version_value)
6433 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED,
6434 version_name, version_value);
6436 EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put);
6438 int devlink_info_version_stored_put(struct devlink_info_req *req,
6439 const char *version_name,
6440 const char *version_value)
6442 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED,
6443 version_name, version_value);
6445 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put);
6447 int devlink_info_version_running_put(struct devlink_info_req *req,
6448 const char *version_name,
6449 const char *version_value)
6451 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING,
6452 version_name, version_value);
6454 EXPORT_SYMBOL_GPL(devlink_info_version_running_put);
6457 devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
6458 enum devlink_command cmd, u32 portid,
6459 u32 seq, int flags, struct netlink_ext_ack *extack)
6461 struct devlink_info_req req;
6465 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
6470 if (devlink_nl_put_handle(msg, devlink))
6471 goto err_cancel_msg;
6474 err = devlink->ops->info_get(devlink, &req, extack);
6476 goto err_cancel_msg;
6478 genlmsg_end(msg, hdr);
6482 genlmsg_cancel(msg, hdr);
6486 static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb,
6487 struct genl_info *info)
6489 struct devlink *devlink = info->user_ptr[0];
6490 struct sk_buff *msg;
6493 if (!devlink->ops->info_get)
6496 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6500 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
6501 info->snd_portid, info->snd_seq, 0,
6508 return genlmsg_reply(msg, info);
6511 static int devlink_nl_cmd_info_get_dumpit(struct sk_buff *msg,
6512 struct netlink_callback *cb)
6514 struct devlink *devlink;
6515 int start = cb->args[0];
6516 unsigned long index;
6520 mutex_lock(&devlink_mutex);
6521 devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
6522 if (idx < start || !devlink->ops->info_get)
6526 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
6527 NETLINK_CB(cb->skb).portid,
6528 cb->nlh->nlmsg_seq, NLM_F_MULTI,
6530 devl_unlock(devlink);
6531 if (err == -EOPNOTSUPP)
6534 devlink_put(devlink);
6539 devlink_put(devlink);
6541 mutex_unlock(&devlink_mutex);
6543 if (err != -EMSGSIZE)
6550 struct devlink_fmsg_item {
6551 struct list_head list;
6558 struct devlink_fmsg {
6559 struct list_head item_list;
6560 bool putting_binary; /* This flag forces enclosing of binary data
6561 * in an array brackets. It forces using
6562 * of designated API:
6563 * devlink_fmsg_binary_pair_nest_start()
6564 * devlink_fmsg_binary_pair_nest_end()
6568 static struct devlink_fmsg *devlink_fmsg_alloc(void)
6570 struct devlink_fmsg *fmsg;
6572 fmsg = kzalloc(sizeof(*fmsg), GFP_KERNEL);
6576 INIT_LIST_HEAD(&fmsg->item_list);
6581 static void devlink_fmsg_free(struct devlink_fmsg *fmsg)
6583 struct devlink_fmsg_item *item, *tmp;
6585 list_for_each_entry_safe(item, tmp, &fmsg->item_list, list) {
6586 list_del(&item->list);
6592 static int devlink_fmsg_nest_common(struct devlink_fmsg *fmsg,
6595 struct devlink_fmsg_item *item;
6597 item = kzalloc(sizeof(*item), GFP_KERNEL);
6601 item->attrtype = attrtype;
6602 list_add_tail(&item->list, &fmsg->item_list);
6607 int devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg)
6609 if (fmsg->putting_binary)
6612 return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_OBJ_NEST_START);
6614 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start);
6616 static int devlink_fmsg_nest_end(struct devlink_fmsg *fmsg)
6618 if (fmsg->putting_binary)
6621 return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_NEST_END);
6624 int devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg)
6626 if (fmsg->putting_binary)
6629 return devlink_fmsg_nest_end(fmsg);
6631 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end);
6633 #define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN)
6635 static int devlink_fmsg_put_name(struct devlink_fmsg *fmsg, const char *name)
6637 struct devlink_fmsg_item *item;
6639 if (fmsg->putting_binary)
6642 if (strlen(name) + 1 > DEVLINK_FMSG_MAX_SIZE)
6645 item = kzalloc(sizeof(*item) + strlen(name) + 1, GFP_KERNEL);
6649 item->nla_type = NLA_NUL_STRING;
6650 item->len = strlen(name) + 1;
6651 item->attrtype = DEVLINK_ATTR_FMSG_OBJ_NAME;
6652 memcpy(&item->value, name, item->len);
6653 list_add_tail(&item->list, &fmsg->item_list);
6658 int devlink_fmsg_pair_nest_start(struct devlink_fmsg *fmsg, const char *name)
6662 if (fmsg->putting_binary)
6665 err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_PAIR_NEST_START);
6669 err = devlink_fmsg_put_name(fmsg, name);
6675 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start);
6677 int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg)
6679 if (fmsg->putting_binary)
6682 return devlink_fmsg_nest_end(fmsg);
6684 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end);
6686 int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg,
6691 if (fmsg->putting_binary)
6694 err = devlink_fmsg_pair_nest_start(fmsg, name);
6698 err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_ARR_NEST_START);
6704 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start);
6706 int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg)
6710 if (fmsg->putting_binary)
6713 err = devlink_fmsg_nest_end(fmsg);
6717 err = devlink_fmsg_nest_end(fmsg);
6723 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end);
6725 int devlink_fmsg_binary_pair_nest_start(struct devlink_fmsg *fmsg,
6730 err = devlink_fmsg_arr_pair_nest_start(fmsg, name);
6734 fmsg->putting_binary = true;
6737 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_start);
6739 int devlink_fmsg_binary_pair_nest_end(struct devlink_fmsg *fmsg)
6741 if (!fmsg->putting_binary)
6744 fmsg->putting_binary = false;
6745 return devlink_fmsg_arr_pair_nest_end(fmsg);
6747 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_end);
6749 static int devlink_fmsg_put_value(struct devlink_fmsg *fmsg,
6750 const void *value, u16 value_len,
6753 struct devlink_fmsg_item *item;
6755 if (value_len > DEVLINK_FMSG_MAX_SIZE)
6758 item = kzalloc(sizeof(*item) + value_len, GFP_KERNEL);
6762 item->nla_type = value_nla_type;
6763 item->len = value_len;
6764 item->attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
6765 memcpy(&item->value, value, item->len);
6766 list_add_tail(&item->list, &fmsg->item_list);
6771 static int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value)
6773 if (fmsg->putting_binary)
6776 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_FLAG);
6779 static int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value)
6781 if (fmsg->putting_binary)
6784 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U8);
6787 int devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value)
6789 if (fmsg->putting_binary)
6792 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U32);
6794 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put);
6796 static int devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value)
6798 if (fmsg->putting_binary)
6801 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U64);
6804 int devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value)
6806 if (fmsg->putting_binary)
6809 return devlink_fmsg_put_value(fmsg, value, strlen(value) + 1,
6812 EXPORT_SYMBOL_GPL(devlink_fmsg_string_put);
6814 int devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value,
6817 if (!fmsg->putting_binary)
6820 return devlink_fmsg_put_value(fmsg, value, value_len, NLA_BINARY);
6822 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put);
6824 int devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name,
6829 err = devlink_fmsg_pair_nest_start(fmsg, name);
6833 err = devlink_fmsg_bool_put(fmsg, value);
6837 err = devlink_fmsg_pair_nest_end(fmsg);
6843 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put);
6845 int devlink_fmsg_u8_pair_put(struct devlink_fmsg *fmsg, const char *name,
6850 err = devlink_fmsg_pair_nest_start(fmsg, name);
6854 err = devlink_fmsg_u8_put(fmsg, value);
6858 err = devlink_fmsg_pair_nest_end(fmsg);
6864 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put);
6866 int devlink_fmsg_u32_pair_put(struct devlink_fmsg *fmsg, const char *name,
6871 err = devlink_fmsg_pair_nest_start(fmsg, name);
6875 err = devlink_fmsg_u32_put(fmsg, value);
6879 err = devlink_fmsg_pair_nest_end(fmsg);
6885 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put);
6887 int devlink_fmsg_u64_pair_put(struct devlink_fmsg *fmsg, const char *name,
6892 err = devlink_fmsg_pair_nest_start(fmsg, name);
6896 err = devlink_fmsg_u64_put(fmsg, value);
6900 err = devlink_fmsg_pair_nest_end(fmsg);
6906 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put);
6908 int devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name,
6913 err = devlink_fmsg_pair_nest_start(fmsg, name);
6917 err = devlink_fmsg_string_put(fmsg, value);
6921 err = devlink_fmsg_pair_nest_end(fmsg);
6927 EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put);
6929 int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name,
6930 const void *value, u32 value_len)
6937 err = devlink_fmsg_binary_pair_nest_start(fmsg, name);
6941 for (offset = 0; offset < value_len; offset += data_size) {
6942 data_size = value_len - offset;
6943 if (data_size > DEVLINK_FMSG_MAX_SIZE)
6944 data_size = DEVLINK_FMSG_MAX_SIZE;
6945 err = devlink_fmsg_binary_put(fmsg, value + offset, data_size);
6948 /* Exit from loop with a break (instead of
6949 * return) to make sure putting_binary is turned off in
6950 * devlink_fmsg_binary_pair_nest_end
6954 end_err = devlink_fmsg_binary_pair_nest_end(fmsg);
6960 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put);
6963 devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb)
6965 switch (msg->nla_type) {
6970 case NLA_NUL_STRING:
6972 return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE,
6980 devlink_fmsg_item_fill_data(struct devlink_fmsg_item *msg, struct sk_buff *skb)
6982 int attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
6985 switch (msg->nla_type) {
6987 /* Always provide flag data, regardless of its value */
6988 tmp = *(bool *) msg->value;
6990 return nla_put_u8(skb, attrtype, tmp);
6992 return nla_put_u8(skb, attrtype, *(u8 *) msg->value);
6994 return nla_put_u32(skb, attrtype, *(u32 *) msg->value);
6996 return nla_put_u64_64bit(skb, attrtype, *(u64 *) msg->value,
6998 case NLA_NUL_STRING:
6999 return nla_put_string(skb, attrtype, (char *) &msg->value);
7001 return nla_put(skb, attrtype, msg->len, (void *) &msg->value);
7008 devlink_fmsg_prepare_skb(struct devlink_fmsg *fmsg, struct sk_buff *skb,
7011 struct devlink_fmsg_item *item;
7012 struct nlattr *fmsg_nlattr;
7016 fmsg_nlattr = nla_nest_start_noflag(skb, DEVLINK_ATTR_FMSG);
7020 list_for_each_entry(item, &fmsg->item_list, list) {
7026 switch (item->attrtype) {
7027 case DEVLINK_ATTR_FMSG_OBJ_NEST_START:
7028 case DEVLINK_ATTR_FMSG_PAIR_NEST_START:
7029 case DEVLINK_ATTR_FMSG_ARR_NEST_START:
7030 case DEVLINK_ATTR_FMSG_NEST_END:
7031 err = nla_put_flag(skb, item->attrtype);
7033 case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA:
7034 err = devlink_fmsg_item_fill_type(item, skb);
7037 err = devlink_fmsg_item_fill_data(item, skb);
7039 case DEVLINK_ATTR_FMSG_OBJ_NAME:
7040 err = nla_put_string(skb, item->attrtype,
7041 (char *) &item->value);
7053 nla_nest_end(skb, fmsg_nlattr);
7057 static int devlink_fmsg_snd(struct devlink_fmsg *fmsg,
7058 struct genl_info *info,
7059 enum devlink_command cmd, int flags)
7061 struct nlmsghdr *nlh;
7062 struct sk_buff *skb;
7069 int tmp_index = index;
7071 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
7075 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
7076 &devlink_nl_family, flags | NLM_F_MULTI, cmd);
7079 goto nla_put_failure;
7082 err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
7085 else if (err != -EMSGSIZE || tmp_index == index)
7086 goto nla_put_failure;
7088 genlmsg_end(skb, hdr);
7089 err = genlmsg_reply(skb, info);
7094 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
7097 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
7098 NLMSG_DONE, 0, flags | NLM_F_MULTI);
7101 goto nla_put_failure;
7104 return genlmsg_reply(skb, info);
7111 static int devlink_fmsg_dumpit(struct devlink_fmsg *fmsg, struct sk_buff *skb,
7112 struct netlink_callback *cb,
7113 enum devlink_command cmd)
7115 int index = cb->args[0];
7116 int tmp_index = index;
7120 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
7121 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, cmd);
7124 goto nla_put_failure;
7127 err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
7128 if ((err && err != -EMSGSIZE) || tmp_index == index)
7129 goto nla_put_failure;
7131 cb->args[0] = index;
7132 genlmsg_end(skb, hdr);
7136 genlmsg_cancel(skb, hdr);
7140 struct devlink_health_reporter {
7141 struct list_head list;
7143 const struct devlink_health_reporter_ops *ops;
7144 struct devlink *devlink;
7145 struct devlink_port *devlink_port;
7146 struct devlink_fmsg *dump_fmsg;
7147 struct mutex dump_lock; /* lock parallel read/write from dump buffers */
7148 u64 graceful_period;
7156 u64 last_recovery_ts;
7157 refcount_t refcount;
7161 devlink_health_reporter_priv(struct devlink_health_reporter *reporter)
7163 return reporter->priv;
7165 EXPORT_SYMBOL_GPL(devlink_health_reporter_priv);
7167 static struct devlink_health_reporter *
7168 __devlink_health_reporter_find_by_name(struct list_head *reporter_list,
7169 struct mutex *list_lock,
7170 const char *reporter_name)
7172 struct devlink_health_reporter *reporter;
7174 lockdep_assert_held(list_lock);
7175 list_for_each_entry(reporter, reporter_list, list)
7176 if (!strcmp(reporter->ops->name, reporter_name))
7181 static struct devlink_health_reporter *
7182 devlink_health_reporter_find_by_name(struct devlink *devlink,
7183 const char *reporter_name)
7185 return __devlink_health_reporter_find_by_name(&devlink->reporter_list,
7186 &devlink->reporters_lock,
7190 static struct devlink_health_reporter *
7191 devlink_port_health_reporter_find_by_name(struct devlink_port *devlink_port,
7192 const char *reporter_name)
7194 return __devlink_health_reporter_find_by_name(&devlink_port->reporter_list,
7195 &devlink_port->reporters_lock,
7199 static struct devlink_health_reporter *
7200 __devlink_health_reporter_create(struct devlink *devlink,
7201 const struct devlink_health_reporter_ops *ops,
7202 u64 graceful_period, void *priv)
7204 struct devlink_health_reporter *reporter;
7206 if (WARN_ON(graceful_period && !ops->recover))
7207 return ERR_PTR(-EINVAL);
7209 reporter = kzalloc(sizeof(*reporter), GFP_KERNEL);
7211 return ERR_PTR(-ENOMEM);
7213 reporter->priv = priv;
7214 reporter->ops = ops;
7215 reporter->devlink = devlink;
7216 reporter->graceful_period = graceful_period;
7217 reporter->auto_recover = !!ops->recover;
7218 reporter->auto_dump = !!ops->dump;
7219 mutex_init(&reporter->dump_lock);
7220 refcount_set(&reporter->refcount, 1);
7225 * devlink_port_health_reporter_create - create devlink health reporter for
7226 * specified port instance
7228 * @port: devlink_port which should contain the new reporter
7230 * @graceful_period: to avoid recovery loops, in msecs
7233 struct devlink_health_reporter *
7234 devlink_port_health_reporter_create(struct devlink_port *port,
7235 const struct devlink_health_reporter_ops *ops,
7236 u64 graceful_period, void *priv)
7238 struct devlink_health_reporter *reporter;
7240 mutex_lock(&port->reporters_lock);
7241 if (__devlink_health_reporter_find_by_name(&port->reporter_list,
7242 &port->reporters_lock, ops->name)) {
7243 reporter = ERR_PTR(-EEXIST);
7247 reporter = __devlink_health_reporter_create(port->devlink, ops,
7248 graceful_period, priv);
7249 if (IS_ERR(reporter))
7252 reporter->devlink_port = port;
7253 list_add_tail(&reporter->list, &port->reporter_list);
7255 mutex_unlock(&port->reporters_lock);
7258 EXPORT_SYMBOL_GPL(devlink_port_health_reporter_create);
7261 * devlink_health_reporter_create - create devlink health reporter
7265 * @graceful_period: to avoid recovery loops, in msecs
7268 struct devlink_health_reporter *
7269 devlink_health_reporter_create(struct devlink *devlink,
7270 const struct devlink_health_reporter_ops *ops,
7271 u64 graceful_period, void *priv)
7273 struct devlink_health_reporter *reporter;
7275 mutex_lock(&devlink->reporters_lock);
7276 if (devlink_health_reporter_find_by_name(devlink, ops->name)) {
7277 reporter = ERR_PTR(-EEXIST);
7281 reporter = __devlink_health_reporter_create(devlink, ops,
7282 graceful_period, priv);
7283 if (IS_ERR(reporter))
7286 list_add_tail(&reporter->list, &devlink->reporter_list);
7288 mutex_unlock(&devlink->reporters_lock);
7291 EXPORT_SYMBOL_GPL(devlink_health_reporter_create);
7294 devlink_health_reporter_free(struct devlink_health_reporter *reporter)
7296 mutex_destroy(&reporter->dump_lock);
7297 if (reporter->dump_fmsg)
7298 devlink_fmsg_free(reporter->dump_fmsg);
7303 devlink_health_reporter_put(struct devlink_health_reporter *reporter)
7305 if (refcount_dec_and_test(&reporter->refcount))
7306 devlink_health_reporter_free(reporter);
7310 __devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
7312 list_del(&reporter->list);
7313 devlink_health_reporter_put(reporter);
7317 * devlink_health_reporter_destroy - destroy devlink health reporter
7319 * @reporter: devlink health reporter to destroy
7322 devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
7324 struct mutex *lock = &reporter->devlink->reporters_lock;
7327 __devlink_health_reporter_destroy(reporter);
7330 EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy);
7333 * devlink_port_health_reporter_destroy - destroy devlink port health reporter
7335 * @reporter: devlink health reporter to destroy
7338 devlink_port_health_reporter_destroy(struct devlink_health_reporter *reporter)
7340 struct mutex *lock = &reporter->devlink_port->reporters_lock;
7343 __devlink_health_reporter_destroy(reporter);
7346 EXPORT_SYMBOL_GPL(devlink_port_health_reporter_destroy);
7349 devlink_nl_health_reporter_fill(struct sk_buff *msg,
7350 struct devlink_health_reporter *reporter,
7351 enum devlink_command cmd, u32 portid,
7354 struct devlink *devlink = reporter->devlink;
7355 struct nlattr *reporter_attr;
7358 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
7362 if (devlink_nl_put_handle(msg, devlink))
7363 goto genlmsg_cancel;
7365 if (reporter->devlink_port) {
7366 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, reporter->devlink_port->index))
7367 goto genlmsg_cancel;
7369 reporter_attr = nla_nest_start_noflag(msg,
7370 DEVLINK_ATTR_HEALTH_REPORTER);
7372 goto genlmsg_cancel;
7373 if (nla_put_string(msg, DEVLINK_ATTR_HEALTH_REPORTER_NAME,
7374 reporter->ops->name))
7375 goto reporter_nest_cancel;
7376 if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_STATE,
7377 reporter->health_state))
7378 goto reporter_nest_cancel;
7379 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT,
7380 reporter->error_count, DEVLINK_ATTR_PAD))
7381 goto reporter_nest_cancel;
7382 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT,
7383 reporter->recovery_count, DEVLINK_ATTR_PAD))
7384 goto reporter_nest_cancel;
7385 if (reporter->ops->recover &&
7386 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD,
7387 reporter->graceful_period,
7389 goto reporter_nest_cancel;
7390 if (reporter->ops->recover &&
7391 nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER,
7392 reporter->auto_recover))
7393 goto reporter_nest_cancel;
7394 if (reporter->dump_fmsg &&
7395 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS,
7396 jiffies_to_msecs(reporter->dump_ts),
7398 goto reporter_nest_cancel;
7399 if (reporter->dump_fmsg &&
7400 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS,
7401 reporter->dump_real_ts, DEVLINK_ATTR_PAD))
7402 goto reporter_nest_cancel;
7403 if (reporter->ops->dump &&
7404 nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP,
7405 reporter->auto_dump))
7406 goto reporter_nest_cancel;
7408 nla_nest_end(msg, reporter_attr);
7409 genlmsg_end(msg, hdr);
7412 reporter_nest_cancel:
7413 nla_nest_end(msg, reporter_attr);
7415 genlmsg_cancel(msg, hdr);
7419 static void devlink_recover_notify(struct devlink_health_reporter *reporter,
7420 enum devlink_command cmd)
7422 struct devlink *devlink = reporter->devlink;
7423 struct sk_buff *msg;
7426 WARN_ON(cmd != DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
7427 WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED));
7429 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7433 err = devlink_nl_health_reporter_fill(msg, reporter, cmd, 0, 0, 0);
7439 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
7440 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
7444 devlink_health_reporter_recovery_done(struct devlink_health_reporter *reporter)
7446 reporter->recovery_count++;
7447 reporter->last_recovery_ts = jiffies;
7449 EXPORT_SYMBOL_GPL(devlink_health_reporter_recovery_done);
7452 devlink_health_reporter_recover(struct devlink_health_reporter *reporter,
7453 void *priv_ctx, struct netlink_ext_ack *extack)
7457 if (reporter->health_state == DEVLINK_HEALTH_REPORTER_STATE_HEALTHY)
7460 if (!reporter->ops->recover)
7463 err = reporter->ops->recover(reporter, priv_ctx, extack);
7467 devlink_health_reporter_recovery_done(reporter);
7468 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY;
7469 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
7475 devlink_health_dump_clear(struct devlink_health_reporter *reporter)
7477 if (!reporter->dump_fmsg)
7479 devlink_fmsg_free(reporter->dump_fmsg);
7480 reporter->dump_fmsg = NULL;
7483 static int devlink_health_do_dump(struct devlink_health_reporter *reporter,
7485 struct netlink_ext_ack *extack)
7489 if (!reporter->ops->dump)
7492 if (reporter->dump_fmsg)
7495 reporter->dump_fmsg = devlink_fmsg_alloc();
7496 if (!reporter->dump_fmsg) {
7501 err = devlink_fmsg_obj_nest_start(reporter->dump_fmsg);
7505 err = reporter->ops->dump(reporter, reporter->dump_fmsg,
7510 err = devlink_fmsg_obj_nest_end(reporter->dump_fmsg);
7514 reporter->dump_ts = jiffies;
7515 reporter->dump_real_ts = ktime_get_real_ns();
7520 devlink_health_dump_clear(reporter);
7524 int devlink_health_report(struct devlink_health_reporter *reporter,
7525 const char *msg, void *priv_ctx)
7527 enum devlink_health_reporter_state prev_health_state;
7528 struct devlink *devlink = reporter->devlink;
7529 unsigned long recover_ts_threshold;
7531 /* write a log message of the current error */
7533 trace_devlink_health_report(devlink, reporter->ops->name, msg);
7534 reporter->error_count++;
7535 prev_health_state = reporter->health_state;
7536 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
7537 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
7539 /* abort if the previous error wasn't recovered */
7540 recover_ts_threshold = reporter->last_recovery_ts +
7541 msecs_to_jiffies(reporter->graceful_period);
7542 if (reporter->auto_recover &&
7543 (prev_health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY ||
7544 (reporter->last_recovery_ts && reporter->recovery_count &&
7545 time_is_after_jiffies(recover_ts_threshold)))) {
7546 trace_devlink_health_recover_aborted(devlink,
7547 reporter->ops->name,
7548 reporter->health_state,
7550 reporter->last_recovery_ts);
7554 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
7556 if (reporter->auto_dump) {
7557 mutex_lock(&reporter->dump_lock);
7558 /* store current dump of current error, for later analysis */
7559 devlink_health_do_dump(reporter, priv_ctx, NULL);
7560 mutex_unlock(&reporter->dump_lock);
7563 if (reporter->auto_recover)
7564 return devlink_health_reporter_recover(reporter,
7569 EXPORT_SYMBOL_GPL(devlink_health_report);
7571 static struct devlink_health_reporter *
7572 devlink_health_reporter_get_from_attrs(struct devlink *devlink,
7573 struct nlattr **attrs)
7575 struct devlink_health_reporter *reporter;
7576 struct devlink_port *devlink_port;
7577 char *reporter_name;
7579 if (!attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME])
7582 reporter_name = nla_data(attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]);
7583 devlink_port = devlink_port_get_from_attrs(devlink, attrs);
7584 if (IS_ERR(devlink_port)) {
7585 mutex_lock(&devlink->reporters_lock);
7586 reporter = devlink_health_reporter_find_by_name(devlink, reporter_name);
7588 refcount_inc(&reporter->refcount);
7589 mutex_unlock(&devlink->reporters_lock);
7591 mutex_lock(&devlink_port->reporters_lock);
7592 reporter = devlink_port_health_reporter_find_by_name(devlink_port, reporter_name);
7594 refcount_inc(&reporter->refcount);
7595 mutex_unlock(&devlink_port->reporters_lock);
7601 static struct devlink_health_reporter *
7602 devlink_health_reporter_get_from_info(struct devlink *devlink,
7603 struct genl_info *info)
7605 return devlink_health_reporter_get_from_attrs(devlink, info->attrs);
7608 static struct devlink_health_reporter *
7609 devlink_health_reporter_get_from_cb(struct netlink_callback *cb)
7611 const struct genl_dumpit_info *info = genl_dumpit_info(cb);
7612 struct devlink_health_reporter *reporter;
7613 struct nlattr **attrs = info->attrs;
7614 struct devlink *devlink;
7616 mutex_lock(&devlink_mutex);
7617 devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs);
7618 if (IS_ERR(devlink))
7621 reporter = devlink_health_reporter_get_from_attrs(devlink, attrs);
7622 devlink_put(devlink);
7623 mutex_unlock(&devlink_mutex);
7626 mutex_unlock(&devlink_mutex);
7631 devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
7632 enum devlink_health_reporter_state state)
7634 if (WARN_ON(state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY &&
7635 state != DEVLINK_HEALTH_REPORTER_STATE_ERROR))
7638 if (reporter->health_state == state)
7641 reporter->health_state = state;
7642 trace_devlink_health_reporter_state_update(reporter->devlink,
7643 reporter->ops->name, state);
7644 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
7646 EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update);
7648 static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb,
7649 struct genl_info *info)
7651 struct devlink *devlink = info->user_ptr[0];
7652 struct devlink_health_reporter *reporter;
7653 struct sk_buff *msg;
7656 reporter = devlink_health_reporter_get_from_info(devlink, info);
7660 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7666 err = devlink_nl_health_reporter_fill(msg, reporter,
7667 DEVLINK_CMD_HEALTH_REPORTER_GET,
7668 info->snd_portid, info->snd_seq,
7675 err = genlmsg_reply(msg, info);
7677 devlink_health_reporter_put(reporter);
7682 devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff *msg,
7683 struct netlink_callback *cb)
7685 struct devlink_health_reporter *reporter;
7686 struct devlink_port *port;
7687 struct devlink *devlink;
7688 int start = cb->args[0];
7689 unsigned long index;
7693 mutex_lock(&devlink_mutex);
7694 devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
7695 mutex_lock(&devlink->reporters_lock);
7696 list_for_each_entry(reporter, &devlink->reporter_list,
7702 err = devlink_nl_health_reporter_fill(
7703 msg, reporter, DEVLINK_CMD_HEALTH_REPORTER_GET,
7704 NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
7707 mutex_unlock(&devlink->reporters_lock);
7708 devlink_put(devlink);
7713 mutex_unlock(&devlink->reporters_lock);
7714 devlink_put(devlink);
7717 devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
7719 list_for_each_entry(port, &devlink->port_list, list) {
7720 mutex_lock(&port->reporters_lock);
7721 list_for_each_entry(reporter, &port->reporter_list, list) {
7726 err = devlink_nl_health_reporter_fill(
7728 DEVLINK_CMD_HEALTH_REPORTER_GET,
7729 NETLINK_CB(cb->skb).portid,
7730 cb->nlh->nlmsg_seq, NLM_F_MULTI);
7732 mutex_unlock(&port->reporters_lock);
7733 devl_unlock(devlink);
7734 devlink_put(devlink);
7739 mutex_unlock(&port->reporters_lock);
7741 devl_unlock(devlink);
7742 devlink_put(devlink);
7745 mutex_unlock(&devlink_mutex);
7752 devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb,
7753 struct genl_info *info)
7755 struct devlink *devlink = info->user_ptr[0];
7756 struct devlink_health_reporter *reporter;
7759 reporter = devlink_health_reporter_get_from_info(devlink, info);
7763 if (!reporter->ops->recover &&
7764 (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] ||
7765 info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])) {
7769 if (!reporter->ops->dump &&
7770 info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]) {
7775 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD])
7776 reporter->graceful_period =
7777 nla_get_u64(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]);
7779 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])
7780 reporter->auto_recover =
7781 nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]);
7783 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP])
7784 reporter->auto_dump =
7785 nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]);
7787 devlink_health_reporter_put(reporter);
7790 devlink_health_reporter_put(reporter);
7794 static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb,
7795 struct genl_info *info)
7797 struct devlink *devlink = info->user_ptr[0];
7798 struct devlink_health_reporter *reporter;
7801 reporter = devlink_health_reporter_get_from_info(devlink, info);
7805 err = devlink_health_reporter_recover(reporter, NULL, info->extack);
7807 devlink_health_reporter_put(reporter);
7811 static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb,
7812 struct genl_info *info)
7814 struct devlink *devlink = info->user_ptr[0];
7815 struct devlink_health_reporter *reporter;
7816 struct devlink_fmsg *fmsg;
7819 reporter = devlink_health_reporter_get_from_info(devlink, info);
7823 if (!reporter->ops->diagnose) {
7824 devlink_health_reporter_put(reporter);
7828 fmsg = devlink_fmsg_alloc();
7830 devlink_health_reporter_put(reporter);
7834 err = devlink_fmsg_obj_nest_start(fmsg);
7838 err = reporter->ops->diagnose(reporter, fmsg, info->extack);
7842 err = devlink_fmsg_obj_nest_end(fmsg);
7846 err = devlink_fmsg_snd(fmsg, info,
7847 DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 0);
7850 devlink_fmsg_free(fmsg);
7851 devlink_health_reporter_put(reporter);
7856 devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff *skb,
7857 struct netlink_callback *cb)
7859 struct devlink_health_reporter *reporter;
7860 u64 start = cb->args[0];
7863 reporter = devlink_health_reporter_get_from_cb(cb);
7867 if (!reporter->ops->dump) {
7871 mutex_lock(&reporter->dump_lock);
7873 err = devlink_health_do_dump(reporter, NULL, cb->extack);
7876 cb->args[1] = reporter->dump_ts;
7878 if (!reporter->dump_fmsg || cb->args[1] != reporter->dump_ts) {
7879 NL_SET_ERR_MSG_MOD(cb->extack, "Dump trampled, please retry");
7884 err = devlink_fmsg_dumpit(reporter->dump_fmsg, skb, cb,
7885 DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET);
7887 mutex_unlock(&reporter->dump_lock);
7889 devlink_health_reporter_put(reporter);
7894 devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb,
7895 struct genl_info *info)
7897 struct devlink *devlink = info->user_ptr[0];
7898 struct devlink_health_reporter *reporter;
7900 reporter = devlink_health_reporter_get_from_info(devlink, info);
7904 if (!reporter->ops->dump) {
7905 devlink_health_reporter_put(reporter);
7909 mutex_lock(&reporter->dump_lock);
7910 devlink_health_dump_clear(reporter);
7911 mutex_unlock(&reporter->dump_lock);
7912 devlink_health_reporter_put(reporter);
7916 static int devlink_nl_cmd_health_reporter_test_doit(struct sk_buff *skb,
7917 struct genl_info *info)
7919 struct devlink *devlink = info->user_ptr[0];
7920 struct devlink_health_reporter *reporter;
7923 reporter = devlink_health_reporter_get_from_info(devlink, info);
7927 if (!reporter->ops->test) {
7928 devlink_health_reporter_put(reporter);
7932 err = reporter->ops->test(reporter, info->extack);
7934 devlink_health_reporter_put(reporter);
7938 struct devlink_stats {
7939 u64_stats_t rx_bytes;
7940 u64_stats_t rx_packets;
7941 struct u64_stats_sync syncp;
7945 * struct devlink_trap_policer_item - Packet trap policer attributes.
7946 * @policer: Immutable packet trap policer attributes.
7947 * @rate: Rate in packets / sec.
7948 * @burst: Burst size in packets.
7949 * @list: trap_policer_list member.
7951 * Describes packet trap policer attributes. Created by devlink during trap
7952 * policer registration.
7954 struct devlink_trap_policer_item {
7955 const struct devlink_trap_policer *policer;
7958 struct list_head list;
7962 * struct devlink_trap_group_item - Packet trap group attributes.
7963 * @group: Immutable packet trap group attributes.
7964 * @policer_item: Associated policer item. Can be NULL.
7965 * @list: trap_group_list member.
7966 * @stats: Trap group statistics.
7968 * Describes packet trap group attributes. Created by devlink during trap
7969 * group registration.
7971 struct devlink_trap_group_item {
7972 const struct devlink_trap_group *group;
7973 struct devlink_trap_policer_item *policer_item;
7974 struct list_head list;
7975 struct devlink_stats __percpu *stats;
7979 * struct devlink_trap_item - Packet trap attributes.
7980 * @trap: Immutable packet trap attributes.
7981 * @group_item: Associated group item.
7982 * @list: trap_list member.
7983 * @action: Trap action.
7984 * @stats: Trap statistics.
7985 * @priv: Driver private information.
7987 * Describes both mutable and immutable packet trap attributes. Created by
7988 * devlink during trap registration and used for all trap related operations.
7990 struct devlink_trap_item {
7991 const struct devlink_trap *trap;
7992 struct devlink_trap_group_item *group_item;
7993 struct list_head list;
7994 enum devlink_trap_action action;
7995 struct devlink_stats __percpu *stats;
7999 static struct devlink_trap_policer_item *
8000 devlink_trap_policer_item_lookup(struct devlink *devlink, u32 id)
8002 struct devlink_trap_policer_item *policer_item;
8004 list_for_each_entry(policer_item, &devlink->trap_policer_list, list) {
8005 if (policer_item->policer->id == id)
8006 return policer_item;
8012 static struct devlink_trap_item *
8013 devlink_trap_item_lookup(struct devlink *devlink, const char *name)
8015 struct devlink_trap_item *trap_item;
8017 list_for_each_entry(trap_item, &devlink->trap_list, list) {
8018 if (!strcmp(trap_item->trap->name, name))
8025 static struct devlink_trap_item *
8026 devlink_trap_item_get_from_info(struct devlink *devlink,
8027 struct genl_info *info)
8029 struct nlattr *attr;
8031 if (!info->attrs[DEVLINK_ATTR_TRAP_NAME])
8033 attr = info->attrs[DEVLINK_ATTR_TRAP_NAME];
8035 return devlink_trap_item_lookup(devlink, nla_data(attr));
8039 devlink_trap_action_get_from_info(struct genl_info *info,
8040 enum devlink_trap_action *p_trap_action)
8044 val = nla_get_u8(info->attrs[DEVLINK_ATTR_TRAP_ACTION]);
8046 case DEVLINK_TRAP_ACTION_DROP:
8047 case DEVLINK_TRAP_ACTION_TRAP:
8048 case DEVLINK_TRAP_ACTION_MIRROR:
8049 *p_trap_action = val;
8058 static int devlink_trap_metadata_put(struct sk_buff *msg,
8059 const struct devlink_trap *trap)
8061 struct nlattr *attr;
8063 attr = nla_nest_start(msg, DEVLINK_ATTR_TRAP_METADATA);
8067 if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT) &&
8068 nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT))
8069 goto nla_put_failure;
8070 if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE) &&
8071 nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE))
8072 goto nla_put_failure;
8074 nla_nest_end(msg, attr);
8079 nla_nest_cancel(msg, attr);
8083 static void devlink_trap_stats_read(struct devlink_stats __percpu *trap_stats,
8084 struct devlink_stats *stats)
8088 memset(stats, 0, sizeof(*stats));
8089 for_each_possible_cpu(i) {
8090 struct devlink_stats *cpu_stats;
8091 u64 rx_packets, rx_bytes;
8094 cpu_stats = per_cpu_ptr(trap_stats, i);
8096 start = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
8097 rx_packets = u64_stats_read(&cpu_stats->rx_packets);
8098 rx_bytes = u64_stats_read(&cpu_stats->rx_bytes);
8099 } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start));
8101 u64_stats_add(&stats->rx_packets, rx_packets);
8102 u64_stats_add(&stats->rx_bytes, rx_bytes);
8107 devlink_trap_group_stats_put(struct sk_buff *msg,
8108 struct devlink_stats __percpu *trap_stats)
8110 struct devlink_stats stats;
8111 struct nlattr *attr;
8113 devlink_trap_stats_read(trap_stats, &stats);
8115 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
8119 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS,
8120 u64_stats_read(&stats.rx_packets),
8122 goto nla_put_failure;
8124 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES,
8125 u64_stats_read(&stats.rx_bytes),
8127 goto nla_put_failure;
8129 nla_nest_end(msg, attr);
8134 nla_nest_cancel(msg, attr);
8138 static int devlink_trap_stats_put(struct sk_buff *msg, struct devlink *devlink,
8139 const struct devlink_trap_item *trap_item)
8141 struct devlink_stats stats;
8142 struct nlattr *attr;
8146 if (devlink->ops->trap_drop_counter_get) {
8147 err = devlink->ops->trap_drop_counter_get(devlink,
8154 devlink_trap_stats_read(trap_item->stats, &stats);
8156 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
8160 if (devlink->ops->trap_drop_counter_get &&
8161 nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops,
8163 goto nla_put_failure;
8165 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS,
8166 u64_stats_read(&stats.rx_packets),
8168 goto nla_put_failure;
8170 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES,
8171 u64_stats_read(&stats.rx_bytes),
8173 goto nla_put_failure;
8175 nla_nest_end(msg, attr);
8180 nla_nest_cancel(msg, attr);
8184 static int devlink_nl_trap_fill(struct sk_buff *msg, struct devlink *devlink,
8185 const struct devlink_trap_item *trap_item,
8186 enum devlink_command cmd, u32 portid, u32 seq,
8189 struct devlink_trap_group_item *group_item = trap_item->group_item;
8193 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
8197 if (devlink_nl_put_handle(msg, devlink))
8198 goto nla_put_failure;
8200 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
8201 group_item->group->name))
8202 goto nla_put_failure;
8204 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_NAME, trap_item->trap->name))
8205 goto nla_put_failure;
8207 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_TYPE, trap_item->trap->type))
8208 goto nla_put_failure;
8210 if (trap_item->trap->generic &&
8211 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
8212 goto nla_put_failure;
8214 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_ACTION, trap_item->action))
8215 goto nla_put_failure;
8217 err = devlink_trap_metadata_put(msg, trap_item->trap);
8219 goto nla_put_failure;
8221 err = devlink_trap_stats_put(msg, devlink, trap_item);
8223 goto nla_put_failure;
8225 genlmsg_end(msg, hdr);
8230 genlmsg_cancel(msg, hdr);
8234 static int devlink_nl_cmd_trap_get_doit(struct sk_buff *skb,
8235 struct genl_info *info)
8237 struct netlink_ext_ack *extack = info->extack;
8238 struct devlink *devlink = info->user_ptr[0];
8239 struct devlink_trap_item *trap_item;
8240 struct sk_buff *msg;
8243 if (list_empty(&devlink->trap_list))
8246 trap_item = devlink_trap_item_get_from_info(devlink, info);
8248 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
8252 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8256 err = devlink_nl_trap_fill(msg, devlink, trap_item,
8257 DEVLINK_CMD_TRAP_NEW, info->snd_portid,
8262 return genlmsg_reply(msg, info);
8269 static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff *msg,
8270 struct netlink_callback *cb)
8272 struct devlink_trap_item *trap_item;
8273 struct devlink *devlink;
8274 int start = cb->args[0];
8275 unsigned long index;
8279 mutex_lock(&devlink_mutex);
8280 devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
8282 list_for_each_entry(trap_item, &devlink->trap_list, list) {
8287 err = devlink_nl_trap_fill(msg, devlink, trap_item,
8288 DEVLINK_CMD_TRAP_NEW,
8289 NETLINK_CB(cb->skb).portid,
8293 devl_unlock(devlink);
8294 devlink_put(devlink);
8299 devl_unlock(devlink);
8300 devlink_put(devlink);
8303 mutex_unlock(&devlink_mutex);
8309 static int __devlink_trap_action_set(struct devlink *devlink,
8310 struct devlink_trap_item *trap_item,
8311 enum devlink_trap_action trap_action,
8312 struct netlink_ext_ack *extack)
8316 if (trap_item->action != trap_action &&
8317 trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) {
8318 NL_SET_ERR_MSG_MOD(extack, "Cannot change action of non-drop traps. Skipping");
8322 err = devlink->ops->trap_action_set(devlink, trap_item->trap,
8323 trap_action, extack);
8327 trap_item->action = trap_action;
8332 static int devlink_trap_action_set(struct devlink *devlink,
8333 struct devlink_trap_item *trap_item,
8334 struct genl_info *info)
8336 enum devlink_trap_action trap_action;
8339 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
8342 err = devlink_trap_action_get_from_info(info, &trap_action);
8344 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
8348 return __devlink_trap_action_set(devlink, trap_item, trap_action,
8352 static int devlink_nl_cmd_trap_set_doit(struct sk_buff *skb,
8353 struct genl_info *info)
8355 struct netlink_ext_ack *extack = info->extack;
8356 struct devlink *devlink = info->user_ptr[0];
8357 struct devlink_trap_item *trap_item;
8359 if (list_empty(&devlink->trap_list))
8362 trap_item = devlink_trap_item_get_from_info(devlink, info);
8364 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
8368 return devlink_trap_action_set(devlink, trap_item, info);
8371 static struct devlink_trap_group_item *
8372 devlink_trap_group_item_lookup(struct devlink *devlink, const char *name)
8374 struct devlink_trap_group_item *group_item;
8376 list_for_each_entry(group_item, &devlink->trap_group_list, list) {
8377 if (!strcmp(group_item->group->name, name))
8384 static struct devlink_trap_group_item *
8385 devlink_trap_group_item_lookup_by_id(struct devlink *devlink, u16 id)
8387 struct devlink_trap_group_item *group_item;
8389 list_for_each_entry(group_item, &devlink->trap_group_list, list) {
8390 if (group_item->group->id == id)
8397 static struct devlink_trap_group_item *
8398 devlink_trap_group_item_get_from_info(struct devlink *devlink,
8399 struct genl_info *info)
8403 if (!info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME])
8405 name = nla_data(info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]);
8407 return devlink_trap_group_item_lookup(devlink, name);
8411 devlink_nl_trap_group_fill(struct sk_buff *msg, struct devlink *devlink,
8412 const struct devlink_trap_group_item *group_item,
8413 enum devlink_command cmd, u32 portid, u32 seq,
8419 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
8423 if (devlink_nl_put_handle(msg, devlink))
8424 goto nla_put_failure;
8426 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
8427 group_item->group->name))
8428 goto nla_put_failure;
8430 if (group_item->group->generic &&
8431 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
8432 goto nla_put_failure;
8434 if (group_item->policer_item &&
8435 nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
8436 group_item->policer_item->policer->id))
8437 goto nla_put_failure;
8439 err = devlink_trap_group_stats_put(msg, group_item->stats);
8441 goto nla_put_failure;
8443 genlmsg_end(msg, hdr);
8448 genlmsg_cancel(msg, hdr);
8452 static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff *skb,
8453 struct genl_info *info)
8455 struct netlink_ext_ack *extack = info->extack;
8456 struct devlink *devlink = info->user_ptr[0];
8457 struct devlink_trap_group_item *group_item;
8458 struct sk_buff *msg;
8461 if (list_empty(&devlink->trap_group_list))
8464 group_item = devlink_trap_group_item_get_from_info(devlink, info);
8466 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
8470 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8474 err = devlink_nl_trap_group_fill(msg, devlink, group_item,
8475 DEVLINK_CMD_TRAP_GROUP_NEW,
8476 info->snd_portid, info->snd_seq, 0);
8478 goto err_trap_group_fill;
8480 return genlmsg_reply(msg, info);
8482 err_trap_group_fill:
8487 static int devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff *msg,
8488 struct netlink_callback *cb)
8490 enum devlink_command cmd = DEVLINK_CMD_TRAP_GROUP_NEW;
8491 struct devlink_trap_group_item *group_item;
8492 u32 portid = NETLINK_CB(cb->skb).portid;
8493 struct devlink *devlink;
8494 int start = cb->args[0];
8495 unsigned long index;
8499 mutex_lock(&devlink_mutex);
8500 devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
8502 list_for_each_entry(group_item, &devlink->trap_group_list,
8508 err = devlink_nl_trap_group_fill(msg, devlink,
8514 devl_unlock(devlink);
8515 devlink_put(devlink);
8520 devl_unlock(devlink);
8521 devlink_put(devlink);
8524 mutex_unlock(&devlink_mutex);
8531 __devlink_trap_group_action_set(struct devlink *devlink,
8532 struct devlink_trap_group_item *group_item,
8533 enum devlink_trap_action trap_action,
8534 struct netlink_ext_ack *extack)
8536 const char *group_name = group_item->group->name;
8537 struct devlink_trap_item *trap_item;
8540 if (devlink->ops->trap_group_action_set) {
8541 err = devlink->ops->trap_group_action_set(devlink, group_item->group,
8542 trap_action, extack);
8546 list_for_each_entry(trap_item, &devlink->trap_list, list) {
8547 if (strcmp(trap_item->group_item->group->name, group_name))
8549 if (trap_item->action != trap_action &&
8550 trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP)
8552 trap_item->action = trap_action;
8558 list_for_each_entry(trap_item, &devlink->trap_list, list) {
8559 if (strcmp(trap_item->group_item->group->name, group_name))
8561 err = __devlink_trap_action_set(devlink, trap_item,
8562 trap_action, extack);
8571 devlink_trap_group_action_set(struct devlink *devlink,
8572 struct devlink_trap_group_item *group_item,
8573 struct genl_info *info, bool *p_modified)
8575 enum devlink_trap_action trap_action;
8578 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
8581 err = devlink_trap_action_get_from_info(info, &trap_action);
8583 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
8587 err = __devlink_trap_group_action_set(devlink, group_item, trap_action,
8597 static int devlink_trap_group_set(struct devlink *devlink,
8598 struct devlink_trap_group_item *group_item,
8599 struct genl_info *info)
8601 struct devlink_trap_policer_item *policer_item;
8602 struct netlink_ext_ack *extack = info->extack;
8603 const struct devlink_trap_policer *policer;
8604 struct nlattr **attrs = info->attrs;
8607 if (!attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
8610 if (!devlink->ops->trap_group_set)
8613 policer_item = group_item->policer_item;
8614 if (attrs[DEVLINK_ATTR_TRAP_POLICER_ID]) {
8617 policer_id = nla_get_u32(attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
8618 policer_item = devlink_trap_policer_item_lookup(devlink,
8620 if (policer_id && !policer_item) {
8621 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
8625 policer = policer_item ? policer_item->policer : NULL;
8627 err = devlink->ops->trap_group_set(devlink, group_item->group, policer,
8632 group_item->policer_item = policer_item;
8637 static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff *skb,
8638 struct genl_info *info)
8640 struct netlink_ext_ack *extack = info->extack;
8641 struct devlink *devlink = info->user_ptr[0];
8642 struct devlink_trap_group_item *group_item;
8643 bool modified = false;
8646 if (list_empty(&devlink->trap_group_list))
8649 group_item = devlink_trap_group_item_get_from_info(devlink, info);
8651 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
8655 err = devlink_trap_group_action_set(devlink, group_item, info,
8660 err = devlink_trap_group_set(devlink, group_item, info);
8662 goto err_trap_group_set;
8668 NL_SET_ERR_MSG_MOD(extack, "Trap group set failed, but some changes were committed already");
8672 static struct devlink_trap_policer_item *
8673 devlink_trap_policer_item_get_from_info(struct devlink *devlink,
8674 struct genl_info *info)
8678 if (!info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
8680 id = nla_get_u32(info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
8682 return devlink_trap_policer_item_lookup(devlink, id);
8686 devlink_trap_policer_stats_put(struct sk_buff *msg, struct devlink *devlink,
8687 const struct devlink_trap_policer *policer)
8689 struct nlattr *attr;
8693 if (!devlink->ops->trap_policer_counter_get)
8696 err = devlink->ops->trap_policer_counter_get(devlink, policer, &drops);
8700 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
8704 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops,
8706 goto nla_put_failure;
8708 nla_nest_end(msg, attr);
8713 nla_nest_cancel(msg, attr);
8718 devlink_nl_trap_policer_fill(struct sk_buff *msg, struct devlink *devlink,
8719 const struct devlink_trap_policer_item *policer_item,
8720 enum devlink_command cmd, u32 portid, u32 seq,
8726 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
8730 if (devlink_nl_put_handle(msg, devlink))
8731 goto nla_put_failure;
8733 if (nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
8734 policer_item->policer->id))
8735 goto nla_put_failure;
8737 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_RATE,
8738 policer_item->rate, DEVLINK_ATTR_PAD))
8739 goto nla_put_failure;
8741 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_BURST,
8742 policer_item->burst, DEVLINK_ATTR_PAD))
8743 goto nla_put_failure;
8745 err = devlink_trap_policer_stats_put(msg, devlink,
8746 policer_item->policer);
8748 goto nla_put_failure;
8750 genlmsg_end(msg, hdr);
8755 genlmsg_cancel(msg, hdr);
8759 static int devlink_nl_cmd_trap_policer_get_doit(struct sk_buff *skb,
8760 struct genl_info *info)
8762 struct devlink_trap_policer_item *policer_item;
8763 struct netlink_ext_ack *extack = info->extack;
8764 struct devlink *devlink = info->user_ptr[0];
8765 struct sk_buff *msg;
8768 if (list_empty(&devlink->trap_policer_list))
8771 policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
8772 if (!policer_item) {
8773 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
8777 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8781 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item,
8782 DEVLINK_CMD_TRAP_POLICER_NEW,
8783 info->snd_portid, info->snd_seq, 0);
8785 goto err_trap_policer_fill;
8787 return genlmsg_reply(msg, info);
8789 err_trap_policer_fill:
8794 static int devlink_nl_cmd_trap_policer_get_dumpit(struct sk_buff *msg,
8795 struct netlink_callback *cb)
8797 enum devlink_command cmd = DEVLINK_CMD_TRAP_POLICER_NEW;
8798 struct devlink_trap_policer_item *policer_item;
8799 u32 portid = NETLINK_CB(cb->skb).portid;
8800 struct devlink *devlink;
8801 int start = cb->args[0];
8802 unsigned long index;
8806 mutex_lock(&devlink_mutex);
8807 devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) {
8809 list_for_each_entry(policer_item, &devlink->trap_policer_list,
8815 err = devlink_nl_trap_policer_fill(msg, devlink,
8821 devl_unlock(devlink);
8822 devlink_put(devlink);
8827 devl_unlock(devlink);
8828 devlink_put(devlink);
8831 mutex_unlock(&devlink_mutex);
8838 devlink_trap_policer_set(struct devlink *devlink,
8839 struct devlink_trap_policer_item *policer_item,
8840 struct genl_info *info)
8842 struct netlink_ext_ack *extack = info->extack;
8843 struct nlattr **attrs = info->attrs;
8847 rate = policer_item->rate;
8848 burst = policer_item->burst;
8850 if (attrs[DEVLINK_ATTR_TRAP_POLICER_RATE])
8851 rate = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_RATE]);
8853 if (attrs[DEVLINK_ATTR_TRAP_POLICER_BURST])
8854 burst = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_BURST]);
8856 if (rate < policer_item->policer->min_rate) {
8857 NL_SET_ERR_MSG_MOD(extack, "Policer rate lower than limit");
8861 if (rate > policer_item->policer->max_rate) {
8862 NL_SET_ERR_MSG_MOD(extack, "Policer rate higher than limit");
8866 if (burst < policer_item->policer->min_burst) {
8867 NL_SET_ERR_MSG_MOD(extack, "Policer burst size lower than limit");
8871 if (burst > policer_item->policer->max_burst) {
8872 NL_SET_ERR_MSG_MOD(extack, "Policer burst size higher than limit");
8876 err = devlink->ops->trap_policer_set(devlink, policer_item->policer,
8877 rate, burst, info->extack);
8881 policer_item->rate = rate;
8882 policer_item->burst = burst;
8887 static int devlink_nl_cmd_trap_policer_set_doit(struct sk_buff *skb,
8888 struct genl_info *info)
8890 struct devlink_trap_policer_item *policer_item;
8891 struct netlink_ext_ack *extack = info->extack;
8892 struct devlink *devlink = info->user_ptr[0];
8894 if (list_empty(&devlink->trap_policer_list))
8897 if (!devlink->ops->trap_policer_set)
8900 policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
8901 if (!policer_item) {
8902 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
8906 return devlink_trap_policer_set(devlink, policer_item, info);
8909 static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
8910 [DEVLINK_ATTR_UNSPEC] = { .strict_start_type =
8911 DEVLINK_ATTR_TRAP_POLICER_ID },
8912 [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
8913 [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
8914 [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 },
8915 [DEVLINK_ATTR_PORT_TYPE] = NLA_POLICY_RANGE(NLA_U16, DEVLINK_PORT_TYPE_AUTO,
8916 DEVLINK_PORT_TYPE_IB),
8917 [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 },
8918 [DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 },
8919 [DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 },
8920 [DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 },
8921 [DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 },
8922 [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 },
8923 [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
8924 [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
8925 [DEVLINK_ATTR_ESWITCH_MODE] = NLA_POLICY_RANGE(NLA_U16, DEVLINK_ESWITCH_MODE_LEGACY,
8926 DEVLINK_ESWITCH_MODE_SWITCHDEV),
8927 [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 },
8928 [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 },
8929 [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING },
8930 [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 },
8931 [DEVLINK_ATTR_RESOURCE_ID] = { .type = NLA_U64},
8932 [DEVLINK_ATTR_RESOURCE_SIZE] = { .type = NLA_U64},
8933 [DEVLINK_ATTR_PARAM_NAME] = { .type = NLA_NUL_STRING },
8934 [DEVLINK_ATTR_PARAM_TYPE] = { .type = NLA_U8 },
8935 [DEVLINK_ATTR_PARAM_VALUE_CMODE] = { .type = NLA_U8 },
8936 [DEVLINK_ATTR_REGION_NAME] = { .type = NLA_NUL_STRING },
8937 [DEVLINK_ATTR_REGION_SNAPSHOT_ID] = { .type = NLA_U32 },
8938 [DEVLINK_ATTR_REGION_CHUNK_ADDR] = { .type = NLA_U64 },
8939 [DEVLINK_ATTR_REGION_CHUNK_LEN] = { .type = NLA_U64 },
8940 [DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING },
8941 [DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] = { .type = NLA_U64 },
8942 [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER] = { .type = NLA_U8 },
8943 [DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME] = { .type = NLA_NUL_STRING },
8944 [DEVLINK_ATTR_FLASH_UPDATE_COMPONENT] = { .type = NLA_NUL_STRING },
8945 [DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK] =
8946 NLA_POLICY_BITFIELD32(DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS),
8947 [DEVLINK_ATTR_TRAP_NAME] = { .type = NLA_NUL_STRING },
8948 [DEVLINK_ATTR_TRAP_ACTION] = { .type = NLA_U8 },
8949 [DEVLINK_ATTR_TRAP_GROUP_NAME] = { .type = NLA_NUL_STRING },
8950 [DEVLINK_ATTR_NETNS_PID] = { .type = NLA_U32 },
8951 [DEVLINK_ATTR_NETNS_FD] = { .type = NLA_U32 },
8952 [DEVLINK_ATTR_NETNS_ID] = { .type = NLA_U32 },
8953 [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP] = { .type = NLA_U8 },
8954 [DEVLINK_ATTR_TRAP_POLICER_ID] = { .type = NLA_U32 },
8955 [DEVLINK_ATTR_TRAP_POLICER_RATE] = { .type = NLA_U64 },
8956 [DEVLINK_ATTR_TRAP_POLICER_BURST] = { .type = NLA_U64 },
8957 [DEVLINK_ATTR_PORT_FUNCTION] = { .type = NLA_NESTED },
8958 [DEVLINK_ATTR_RELOAD_ACTION] = NLA_POLICY_RANGE(NLA_U8, DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
8959 DEVLINK_RELOAD_ACTION_MAX),
8960 [DEVLINK_ATTR_RELOAD_LIMITS] = NLA_POLICY_BITFIELD32(DEVLINK_RELOAD_LIMITS_VALID_MASK),
8961 [DEVLINK_ATTR_PORT_FLAVOUR] = { .type = NLA_U16 },
8962 [DEVLINK_ATTR_PORT_PCI_PF_NUMBER] = { .type = NLA_U16 },
8963 [DEVLINK_ATTR_PORT_PCI_SF_NUMBER] = { .type = NLA_U32 },
8964 [DEVLINK_ATTR_PORT_CONTROLLER_NUMBER] = { .type = NLA_U32 },
8965 [DEVLINK_ATTR_RATE_TYPE] = { .type = NLA_U16 },
8966 [DEVLINK_ATTR_RATE_TX_SHARE] = { .type = NLA_U64 },
8967 [DEVLINK_ATTR_RATE_TX_MAX] = { .type = NLA_U64 },
8968 [DEVLINK_ATTR_RATE_NODE_NAME] = { .type = NLA_NUL_STRING },
8969 [DEVLINK_ATTR_RATE_PARENT_NODE_NAME] = { .type = NLA_NUL_STRING },
8970 [DEVLINK_ATTR_LINECARD_INDEX] = { .type = NLA_U32 },
8971 [DEVLINK_ATTR_LINECARD_TYPE] = { .type = NLA_NUL_STRING },
8974 static const struct genl_small_ops devlink_nl_ops[] = {
8976 .cmd = DEVLINK_CMD_GET,
8977 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
8978 .doit = devlink_nl_cmd_get_doit,
8979 .dumpit = devlink_nl_cmd_get_dumpit,
8980 /* can be retrieved by unprivileged users */
8983 .cmd = DEVLINK_CMD_PORT_GET,
8984 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
8985 .doit = devlink_nl_cmd_port_get_doit,
8986 .dumpit = devlink_nl_cmd_port_get_dumpit,
8987 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
8988 /* can be retrieved by unprivileged users */
8991 .cmd = DEVLINK_CMD_PORT_SET,
8992 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
8993 .doit = devlink_nl_cmd_port_set_doit,
8994 .flags = GENL_ADMIN_PERM,
8995 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
8998 .cmd = DEVLINK_CMD_RATE_GET,
8999 .doit = devlink_nl_cmd_rate_get_doit,
9000 .dumpit = devlink_nl_cmd_rate_get_dumpit,
9001 .internal_flags = DEVLINK_NL_FLAG_NEED_RATE,
9002 /* can be retrieved by unprivileged users */
9005 .cmd = DEVLINK_CMD_RATE_SET,
9006 .doit = devlink_nl_cmd_rate_set_doit,
9007 .flags = GENL_ADMIN_PERM,
9008 .internal_flags = DEVLINK_NL_FLAG_NEED_RATE,
9011 .cmd = DEVLINK_CMD_RATE_NEW,
9012 .doit = devlink_nl_cmd_rate_new_doit,
9013 .flags = GENL_ADMIN_PERM,
9016 .cmd = DEVLINK_CMD_RATE_DEL,
9017 .doit = devlink_nl_cmd_rate_del_doit,
9018 .flags = GENL_ADMIN_PERM,
9019 .internal_flags = DEVLINK_NL_FLAG_NEED_RATE_NODE,
9022 .cmd = DEVLINK_CMD_PORT_SPLIT,
9023 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9024 .doit = devlink_nl_cmd_port_split_doit,
9025 .flags = GENL_ADMIN_PERM,
9026 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9029 .cmd = DEVLINK_CMD_PORT_UNSPLIT,
9030 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9031 .doit = devlink_nl_cmd_port_unsplit_doit,
9032 .flags = GENL_ADMIN_PERM,
9033 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9036 .cmd = DEVLINK_CMD_PORT_NEW,
9037 .doit = devlink_nl_cmd_port_new_doit,
9038 .flags = GENL_ADMIN_PERM,
9041 .cmd = DEVLINK_CMD_PORT_DEL,
9042 .doit = devlink_nl_cmd_port_del_doit,
9043 .flags = GENL_ADMIN_PERM,
9046 .cmd = DEVLINK_CMD_LINECARD_GET,
9047 .doit = devlink_nl_cmd_linecard_get_doit,
9048 .dumpit = devlink_nl_cmd_linecard_get_dumpit,
9049 .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD,
9050 /* can be retrieved by unprivileged users */
9053 .cmd = DEVLINK_CMD_LINECARD_SET,
9054 .doit = devlink_nl_cmd_linecard_set_doit,
9055 .flags = GENL_ADMIN_PERM,
9056 .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD,
9059 .cmd = DEVLINK_CMD_SB_GET,
9060 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9061 .doit = devlink_nl_cmd_sb_get_doit,
9062 .dumpit = devlink_nl_cmd_sb_get_dumpit,
9063 /* can be retrieved by unprivileged users */
9066 .cmd = DEVLINK_CMD_SB_POOL_GET,
9067 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9068 .doit = devlink_nl_cmd_sb_pool_get_doit,
9069 .dumpit = devlink_nl_cmd_sb_pool_get_dumpit,
9070 /* can be retrieved by unprivileged users */
9073 .cmd = DEVLINK_CMD_SB_POOL_SET,
9074 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9075 .doit = devlink_nl_cmd_sb_pool_set_doit,
9076 .flags = GENL_ADMIN_PERM,
9079 .cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
9080 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9081 .doit = devlink_nl_cmd_sb_port_pool_get_doit,
9082 .dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit,
9083 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9084 /* can be retrieved by unprivileged users */
9087 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
9088 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9089 .doit = devlink_nl_cmd_sb_port_pool_set_doit,
9090 .flags = GENL_ADMIN_PERM,
9091 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9094 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
9095 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9096 .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
9097 .dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit,
9098 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9099 /* can be retrieved by unprivileged users */
9102 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
9103 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9104 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
9105 .flags = GENL_ADMIN_PERM,
9106 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9109 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
9110 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9111 .doit = devlink_nl_cmd_sb_occ_snapshot_doit,
9112 .flags = GENL_ADMIN_PERM,
9115 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
9116 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9117 .doit = devlink_nl_cmd_sb_occ_max_clear_doit,
9118 .flags = GENL_ADMIN_PERM,
9121 .cmd = DEVLINK_CMD_ESWITCH_GET,
9122 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9123 .doit = devlink_nl_cmd_eswitch_get_doit,
9124 .flags = GENL_ADMIN_PERM,
9127 .cmd = DEVLINK_CMD_ESWITCH_SET,
9128 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9129 .doit = devlink_nl_cmd_eswitch_set_doit,
9130 .flags = GENL_ADMIN_PERM,
9133 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET,
9134 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9135 .doit = devlink_nl_cmd_dpipe_table_get,
9136 /* can be retrieved by unprivileged users */
9139 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET,
9140 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9141 .doit = devlink_nl_cmd_dpipe_entries_get,
9142 /* can be retrieved by unprivileged users */
9145 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET,
9146 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9147 .doit = devlink_nl_cmd_dpipe_headers_get,
9148 /* can be retrieved by unprivileged users */
9151 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
9152 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9153 .doit = devlink_nl_cmd_dpipe_table_counters_set,
9154 .flags = GENL_ADMIN_PERM,
9157 .cmd = DEVLINK_CMD_RESOURCE_SET,
9158 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9159 .doit = devlink_nl_cmd_resource_set,
9160 .flags = GENL_ADMIN_PERM,
9163 .cmd = DEVLINK_CMD_RESOURCE_DUMP,
9164 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9165 .doit = devlink_nl_cmd_resource_dump,
9166 /* can be retrieved by unprivileged users */
9169 .cmd = DEVLINK_CMD_RELOAD,
9170 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9171 .doit = devlink_nl_cmd_reload,
9172 .flags = GENL_ADMIN_PERM,
9173 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK,
9176 .cmd = DEVLINK_CMD_PARAM_GET,
9177 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9178 .doit = devlink_nl_cmd_param_get_doit,
9179 .dumpit = devlink_nl_cmd_param_get_dumpit,
9180 /* can be retrieved by unprivileged users */
9183 .cmd = DEVLINK_CMD_PARAM_SET,
9184 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9185 .doit = devlink_nl_cmd_param_set_doit,
9186 .flags = GENL_ADMIN_PERM,
9189 .cmd = DEVLINK_CMD_PORT_PARAM_GET,
9190 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9191 .doit = devlink_nl_cmd_port_param_get_doit,
9192 .dumpit = devlink_nl_cmd_port_param_get_dumpit,
9193 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9194 /* can be retrieved by unprivileged users */
9197 .cmd = DEVLINK_CMD_PORT_PARAM_SET,
9198 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9199 .doit = devlink_nl_cmd_port_param_set_doit,
9200 .flags = GENL_ADMIN_PERM,
9201 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9204 .cmd = DEVLINK_CMD_REGION_GET,
9205 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9206 .doit = devlink_nl_cmd_region_get_doit,
9207 .dumpit = devlink_nl_cmd_region_get_dumpit,
9208 .flags = GENL_ADMIN_PERM,
9211 .cmd = DEVLINK_CMD_REGION_NEW,
9212 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9213 .doit = devlink_nl_cmd_region_new,
9214 .flags = GENL_ADMIN_PERM,
9217 .cmd = DEVLINK_CMD_REGION_DEL,
9218 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9219 .doit = devlink_nl_cmd_region_del,
9220 .flags = GENL_ADMIN_PERM,
9223 .cmd = DEVLINK_CMD_REGION_READ,
9224 .validate = GENL_DONT_VALIDATE_STRICT |
9225 GENL_DONT_VALIDATE_DUMP_STRICT,
9226 .dumpit = devlink_nl_cmd_region_read_dumpit,
9227 .flags = GENL_ADMIN_PERM,
9230 .cmd = DEVLINK_CMD_INFO_GET,
9231 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9232 .doit = devlink_nl_cmd_info_get_doit,
9233 .dumpit = devlink_nl_cmd_info_get_dumpit,
9234 /* can be retrieved by unprivileged users */
9237 .cmd = DEVLINK_CMD_HEALTH_REPORTER_GET,
9238 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9239 .doit = devlink_nl_cmd_health_reporter_get_doit,
9240 .dumpit = devlink_nl_cmd_health_reporter_get_dumpit,
9241 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT |
9242 DEVLINK_NL_FLAG_NO_LOCK,
9243 /* can be retrieved by unprivileged users */
9246 .cmd = DEVLINK_CMD_HEALTH_REPORTER_SET,
9247 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9248 .doit = devlink_nl_cmd_health_reporter_set_doit,
9249 .flags = GENL_ADMIN_PERM,
9250 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT |
9251 DEVLINK_NL_FLAG_NO_LOCK,
9254 .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER,
9255 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9256 .doit = devlink_nl_cmd_health_reporter_recover_doit,
9257 .flags = GENL_ADMIN_PERM,
9258 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT |
9259 DEVLINK_NL_FLAG_NO_LOCK,
9262 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE,
9263 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9264 .doit = devlink_nl_cmd_health_reporter_diagnose_doit,
9265 .flags = GENL_ADMIN_PERM,
9266 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT |
9267 DEVLINK_NL_FLAG_NO_LOCK,
9270 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET,
9271 .validate = GENL_DONT_VALIDATE_STRICT |
9272 GENL_DONT_VALIDATE_DUMP_STRICT,
9273 .dumpit = devlink_nl_cmd_health_reporter_dump_get_dumpit,
9274 .flags = GENL_ADMIN_PERM,
9277 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR,
9278 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9279 .doit = devlink_nl_cmd_health_reporter_dump_clear_doit,
9280 .flags = GENL_ADMIN_PERM,
9281 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT |
9282 DEVLINK_NL_FLAG_NO_LOCK,
9285 .cmd = DEVLINK_CMD_HEALTH_REPORTER_TEST,
9286 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9287 .doit = devlink_nl_cmd_health_reporter_test_doit,
9288 .flags = GENL_ADMIN_PERM,
9289 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT |
9290 DEVLINK_NL_FLAG_NO_LOCK,
9293 .cmd = DEVLINK_CMD_FLASH_UPDATE,
9294 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9295 .doit = devlink_nl_cmd_flash_update,
9296 .flags = GENL_ADMIN_PERM,
9299 .cmd = DEVLINK_CMD_TRAP_GET,
9300 .doit = devlink_nl_cmd_trap_get_doit,
9301 .dumpit = devlink_nl_cmd_trap_get_dumpit,
9302 /* can be retrieved by unprivileged users */
9305 .cmd = DEVLINK_CMD_TRAP_SET,
9306 .doit = devlink_nl_cmd_trap_set_doit,
9307 .flags = GENL_ADMIN_PERM,
9310 .cmd = DEVLINK_CMD_TRAP_GROUP_GET,
9311 .doit = devlink_nl_cmd_trap_group_get_doit,
9312 .dumpit = devlink_nl_cmd_trap_group_get_dumpit,
9313 /* can be retrieved by unprivileged users */
9316 .cmd = DEVLINK_CMD_TRAP_GROUP_SET,
9317 .doit = devlink_nl_cmd_trap_group_set_doit,
9318 .flags = GENL_ADMIN_PERM,
9321 .cmd = DEVLINK_CMD_TRAP_POLICER_GET,
9322 .doit = devlink_nl_cmd_trap_policer_get_doit,
9323 .dumpit = devlink_nl_cmd_trap_policer_get_dumpit,
9324 /* can be retrieved by unprivileged users */
9327 .cmd = DEVLINK_CMD_TRAP_POLICER_SET,
9328 .doit = devlink_nl_cmd_trap_policer_set_doit,
9329 .flags = GENL_ADMIN_PERM,
9333 static struct genl_family devlink_nl_family __ro_after_init = {
9334 .name = DEVLINK_GENL_NAME,
9335 .version = DEVLINK_GENL_VERSION,
9336 .maxattr = DEVLINK_ATTR_MAX,
9337 .policy = devlink_nl_policy,
9339 .pre_doit = devlink_nl_pre_doit,
9340 .post_doit = devlink_nl_post_doit,
9341 .module = THIS_MODULE,
9342 .small_ops = devlink_nl_ops,
9343 .n_small_ops = ARRAY_SIZE(devlink_nl_ops),
9344 .mcgrps = devlink_nl_mcgrps,
9345 .n_mcgrps = ARRAY_SIZE(devlink_nl_mcgrps),
9348 static bool devlink_reload_actions_valid(const struct devlink_ops *ops)
9350 const struct devlink_reload_combination *comb;
9353 if (!devlink_reload_supported(ops)) {
9354 if (WARN_ON(ops->reload_actions))
9359 if (WARN_ON(!ops->reload_actions ||
9360 ops->reload_actions & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) ||
9361 ops->reload_actions >= BIT(__DEVLINK_RELOAD_ACTION_MAX)))
9364 if (WARN_ON(ops->reload_limits & BIT(DEVLINK_RELOAD_LIMIT_UNSPEC) ||
9365 ops->reload_limits >= BIT(__DEVLINK_RELOAD_LIMIT_MAX)))
9368 for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++) {
9369 comb = &devlink_reload_invalid_combinations[i];
9370 if (ops->reload_actions == BIT(comb->action) &&
9371 ops->reload_limits == BIT(comb->limit))
9378 * devlink_set_features - Set devlink supported features
9381 * @features: devlink support features
9383 * This interface allows us to set reload ops separatelly from
9384 * the devlink_alloc.
9386 void devlink_set_features(struct devlink *devlink, u64 features)
9388 ASSERT_DEVLINK_NOT_REGISTERED(devlink);
9390 WARN_ON(features & DEVLINK_F_RELOAD &&
9391 !devlink_reload_supported(devlink->ops));
9392 devlink->features = features;
9394 EXPORT_SYMBOL_GPL(devlink_set_features);
9397 * devlink_alloc_ns - Allocate new devlink instance resources
9398 * in specific namespace
9401 * @priv_size: size of user private data
9402 * @net: net namespace
9403 * @dev: parent device
9405 * Allocate new devlink instance resources, including devlink index
9408 struct devlink *devlink_alloc_ns(const struct devlink_ops *ops,
9409 size_t priv_size, struct net *net,
9412 struct devlink *devlink;
9416 WARN_ON(!ops || !dev);
9417 if (!devlink_reload_actions_valid(ops))
9420 devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
9424 ret = xa_alloc_cyclic(&devlinks, &devlink->index, devlink, xa_limit_31b,
9425 &last_id, GFP_KERNEL);
9433 xa_init_flags(&devlink->snapshot_ids, XA_FLAGS_ALLOC);
9434 write_pnet(&devlink->_net, net);
9435 INIT_LIST_HEAD(&devlink->port_list);
9436 INIT_LIST_HEAD(&devlink->rate_list);
9437 INIT_LIST_HEAD(&devlink->linecard_list);
9438 INIT_LIST_HEAD(&devlink->sb_list);
9439 INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list);
9440 INIT_LIST_HEAD(&devlink->resource_list);
9441 INIT_LIST_HEAD(&devlink->param_list);
9442 INIT_LIST_HEAD(&devlink->region_list);
9443 INIT_LIST_HEAD(&devlink->reporter_list);
9444 INIT_LIST_HEAD(&devlink->trap_list);
9445 INIT_LIST_HEAD(&devlink->trap_group_list);
9446 INIT_LIST_HEAD(&devlink->trap_policer_list);
9447 lockdep_register_key(&devlink->lock_key);
9448 mutex_init(&devlink->lock);
9449 lockdep_set_class(&devlink->lock, &devlink->lock_key);
9450 mutex_init(&devlink->reporters_lock);
9451 mutex_init(&devlink->linecards_lock);
9452 refcount_set(&devlink->refcount, 1);
9453 init_completion(&devlink->comp);
9457 EXPORT_SYMBOL_GPL(devlink_alloc_ns);
9460 devlink_trap_policer_notify(struct devlink *devlink,
9461 const struct devlink_trap_policer_item *policer_item,
9462 enum devlink_command cmd);
9464 devlink_trap_group_notify(struct devlink *devlink,
9465 const struct devlink_trap_group_item *group_item,
9466 enum devlink_command cmd);
9467 static void devlink_trap_notify(struct devlink *devlink,
9468 const struct devlink_trap_item *trap_item,
9469 enum devlink_command cmd);
9471 static void devlink_notify_register(struct devlink *devlink)
9473 struct devlink_trap_policer_item *policer_item;
9474 struct devlink_trap_group_item *group_item;
9475 struct devlink_param_item *param_item;
9476 struct devlink_trap_item *trap_item;
9477 struct devlink_port *devlink_port;
9478 struct devlink_linecard *linecard;
9479 struct devlink_rate *rate_node;
9480 struct devlink_region *region;
9482 devlink_notify(devlink, DEVLINK_CMD_NEW);
9483 list_for_each_entry(linecard, &devlink->linecard_list, list)
9484 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
9486 list_for_each_entry(devlink_port, &devlink->port_list, list)
9487 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
9489 list_for_each_entry(policer_item, &devlink->trap_policer_list, list)
9490 devlink_trap_policer_notify(devlink, policer_item,
9491 DEVLINK_CMD_TRAP_POLICER_NEW);
9493 list_for_each_entry(group_item, &devlink->trap_group_list, list)
9494 devlink_trap_group_notify(devlink, group_item,
9495 DEVLINK_CMD_TRAP_GROUP_NEW);
9497 list_for_each_entry(trap_item, &devlink->trap_list, list)
9498 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
9500 list_for_each_entry(rate_node, &devlink->rate_list, list)
9501 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
9503 list_for_each_entry(region, &devlink->region_list, list)
9504 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
9506 list_for_each_entry(param_item, &devlink->param_list, list)
9507 devlink_param_notify(devlink, 0, param_item,
9508 DEVLINK_CMD_PARAM_NEW);
9511 static void devlink_notify_unregister(struct devlink *devlink)
9513 struct devlink_trap_policer_item *policer_item;
9514 struct devlink_trap_group_item *group_item;
9515 struct devlink_param_item *param_item;
9516 struct devlink_trap_item *trap_item;
9517 struct devlink_port *devlink_port;
9518 struct devlink_rate *rate_node;
9519 struct devlink_region *region;
9521 list_for_each_entry_reverse(param_item, &devlink->param_list, list)
9522 devlink_param_notify(devlink, 0, param_item,
9523 DEVLINK_CMD_PARAM_DEL);
9525 list_for_each_entry_reverse(region, &devlink->region_list, list)
9526 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
9528 list_for_each_entry_reverse(rate_node, &devlink->rate_list, list)
9529 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL);
9531 list_for_each_entry_reverse(trap_item, &devlink->trap_list, list)
9532 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL);
9534 list_for_each_entry_reverse(group_item, &devlink->trap_group_list, list)
9535 devlink_trap_group_notify(devlink, group_item,
9536 DEVLINK_CMD_TRAP_GROUP_DEL);
9537 list_for_each_entry_reverse(policer_item, &devlink->trap_policer_list,
9539 devlink_trap_policer_notify(devlink, policer_item,
9540 DEVLINK_CMD_TRAP_POLICER_DEL);
9542 list_for_each_entry_reverse(devlink_port, &devlink->port_list, list)
9543 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
9544 devlink_notify(devlink, DEVLINK_CMD_DEL);
9548 * devlink_register - Register devlink instance
9552 void devlink_register(struct devlink *devlink)
9554 ASSERT_DEVLINK_NOT_REGISTERED(devlink);
9555 /* Make sure that we are in .probe() routine */
9557 xa_set_mark(&devlinks, devlink->index, DEVLINK_REGISTERED);
9558 devlink_notify_register(devlink);
9560 EXPORT_SYMBOL_GPL(devlink_register);
9563 * devlink_unregister - Unregister devlink instance
9567 void devlink_unregister(struct devlink *devlink)
9569 ASSERT_DEVLINK_REGISTERED(devlink);
9570 /* Make sure that we are in .remove() routine */
9572 devlink_put(devlink);
9573 wait_for_completion(&devlink->comp);
9575 devlink_notify_unregister(devlink);
9576 xa_clear_mark(&devlinks, devlink->index, DEVLINK_REGISTERED);
9578 EXPORT_SYMBOL_GPL(devlink_unregister);
9581 * devlink_free - Free devlink instance resources
9585 void devlink_free(struct devlink *devlink)
9587 ASSERT_DEVLINK_NOT_REGISTERED(devlink);
9589 mutex_destroy(&devlink->linecards_lock);
9590 mutex_destroy(&devlink->reporters_lock);
9591 mutex_destroy(&devlink->lock);
9592 lockdep_unregister_key(&devlink->lock_key);
9593 WARN_ON(!list_empty(&devlink->trap_policer_list));
9594 WARN_ON(!list_empty(&devlink->trap_group_list));
9595 WARN_ON(!list_empty(&devlink->trap_list));
9596 WARN_ON(!list_empty(&devlink->reporter_list));
9597 WARN_ON(!list_empty(&devlink->region_list));
9598 WARN_ON(!list_empty(&devlink->param_list));
9599 WARN_ON(!list_empty(&devlink->resource_list));
9600 WARN_ON(!list_empty(&devlink->dpipe_table_list));
9601 WARN_ON(!list_empty(&devlink->sb_list));
9602 WARN_ON(!list_empty(&devlink->rate_list));
9603 WARN_ON(!list_empty(&devlink->linecard_list));
9604 WARN_ON(!list_empty(&devlink->port_list));
9606 xa_destroy(&devlink->snapshot_ids);
9607 xa_erase(&devlinks, devlink->index);
9611 EXPORT_SYMBOL_GPL(devlink_free);
9613 static void devlink_port_type_warn(struct work_struct *work)
9615 WARN(true, "Type was not set for devlink port.");
9618 static bool devlink_port_type_should_warn(struct devlink_port *devlink_port)
9620 /* Ignore CPU and DSA flavours. */
9621 return devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_CPU &&
9622 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_DSA &&
9623 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_UNUSED;
9626 #define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 3600)
9628 static void devlink_port_type_warn_schedule(struct devlink_port *devlink_port)
9630 if (!devlink_port_type_should_warn(devlink_port))
9632 /* Schedule a work to WARN in case driver does not set port
9633 * type within timeout.
9635 schedule_delayed_work(&devlink_port->type_warn_dw,
9636 DEVLINK_PORT_TYPE_WARN_TIMEOUT);
9639 static void devlink_port_type_warn_cancel(struct devlink_port *devlink_port)
9641 if (!devlink_port_type_should_warn(devlink_port))
9643 cancel_delayed_work_sync(&devlink_port->type_warn_dw);
9647 * devl_port_register() - Register devlink port
9650 * @devlink_port: devlink port
9651 * @port_index: driver-specific numerical identifier of the port
9653 * Register devlink port with provided port index. User can use
9654 * any indexing, even hw-related one. devlink_port structure
9655 * is convenient to be embedded inside user driver private structure.
9656 * Note that the caller should take care of zeroing the devlink_port
9659 int devl_port_register(struct devlink *devlink,
9660 struct devlink_port *devlink_port,
9661 unsigned int port_index)
9663 devl_assert_locked(devlink);
9665 if (devlink_port_index_exists(devlink, port_index))
9668 WARN_ON(devlink_port->devlink);
9669 devlink_port->devlink = devlink;
9670 devlink_port->index = port_index;
9671 spin_lock_init(&devlink_port->type_lock);
9672 INIT_LIST_HEAD(&devlink_port->reporter_list);
9673 mutex_init(&devlink_port->reporters_lock);
9674 list_add_tail(&devlink_port->list, &devlink->port_list);
9675 INIT_LIST_HEAD(&devlink_port->param_list);
9676 INIT_LIST_HEAD(&devlink_port->region_list);
9678 INIT_DELAYED_WORK(&devlink_port->type_warn_dw, &devlink_port_type_warn);
9679 devlink_port_type_warn_schedule(devlink_port);
9680 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
9683 EXPORT_SYMBOL_GPL(devl_port_register);
9686 * devlink_port_register - Register devlink port
9689 * @devlink_port: devlink port
9690 * @port_index: driver-specific numerical identifier of the port
9692 * Register devlink port with provided port index. User can use
9693 * any indexing, even hw-related one. devlink_port structure
9694 * is convenient to be embedded inside user driver private structure.
9695 * Note that the caller should take care of zeroing the devlink_port
9698 * Context: Takes and release devlink->lock <mutex>.
9700 int devlink_port_register(struct devlink *devlink,
9701 struct devlink_port *devlink_port,
9702 unsigned int port_index)
9707 err = devl_port_register(devlink, devlink_port, port_index);
9708 devl_unlock(devlink);
9711 EXPORT_SYMBOL_GPL(devlink_port_register);
9714 * devl_port_unregister() - Unregister devlink port
9716 * @devlink_port: devlink port
9718 void devl_port_unregister(struct devlink_port *devlink_port)
9720 lockdep_assert_held(&devlink_port->devlink->lock);
9722 devlink_port_type_warn_cancel(devlink_port);
9723 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
9724 list_del(&devlink_port->list);
9725 WARN_ON(!list_empty(&devlink_port->reporter_list));
9726 WARN_ON(!list_empty(&devlink_port->region_list));
9727 mutex_destroy(&devlink_port->reporters_lock);
9729 EXPORT_SYMBOL_GPL(devl_port_unregister);
9732 * devlink_port_unregister - Unregister devlink port
9734 * @devlink_port: devlink port
9736 * Context: Takes and release devlink->lock <mutex>.
9738 void devlink_port_unregister(struct devlink_port *devlink_port)
9740 struct devlink *devlink = devlink_port->devlink;
9743 devl_port_unregister(devlink_port);
9744 devl_unlock(devlink);
9746 EXPORT_SYMBOL_GPL(devlink_port_unregister);
9748 static void __devlink_port_type_set(struct devlink_port *devlink_port,
9749 enum devlink_port_type type,
9752 if (WARN_ON(!devlink_port->devlink))
9754 devlink_port_type_warn_cancel(devlink_port);
9755 spin_lock_bh(&devlink_port->type_lock);
9756 devlink_port->type = type;
9757 devlink_port->type_dev = type_dev;
9758 spin_unlock_bh(&devlink_port->type_lock);
9759 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
9762 static void devlink_port_type_netdev_checks(struct devlink_port *devlink_port,
9763 struct net_device *netdev)
9765 const struct net_device_ops *ops = netdev->netdev_ops;
9767 /* If driver registers devlink port, it should set devlink port
9768 * attributes accordingly so the compat functions are called
9769 * and the original ops are not used.
9771 if (ops->ndo_get_phys_port_name) {
9772 /* Some drivers use the same set of ndos for netdevs
9773 * that have devlink_port registered and also for
9774 * those who don't. Make sure that ndo_get_phys_port_name
9775 * returns -EOPNOTSUPP here in case it is defined.
9778 char name[IFNAMSIZ];
9781 err = ops->ndo_get_phys_port_name(netdev, name, sizeof(name));
9782 WARN_ON(err != -EOPNOTSUPP);
9784 if (ops->ndo_get_port_parent_id) {
9785 /* Some drivers use the same set of ndos for netdevs
9786 * that have devlink_port registered and also for
9787 * those who don't. Make sure that ndo_get_port_parent_id
9788 * returns -EOPNOTSUPP here in case it is defined.
9791 struct netdev_phys_item_id ppid;
9794 err = ops->ndo_get_port_parent_id(netdev, &ppid);
9795 WARN_ON(err != -EOPNOTSUPP);
9800 * devlink_port_type_eth_set - Set port type to Ethernet
9802 * @devlink_port: devlink port
9803 * @netdev: related netdevice
9805 void devlink_port_type_eth_set(struct devlink_port *devlink_port,
9806 struct net_device *netdev)
9809 devlink_port_type_netdev_checks(devlink_port, netdev);
9811 dev_warn(devlink_port->devlink->dev,
9812 "devlink port type for port %d set to Ethernet without a software interface reference, device type not supported by the kernel?\n",
9813 devlink_port->index);
9815 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, netdev);
9817 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
9820 * devlink_port_type_ib_set - Set port type to InfiniBand
9822 * @devlink_port: devlink port
9823 * @ibdev: related IB device
9825 void devlink_port_type_ib_set(struct devlink_port *devlink_port,
9826 struct ib_device *ibdev)
9828 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_IB, ibdev);
9830 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
9833 * devlink_port_type_clear - Clear port type
9835 * @devlink_port: devlink port
9837 void devlink_port_type_clear(struct devlink_port *devlink_port)
9839 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, NULL);
9840 devlink_port_type_warn_schedule(devlink_port);
9842 EXPORT_SYMBOL_GPL(devlink_port_type_clear);
9844 static int __devlink_port_attrs_set(struct devlink_port *devlink_port,
9845 enum devlink_port_flavour flavour)
9847 struct devlink_port_attrs *attrs = &devlink_port->attrs;
9849 devlink_port->attrs_set = true;
9850 attrs->flavour = flavour;
9851 if (attrs->switch_id.id_len) {
9852 devlink_port->switch_port = true;
9853 if (WARN_ON(attrs->switch_id.id_len > MAX_PHYS_ITEM_ID_LEN))
9854 attrs->switch_id.id_len = MAX_PHYS_ITEM_ID_LEN;
9856 devlink_port->switch_port = false;
9862 * devlink_port_attrs_set - Set port attributes
9864 * @devlink_port: devlink port
9865 * @attrs: devlink port attrs
9867 void devlink_port_attrs_set(struct devlink_port *devlink_port,
9868 struct devlink_port_attrs *attrs)
9872 if (WARN_ON(devlink_port->devlink))
9874 devlink_port->attrs = *attrs;
9875 ret = __devlink_port_attrs_set(devlink_port, attrs->flavour);
9878 WARN_ON(attrs->splittable && attrs->split);
9880 EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
9883 * devlink_port_attrs_pci_pf_set - Set PCI PF port attributes
9885 * @devlink_port: devlink port
9886 * @controller: associated controller number for the devlink port instance
9887 * @pf: associated PF for the devlink port instance
9888 * @external: indicates if the port is for an external controller
9890 void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u32 controller,
9891 u16 pf, bool external)
9893 struct devlink_port_attrs *attrs = &devlink_port->attrs;
9896 if (WARN_ON(devlink_port->devlink))
9898 ret = __devlink_port_attrs_set(devlink_port,
9899 DEVLINK_PORT_FLAVOUR_PCI_PF);
9902 attrs->pci_pf.controller = controller;
9903 attrs->pci_pf.pf = pf;
9904 attrs->pci_pf.external = external;
9906 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set);
9909 * devlink_port_attrs_pci_vf_set - Set PCI VF port attributes
9911 * @devlink_port: devlink port
9912 * @controller: associated controller number for the devlink port instance
9913 * @pf: associated PF for the devlink port instance
9914 * @vf: associated VF of a PF for the devlink port instance
9915 * @external: indicates if the port is for an external controller
9917 void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port, u32 controller,
9918 u16 pf, u16 vf, bool external)
9920 struct devlink_port_attrs *attrs = &devlink_port->attrs;
9923 if (WARN_ON(devlink_port->devlink))
9925 ret = __devlink_port_attrs_set(devlink_port,
9926 DEVLINK_PORT_FLAVOUR_PCI_VF);
9929 attrs->pci_vf.controller = controller;
9930 attrs->pci_vf.pf = pf;
9931 attrs->pci_vf.vf = vf;
9932 attrs->pci_vf.external = external;
9934 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set);
9937 * devlink_port_attrs_pci_sf_set - Set PCI SF port attributes
9939 * @devlink_port: devlink port
9940 * @controller: associated controller number for the devlink port instance
9941 * @pf: associated PF for the devlink port instance
9942 * @sf: associated SF of a PF for the devlink port instance
9943 * @external: indicates if the port is for an external controller
9945 void devlink_port_attrs_pci_sf_set(struct devlink_port *devlink_port, u32 controller,
9946 u16 pf, u32 sf, bool external)
9948 struct devlink_port_attrs *attrs = &devlink_port->attrs;
9951 if (WARN_ON(devlink_port->devlink))
9953 ret = __devlink_port_attrs_set(devlink_port,
9954 DEVLINK_PORT_FLAVOUR_PCI_SF);
9957 attrs->pci_sf.controller = controller;
9958 attrs->pci_sf.pf = pf;
9959 attrs->pci_sf.sf = sf;
9960 attrs->pci_sf.external = external;
9962 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_sf_set);
9965 * devl_rate_leaf_create - create devlink rate leaf
9966 * @devlink_port: devlink port object to create rate object on
9967 * @priv: driver private data
9969 * Create devlink rate object of type leaf on provided @devlink_port.
9971 int devl_rate_leaf_create(struct devlink_port *devlink_port, void *priv)
9973 struct devlink *devlink = devlink_port->devlink;
9974 struct devlink_rate *devlink_rate;
9976 devl_assert_locked(devlink_port->devlink);
9978 if (WARN_ON(devlink_port->devlink_rate))
9981 devlink_rate = kzalloc(sizeof(*devlink_rate), GFP_KERNEL);
9985 devlink_rate->type = DEVLINK_RATE_TYPE_LEAF;
9986 devlink_rate->devlink = devlink;
9987 devlink_rate->devlink_port = devlink_port;
9988 devlink_rate->priv = priv;
9989 list_add_tail(&devlink_rate->list, &devlink->rate_list);
9990 devlink_port->devlink_rate = devlink_rate;
9991 devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW);
9995 EXPORT_SYMBOL_GPL(devl_rate_leaf_create);
9998 * devl_rate_leaf_destroy - destroy devlink rate leaf
10000 * @devlink_port: devlink port linked to the rate object
10002 * Destroy the devlink rate object of type leaf on provided @devlink_port.
10004 void devl_rate_leaf_destroy(struct devlink_port *devlink_port)
10006 struct devlink_rate *devlink_rate = devlink_port->devlink_rate;
10008 devl_assert_locked(devlink_port->devlink);
10012 devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_DEL);
10013 if (devlink_rate->parent)
10014 refcount_dec(&devlink_rate->parent->refcnt);
10015 list_del(&devlink_rate->list);
10016 devlink_port->devlink_rate = NULL;
10017 kfree(devlink_rate);
10019 EXPORT_SYMBOL_GPL(devl_rate_leaf_destroy);
10022 * devl_rate_nodes_destroy - destroy all devlink rate nodes on device
10023 * @devlink: devlink instance
10025 * Unset parent for all rate objects and destroy all rate nodes
10026 * on specified device.
10028 void devl_rate_nodes_destroy(struct devlink *devlink)
10030 static struct devlink_rate *devlink_rate, *tmp;
10031 const struct devlink_ops *ops = devlink->ops;
10033 devl_assert_locked(devlink);
10035 list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
10036 if (!devlink_rate->parent)
10039 refcount_dec(&devlink_rate->parent->refcnt);
10040 if (devlink_rate_is_leaf(devlink_rate))
10041 ops->rate_leaf_parent_set(devlink_rate, NULL, devlink_rate->priv,
10043 else if (devlink_rate_is_node(devlink_rate))
10044 ops->rate_node_parent_set(devlink_rate, NULL, devlink_rate->priv,
10047 list_for_each_entry_safe(devlink_rate, tmp, &devlink->rate_list, list) {
10048 if (devlink_rate_is_node(devlink_rate)) {
10049 ops->rate_node_del(devlink_rate, devlink_rate->priv, NULL);
10050 list_del(&devlink_rate->list);
10051 kfree(devlink_rate->name);
10052 kfree(devlink_rate);
10056 EXPORT_SYMBOL_GPL(devl_rate_nodes_destroy);
10059 * devlink_port_linecard_set - Link port with a linecard
10061 * @devlink_port: devlink port
10062 * @linecard: devlink linecard
10064 void devlink_port_linecard_set(struct devlink_port *devlink_port,
10065 struct devlink_linecard *linecard)
10067 if (WARN_ON(devlink_port->devlink))
10069 devlink_port->linecard = linecard;
10071 EXPORT_SYMBOL_GPL(devlink_port_linecard_set);
10073 static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
10074 char *name, size_t len)
10076 struct devlink_port_attrs *attrs = &devlink_port->attrs;
10079 if (!devlink_port->attrs_set)
10080 return -EOPNOTSUPP;
10082 switch (attrs->flavour) {
10083 case DEVLINK_PORT_FLAVOUR_PHYSICAL:
10084 if (devlink_port->linecard)
10085 n = snprintf(name, len, "l%u",
10086 devlink_port->linecard->index);
10088 n += snprintf(name + n, len - n, "p%u",
10089 attrs->phys.port_number);
10090 if (n < len && attrs->split)
10091 n += snprintf(name + n, len - n, "s%u",
10092 attrs->phys.split_subport_number);
10094 case DEVLINK_PORT_FLAVOUR_CPU:
10095 case DEVLINK_PORT_FLAVOUR_DSA:
10096 case DEVLINK_PORT_FLAVOUR_UNUSED:
10097 /* As CPU and DSA ports do not have a netdevice associated
10098 * case should not ever happen.
10102 case DEVLINK_PORT_FLAVOUR_PCI_PF:
10103 if (attrs->pci_pf.external) {
10104 n = snprintf(name, len, "c%u", attrs->pci_pf.controller);
10110 n = snprintf(name, len, "pf%u", attrs->pci_pf.pf);
10112 case DEVLINK_PORT_FLAVOUR_PCI_VF:
10113 if (attrs->pci_vf.external) {
10114 n = snprintf(name, len, "c%u", attrs->pci_vf.controller);
10120 n = snprintf(name, len, "pf%uvf%u",
10121 attrs->pci_vf.pf, attrs->pci_vf.vf);
10123 case DEVLINK_PORT_FLAVOUR_PCI_SF:
10124 if (attrs->pci_sf.external) {
10125 n = snprintf(name, len, "c%u", attrs->pci_sf.controller);
10131 n = snprintf(name, len, "pf%usf%u", attrs->pci_sf.pf,
10134 case DEVLINK_PORT_FLAVOUR_VIRTUAL:
10135 return -EOPNOTSUPP;
10144 static int devlink_linecard_types_init(struct devlink_linecard *linecard)
10146 struct devlink_linecard_type *linecard_type;
10147 unsigned int count;
10150 count = linecard->ops->types_count(linecard, linecard->priv);
10151 linecard->types = kmalloc_array(count, sizeof(*linecard_type),
10153 if (!linecard->types)
10155 linecard->types_count = count;
10157 for (i = 0; i < count; i++) {
10158 linecard_type = &linecard->types[i];
10159 linecard->ops->types_get(linecard, linecard->priv, i,
10160 &linecard_type->type,
10161 &linecard_type->priv);
10166 static void devlink_linecard_types_fini(struct devlink_linecard *linecard)
10168 kfree(linecard->types);
10172 * devlink_linecard_create - Create devlink linecard
10174 * @devlink: devlink
10175 * @linecard_index: driver-specific numerical identifier of the linecard
10176 * @ops: linecards ops
10177 * @priv: user priv pointer
10179 * Create devlink linecard instance with provided linecard index.
10180 * Caller can use any indexing, even hw-related one.
10182 * Return: Line card structure or an ERR_PTR() encoded error code.
10184 struct devlink_linecard *
10185 devlink_linecard_create(struct devlink *devlink, unsigned int linecard_index,
10186 const struct devlink_linecard_ops *ops, void *priv)
10188 struct devlink_linecard *linecard;
10191 if (WARN_ON(!ops || !ops->provision || !ops->unprovision ||
10192 !ops->types_count || !ops->types_get))
10193 return ERR_PTR(-EINVAL);
10195 mutex_lock(&devlink->linecards_lock);
10196 if (devlink_linecard_index_exists(devlink, linecard_index)) {
10197 mutex_unlock(&devlink->linecards_lock);
10198 return ERR_PTR(-EEXIST);
10201 linecard = kzalloc(sizeof(*linecard), GFP_KERNEL);
10203 mutex_unlock(&devlink->linecards_lock);
10204 return ERR_PTR(-ENOMEM);
10207 linecard->devlink = devlink;
10208 linecard->index = linecard_index;
10209 linecard->ops = ops;
10210 linecard->priv = priv;
10211 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
10212 mutex_init(&linecard->state_lock);
10214 err = devlink_linecard_types_init(linecard);
10216 mutex_destroy(&linecard->state_lock);
10218 mutex_unlock(&devlink->linecards_lock);
10219 return ERR_PTR(err);
10222 list_add_tail(&linecard->list, &devlink->linecard_list);
10223 refcount_set(&linecard->refcount, 1);
10224 mutex_unlock(&devlink->linecards_lock);
10225 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10228 EXPORT_SYMBOL_GPL(devlink_linecard_create);
10231 * devlink_linecard_destroy - Destroy devlink linecard
10233 * @linecard: devlink linecard
10235 void devlink_linecard_destroy(struct devlink_linecard *linecard)
10237 struct devlink *devlink = linecard->devlink;
10239 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_DEL);
10240 mutex_lock(&devlink->linecards_lock);
10241 list_del(&linecard->list);
10242 devlink_linecard_types_fini(linecard);
10243 mutex_unlock(&devlink->linecards_lock);
10244 devlink_linecard_put(linecard);
10246 EXPORT_SYMBOL_GPL(devlink_linecard_destroy);
10249 * devlink_linecard_provision_set - Set provisioning on linecard
10251 * @linecard: devlink linecard
10252 * @type: linecard type
10254 * This is either called directly from the provision() op call or
10255 * as a result of the provision() op call asynchronously.
10257 void devlink_linecard_provision_set(struct devlink_linecard *linecard,
10260 mutex_lock(&linecard->state_lock);
10261 WARN_ON(linecard->type && strcmp(linecard->type, type));
10262 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED;
10263 linecard->type = type;
10264 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10265 mutex_unlock(&linecard->state_lock);
10267 EXPORT_SYMBOL_GPL(devlink_linecard_provision_set);
10270 * devlink_linecard_provision_clear - Clear provisioning on linecard
10272 * @linecard: devlink linecard
10274 * This is either called directly from the unprovision() op call or
10275 * as a result of the unprovision() op call asynchronously.
10277 void devlink_linecard_provision_clear(struct devlink_linecard *linecard)
10279 mutex_lock(&linecard->state_lock);
10280 WARN_ON(linecard->nested_devlink);
10281 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
10282 linecard->type = NULL;
10283 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10284 mutex_unlock(&linecard->state_lock);
10286 EXPORT_SYMBOL_GPL(devlink_linecard_provision_clear);
10289 * devlink_linecard_provision_fail - Fail provisioning on linecard
10291 * @linecard: devlink linecard
10293 * This is either called directly from the provision() op call or
10294 * as a result of the provision() op call asynchronously.
10296 void devlink_linecard_provision_fail(struct devlink_linecard *linecard)
10298 mutex_lock(&linecard->state_lock);
10299 WARN_ON(linecard->nested_devlink);
10300 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING_FAILED;
10301 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10302 mutex_unlock(&linecard->state_lock);
10304 EXPORT_SYMBOL_GPL(devlink_linecard_provision_fail);
10307 * devlink_linecard_activate - Set linecard active
10309 * @linecard: devlink linecard
10311 void devlink_linecard_activate(struct devlink_linecard *linecard)
10313 mutex_lock(&linecard->state_lock);
10314 WARN_ON(linecard->state != DEVLINK_LINECARD_STATE_PROVISIONED);
10315 linecard->state = DEVLINK_LINECARD_STATE_ACTIVE;
10316 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10317 mutex_unlock(&linecard->state_lock);
10319 EXPORT_SYMBOL_GPL(devlink_linecard_activate);
10322 * devlink_linecard_deactivate - Set linecard inactive
10324 * @linecard: devlink linecard
10326 void devlink_linecard_deactivate(struct devlink_linecard *linecard)
10328 mutex_lock(&linecard->state_lock);
10329 switch (linecard->state) {
10330 case DEVLINK_LINECARD_STATE_ACTIVE:
10331 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED;
10332 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10334 case DEVLINK_LINECARD_STATE_UNPROVISIONING:
10335 /* Line card is being deactivated as part
10336 * of unprovisioning flow.
10343 mutex_unlock(&linecard->state_lock);
10345 EXPORT_SYMBOL_GPL(devlink_linecard_deactivate);
10348 * devlink_linecard_nested_dl_set - Attach/detach nested devlink
10349 * instance to linecard.
10351 * @linecard: devlink linecard
10352 * @nested_devlink: devlink instance to attach or NULL to detach
10354 void devlink_linecard_nested_dl_set(struct devlink_linecard *linecard,
10355 struct devlink *nested_devlink)
10357 mutex_lock(&linecard->state_lock);
10358 linecard->nested_devlink = nested_devlink;
10359 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10360 mutex_unlock(&linecard->state_lock);
10362 EXPORT_SYMBOL_GPL(devlink_linecard_nested_dl_set);
10364 int devl_sb_register(struct devlink *devlink, unsigned int sb_index,
10365 u32 size, u16 ingress_pools_count,
10366 u16 egress_pools_count, u16 ingress_tc_count,
10367 u16 egress_tc_count)
10369 struct devlink_sb *devlink_sb;
10371 lockdep_assert_held(&devlink->lock);
10373 if (devlink_sb_index_exists(devlink, sb_index))
10376 devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
10379 devlink_sb->index = sb_index;
10380 devlink_sb->size = size;
10381 devlink_sb->ingress_pools_count = ingress_pools_count;
10382 devlink_sb->egress_pools_count = egress_pools_count;
10383 devlink_sb->ingress_tc_count = ingress_tc_count;
10384 devlink_sb->egress_tc_count = egress_tc_count;
10385 list_add_tail(&devlink_sb->list, &devlink->sb_list);
10388 EXPORT_SYMBOL_GPL(devl_sb_register);
10390 int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
10391 u32 size, u16 ingress_pools_count,
10392 u16 egress_pools_count, u16 ingress_tc_count,
10393 u16 egress_tc_count)
10397 devl_lock(devlink);
10398 err = devl_sb_register(devlink, sb_index, size, ingress_pools_count,
10399 egress_pools_count, ingress_tc_count,
10401 devl_unlock(devlink);
10404 EXPORT_SYMBOL_GPL(devlink_sb_register);
10406 void devl_sb_unregister(struct devlink *devlink, unsigned int sb_index)
10408 struct devlink_sb *devlink_sb;
10410 lockdep_assert_held(&devlink->lock);
10412 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
10413 WARN_ON(!devlink_sb);
10414 list_del(&devlink_sb->list);
10417 EXPORT_SYMBOL_GPL(devl_sb_unregister);
10419 void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
10421 devl_lock(devlink);
10422 devl_sb_unregister(devlink, sb_index);
10423 devl_unlock(devlink);
10425 EXPORT_SYMBOL_GPL(devlink_sb_unregister);
10428 * devl_dpipe_headers_register - register dpipe headers
10430 * @devlink: devlink
10431 * @dpipe_headers: dpipe header array
10433 * Register the headers supported by hardware.
10435 void devl_dpipe_headers_register(struct devlink *devlink,
10436 struct devlink_dpipe_headers *dpipe_headers)
10438 lockdep_assert_held(&devlink->lock);
10440 devlink->dpipe_headers = dpipe_headers;
10442 EXPORT_SYMBOL_GPL(devl_dpipe_headers_register);
10445 * devl_dpipe_headers_unregister - unregister dpipe headers
10447 * @devlink: devlink
10449 * Unregister the headers supported by hardware.
10451 void devl_dpipe_headers_unregister(struct devlink *devlink)
10453 lockdep_assert_held(&devlink->lock);
10455 devlink->dpipe_headers = NULL;
10457 EXPORT_SYMBOL_GPL(devl_dpipe_headers_unregister);
10460 * devlink_dpipe_table_counter_enabled - check if counter allocation
10462 * @devlink: devlink
10463 * @table_name: tables name
10465 * Used by driver to check if counter allocation is required.
10466 * After counter allocation is turned on the table entries
10467 * are updated to include counter statistics.
10469 * After that point on the driver must respect the counter
10470 * state so that each entry added to the table is added
10473 bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
10474 const char *table_name)
10476 struct devlink_dpipe_table *table;
10480 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
10481 table_name, devlink);
10484 enabled = table->counters_enabled;
10488 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled);
10491 * devl_dpipe_table_register - register dpipe table
10493 * @devlink: devlink
10494 * @table_name: table name
10495 * @table_ops: table ops
10497 * @counter_control_extern: external control for counters
10499 int devl_dpipe_table_register(struct devlink *devlink,
10500 const char *table_name,
10501 struct devlink_dpipe_table_ops *table_ops,
10502 void *priv, bool counter_control_extern)
10504 struct devlink_dpipe_table *table;
10506 lockdep_assert_held(&devlink->lock);
10508 if (WARN_ON(!table_ops->size_get))
10511 if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name,
10515 table = kzalloc(sizeof(*table), GFP_KERNEL);
10519 table->name = table_name;
10520 table->table_ops = table_ops;
10521 table->priv = priv;
10522 table->counter_control_extern = counter_control_extern;
10524 list_add_tail_rcu(&table->list, &devlink->dpipe_table_list);
10528 EXPORT_SYMBOL_GPL(devl_dpipe_table_register);
10531 * devl_dpipe_table_unregister - unregister dpipe table
10533 * @devlink: devlink
10534 * @table_name: table name
10536 void devl_dpipe_table_unregister(struct devlink *devlink,
10537 const char *table_name)
10539 struct devlink_dpipe_table *table;
10541 lockdep_assert_held(&devlink->lock);
10543 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
10544 table_name, devlink);
10547 list_del_rcu(&table->list);
10548 kfree_rcu(table, rcu);
10550 EXPORT_SYMBOL_GPL(devl_dpipe_table_unregister);
10553 * devl_resource_register - devlink resource register
10555 * @devlink: devlink
10556 * @resource_name: resource's name
10557 * @resource_size: resource's size
10558 * @resource_id: resource's id
10559 * @parent_resource_id: resource's parent id
10560 * @size_params: size parameters
10562 * Generic resources should reuse the same names across drivers.
10563 * Please see the generic resources list at:
10564 * Documentation/networking/devlink/devlink-resource.rst
10566 int devl_resource_register(struct devlink *devlink,
10567 const char *resource_name,
10570 u64 parent_resource_id,
10571 const struct devlink_resource_size_params *size_params)
10573 struct devlink_resource *resource;
10574 struct list_head *resource_list;
10575 bool top_hierarchy;
10577 lockdep_assert_held(&devlink->lock);
10579 top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
10581 resource = devlink_resource_find(devlink, NULL, resource_id);
10585 resource = kzalloc(sizeof(*resource), GFP_KERNEL);
10589 if (top_hierarchy) {
10590 resource_list = &devlink->resource_list;
10592 struct devlink_resource *parent_resource;
10594 parent_resource = devlink_resource_find(devlink, NULL,
10595 parent_resource_id);
10596 if (parent_resource) {
10597 resource_list = &parent_resource->resource_list;
10598 resource->parent = parent_resource;
10605 resource->name = resource_name;
10606 resource->size = resource_size;
10607 resource->size_new = resource_size;
10608 resource->id = resource_id;
10609 resource->size_valid = true;
10610 memcpy(&resource->size_params, size_params,
10611 sizeof(resource->size_params));
10612 INIT_LIST_HEAD(&resource->resource_list);
10613 list_add_tail(&resource->list, resource_list);
10617 EXPORT_SYMBOL_GPL(devl_resource_register);
10620 * devlink_resource_register - devlink resource register
10622 * @devlink: devlink
10623 * @resource_name: resource's name
10624 * @resource_size: resource's size
10625 * @resource_id: resource's id
10626 * @parent_resource_id: resource's parent id
10627 * @size_params: size parameters
10629 * Generic resources should reuse the same names across drivers.
10630 * Please see the generic resources list at:
10631 * Documentation/networking/devlink/devlink-resource.rst
10633 * Context: Takes and release devlink->lock <mutex>.
10635 int devlink_resource_register(struct devlink *devlink,
10636 const char *resource_name,
10639 u64 parent_resource_id,
10640 const struct devlink_resource_size_params *size_params)
10644 devl_lock(devlink);
10645 err = devl_resource_register(devlink, resource_name, resource_size,
10646 resource_id, parent_resource_id, size_params);
10647 devl_unlock(devlink);
10650 EXPORT_SYMBOL_GPL(devlink_resource_register);
10652 static void devlink_resource_unregister(struct devlink *devlink,
10653 struct devlink_resource *resource)
10655 struct devlink_resource *tmp, *child_resource;
10657 list_for_each_entry_safe(child_resource, tmp, &resource->resource_list,
10659 devlink_resource_unregister(devlink, child_resource);
10660 list_del(&child_resource->list);
10661 kfree(child_resource);
10666 * devl_resources_unregister - free all resources
10668 * @devlink: devlink
10670 void devl_resources_unregister(struct devlink *devlink)
10672 struct devlink_resource *tmp, *child_resource;
10674 lockdep_assert_held(&devlink->lock);
10676 list_for_each_entry_safe(child_resource, tmp, &devlink->resource_list,
10678 devlink_resource_unregister(devlink, child_resource);
10679 list_del(&child_resource->list);
10680 kfree(child_resource);
10683 EXPORT_SYMBOL_GPL(devl_resources_unregister);
10686 * devlink_resources_unregister - free all resources
10688 * @devlink: devlink
10690 * Context: Takes and release devlink->lock <mutex>.
10692 void devlink_resources_unregister(struct devlink *devlink)
10694 devl_lock(devlink);
10695 devl_resources_unregister(devlink);
10696 devl_unlock(devlink);
10698 EXPORT_SYMBOL_GPL(devlink_resources_unregister);
10701 * devl_resource_size_get - get and update size
10703 * @devlink: devlink
10704 * @resource_id: the requested resource id
10705 * @p_resource_size: ptr to update
10707 int devl_resource_size_get(struct devlink *devlink,
10709 u64 *p_resource_size)
10711 struct devlink_resource *resource;
10713 lockdep_assert_held(&devlink->lock);
10715 resource = devlink_resource_find(devlink, NULL, resource_id);
10718 *p_resource_size = resource->size_new;
10719 resource->size = resource->size_new;
10722 EXPORT_SYMBOL_GPL(devl_resource_size_get);
10725 * devl_dpipe_table_resource_set - set the resource id
10727 * @devlink: devlink
10728 * @table_name: table name
10729 * @resource_id: resource id
10730 * @resource_units: number of resource's units consumed per table's entry
10732 int devl_dpipe_table_resource_set(struct devlink *devlink,
10733 const char *table_name, u64 resource_id,
10734 u64 resource_units)
10736 struct devlink_dpipe_table *table;
10738 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
10739 table_name, devlink);
10743 table->resource_id = resource_id;
10744 table->resource_units = resource_units;
10745 table->resource_valid = true;
10748 EXPORT_SYMBOL_GPL(devl_dpipe_table_resource_set);
10751 * devl_resource_occ_get_register - register occupancy getter
10753 * @devlink: devlink
10754 * @resource_id: resource id
10755 * @occ_get: occupancy getter callback
10756 * @occ_get_priv: occupancy getter callback priv
10758 void devl_resource_occ_get_register(struct devlink *devlink,
10760 devlink_resource_occ_get_t *occ_get,
10761 void *occ_get_priv)
10763 struct devlink_resource *resource;
10765 lockdep_assert_held(&devlink->lock);
10767 resource = devlink_resource_find(devlink, NULL, resource_id);
10768 if (WARN_ON(!resource))
10770 WARN_ON(resource->occ_get);
10772 resource->occ_get = occ_get;
10773 resource->occ_get_priv = occ_get_priv;
10775 EXPORT_SYMBOL_GPL(devl_resource_occ_get_register);
10778 * devlink_resource_occ_get_register - register occupancy getter
10780 * @devlink: devlink
10781 * @resource_id: resource id
10782 * @occ_get: occupancy getter callback
10783 * @occ_get_priv: occupancy getter callback priv
10785 * Context: Takes and release devlink->lock <mutex>.
10787 void devlink_resource_occ_get_register(struct devlink *devlink,
10789 devlink_resource_occ_get_t *occ_get,
10790 void *occ_get_priv)
10792 devl_lock(devlink);
10793 devl_resource_occ_get_register(devlink, resource_id,
10794 occ_get, occ_get_priv);
10795 devl_unlock(devlink);
10797 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register);
10800 * devl_resource_occ_get_unregister - unregister occupancy getter
10802 * @devlink: devlink
10803 * @resource_id: resource id
10805 void devl_resource_occ_get_unregister(struct devlink *devlink,
10808 struct devlink_resource *resource;
10810 lockdep_assert_held(&devlink->lock);
10812 resource = devlink_resource_find(devlink, NULL, resource_id);
10813 if (WARN_ON(!resource))
10815 WARN_ON(!resource->occ_get);
10817 resource->occ_get = NULL;
10818 resource->occ_get_priv = NULL;
10820 EXPORT_SYMBOL_GPL(devl_resource_occ_get_unregister);
10823 * devlink_resource_occ_get_unregister - unregister occupancy getter
10825 * @devlink: devlink
10826 * @resource_id: resource id
10828 * Context: Takes and release devlink->lock <mutex>.
10830 void devlink_resource_occ_get_unregister(struct devlink *devlink,
10833 devl_lock(devlink);
10834 devl_resource_occ_get_unregister(devlink, resource_id);
10835 devl_unlock(devlink);
10837 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister);
10839 static int devlink_param_verify(const struct devlink_param *param)
10841 if (!param || !param->name || !param->supported_cmodes)
10843 if (param->generic)
10844 return devlink_param_generic_verify(param);
10846 return devlink_param_driver_verify(param);
10850 * devlink_params_register - register configuration parameters
10852 * @devlink: devlink
10853 * @params: configuration parameters array
10854 * @params_count: number of parameters provided
10856 * Register the configuration parameters supported by the driver.
10858 int devlink_params_register(struct devlink *devlink,
10859 const struct devlink_param *params,
10860 size_t params_count)
10862 const struct devlink_param *param = params;
10865 ASSERT_DEVLINK_NOT_REGISTERED(devlink);
10867 for (i = 0; i < params_count; i++, param++) {
10868 err = devlink_param_register(devlink, param);
10878 for (param--; i > 0; i--, param--)
10879 devlink_param_unregister(devlink, param);
10882 EXPORT_SYMBOL_GPL(devlink_params_register);
10885 * devlink_params_unregister - unregister configuration parameters
10886 * @devlink: devlink
10887 * @params: configuration parameters to unregister
10888 * @params_count: number of parameters provided
10890 void devlink_params_unregister(struct devlink *devlink,
10891 const struct devlink_param *params,
10892 size_t params_count)
10894 const struct devlink_param *param = params;
10897 ASSERT_DEVLINK_NOT_REGISTERED(devlink);
10899 for (i = 0; i < params_count; i++, param++)
10900 devlink_param_unregister(devlink, param);
10902 EXPORT_SYMBOL_GPL(devlink_params_unregister);
10905 * devlink_param_register - register one configuration parameter
10907 * @devlink: devlink
10908 * @param: one configuration parameter
10910 * Register the configuration parameter supported by the driver.
10911 * Return: returns 0 on successful registration or error code otherwise.
10913 int devlink_param_register(struct devlink *devlink,
10914 const struct devlink_param *param)
10916 struct devlink_param_item *param_item;
10918 ASSERT_DEVLINK_NOT_REGISTERED(devlink);
10920 WARN_ON(devlink_param_verify(param));
10921 WARN_ON(devlink_param_find_by_name(&devlink->param_list, param->name));
10923 if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT))
10924 WARN_ON(param->get || param->set);
10926 WARN_ON(!param->get || !param->set);
10928 param_item = kzalloc(sizeof(*param_item), GFP_KERNEL);
10932 param_item->param = param;
10934 list_add_tail(¶m_item->list, &devlink->param_list);
10937 EXPORT_SYMBOL_GPL(devlink_param_register);
10940 * devlink_param_unregister - unregister one configuration parameter
10941 * @devlink: devlink
10942 * @param: configuration parameter to unregister
10944 void devlink_param_unregister(struct devlink *devlink,
10945 const struct devlink_param *param)
10947 struct devlink_param_item *param_item;
10949 ASSERT_DEVLINK_NOT_REGISTERED(devlink);
10952 devlink_param_find_by_name(&devlink->param_list, param->name);
10953 WARN_ON(!param_item);
10954 list_del(¶m_item->list);
10957 EXPORT_SYMBOL_GPL(devlink_param_unregister);
10960 * devlink_param_driverinit_value_get - get configuration parameter
10961 * value for driver initializing
10963 * @devlink: devlink
10964 * @param_id: parameter ID
10965 * @init_val: value of parameter in driverinit configuration mode
10967 * This function should be used by the driver to get driverinit
10968 * configuration for initialization after reload command.
10970 int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
10971 union devlink_param_value *init_val)
10973 struct devlink_param_item *param_item;
10975 if (!devlink_reload_supported(devlink->ops))
10976 return -EOPNOTSUPP;
10978 param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
10982 if (!param_item->driverinit_value_valid ||
10983 !devlink_param_cmode_is_supported(param_item->param,
10984 DEVLINK_PARAM_CMODE_DRIVERINIT))
10985 return -EOPNOTSUPP;
10987 if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
10988 strcpy(init_val->vstr, param_item->driverinit_value.vstr);
10990 *init_val = param_item->driverinit_value;
10994 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_get);
10997 * devlink_param_driverinit_value_set - set value of configuration
10998 * parameter for driverinit
10999 * configuration mode
11001 * @devlink: devlink
11002 * @param_id: parameter ID
11003 * @init_val: value of parameter to set for driverinit configuration mode
11005 * This function should be used by the driver to set driverinit
11006 * configuration mode default value.
11008 int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
11009 union devlink_param_value init_val)
11011 struct devlink_param_item *param_item;
11013 ASSERT_DEVLINK_NOT_REGISTERED(devlink);
11015 param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
11019 if (!devlink_param_cmode_is_supported(param_item->param,
11020 DEVLINK_PARAM_CMODE_DRIVERINIT))
11021 return -EOPNOTSUPP;
11023 if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
11024 strcpy(param_item->driverinit_value.vstr, init_val.vstr);
11026 param_item->driverinit_value = init_val;
11027 param_item->driverinit_value_valid = true;
11030 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set);
11033 * devlink_param_value_changed - notify devlink on a parameter's value
11034 * change. Should be called by the driver
11035 * right after the change.
11037 * @devlink: devlink
11038 * @param_id: parameter ID
11040 * This function should be used by the driver to notify devlink on value
11041 * change, excluding driverinit configuration mode.
11042 * For driverinit configuration mode driver should use the function
11044 void devlink_param_value_changed(struct devlink *devlink, u32 param_id)
11046 struct devlink_param_item *param_item;
11048 param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
11049 WARN_ON(!param_item);
11051 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
11053 EXPORT_SYMBOL_GPL(devlink_param_value_changed);
11056 * devl_region_create - create a new address region
11058 * @devlink: devlink
11059 * @ops: region operations and name
11060 * @region_max_snapshots: Maximum supported number of snapshots for region
11061 * @region_size: size of region
11063 struct devlink_region *devl_region_create(struct devlink *devlink,
11064 const struct devlink_region_ops *ops,
11065 u32 region_max_snapshots,
11068 struct devlink_region *region;
11070 devl_assert_locked(devlink);
11072 if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
11073 return ERR_PTR(-EINVAL);
11075 if (devlink_region_get_by_name(devlink, ops->name))
11076 return ERR_PTR(-EEXIST);
11078 region = kzalloc(sizeof(*region), GFP_KERNEL);
11080 return ERR_PTR(-ENOMEM);
11082 region->devlink = devlink;
11083 region->max_snapshots = region_max_snapshots;
11085 region->size = region_size;
11086 INIT_LIST_HEAD(®ion->snapshot_list);
11087 list_add_tail(®ion->list, &devlink->region_list);
11088 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
11092 EXPORT_SYMBOL_GPL(devl_region_create);
11095 * devlink_region_create - create a new address region
11097 * @devlink: devlink
11098 * @ops: region operations and name
11099 * @region_max_snapshots: Maximum supported number of snapshots for region
11100 * @region_size: size of region
11102 * Context: Takes and release devlink->lock <mutex>.
11104 struct devlink_region *
11105 devlink_region_create(struct devlink *devlink,
11106 const struct devlink_region_ops *ops,
11107 u32 region_max_snapshots, u64 region_size)
11109 struct devlink_region *region;
11111 devl_lock(devlink);
11112 region = devl_region_create(devlink, ops, region_max_snapshots,
11114 devl_unlock(devlink);
11117 EXPORT_SYMBOL_GPL(devlink_region_create);
11120 * devlink_port_region_create - create a new address region for a port
11122 * @port: devlink port
11123 * @ops: region operations and name
11124 * @region_max_snapshots: Maximum supported number of snapshots for region
11125 * @region_size: size of region
11127 * Context: Takes and release devlink->lock <mutex>.
11129 struct devlink_region *
11130 devlink_port_region_create(struct devlink_port *port,
11131 const struct devlink_port_region_ops *ops,
11132 u32 region_max_snapshots, u64 region_size)
11134 struct devlink *devlink = port->devlink;
11135 struct devlink_region *region;
11138 if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
11139 return ERR_PTR(-EINVAL);
11141 devl_lock(devlink);
11143 if (devlink_port_region_get_by_name(port, ops->name)) {
11148 region = kzalloc(sizeof(*region), GFP_KERNEL);
11154 region->devlink = devlink;
11155 region->port = port;
11156 region->max_snapshots = region_max_snapshots;
11157 region->port_ops = ops;
11158 region->size = region_size;
11159 INIT_LIST_HEAD(®ion->snapshot_list);
11160 list_add_tail(®ion->list, &port->region_list);
11161 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
11163 devl_unlock(devlink);
11167 devl_unlock(devlink);
11168 return ERR_PTR(err);
11170 EXPORT_SYMBOL_GPL(devlink_port_region_create);
11173 * devl_region_destroy - destroy address region
11175 * @region: devlink region to destroy
11177 void devl_region_destroy(struct devlink_region *region)
11179 struct devlink *devlink = region->devlink;
11180 struct devlink_snapshot *snapshot, *ts;
11182 devl_assert_locked(devlink);
11184 /* Free all snapshots of region */
11185 list_for_each_entry_safe(snapshot, ts, ®ion->snapshot_list, list)
11186 devlink_region_snapshot_del(region, snapshot);
11188 list_del(®ion->list);
11190 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
11193 EXPORT_SYMBOL_GPL(devl_region_destroy);
11196 * devlink_region_destroy - destroy address region
11198 * @region: devlink region to destroy
11200 * Context: Takes and release devlink->lock <mutex>.
11202 void devlink_region_destroy(struct devlink_region *region)
11204 struct devlink *devlink = region->devlink;
11206 devl_lock(devlink);
11207 devl_region_destroy(region);
11208 devl_unlock(devlink);
11210 EXPORT_SYMBOL_GPL(devlink_region_destroy);
11213 * devlink_region_snapshot_id_get - get snapshot ID
11215 * This callback should be called when adding a new snapshot,
11216 * Driver should use the same id for multiple snapshots taken
11217 * on multiple regions at the same time/by the same trigger.
11219 * The caller of this function must use devlink_region_snapshot_id_put
11220 * when finished creating regions using this id.
11222 * Returns zero on success, or a negative error code on failure.
11224 * @devlink: devlink
11225 * @id: storage to return id
11227 int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
11231 devl_lock(devlink);
11232 err = __devlink_region_snapshot_id_get(devlink, id);
11233 devl_unlock(devlink);
11237 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get);
11240 * devlink_region_snapshot_id_put - put snapshot ID reference
11242 * This should be called by a driver after finishing creating snapshots
11243 * with an id. Doing so ensures that the ID can later be released in the
11244 * event that all snapshots using it have been destroyed.
11246 * @devlink: devlink
11247 * @id: id to release reference on
11249 void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id)
11251 devl_lock(devlink);
11252 __devlink_snapshot_id_decrement(devlink, id);
11253 devl_unlock(devlink);
11255 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put);
11258 * devlink_region_snapshot_create - create a new snapshot
11259 * This will add a new snapshot of a region. The snapshot
11260 * will be stored on the region struct and can be accessed
11261 * from devlink. This is useful for future analyses of snapshots.
11262 * Multiple snapshots can be created on a region.
11263 * The @snapshot_id should be obtained using the getter function.
11265 * @region: devlink region of the snapshot
11266 * @data: snapshot data
11267 * @snapshot_id: snapshot id to be created
11269 int devlink_region_snapshot_create(struct devlink_region *region,
11270 u8 *data, u32 snapshot_id)
11272 struct devlink *devlink = region->devlink;
11275 devl_lock(devlink);
11276 err = __devlink_region_snapshot_create(region, data, snapshot_id);
11277 devl_unlock(devlink);
11281 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create);
11283 #define DEVLINK_TRAP(_id, _type) \
11285 .type = DEVLINK_TRAP_TYPE_##_type, \
11286 .id = DEVLINK_TRAP_GENERIC_ID_##_id, \
11287 .name = DEVLINK_TRAP_GENERIC_NAME_##_id, \
11290 static const struct devlink_trap devlink_trap_generic[] = {
11291 DEVLINK_TRAP(SMAC_MC, DROP),
11292 DEVLINK_TRAP(VLAN_TAG_MISMATCH, DROP),
11293 DEVLINK_TRAP(INGRESS_VLAN_FILTER, DROP),
11294 DEVLINK_TRAP(INGRESS_STP_FILTER, DROP),
11295 DEVLINK_TRAP(EMPTY_TX_LIST, DROP),
11296 DEVLINK_TRAP(PORT_LOOPBACK_FILTER, DROP),
11297 DEVLINK_TRAP(BLACKHOLE_ROUTE, DROP),
11298 DEVLINK_TRAP(TTL_ERROR, EXCEPTION),
11299 DEVLINK_TRAP(TAIL_DROP, DROP),
11300 DEVLINK_TRAP(NON_IP_PACKET, DROP),
11301 DEVLINK_TRAP(UC_DIP_MC_DMAC, DROP),
11302 DEVLINK_TRAP(DIP_LB, DROP),
11303 DEVLINK_TRAP(SIP_MC, DROP),
11304 DEVLINK_TRAP(SIP_LB, DROP),
11305 DEVLINK_TRAP(CORRUPTED_IP_HDR, DROP),
11306 DEVLINK_TRAP(IPV4_SIP_BC, DROP),
11307 DEVLINK_TRAP(IPV6_MC_DIP_RESERVED_SCOPE, DROP),
11308 DEVLINK_TRAP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE, DROP),
11309 DEVLINK_TRAP(MTU_ERROR, EXCEPTION),
11310 DEVLINK_TRAP(UNRESOLVED_NEIGH, EXCEPTION),
11311 DEVLINK_TRAP(RPF, EXCEPTION),
11312 DEVLINK_TRAP(REJECT_ROUTE, EXCEPTION),
11313 DEVLINK_TRAP(IPV4_LPM_UNICAST_MISS, EXCEPTION),
11314 DEVLINK_TRAP(IPV6_LPM_UNICAST_MISS, EXCEPTION),
11315 DEVLINK_TRAP(NON_ROUTABLE, DROP),
11316 DEVLINK_TRAP(DECAP_ERROR, EXCEPTION),
11317 DEVLINK_TRAP(OVERLAY_SMAC_MC, DROP),
11318 DEVLINK_TRAP(INGRESS_FLOW_ACTION_DROP, DROP),
11319 DEVLINK_TRAP(EGRESS_FLOW_ACTION_DROP, DROP),
11320 DEVLINK_TRAP(STP, CONTROL),
11321 DEVLINK_TRAP(LACP, CONTROL),
11322 DEVLINK_TRAP(LLDP, CONTROL),
11323 DEVLINK_TRAP(IGMP_QUERY, CONTROL),
11324 DEVLINK_TRAP(IGMP_V1_REPORT, CONTROL),
11325 DEVLINK_TRAP(IGMP_V2_REPORT, CONTROL),
11326 DEVLINK_TRAP(IGMP_V3_REPORT, CONTROL),
11327 DEVLINK_TRAP(IGMP_V2_LEAVE, CONTROL),
11328 DEVLINK_TRAP(MLD_QUERY, CONTROL),
11329 DEVLINK_TRAP(MLD_V1_REPORT, CONTROL),
11330 DEVLINK_TRAP(MLD_V2_REPORT, CONTROL),
11331 DEVLINK_TRAP(MLD_V1_DONE, CONTROL),
11332 DEVLINK_TRAP(IPV4_DHCP, CONTROL),
11333 DEVLINK_TRAP(IPV6_DHCP, CONTROL),
11334 DEVLINK_TRAP(ARP_REQUEST, CONTROL),
11335 DEVLINK_TRAP(ARP_RESPONSE, CONTROL),
11336 DEVLINK_TRAP(ARP_OVERLAY, CONTROL),
11337 DEVLINK_TRAP(IPV6_NEIGH_SOLICIT, CONTROL),
11338 DEVLINK_TRAP(IPV6_NEIGH_ADVERT, CONTROL),
11339 DEVLINK_TRAP(IPV4_BFD, CONTROL),
11340 DEVLINK_TRAP(IPV6_BFD, CONTROL),
11341 DEVLINK_TRAP(IPV4_OSPF, CONTROL),
11342 DEVLINK_TRAP(IPV6_OSPF, CONTROL),
11343 DEVLINK_TRAP(IPV4_BGP, CONTROL),
11344 DEVLINK_TRAP(IPV6_BGP, CONTROL),
11345 DEVLINK_TRAP(IPV4_VRRP, CONTROL),
11346 DEVLINK_TRAP(IPV6_VRRP, CONTROL),
11347 DEVLINK_TRAP(IPV4_PIM, CONTROL),
11348 DEVLINK_TRAP(IPV6_PIM, CONTROL),
11349 DEVLINK_TRAP(UC_LB, CONTROL),
11350 DEVLINK_TRAP(LOCAL_ROUTE, CONTROL),
11351 DEVLINK_TRAP(EXTERNAL_ROUTE, CONTROL),
11352 DEVLINK_TRAP(IPV6_UC_DIP_LINK_LOCAL_SCOPE, CONTROL),
11353 DEVLINK_TRAP(IPV6_DIP_ALL_NODES, CONTROL),
11354 DEVLINK_TRAP(IPV6_DIP_ALL_ROUTERS, CONTROL),
11355 DEVLINK_TRAP(IPV6_ROUTER_SOLICIT, CONTROL),
11356 DEVLINK_TRAP(IPV6_ROUTER_ADVERT, CONTROL),
11357 DEVLINK_TRAP(IPV6_REDIRECT, CONTROL),
11358 DEVLINK_TRAP(IPV4_ROUTER_ALERT, CONTROL),
11359 DEVLINK_TRAP(IPV6_ROUTER_ALERT, CONTROL),
11360 DEVLINK_TRAP(PTP_EVENT, CONTROL),
11361 DEVLINK_TRAP(PTP_GENERAL, CONTROL),
11362 DEVLINK_TRAP(FLOW_ACTION_SAMPLE, CONTROL),
11363 DEVLINK_TRAP(FLOW_ACTION_TRAP, CONTROL),
11364 DEVLINK_TRAP(EARLY_DROP, DROP),
11365 DEVLINK_TRAP(VXLAN_PARSING, DROP),
11366 DEVLINK_TRAP(LLC_SNAP_PARSING, DROP),
11367 DEVLINK_TRAP(VLAN_PARSING, DROP),
11368 DEVLINK_TRAP(PPPOE_PPP_PARSING, DROP),
11369 DEVLINK_TRAP(MPLS_PARSING, DROP),
11370 DEVLINK_TRAP(ARP_PARSING, DROP),
11371 DEVLINK_TRAP(IP_1_PARSING, DROP),
11372 DEVLINK_TRAP(IP_N_PARSING, DROP),
11373 DEVLINK_TRAP(GRE_PARSING, DROP),
11374 DEVLINK_TRAP(UDP_PARSING, DROP),
11375 DEVLINK_TRAP(TCP_PARSING, DROP),
11376 DEVLINK_TRAP(IPSEC_PARSING, DROP),
11377 DEVLINK_TRAP(SCTP_PARSING, DROP),
11378 DEVLINK_TRAP(DCCP_PARSING, DROP),
11379 DEVLINK_TRAP(GTP_PARSING, DROP),
11380 DEVLINK_TRAP(ESP_PARSING, DROP),
11381 DEVLINK_TRAP(BLACKHOLE_NEXTHOP, DROP),
11382 DEVLINK_TRAP(DMAC_FILTER, DROP),
11385 #define DEVLINK_TRAP_GROUP(_id) \
11387 .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \
11388 .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \
11391 static const struct devlink_trap_group devlink_trap_group_generic[] = {
11392 DEVLINK_TRAP_GROUP(L2_DROPS),
11393 DEVLINK_TRAP_GROUP(L3_DROPS),
11394 DEVLINK_TRAP_GROUP(L3_EXCEPTIONS),
11395 DEVLINK_TRAP_GROUP(BUFFER_DROPS),
11396 DEVLINK_TRAP_GROUP(TUNNEL_DROPS),
11397 DEVLINK_TRAP_GROUP(ACL_DROPS),
11398 DEVLINK_TRAP_GROUP(STP),
11399 DEVLINK_TRAP_GROUP(LACP),
11400 DEVLINK_TRAP_GROUP(LLDP),
11401 DEVLINK_TRAP_GROUP(MC_SNOOPING),
11402 DEVLINK_TRAP_GROUP(DHCP),
11403 DEVLINK_TRAP_GROUP(NEIGH_DISCOVERY),
11404 DEVLINK_TRAP_GROUP(BFD),
11405 DEVLINK_TRAP_GROUP(OSPF),
11406 DEVLINK_TRAP_GROUP(BGP),
11407 DEVLINK_TRAP_GROUP(VRRP),
11408 DEVLINK_TRAP_GROUP(PIM),
11409 DEVLINK_TRAP_GROUP(UC_LB),
11410 DEVLINK_TRAP_GROUP(LOCAL_DELIVERY),
11411 DEVLINK_TRAP_GROUP(EXTERNAL_DELIVERY),
11412 DEVLINK_TRAP_GROUP(IPV6),
11413 DEVLINK_TRAP_GROUP(PTP_EVENT),
11414 DEVLINK_TRAP_GROUP(PTP_GENERAL),
11415 DEVLINK_TRAP_GROUP(ACL_SAMPLE),
11416 DEVLINK_TRAP_GROUP(ACL_TRAP),
11417 DEVLINK_TRAP_GROUP(PARSER_ERROR_DROPS),
11420 static int devlink_trap_generic_verify(const struct devlink_trap *trap)
11422 if (trap->id > DEVLINK_TRAP_GENERIC_ID_MAX)
11425 if (strcmp(trap->name, devlink_trap_generic[trap->id].name))
11428 if (trap->type != devlink_trap_generic[trap->id].type)
11434 static int devlink_trap_driver_verify(const struct devlink_trap *trap)
11438 if (trap->id <= DEVLINK_TRAP_GENERIC_ID_MAX)
11441 for (i = 0; i < ARRAY_SIZE(devlink_trap_generic); i++) {
11442 if (!strcmp(trap->name, devlink_trap_generic[i].name))
11449 static int devlink_trap_verify(const struct devlink_trap *trap)
11451 if (!trap || !trap->name)
11455 return devlink_trap_generic_verify(trap);
11457 return devlink_trap_driver_verify(trap);
11461 devlink_trap_group_generic_verify(const struct devlink_trap_group *group)
11463 if (group->id > DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
11466 if (strcmp(group->name, devlink_trap_group_generic[group->id].name))
11473 devlink_trap_group_driver_verify(const struct devlink_trap_group *group)
11477 if (group->id <= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
11480 for (i = 0; i < ARRAY_SIZE(devlink_trap_group_generic); i++) {
11481 if (!strcmp(group->name, devlink_trap_group_generic[i].name))
11488 static int devlink_trap_group_verify(const struct devlink_trap_group *group)
11490 if (group->generic)
11491 return devlink_trap_group_generic_verify(group);
11493 return devlink_trap_group_driver_verify(group);
11497 devlink_trap_group_notify(struct devlink *devlink,
11498 const struct devlink_trap_group_item *group_item,
11499 enum devlink_command cmd)
11501 struct sk_buff *msg;
11504 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_GROUP_NEW &&
11505 cmd != DEVLINK_CMD_TRAP_GROUP_DEL);
11506 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
11509 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11513 err = devlink_nl_trap_group_fill(msg, devlink, group_item, cmd, 0, 0,
11520 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
11521 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
11525 devlink_trap_item_group_link(struct devlink *devlink,
11526 struct devlink_trap_item *trap_item)
11528 u16 group_id = trap_item->trap->init_group_id;
11529 struct devlink_trap_group_item *group_item;
11531 group_item = devlink_trap_group_item_lookup_by_id(devlink, group_id);
11532 if (WARN_ON_ONCE(!group_item))
11535 trap_item->group_item = group_item;
11540 static void devlink_trap_notify(struct devlink *devlink,
11541 const struct devlink_trap_item *trap_item,
11542 enum devlink_command cmd)
11544 struct sk_buff *msg;
11547 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_NEW &&
11548 cmd != DEVLINK_CMD_TRAP_DEL);
11549 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
11552 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11556 err = devlink_nl_trap_fill(msg, devlink, trap_item, cmd, 0, 0, 0);
11562 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
11563 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
11567 devlink_trap_register(struct devlink *devlink,
11568 const struct devlink_trap *trap, void *priv)
11570 struct devlink_trap_item *trap_item;
11573 if (devlink_trap_item_lookup(devlink, trap->name))
11576 trap_item = kzalloc(sizeof(*trap_item), GFP_KERNEL);
11580 trap_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
11581 if (!trap_item->stats) {
11583 goto err_stats_alloc;
11586 trap_item->trap = trap;
11587 trap_item->action = trap->init_action;
11588 trap_item->priv = priv;
11590 err = devlink_trap_item_group_link(devlink, trap_item);
11592 goto err_group_link;
11594 err = devlink->ops->trap_init(devlink, trap, trap_item);
11596 goto err_trap_init;
11598 list_add_tail(&trap_item->list, &devlink->trap_list);
11599 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
11605 free_percpu(trap_item->stats);
11611 static void devlink_trap_unregister(struct devlink *devlink,
11612 const struct devlink_trap *trap)
11614 struct devlink_trap_item *trap_item;
11616 trap_item = devlink_trap_item_lookup(devlink, trap->name);
11617 if (WARN_ON_ONCE(!trap_item))
11620 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL);
11621 list_del(&trap_item->list);
11622 if (devlink->ops->trap_fini)
11623 devlink->ops->trap_fini(devlink, trap, trap_item);
11624 free_percpu(trap_item->stats);
11628 static void devlink_trap_disable(struct devlink *devlink,
11629 const struct devlink_trap *trap)
11631 struct devlink_trap_item *trap_item;
11633 trap_item = devlink_trap_item_lookup(devlink, trap->name);
11634 if (WARN_ON_ONCE(!trap_item))
11637 devlink->ops->trap_action_set(devlink, trap, DEVLINK_TRAP_ACTION_DROP,
11639 trap_item->action = DEVLINK_TRAP_ACTION_DROP;
11643 * devl_traps_register - Register packet traps with devlink.
11644 * @devlink: devlink.
11645 * @traps: Packet traps.
11646 * @traps_count: Count of provided packet traps.
11647 * @priv: Driver private information.
11649 * Return: Non-zero value on failure.
11651 int devl_traps_register(struct devlink *devlink,
11652 const struct devlink_trap *traps,
11653 size_t traps_count, void *priv)
11657 if (!devlink->ops->trap_init || !devlink->ops->trap_action_set)
11660 devl_assert_locked(devlink);
11661 for (i = 0; i < traps_count; i++) {
11662 const struct devlink_trap *trap = &traps[i];
11664 err = devlink_trap_verify(trap);
11666 goto err_trap_verify;
11668 err = devlink_trap_register(devlink, trap, priv);
11670 goto err_trap_register;
11677 for (i--; i >= 0; i--)
11678 devlink_trap_unregister(devlink, &traps[i]);
11681 EXPORT_SYMBOL_GPL(devl_traps_register);
11684 * devlink_traps_register - Register packet traps with devlink.
11685 * @devlink: devlink.
11686 * @traps: Packet traps.
11687 * @traps_count: Count of provided packet traps.
11688 * @priv: Driver private information.
11690 * Context: Takes and release devlink->lock <mutex>.
11692 * Return: Non-zero value on failure.
11694 int devlink_traps_register(struct devlink *devlink,
11695 const struct devlink_trap *traps,
11696 size_t traps_count, void *priv)
11700 devl_lock(devlink);
11701 err = devl_traps_register(devlink, traps, traps_count, priv);
11702 devl_unlock(devlink);
11705 EXPORT_SYMBOL_GPL(devlink_traps_register);
11708 * devl_traps_unregister - Unregister packet traps from devlink.
11709 * @devlink: devlink.
11710 * @traps: Packet traps.
11711 * @traps_count: Count of provided packet traps.
11713 void devl_traps_unregister(struct devlink *devlink,
11714 const struct devlink_trap *traps,
11715 size_t traps_count)
11719 devl_assert_locked(devlink);
11720 /* Make sure we do not have any packets in-flight while unregistering
11721 * traps by disabling all of them and waiting for a grace period.
11723 for (i = traps_count - 1; i >= 0; i--)
11724 devlink_trap_disable(devlink, &traps[i]);
11726 for (i = traps_count - 1; i >= 0; i--)
11727 devlink_trap_unregister(devlink, &traps[i]);
11729 EXPORT_SYMBOL_GPL(devl_traps_unregister);
11732 * devlink_traps_unregister - Unregister packet traps from devlink.
11733 * @devlink: devlink.
11734 * @traps: Packet traps.
11735 * @traps_count: Count of provided packet traps.
11737 * Context: Takes and release devlink->lock <mutex>.
11739 void devlink_traps_unregister(struct devlink *devlink,
11740 const struct devlink_trap *traps,
11741 size_t traps_count)
11743 devl_lock(devlink);
11744 devl_traps_unregister(devlink, traps, traps_count);
11745 devl_unlock(devlink);
11747 EXPORT_SYMBOL_GPL(devlink_traps_unregister);
11750 devlink_trap_stats_update(struct devlink_stats __percpu *trap_stats,
11753 struct devlink_stats *stats;
11755 stats = this_cpu_ptr(trap_stats);
11756 u64_stats_update_begin(&stats->syncp);
11757 u64_stats_add(&stats->rx_bytes, skb_len);
11758 u64_stats_inc(&stats->rx_packets);
11759 u64_stats_update_end(&stats->syncp);
11763 devlink_trap_report_metadata_set(struct devlink_trap_metadata *metadata,
11764 const struct devlink_trap_item *trap_item,
11765 struct devlink_port *in_devlink_port,
11766 const struct flow_action_cookie *fa_cookie)
11768 metadata->trap_name = trap_item->trap->name;
11769 metadata->trap_group_name = trap_item->group_item->group->name;
11770 metadata->fa_cookie = fa_cookie;
11771 metadata->trap_type = trap_item->trap->type;
11773 spin_lock(&in_devlink_port->type_lock);
11774 if (in_devlink_port->type == DEVLINK_PORT_TYPE_ETH)
11775 metadata->input_dev = in_devlink_port->type_dev;
11776 spin_unlock(&in_devlink_port->type_lock);
11780 * devlink_trap_report - Report trapped packet to drop monitor.
11781 * @devlink: devlink.
11782 * @skb: Trapped packet.
11783 * @trap_ctx: Trap context.
11784 * @in_devlink_port: Input devlink port.
11785 * @fa_cookie: Flow action cookie. Could be NULL.
11787 void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb,
11788 void *trap_ctx, struct devlink_port *in_devlink_port,
11789 const struct flow_action_cookie *fa_cookie)
11792 struct devlink_trap_item *trap_item = trap_ctx;
11794 devlink_trap_stats_update(trap_item->stats, skb->len);
11795 devlink_trap_stats_update(trap_item->group_item->stats, skb->len);
11797 if (trace_devlink_trap_report_enabled()) {
11798 struct devlink_trap_metadata metadata = {};
11800 devlink_trap_report_metadata_set(&metadata, trap_item,
11801 in_devlink_port, fa_cookie);
11802 trace_devlink_trap_report(devlink, skb, &metadata);
11805 EXPORT_SYMBOL_GPL(devlink_trap_report);
11808 * devlink_trap_ctx_priv - Trap context to driver private information.
11809 * @trap_ctx: Trap context.
11811 * Return: Driver private information passed during registration.
11813 void *devlink_trap_ctx_priv(void *trap_ctx)
11815 struct devlink_trap_item *trap_item = trap_ctx;
11817 return trap_item->priv;
11819 EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv);
11822 devlink_trap_group_item_policer_link(struct devlink *devlink,
11823 struct devlink_trap_group_item *group_item)
11825 u32 policer_id = group_item->group->init_policer_id;
11826 struct devlink_trap_policer_item *policer_item;
11828 if (policer_id == 0)
11831 policer_item = devlink_trap_policer_item_lookup(devlink, policer_id);
11832 if (WARN_ON_ONCE(!policer_item))
11835 group_item->policer_item = policer_item;
11841 devlink_trap_group_register(struct devlink *devlink,
11842 const struct devlink_trap_group *group)
11844 struct devlink_trap_group_item *group_item;
11847 if (devlink_trap_group_item_lookup(devlink, group->name))
11850 group_item = kzalloc(sizeof(*group_item), GFP_KERNEL);
11854 group_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
11855 if (!group_item->stats) {
11857 goto err_stats_alloc;
11860 group_item->group = group;
11862 err = devlink_trap_group_item_policer_link(devlink, group_item);
11864 goto err_policer_link;
11866 if (devlink->ops->trap_group_init) {
11867 err = devlink->ops->trap_group_init(devlink, group);
11869 goto err_group_init;
11872 list_add_tail(&group_item->list, &devlink->trap_group_list);
11873 devlink_trap_group_notify(devlink, group_item,
11874 DEVLINK_CMD_TRAP_GROUP_NEW);
11880 free_percpu(group_item->stats);
11887 devlink_trap_group_unregister(struct devlink *devlink,
11888 const struct devlink_trap_group *group)
11890 struct devlink_trap_group_item *group_item;
11892 group_item = devlink_trap_group_item_lookup(devlink, group->name);
11893 if (WARN_ON_ONCE(!group_item))
11896 devlink_trap_group_notify(devlink, group_item,
11897 DEVLINK_CMD_TRAP_GROUP_DEL);
11898 list_del(&group_item->list);
11899 free_percpu(group_item->stats);
11904 * devl_trap_groups_register - Register packet trap groups with devlink.
11905 * @devlink: devlink.
11906 * @groups: Packet trap groups.
11907 * @groups_count: Count of provided packet trap groups.
11909 * Return: Non-zero value on failure.
11911 int devl_trap_groups_register(struct devlink *devlink,
11912 const struct devlink_trap_group *groups,
11913 size_t groups_count)
11917 devl_assert_locked(devlink);
11918 for (i = 0; i < groups_count; i++) {
11919 const struct devlink_trap_group *group = &groups[i];
11921 err = devlink_trap_group_verify(group);
11923 goto err_trap_group_verify;
11925 err = devlink_trap_group_register(devlink, group);
11927 goto err_trap_group_register;
11932 err_trap_group_register:
11933 err_trap_group_verify:
11934 for (i--; i >= 0; i--)
11935 devlink_trap_group_unregister(devlink, &groups[i]);
11938 EXPORT_SYMBOL_GPL(devl_trap_groups_register);
11941 * devlink_trap_groups_register - Register packet trap groups with devlink.
11942 * @devlink: devlink.
11943 * @groups: Packet trap groups.
11944 * @groups_count: Count of provided packet trap groups.
11946 * Context: Takes and release devlink->lock <mutex>.
11948 * Return: Non-zero value on failure.
11950 int devlink_trap_groups_register(struct devlink *devlink,
11951 const struct devlink_trap_group *groups,
11952 size_t groups_count)
11956 devl_lock(devlink);
11957 err = devl_trap_groups_register(devlink, groups, groups_count);
11958 devl_unlock(devlink);
11961 EXPORT_SYMBOL_GPL(devlink_trap_groups_register);
11964 * devl_trap_groups_unregister - Unregister packet trap groups from devlink.
11965 * @devlink: devlink.
11966 * @groups: Packet trap groups.
11967 * @groups_count: Count of provided packet trap groups.
11969 void devl_trap_groups_unregister(struct devlink *devlink,
11970 const struct devlink_trap_group *groups,
11971 size_t groups_count)
11975 devl_assert_locked(devlink);
11976 for (i = groups_count - 1; i >= 0; i--)
11977 devlink_trap_group_unregister(devlink, &groups[i]);
11979 EXPORT_SYMBOL_GPL(devl_trap_groups_unregister);
11982 * devlink_trap_groups_unregister - Unregister packet trap groups from devlink.
11983 * @devlink: devlink.
11984 * @groups: Packet trap groups.
11985 * @groups_count: Count of provided packet trap groups.
11987 * Context: Takes and release devlink->lock <mutex>.
11989 void devlink_trap_groups_unregister(struct devlink *devlink,
11990 const struct devlink_trap_group *groups,
11991 size_t groups_count)
11993 devl_lock(devlink);
11994 devl_trap_groups_unregister(devlink, groups, groups_count);
11995 devl_unlock(devlink);
11997 EXPORT_SYMBOL_GPL(devlink_trap_groups_unregister);
12000 devlink_trap_policer_notify(struct devlink *devlink,
12001 const struct devlink_trap_policer_item *policer_item,
12002 enum devlink_command cmd)
12004 struct sk_buff *msg;
12007 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_POLICER_NEW &&
12008 cmd != DEVLINK_CMD_TRAP_POLICER_DEL);
12009 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
12012 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12016 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, cmd, 0,
12023 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
12024 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
12028 devlink_trap_policer_register(struct devlink *devlink,
12029 const struct devlink_trap_policer *policer)
12031 struct devlink_trap_policer_item *policer_item;
12034 if (devlink_trap_policer_item_lookup(devlink, policer->id))
12037 policer_item = kzalloc(sizeof(*policer_item), GFP_KERNEL);
12041 policer_item->policer = policer;
12042 policer_item->rate = policer->init_rate;
12043 policer_item->burst = policer->init_burst;
12045 if (devlink->ops->trap_policer_init) {
12046 err = devlink->ops->trap_policer_init(devlink, policer);
12048 goto err_policer_init;
12051 list_add_tail(&policer_item->list, &devlink->trap_policer_list);
12052 devlink_trap_policer_notify(devlink, policer_item,
12053 DEVLINK_CMD_TRAP_POLICER_NEW);
12058 kfree(policer_item);
12063 devlink_trap_policer_unregister(struct devlink *devlink,
12064 const struct devlink_trap_policer *policer)
12066 struct devlink_trap_policer_item *policer_item;
12068 policer_item = devlink_trap_policer_item_lookup(devlink, policer->id);
12069 if (WARN_ON_ONCE(!policer_item))
12072 devlink_trap_policer_notify(devlink, policer_item,
12073 DEVLINK_CMD_TRAP_POLICER_DEL);
12074 list_del(&policer_item->list);
12075 if (devlink->ops->trap_policer_fini)
12076 devlink->ops->trap_policer_fini(devlink, policer);
12077 kfree(policer_item);
12081 * devl_trap_policers_register - Register packet trap policers with devlink.
12082 * @devlink: devlink.
12083 * @policers: Packet trap policers.
12084 * @policers_count: Count of provided packet trap policers.
12086 * Return: Non-zero value on failure.
12089 devl_trap_policers_register(struct devlink *devlink,
12090 const struct devlink_trap_policer *policers,
12091 size_t policers_count)
12095 devl_assert_locked(devlink);
12096 for (i = 0; i < policers_count; i++) {
12097 const struct devlink_trap_policer *policer = &policers[i];
12099 if (WARN_ON(policer->id == 0 ||
12100 policer->max_rate < policer->min_rate ||
12101 policer->max_burst < policer->min_burst)) {
12103 goto err_trap_policer_verify;
12106 err = devlink_trap_policer_register(devlink, policer);
12108 goto err_trap_policer_register;
12112 err_trap_policer_register:
12113 err_trap_policer_verify:
12114 for (i--; i >= 0; i--)
12115 devlink_trap_policer_unregister(devlink, &policers[i]);
12118 EXPORT_SYMBOL_GPL(devl_trap_policers_register);
12121 * devl_trap_policers_unregister - Unregister packet trap policers from devlink.
12122 * @devlink: devlink.
12123 * @policers: Packet trap policers.
12124 * @policers_count: Count of provided packet trap policers.
12127 devl_trap_policers_unregister(struct devlink *devlink,
12128 const struct devlink_trap_policer *policers,
12129 size_t policers_count)
12133 devl_assert_locked(devlink);
12134 for (i = policers_count - 1; i >= 0; i--)
12135 devlink_trap_policer_unregister(devlink, &policers[i]);
12137 EXPORT_SYMBOL_GPL(devl_trap_policers_unregister);
12139 static void __devlink_compat_running_version(struct devlink *devlink,
12140 char *buf, size_t len)
12142 const struct nlattr *nlattr;
12143 struct devlink_info_req req;
12144 struct sk_buff *msg;
12147 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12152 err = devlink->ops->info_get(devlink, &req, NULL);
12156 nla_for_each_attr(nlattr, (void *)msg->data, msg->len, rem) {
12157 const struct nlattr *kv;
12160 if (nla_type(nlattr) != DEVLINK_ATTR_INFO_VERSION_RUNNING)
12163 nla_for_each_nested(kv, nlattr, rem_kv) {
12164 if (nla_type(kv) != DEVLINK_ATTR_INFO_VERSION_VALUE)
12167 strlcat(buf, nla_data(kv), len);
12168 strlcat(buf, " ", len);
12175 static struct devlink_port *netdev_to_devlink_port(struct net_device *dev)
12177 if (!dev->netdev_ops->ndo_get_devlink_port)
12180 return dev->netdev_ops->ndo_get_devlink_port(dev);
12183 void devlink_compat_running_version(struct devlink *devlink,
12184 char *buf, size_t len)
12186 if (!devlink->ops->info_get)
12189 devl_lock(devlink);
12190 __devlink_compat_running_version(devlink, buf, len);
12191 devl_unlock(devlink);
12194 int devlink_compat_flash_update(struct devlink *devlink, const char *file_name)
12196 struct devlink_flash_update_params params = {};
12199 if (!devlink->ops->flash_update)
12200 return -EOPNOTSUPP;
12202 ret = request_firmware(¶ms.fw, file_name, devlink->dev);
12206 devl_lock(devlink);
12207 devlink_flash_update_begin_notify(devlink);
12208 ret = devlink->ops->flash_update(devlink, ¶ms, NULL);
12209 devlink_flash_update_end_notify(devlink);
12210 devl_unlock(devlink);
12212 release_firmware(params.fw);
12217 int devlink_compat_phys_port_name_get(struct net_device *dev,
12218 char *name, size_t len)
12220 struct devlink_port *devlink_port;
12222 /* RTNL mutex is held here which ensures that devlink_port
12223 * instance cannot disappear in the middle. No need to take
12224 * any devlink lock as only permanent values are accessed.
12228 devlink_port = netdev_to_devlink_port(dev);
12230 return -EOPNOTSUPP;
12232 return __devlink_port_phys_port_name_get(devlink_port, name, len);
12235 int devlink_compat_switch_id_get(struct net_device *dev,
12236 struct netdev_phys_item_id *ppid)
12238 struct devlink_port *devlink_port;
12240 /* Caller must hold RTNL mutex or reference to dev, which ensures that
12241 * devlink_port instance cannot disappear in the middle. No need to take
12242 * any devlink lock as only permanent values are accessed.
12244 devlink_port = netdev_to_devlink_port(dev);
12245 if (!devlink_port || !devlink_port->switch_port)
12246 return -EOPNOTSUPP;
12248 memcpy(ppid, &devlink_port->attrs.switch_id, sizeof(*ppid));
12253 static void __net_exit devlink_pernet_pre_exit(struct net *net)
12255 struct devlink *devlink;
12256 u32 actions_performed;
12257 unsigned long index;
12260 /* In case network namespace is getting destroyed, reload
12261 * all devlink instances from this namespace into init_net.
12263 mutex_lock(&devlink_mutex);
12264 devlinks_xa_for_each_registered_get(net, index, devlink) {
12265 WARN_ON(!(devlink->features & DEVLINK_F_RELOAD));
12266 err = devlink_reload(devlink, &init_net,
12267 DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
12268 DEVLINK_RELOAD_LIMIT_UNSPEC,
12269 &actions_performed, NULL);
12270 if (err && err != -EOPNOTSUPP)
12271 pr_warn("Failed to reload devlink instance into init_net\n");
12272 devlink_put(devlink);
12274 mutex_unlock(&devlink_mutex);
12277 static struct pernet_operations devlink_pernet_ops __net_initdata = {
12278 .pre_exit = devlink_pernet_pre_exit,
12281 static int __init devlink_init(void)
12285 err = genl_register_family(&devlink_nl_family);
12288 err = register_pernet_subsys(&devlink_pernet_ops);
12295 subsys_initcall(devlink_init);