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/kernel.h>
11 #include <linux/module.h>
12 #include <linux/types.h>
13 #include <linux/slab.h>
14 #include <linux/gfp.h>
15 #include <linux/device.h>
16 #include <linux/list.h>
17 #include <linux/netdevice.h>
18 #include <linux/spinlock.h>
19 #include <linux/refcount.h>
20 #include <linux/workqueue.h>
21 #include <linux/u64_stats_sync.h>
22 #include <linux/timekeeping.h>
23 #include <rdma/ib_verbs.h>
24 #include <net/netlink.h>
25 #include <net/genetlink.h>
26 #include <net/rtnetlink.h>
27 #include <net/net_namespace.h>
29 #include <net/devlink.h>
30 #include <net/drop_monitor.h>
31 #define CREATE_TRACE_POINTS
32 #include <trace/events/devlink.h>
34 static struct devlink_dpipe_field devlink_dpipe_fields_ethernet
[] = {
36 .name
= "destination mac",
37 .id
= DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC
,
42 struct devlink_dpipe_header devlink_dpipe_header_ethernet
= {
44 .id
= DEVLINK_DPIPE_HEADER_ETHERNET
,
45 .fields
= devlink_dpipe_fields_ethernet
,
46 .fields_count
= ARRAY_SIZE(devlink_dpipe_fields_ethernet
),
49 EXPORT_SYMBOL(devlink_dpipe_header_ethernet
);
51 static struct devlink_dpipe_field devlink_dpipe_fields_ipv4
[] = {
53 .name
= "destination ip",
54 .id
= DEVLINK_DPIPE_FIELD_IPV4_DST_IP
,
59 struct devlink_dpipe_header devlink_dpipe_header_ipv4
= {
61 .id
= DEVLINK_DPIPE_HEADER_IPV4
,
62 .fields
= devlink_dpipe_fields_ipv4
,
63 .fields_count
= ARRAY_SIZE(devlink_dpipe_fields_ipv4
),
66 EXPORT_SYMBOL(devlink_dpipe_header_ipv4
);
68 static struct devlink_dpipe_field devlink_dpipe_fields_ipv6
[] = {
70 .name
= "destination ip",
71 .id
= DEVLINK_DPIPE_FIELD_IPV6_DST_IP
,
76 struct devlink_dpipe_header devlink_dpipe_header_ipv6
= {
78 .id
= DEVLINK_DPIPE_HEADER_IPV6
,
79 .fields
= devlink_dpipe_fields_ipv6
,
80 .fields_count
= ARRAY_SIZE(devlink_dpipe_fields_ipv6
),
83 EXPORT_SYMBOL(devlink_dpipe_header_ipv6
);
85 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg
);
86 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwerr
);
88 static LIST_HEAD(devlink_list
);
92 * An overall lock guarding every operation coming from userspace.
93 * It also guards devlink devices list and it is taken when
94 * driver registers/unregisters it.
96 static DEFINE_MUTEX(devlink_mutex
);
98 static struct net
*devlink_net(const struct devlink
*devlink
)
100 return read_pnet(&devlink
->_net
);
103 static void devlink_net_set(struct devlink
*devlink
, struct net
*net
)
105 write_pnet(&devlink
->_net
, net
);
108 static struct devlink
*devlink_get_from_attrs(struct net
*net
,
109 struct nlattr
**attrs
)
111 struct devlink
*devlink
;
115 if (!attrs
[DEVLINK_ATTR_BUS_NAME
] || !attrs
[DEVLINK_ATTR_DEV_NAME
])
116 return ERR_PTR(-EINVAL
);
118 busname
= nla_data(attrs
[DEVLINK_ATTR_BUS_NAME
]);
119 devname
= nla_data(attrs
[DEVLINK_ATTR_DEV_NAME
]);
121 lockdep_assert_held(&devlink_mutex
);
123 list_for_each_entry(devlink
, &devlink_list
, list
) {
124 if (strcmp(devlink
->dev
->bus
->name
, busname
) == 0 &&
125 strcmp(dev_name(devlink
->dev
), devname
) == 0 &&
126 net_eq(devlink_net(devlink
), net
))
130 return ERR_PTR(-ENODEV
);
133 static struct devlink
*devlink_get_from_info(struct genl_info
*info
)
135 return devlink_get_from_attrs(genl_info_net(info
), info
->attrs
);
138 static struct devlink_port
*devlink_port_get_by_index(struct devlink
*devlink
,
139 unsigned int port_index
)
141 struct devlink_port
*devlink_port
;
143 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
144 if (devlink_port
->index
== port_index
)
150 static bool devlink_port_index_exists(struct devlink
*devlink
,
151 unsigned int port_index
)
153 return devlink_port_get_by_index(devlink
, port_index
);
156 static struct devlink_port
*devlink_port_get_from_attrs(struct devlink
*devlink
,
157 struct nlattr
**attrs
)
159 if (attrs
[DEVLINK_ATTR_PORT_INDEX
]) {
160 u32 port_index
= nla_get_u32(attrs
[DEVLINK_ATTR_PORT_INDEX
]);
161 struct devlink_port
*devlink_port
;
163 devlink_port
= devlink_port_get_by_index(devlink
, port_index
);
165 return ERR_PTR(-ENODEV
);
168 return ERR_PTR(-EINVAL
);
171 static struct devlink_port
*devlink_port_get_from_info(struct devlink
*devlink
,
172 struct genl_info
*info
)
174 return devlink_port_get_from_attrs(devlink
, info
->attrs
);
178 struct list_head list
;
181 u16 ingress_pools_count
;
182 u16 egress_pools_count
;
183 u16 ingress_tc_count
;
187 static u16
devlink_sb_pool_count(struct devlink_sb
*devlink_sb
)
189 return devlink_sb
->ingress_pools_count
+ devlink_sb
->egress_pools_count
;
192 static struct devlink_sb
*devlink_sb_get_by_index(struct devlink
*devlink
,
193 unsigned int sb_index
)
195 struct devlink_sb
*devlink_sb
;
197 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
198 if (devlink_sb
->index
== sb_index
)
204 static bool devlink_sb_index_exists(struct devlink
*devlink
,
205 unsigned int sb_index
)
207 return devlink_sb_get_by_index(devlink
, sb_index
);
210 static struct devlink_sb
*devlink_sb_get_from_attrs(struct devlink
*devlink
,
211 struct nlattr
**attrs
)
213 if (attrs
[DEVLINK_ATTR_SB_INDEX
]) {
214 u32 sb_index
= nla_get_u32(attrs
[DEVLINK_ATTR_SB_INDEX
]);
215 struct devlink_sb
*devlink_sb
;
217 devlink_sb
= devlink_sb_get_by_index(devlink
, sb_index
);
219 return ERR_PTR(-ENODEV
);
222 return ERR_PTR(-EINVAL
);
225 static struct devlink_sb
*devlink_sb_get_from_info(struct devlink
*devlink
,
226 struct genl_info
*info
)
228 return devlink_sb_get_from_attrs(devlink
, info
->attrs
);
231 static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb
*devlink_sb
,
232 struct nlattr
**attrs
,
237 if (!attrs
[DEVLINK_ATTR_SB_POOL_INDEX
])
240 val
= nla_get_u16(attrs
[DEVLINK_ATTR_SB_POOL_INDEX
]);
241 if (val
>= devlink_sb_pool_count(devlink_sb
))
247 static int devlink_sb_pool_index_get_from_info(struct devlink_sb
*devlink_sb
,
248 struct genl_info
*info
,
251 return devlink_sb_pool_index_get_from_attrs(devlink_sb
, info
->attrs
,
256 devlink_sb_pool_type_get_from_attrs(struct nlattr
**attrs
,
257 enum devlink_sb_pool_type
*p_pool_type
)
261 if (!attrs
[DEVLINK_ATTR_SB_POOL_TYPE
])
264 val
= nla_get_u8(attrs
[DEVLINK_ATTR_SB_POOL_TYPE
]);
265 if (val
!= DEVLINK_SB_POOL_TYPE_INGRESS
&&
266 val
!= DEVLINK_SB_POOL_TYPE_EGRESS
)
273 devlink_sb_pool_type_get_from_info(struct genl_info
*info
,
274 enum devlink_sb_pool_type
*p_pool_type
)
276 return devlink_sb_pool_type_get_from_attrs(info
->attrs
, p_pool_type
);
280 devlink_sb_th_type_get_from_attrs(struct nlattr
**attrs
,
281 enum devlink_sb_threshold_type
*p_th_type
)
285 if (!attrs
[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
])
288 val
= nla_get_u8(attrs
[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
]);
289 if (val
!= DEVLINK_SB_THRESHOLD_TYPE_STATIC
&&
290 val
!= DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC
)
297 devlink_sb_th_type_get_from_info(struct genl_info
*info
,
298 enum devlink_sb_threshold_type
*p_th_type
)
300 return devlink_sb_th_type_get_from_attrs(info
->attrs
, p_th_type
);
304 devlink_sb_tc_index_get_from_attrs(struct devlink_sb
*devlink_sb
,
305 struct nlattr
**attrs
,
306 enum devlink_sb_pool_type pool_type
,
311 if (!attrs
[DEVLINK_ATTR_SB_TC_INDEX
])
314 val
= nla_get_u16(attrs
[DEVLINK_ATTR_SB_TC_INDEX
]);
315 if (pool_type
== DEVLINK_SB_POOL_TYPE_INGRESS
&&
316 val
>= devlink_sb
->ingress_tc_count
)
318 if (pool_type
== DEVLINK_SB_POOL_TYPE_EGRESS
&&
319 val
>= devlink_sb
->egress_tc_count
)
326 devlink_sb_tc_index_get_from_info(struct devlink_sb
*devlink_sb
,
327 struct genl_info
*info
,
328 enum devlink_sb_pool_type pool_type
,
331 return devlink_sb_tc_index_get_from_attrs(devlink_sb
, info
->attrs
,
332 pool_type
, p_tc_index
);
335 struct devlink_region
{
336 struct devlink
*devlink
;
337 struct list_head list
;
339 struct list_head snapshot_list
;
345 struct devlink_snapshot
{
346 struct list_head list
;
347 struct devlink_region
*region
;
348 devlink_snapshot_data_dest_t
*data_destructor
;
353 static struct devlink_region
*
354 devlink_region_get_by_name(struct devlink
*devlink
, const char *region_name
)
356 struct devlink_region
*region
;
358 list_for_each_entry(region
, &devlink
->region_list
, list
)
359 if (!strcmp(region
->name
, region_name
))
365 static struct devlink_snapshot
*
366 devlink_region_snapshot_get_by_id(struct devlink_region
*region
, u32 id
)
368 struct devlink_snapshot
*snapshot
;
370 list_for_each_entry(snapshot
, ®ion
->snapshot_list
, list
)
371 if (snapshot
->id
== id
)
377 #define DEVLINK_NL_FLAG_NEED_DEVLINK BIT(0)
378 #define DEVLINK_NL_FLAG_NEED_PORT BIT(1)
379 #define DEVLINK_NL_FLAG_NEED_SB BIT(2)
381 /* The per devlink instance lock is taken by default in the pre-doit
382 * operation, yet several commands do not require this. The global
383 * devlink lock is taken and protects from disruption by user-calls.
385 #define DEVLINK_NL_FLAG_NO_LOCK BIT(3)
387 static int devlink_nl_pre_doit(const struct genl_ops
*ops
,
388 struct sk_buff
*skb
, struct genl_info
*info
)
390 struct devlink
*devlink
;
393 mutex_lock(&devlink_mutex
);
394 devlink
= devlink_get_from_info(info
);
395 if (IS_ERR(devlink
)) {
396 mutex_unlock(&devlink_mutex
);
397 return PTR_ERR(devlink
);
399 if (~ops
->internal_flags
& DEVLINK_NL_FLAG_NO_LOCK
)
400 mutex_lock(&devlink
->lock
);
401 if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_DEVLINK
) {
402 info
->user_ptr
[0] = devlink
;
403 } else if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_PORT
) {
404 struct devlink_port
*devlink_port
;
406 devlink_port
= devlink_port_get_from_info(devlink
, info
);
407 if (IS_ERR(devlink_port
)) {
408 err
= PTR_ERR(devlink_port
);
411 info
->user_ptr
[0] = devlink_port
;
413 if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_SB
) {
414 struct devlink_sb
*devlink_sb
;
416 devlink_sb
= devlink_sb_get_from_info(devlink
, info
);
417 if (IS_ERR(devlink_sb
)) {
418 err
= PTR_ERR(devlink_sb
);
421 info
->user_ptr
[1] = devlink_sb
;
426 if (~ops
->internal_flags
& DEVLINK_NL_FLAG_NO_LOCK
)
427 mutex_unlock(&devlink
->lock
);
428 mutex_unlock(&devlink_mutex
);
432 static void devlink_nl_post_doit(const struct genl_ops
*ops
,
433 struct sk_buff
*skb
, struct genl_info
*info
)
435 struct devlink
*devlink
;
437 devlink
= devlink_get_from_info(info
);
438 if (~ops
->internal_flags
& DEVLINK_NL_FLAG_NO_LOCK
)
439 mutex_unlock(&devlink
->lock
);
440 mutex_unlock(&devlink_mutex
);
443 static struct genl_family devlink_nl_family
;
445 enum devlink_multicast_groups
{
446 DEVLINK_MCGRP_CONFIG
,
449 static const struct genl_multicast_group devlink_nl_mcgrps
[] = {
450 [DEVLINK_MCGRP_CONFIG
] = { .name
= DEVLINK_GENL_MCGRP_CONFIG_NAME
},
453 static int devlink_nl_put_handle(struct sk_buff
*msg
, struct devlink
*devlink
)
455 if (nla_put_string(msg
, DEVLINK_ATTR_BUS_NAME
, devlink
->dev
->bus
->name
))
457 if (nla_put_string(msg
, DEVLINK_ATTR_DEV_NAME
, dev_name(devlink
->dev
)))
462 static int devlink_nl_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
463 enum devlink_command cmd
, u32 portid
,
468 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
472 if (devlink_nl_put_handle(msg
, devlink
))
473 goto nla_put_failure
;
474 if (nla_put_u8(msg
, DEVLINK_ATTR_RELOAD_FAILED
, devlink
->reload_failed
))
475 goto nla_put_failure
;
477 genlmsg_end(msg
, hdr
);
481 genlmsg_cancel(msg
, hdr
);
485 static void devlink_notify(struct devlink
*devlink
, enum devlink_command cmd
)
490 WARN_ON(cmd
!= DEVLINK_CMD_NEW
&& cmd
!= DEVLINK_CMD_DEL
);
492 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
496 err
= devlink_nl_fill(msg
, devlink
, cmd
, 0, 0, 0);
502 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
503 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
506 static int devlink_nl_port_attrs_put(struct sk_buff
*msg
,
507 struct devlink_port
*devlink_port
)
509 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
513 if (nla_put_u16(msg
, DEVLINK_ATTR_PORT_FLAVOUR
, attrs
->flavour
))
515 switch (devlink_port
->attrs
.flavour
) {
516 case DEVLINK_PORT_FLAVOUR_PCI_PF
:
517 if (nla_put_u16(msg
, DEVLINK_ATTR_PORT_PCI_PF_NUMBER
,
521 case DEVLINK_PORT_FLAVOUR_PCI_VF
:
522 if (nla_put_u16(msg
, DEVLINK_ATTR_PORT_PCI_PF_NUMBER
,
524 nla_put_u16(msg
, DEVLINK_ATTR_PORT_PCI_VF_NUMBER
,
528 case DEVLINK_PORT_FLAVOUR_PHYSICAL
:
529 case DEVLINK_PORT_FLAVOUR_CPU
:
530 case DEVLINK_PORT_FLAVOUR_DSA
:
531 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_NUMBER
,
532 attrs
->phys
.port_number
))
536 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_SPLIT_GROUP
,
537 attrs
->phys
.port_number
))
539 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER
,
540 attrs
->phys
.split_subport_number
))
549 static int devlink_nl_port_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
550 struct devlink_port
*devlink_port
,
551 enum devlink_command cmd
, u32 portid
,
556 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
560 if (devlink_nl_put_handle(msg
, devlink
))
561 goto nla_put_failure
;
562 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, devlink_port
->index
))
563 goto nla_put_failure
;
565 spin_lock_bh(&devlink_port
->type_lock
);
566 if (nla_put_u16(msg
, DEVLINK_ATTR_PORT_TYPE
, devlink_port
->type
))
567 goto nla_put_failure_type_locked
;
568 if (devlink_port
->desired_type
!= DEVLINK_PORT_TYPE_NOTSET
&&
569 nla_put_u16(msg
, DEVLINK_ATTR_PORT_DESIRED_TYPE
,
570 devlink_port
->desired_type
))
571 goto nla_put_failure_type_locked
;
572 if (devlink_port
->type
== DEVLINK_PORT_TYPE_ETH
) {
573 struct net_device
*netdev
= devlink_port
->type_dev
;
576 (nla_put_u32(msg
, DEVLINK_ATTR_PORT_NETDEV_IFINDEX
,
578 nla_put_string(msg
, DEVLINK_ATTR_PORT_NETDEV_NAME
,
580 goto nla_put_failure_type_locked
;
582 if (devlink_port
->type
== DEVLINK_PORT_TYPE_IB
) {
583 struct ib_device
*ibdev
= devlink_port
->type_dev
;
586 nla_put_string(msg
, DEVLINK_ATTR_PORT_IBDEV_NAME
,
588 goto nla_put_failure_type_locked
;
590 spin_unlock_bh(&devlink_port
->type_lock
);
591 if (devlink_nl_port_attrs_put(msg
, devlink_port
))
592 goto nla_put_failure
;
594 genlmsg_end(msg
, hdr
);
597 nla_put_failure_type_locked
:
598 spin_unlock_bh(&devlink_port
->type_lock
);
600 genlmsg_cancel(msg
, hdr
);
604 static void devlink_port_notify(struct devlink_port
*devlink_port
,
605 enum devlink_command cmd
)
607 struct devlink
*devlink
= devlink_port
->devlink
;
611 if (!devlink_port
->registered
)
614 WARN_ON(cmd
!= DEVLINK_CMD_PORT_NEW
&& cmd
!= DEVLINK_CMD_PORT_DEL
);
616 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
620 err
= devlink_nl_port_fill(msg
, devlink
, devlink_port
, cmd
, 0, 0, 0);
626 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
627 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
630 static int devlink_nl_cmd_get_doit(struct sk_buff
*skb
, struct genl_info
*info
)
632 struct devlink
*devlink
= info
->user_ptr
[0];
636 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
640 err
= devlink_nl_fill(msg
, devlink
, DEVLINK_CMD_NEW
,
641 info
->snd_portid
, info
->snd_seq
, 0);
647 return genlmsg_reply(msg
, info
);
650 static int devlink_nl_cmd_get_dumpit(struct sk_buff
*msg
,
651 struct netlink_callback
*cb
)
653 struct devlink
*devlink
;
654 int start
= cb
->args
[0];
658 mutex_lock(&devlink_mutex
);
659 list_for_each_entry(devlink
, &devlink_list
, list
) {
660 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
666 err
= devlink_nl_fill(msg
, devlink
, DEVLINK_CMD_NEW
,
667 NETLINK_CB(cb
->skb
).portid
,
668 cb
->nlh
->nlmsg_seq
, NLM_F_MULTI
);
674 mutex_unlock(&devlink_mutex
);
680 static int devlink_nl_cmd_port_get_doit(struct sk_buff
*skb
,
681 struct genl_info
*info
)
683 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
684 struct devlink
*devlink
= devlink_port
->devlink
;
688 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
692 err
= devlink_nl_port_fill(msg
, devlink
, devlink_port
,
693 DEVLINK_CMD_PORT_NEW
,
694 info
->snd_portid
, info
->snd_seq
, 0);
700 return genlmsg_reply(msg
, info
);
703 static int devlink_nl_cmd_port_get_dumpit(struct sk_buff
*msg
,
704 struct netlink_callback
*cb
)
706 struct devlink
*devlink
;
707 struct devlink_port
*devlink_port
;
708 int start
= cb
->args
[0];
712 mutex_lock(&devlink_mutex
);
713 list_for_each_entry(devlink
, &devlink_list
, list
) {
714 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
716 mutex_lock(&devlink
->lock
);
717 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
722 err
= devlink_nl_port_fill(msg
, devlink
, devlink_port
,
724 NETLINK_CB(cb
->skb
).portid
,
728 mutex_unlock(&devlink
->lock
);
733 mutex_unlock(&devlink
->lock
);
736 mutex_unlock(&devlink_mutex
);
742 static int devlink_port_type_set(struct devlink
*devlink
,
743 struct devlink_port
*devlink_port
,
744 enum devlink_port_type port_type
)
749 if (devlink
->ops
->port_type_set
) {
750 if (port_type
== DEVLINK_PORT_TYPE_NOTSET
)
752 if (port_type
== devlink_port
->type
)
754 err
= devlink
->ops
->port_type_set(devlink_port
, port_type
);
757 devlink_port
->desired_type
= port_type
;
758 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
764 static int devlink_nl_cmd_port_set_doit(struct sk_buff
*skb
,
765 struct genl_info
*info
)
767 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
768 struct devlink
*devlink
= devlink_port
->devlink
;
771 if (info
->attrs
[DEVLINK_ATTR_PORT_TYPE
]) {
772 enum devlink_port_type port_type
;
774 port_type
= nla_get_u16(info
->attrs
[DEVLINK_ATTR_PORT_TYPE
]);
775 err
= devlink_port_type_set(devlink
, devlink_port
, port_type
);
782 static int devlink_port_split(struct devlink
*devlink
, u32 port_index
,
783 u32 count
, struct netlink_ext_ack
*extack
)
786 if (devlink
->ops
->port_split
)
787 return devlink
->ops
->port_split(devlink
, port_index
, count
,
792 static int devlink_nl_cmd_port_split_doit(struct sk_buff
*skb
,
793 struct genl_info
*info
)
795 struct devlink
*devlink
= info
->user_ptr
[0];
799 if (!info
->attrs
[DEVLINK_ATTR_PORT_INDEX
] ||
800 !info
->attrs
[DEVLINK_ATTR_PORT_SPLIT_COUNT
])
803 port_index
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_PORT_INDEX
]);
804 count
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_PORT_SPLIT_COUNT
]);
805 return devlink_port_split(devlink
, port_index
, count
, info
->extack
);
808 static int devlink_port_unsplit(struct devlink
*devlink
, u32 port_index
,
809 struct netlink_ext_ack
*extack
)
812 if (devlink
->ops
->port_unsplit
)
813 return devlink
->ops
->port_unsplit(devlink
, port_index
, extack
);
817 static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff
*skb
,
818 struct genl_info
*info
)
820 struct devlink
*devlink
= info
->user_ptr
[0];
823 if (!info
->attrs
[DEVLINK_ATTR_PORT_INDEX
])
826 port_index
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_PORT_INDEX
]);
827 return devlink_port_unsplit(devlink
, port_index
, info
->extack
);
830 static int devlink_nl_sb_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
831 struct devlink_sb
*devlink_sb
,
832 enum devlink_command cmd
, u32 portid
,
837 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
841 if (devlink_nl_put_handle(msg
, devlink
))
842 goto nla_put_failure
;
843 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
844 goto nla_put_failure
;
845 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_SIZE
, devlink_sb
->size
))
846 goto nla_put_failure
;
847 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT
,
848 devlink_sb
->ingress_pools_count
))
849 goto nla_put_failure
;
850 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT
,
851 devlink_sb
->egress_pools_count
))
852 goto nla_put_failure
;
853 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_INGRESS_TC_COUNT
,
854 devlink_sb
->ingress_tc_count
))
855 goto nla_put_failure
;
856 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_EGRESS_TC_COUNT
,
857 devlink_sb
->egress_tc_count
))
858 goto nla_put_failure
;
860 genlmsg_end(msg
, hdr
);
864 genlmsg_cancel(msg
, hdr
);
868 static int devlink_nl_cmd_sb_get_doit(struct sk_buff
*skb
,
869 struct genl_info
*info
)
871 struct devlink
*devlink
= info
->user_ptr
[0];
872 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
876 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
880 err
= devlink_nl_sb_fill(msg
, devlink
, devlink_sb
,
882 info
->snd_portid
, info
->snd_seq
, 0);
888 return genlmsg_reply(msg
, info
);
891 static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff
*msg
,
892 struct netlink_callback
*cb
)
894 struct devlink
*devlink
;
895 struct devlink_sb
*devlink_sb
;
896 int start
= cb
->args
[0];
900 mutex_lock(&devlink_mutex
);
901 list_for_each_entry(devlink
, &devlink_list
, list
) {
902 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
904 mutex_lock(&devlink
->lock
);
905 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
910 err
= devlink_nl_sb_fill(msg
, devlink
, devlink_sb
,
912 NETLINK_CB(cb
->skb
).portid
,
916 mutex_unlock(&devlink
->lock
);
921 mutex_unlock(&devlink
->lock
);
924 mutex_unlock(&devlink_mutex
);
930 static int devlink_nl_sb_pool_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
931 struct devlink_sb
*devlink_sb
,
932 u16 pool_index
, enum devlink_command cmd
,
933 u32 portid
, u32 seq
, int flags
)
935 struct devlink_sb_pool_info pool_info
;
939 err
= devlink
->ops
->sb_pool_get(devlink
, devlink_sb
->index
,
940 pool_index
, &pool_info
);
944 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
948 if (devlink_nl_put_handle(msg
, devlink
))
949 goto nla_put_failure
;
950 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
951 goto nla_put_failure
;
952 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_POOL_INDEX
, pool_index
))
953 goto nla_put_failure
;
954 if (nla_put_u8(msg
, DEVLINK_ATTR_SB_POOL_TYPE
, pool_info
.pool_type
))
955 goto nla_put_failure
;
956 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_POOL_SIZE
, pool_info
.size
))
957 goto nla_put_failure
;
958 if (nla_put_u8(msg
, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
,
959 pool_info
.threshold_type
))
960 goto nla_put_failure
;
961 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_POOL_CELL_SIZE
,
962 pool_info
.cell_size
))
963 goto nla_put_failure
;
965 genlmsg_end(msg
, hdr
);
969 genlmsg_cancel(msg
, hdr
);
973 static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff
*skb
,
974 struct genl_info
*info
)
976 struct devlink
*devlink
= info
->user_ptr
[0];
977 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
982 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
987 if (!devlink
->ops
->sb_pool_get
)
990 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
994 err
= devlink_nl_sb_pool_fill(msg
, devlink
, devlink_sb
, pool_index
,
995 DEVLINK_CMD_SB_POOL_NEW
,
996 info
->snd_portid
, info
->snd_seq
, 0);
1002 return genlmsg_reply(msg
, info
);
1005 static int __sb_pool_get_dumpit(struct sk_buff
*msg
, int start
, int *p_idx
,
1006 struct devlink
*devlink
,
1007 struct devlink_sb
*devlink_sb
,
1008 u32 portid
, u32 seq
)
1010 u16 pool_count
= devlink_sb_pool_count(devlink_sb
);
1014 for (pool_index
= 0; pool_index
< pool_count
; pool_index
++) {
1015 if (*p_idx
< start
) {
1019 err
= devlink_nl_sb_pool_fill(msg
, devlink
,
1022 DEVLINK_CMD_SB_POOL_NEW
,
1023 portid
, seq
, NLM_F_MULTI
);
1031 static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff
*msg
,
1032 struct netlink_callback
*cb
)
1034 struct devlink
*devlink
;
1035 struct devlink_sb
*devlink_sb
;
1036 int start
= cb
->args
[0];
1040 mutex_lock(&devlink_mutex
);
1041 list_for_each_entry(devlink
, &devlink_list
, list
) {
1042 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)) ||
1043 !devlink
->ops
->sb_pool_get
)
1045 mutex_lock(&devlink
->lock
);
1046 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
1047 err
= __sb_pool_get_dumpit(msg
, start
, &idx
, devlink
,
1049 NETLINK_CB(cb
->skb
).portid
,
1050 cb
->nlh
->nlmsg_seq
);
1051 if (err
&& err
!= -EOPNOTSUPP
) {
1052 mutex_unlock(&devlink
->lock
);
1056 mutex_unlock(&devlink
->lock
);
1059 mutex_unlock(&devlink_mutex
);
1065 static int devlink_sb_pool_set(struct devlink
*devlink
, unsigned int sb_index
,
1066 u16 pool_index
, u32 size
,
1067 enum devlink_sb_threshold_type threshold_type
,
1068 struct netlink_ext_ack
*extack
)
1071 const struct devlink_ops
*ops
= devlink
->ops
;
1073 if (ops
->sb_pool_set
)
1074 return ops
->sb_pool_set(devlink
, sb_index
, pool_index
,
1075 size
, threshold_type
, extack
);
1079 static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff
*skb
,
1080 struct genl_info
*info
)
1082 struct devlink
*devlink
= info
->user_ptr
[0];
1083 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1084 enum devlink_sb_threshold_type threshold_type
;
1089 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1094 err
= devlink_sb_th_type_get_from_info(info
, &threshold_type
);
1098 if (!info
->attrs
[DEVLINK_ATTR_SB_POOL_SIZE
])
1101 size
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_SB_POOL_SIZE
]);
1102 return devlink_sb_pool_set(devlink
, devlink_sb
->index
,
1103 pool_index
, size
, threshold_type
,
1107 static int devlink_nl_sb_port_pool_fill(struct sk_buff
*msg
,
1108 struct devlink
*devlink
,
1109 struct devlink_port
*devlink_port
,
1110 struct devlink_sb
*devlink_sb
,
1112 enum devlink_command cmd
,
1113 u32 portid
, u32 seq
, int flags
)
1115 const struct devlink_ops
*ops
= devlink
->ops
;
1120 err
= ops
->sb_port_pool_get(devlink_port
, devlink_sb
->index
,
1121 pool_index
, &threshold
);
1125 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
1129 if (devlink_nl_put_handle(msg
, devlink
))
1130 goto nla_put_failure
;
1131 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, devlink_port
->index
))
1132 goto nla_put_failure
;
1133 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
1134 goto nla_put_failure
;
1135 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_POOL_INDEX
, pool_index
))
1136 goto nla_put_failure
;
1137 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_THRESHOLD
, threshold
))
1138 goto nla_put_failure
;
1140 if (ops
->sb_occ_port_pool_get
) {
1144 err
= ops
->sb_occ_port_pool_get(devlink_port
, devlink_sb
->index
,
1145 pool_index
, &cur
, &max
);
1146 if (err
&& err
!= -EOPNOTSUPP
)
1149 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_CUR
, cur
))
1150 goto nla_put_failure
;
1151 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_MAX
, max
))
1152 goto nla_put_failure
;
1156 genlmsg_end(msg
, hdr
);
1160 genlmsg_cancel(msg
, hdr
);
1164 static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff
*skb
,
1165 struct genl_info
*info
)
1167 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1168 struct devlink
*devlink
= devlink_port
->devlink
;
1169 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1170 struct sk_buff
*msg
;
1174 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1179 if (!devlink
->ops
->sb_port_pool_get
)
1182 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1186 err
= devlink_nl_sb_port_pool_fill(msg
, devlink
, devlink_port
,
1187 devlink_sb
, pool_index
,
1188 DEVLINK_CMD_SB_PORT_POOL_NEW
,
1189 info
->snd_portid
, info
->snd_seq
, 0);
1195 return genlmsg_reply(msg
, info
);
1198 static int __sb_port_pool_get_dumpit(struct sk_buff
*msg
, int start
, int *p_idx
,
1199 struct devlink
*devlink
,
1200 struct devlink_sb
*devlink_sb
,
1201 u32 portid
, u32 seq
)
1203 struct devlink_port
*devlink_port
;
1204 u16 pool_count
= devlink_sb_pool_count(devlink_sb
);
1208 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
1209 for (pool_index
= 0; pool_index
< pool_count
; pool_index
++) {
1210 if (*p_idx
< start
) {
1214 err
= devlink_nl_sb_port_pool_fill(msg
, devlink
,
1218 DEVLINK_CMD_SB_PORT_POOL_NEW
,
1229 static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff
*msg
,
1230 struct netlink_callback
*cb
)
1232 struct devlink
*devlink
;
1233 struct devlink_sb
*devlink_sb
;
1234 int start
= cb
->args
[0];
1238 mutex_lock(&devlink_mutex
);
1239 list_for_each_entry(devlink
, &devlink_list
, list
) {
1240 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)) ||
1241 !devlink
->ops
->sb_port_pool_get
)
1243 mutex_lock(&devlink
->lock
);
1244 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
1245 err
= __sb_port_pool_get_dumpit(msg
, start
, &idx
,
1246 devlink
, devlink_sb
,
1247 NETLINK_CB(cb
->skb
).portid
,
1248 cb
->nlh
->nlmsg_seq
);
1249 if (err
&& err
!= -EOPNOTSUPP
) {
1250 mutex_unlock(&devlink
->lock
);
1254 mutex_unlock(&devlink
->lock
);
1257 mutex_unlock(&devlink_mutex
);
1263 static int devlink_sb_port_pool_set(struct devlink_port
*devlink_port
,
1264 unsigned int sb_index
, u16 pool_index
,
1266 struct netlink_ext_ack
*extack
)
1269 const struct devlink_ops
*ops
= devlink_port
->devlink
->ops
;
1271 if (ops
->sb_port_pool_set
)
1272 return ops
->sb_port_pool_set(devlink_port
, sb_index
,
1273 pool_index
, threshold
, extack
);
1277 static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff
*skb
,
1278 struct genl_info
*info
)
1280 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1281 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1286 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1291 if (!info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
])
1294 threshold
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
]);
1295 return devlink_sb_port_pool_set(devlink_port
, devlink_sb
->index
,
1296 pool_index
, threshold
, info
->extack
);
1300 devlink_nl_sb_tc_pool_bind_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
1301 struct devlink_port
*devlink_port
,
1302 struct devlink_sb
*devlink_sb
, u16 tc_index
,
1303 enum devlink_sb_pool_type pool_type
,
1304 enum devlink_command cmd
,
1305 u32 portid
, u32 seq
, int flags
)
1307 const struct devlink_ops
*ops
= devlink
->ops
;
1313 err
= ops
->sb_tc_pool_bind_get(devlink_port
, devlink_sb
->index
,
1314 tc_index
, pool_type
,
1315 &pool_index
, &threshold
);
1319 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
1323 if (devlink_nl_put_handle(msg
, devlink
))
1324 goto nla_put_failure
;
1325 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, devlink_port
->index
))
1326 goto nla_put_failure
;
1327 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
1328 goto nla_put_failure
;
1329 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_TC_INDEX
, tc_index
))
1330 goto nla_put_failure
;
1331 if (nla_put_u8(msg
, DEVLINK_ATTR_SB_POOL_TYPE
, pool_type
))
1332 goto nla_put_failure
;
1333 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_POOL_INDEX
, pool_index
))
1334 goto nla_put_failure
;
1335 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_THRESHOLD
, threshold
))
1336 goto nla_put_failure
;
1338 if (ops
->sb_occ_tc_port_bind_get
) {
1342 err
= ops
->sb_occ_tc_port_bind_get(devlink_port
,
1344 tc_index
, pool_type
,
1346 if (err
&& err
!= -EOPNOTSUPP
)
1349 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_CUR
, cur
))
1350 goto nla_put_failure
;
1351 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_MAX
, max
))
1352 goto nla_put_failure
;
1356 genlmsg_end(msg
, hdr
);
1360 genlmsg_cancel(msg
, hdr
);
1364 static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff
*skb
,
1365 struct genl_info
*info
)
1367 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1368 struct devlink
*devlink
= devlink_port
->devlink
;
1369 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1370 struct sk_buff
*msg
;
1371 enum devlink_sb_pool_type pool_type
;
1375 err
= devlink_sb_pool_type_get_from_info(info
, &pool_type
);
1379 err
= devlink_sb_tc_index_get_from_info(devlink_sb
, info
,
1380 pool_type
, &tc_index
);
1384 if (!devlink
->ops
->sb_tc_pool_bind_get
)
1387 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1391 err
= devlink_nl_sb_tc_pool_bind_fill(msg
, devlink
, devlink_port
,
1392 devlink_sb
, tc_index
, pool_type
,
1393 DEVLINK_CMD_SB_TC_POOL_BIND_NEW
,
1401 return genlmsg_reply(msg
, info
);
1404 static int __sb_tc_pool_bind_get_dumpit(struct sk_buff
*msg
,
1405 int start
, int *p_idx
,
1406 struct devlink
*devlink
,
1407 struct devlink_sb
*devlink_sb
,
1408 u32 portid
, u32 seq
)
1410 struct devlink_port
*devlink_port
;
1414 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
1416 tc_index
< devlink_sb
->ingress_tc_count
; tc_index
++) {
1417 if (*p_idx
< start
) {
1421 err
= devlink_nl_sb_tc_pool_bind_fill(msg
, devlink
,
1425 DEVLINK_SB_POOL_TYPE_INGRESS
,
1426 DEVLINK_CMD_SB_TC_POOL_BIND_NEW
,
1434 tc_index
< devlink_sb
->egress_tc_count
; tc_index
++) {
1435 if (*p_idx
< start
) {
1439 err
= devlink_nl_sb_tc_pool_bind_fill(msg
, devlink
,
1443 DEVLINK_SB_POOL_TYPE_EGRESS
,
1444 DEVLINK_CMD_SB_TC_POOL_BIND_NEW
,
1456 devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff
*msg
,
1457 struct netlink_callback
*cb
)
1459 struct devlink
*devlink
;
1460 struct devlink_sb
*devlink_sb
;
1461 int start
= cb
->args
[0];
1465 mutex_lock(&devlink_mutex
);
1466 list_for_each_entry(devlink
, &devlink_list
, list
) {
1467 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)) ||
1468 !devlink
->ops
->sb_tc_pool_bind_get
)
1471 mutex_lock(&devlink
->lock
);
1472 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
1473 err
= __sb_tc_pool_bind_get_dumpit(msg
, start
, &idx
,
1476 NETLINK_CB(cb
->skb
).portid
,
1477 cb
->nlh
->nlmsg_seq
);
1478 if (err
&& err
!= -EOPNOTSUPP
) {
1479 mutex_unlock(&devlink
->lock
);
1483 mutex_unlock(&devlink
->lock
);
1486 mutex_unlock(&devlink_mutex
);
1492 static int devlink_sb_tc_pool_bind_set(struct devlink_port
*devlink_port
,
1493 unsigned int sb_index
, u16 tc_index
,
1494 enum devlink_sb_pool_type pool_type
,
1495 u16 pool_index
, u32 threshold
,
1496 struct netlink_ext_ack
*extack
)
1499 const struct devlink_ops
*ops
= devlink_port
->devlink
->ops
;
1501 if (ops
->sb_tc_pool_bind_set
)
1502 return ops
->sb_tc_pool_bind_set(devlink_port
, sb_index
,
1503 tc_index
, pool_type
,
1504 pool_index
, threshold
, extack
);
1508 static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff
*skb
,
1509 struct genl_info
*info
)
1511 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1512 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1513 enum devlink_sb_pool_type pool_type
;
1519 err
= devlink_sb_pool_type_get_from_info(info
, &pool_type
);
1523 err
= devlink_sb_tc_index_get_from_info(devlink_sb
, info
,
1524 pool_type
, &tc_index
);
1528 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1533 if (!info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
])
1536 threshold
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
]);
1537 return devlink_sb_tc_pool_bind_set(devlink_port
, devlink_sb
->index
,
1538 tc_index
, pool_type
,
1539 pool_index
, threshold
, info
->extack
);
1542 static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff
*skb
,
1543 struct genl_info
*info
)
1545 struct devlink
*devlink
= info
->user_ptr
[0];
1546 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1547 const struct devlink_ops
*ops
= devlink
->ops
;
1549 if (ops
->sb_occ_snapshot
)
1550 return ops
->sb_occ_snapshot(devlink
, devlink_sb
->index
);
1554 static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff
*skb
,
1555 struct genl_info
*info
)
1557 struct devlink
*devlink
= info
->user_ptr
[0];
1558 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1559 const struct devlink_ops
*ops
= devlink
->ops
;
1561 if (ops
->sb_occ_max_clear
)
1562 return ops
->sb_occ_max_clear(devlink
, devlink_sb
->index
);
1566 static int devlink_nl_eswitch_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
1567 enum devlink_command cmd
, u32 portid
,
1570 const struct devlink_ops
*ops
= devlink
->ops
;
1571 enum devlink_eswitch_encap_mode encap_mode
;
1577 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
1581 err
= devlink_nl_put_handle(msg
, devlink
);
1583 goto nla_put_failure
;
1585 if (ops
->eswitch_mode_get
) {
1586 err
= ops
->eswitch_mode_get(devlink
, &mode
);
1588 goto nla_put_failure
;
1589 err
= nla_put_u16(msg
, DEVLINK_ATTR_ESWITCH_MODE
, mode
);
1591 goto nla_put_failure
;
1594 if (ops
->eswitch_inline_mode_get
) {
1595 err
= ops
->eswitch_inline_mode_get(devlink
, &inline_mode
);
1597 goto nla_put_failure
;
1598 err
= nla_put_u8(msg
, DEVLINK_ATTR_ESWITCH_INLINE_MODE
,
1601 goto nla_put_failure
;
1604 if (ops
->eswitch_encap_mode_get
) {
1605 err
= ops
->eswitch_encap_mode_get(devlink
, &encap_mode
);
1607 goto nla_put_failure
;
1608 err
= nla_put_u8(msg
, DEVLINK_ATTR_ESWITCH_ENCAP_MODE
, encap_mode
);
1610 goto nla_put_failure
;
1613 genlmsg_end(msg
, hdr
);
1617 genlmsg_cancel(msg
, hdr
);
1621 static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff
*skb
,
1622 struct genl_info
*info
)
1624 struct devlink
*devlink
= info
->user_ptr
[0];
1625 struct sk_buff
*msg
;
1628 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1632 err
= devlink_nl_eswitch_fill(msg
, devlink
, DEVLINK_CMD_ESWITCH_GET
,
1633 info
->snd_portid
, info
->snd_seq
, 0);
1640 return genlmsg_reply(msg
, info
);
1643 static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff
*skb
,
1644 struct genl_info
*info
)
1646 struct devlink
*devlink
= info
->user_ptr
[0];
1647 const struct devlink_ops
*ops
= devlink
->ops
;
1648 enum devlink_eswitch_encap_mode encap_mode
;
1653 if (info
->attrs
[DEVLINK_ATTR_ESWITCH_MODE
]) {
1654 if (!ops
->eswitch_mode_set
)
1656 mode
= nla_get_u16(info
->attrs
[DEVLINK_ATTR_ESWITCH_MODE
]);
1657 err
= ops
->eswitch_mode_set(devlink
, mode
, info
->extack
);
1662 if (info
->attrs
[DEVLINK_ATTR_ESWITCH_INLINE_MODE
]) {
1663 if (!ops
->eswitch_inline_mode_set
)
1665 inline_mode
= nla_get_u8(
1666 info
->attrs
[DEVLINK_ATTR_ESWITCH_INLINE_MODE
]);
1667 err
= ops
->eswitch_inline_mode_set(devlink
, inline_mode
,
1673 if (info
->attrs
[DEVLINK_ATTR_ESWITCH_ENCAP_MODE
]) {
1674 if (!ops
->eswitch_encap_mode_set
)
1676 encap_mode
= nla_get_u8(info
->attrs
[DEVLINK_ATTR_ESWITCH_ENCAP_MODE
]);
1677 err
= ops
->eswitch_encap_mode_set(devlink
, encap_mode
,
1686 int devlink_dpipe_match_put(struct sk_buff
*skb
,
1687 struct devlink_dpipe_match
*match
)
1689 struct devlink_dpipe_header
*header
= match
->header
;
1690 struct devlink_dpipe_field
*field
= &header
->fields
[match
->field_id
];
1691 struct nlattr
*match_attr
;
1693 match_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_MATCH
);
1697 if (nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_MATCH_TYPE
, match
->type
) ||
1698 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_INDEX
, match
->header_index
) ||
1699 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_ID
, header
->id
) ||
1700 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_ID
, field
->id
) ||
1701 nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL
, header
->global
))
1702 goto nla_put_failure
;
1704 nla_nest_end(skb
, match_attr
);
1708 nla_nest_cancel(skb
, match_attr
);
1711 EXPORT_SYMBOL_GPL(devlink_dpipe_match_put
);
1713 static int devlink_dpipe_matches_put(struct devlink_dpipe_table
*table
,
1714 struct sk_buff
*skb
)
1716 struct nlattr
*matches_attr
;
1718 matches_attr
= nla_nest_start_noflag(skb
,
1719 DEVLINK_ATTR_DPIPE_TABLE_MATCHES
);
1723 if (table
->table_ops
->matches_dump(table
->priv
, skb
))
1724 goto nla_put_failure
;
1726 nla_nest_end(skb
, matches_attr
);
1730 nla_nest_cancel(skb
, matches_attr
);
1734 int devlink_dpipe_action_put(struct sk_buff
*skb
,
1735 struct devlink_dpipe_action
*action
)
1737 struct devlink_dpipe_header
*header
= action
->header
;
1738 struct devlink_dpipe_field
*field
= &header
->fields
[action
->field_id
];
1739 struct nlattr
*action_attr
;
1741 action_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_ACTION
);
1745 if (nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_ACTION_TYPE
, action
->type
) ||
1746 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_INDEX
, action
->header_index
) ||
1747 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_ID
, header
->id
) ||
1748 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_ID
, field
->id
) ||
1749 nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL
, header
->global
))
1750 goto nla_put_failure
;
1752 nla_nest_end(skb
, action_attr
);
1756 nla_nest_cancel(skb
, action_attr
);
1759 EXPORT_SYMBOL_GPL(devlink_dpipe_action_put
);
1761 static int devlink_dpipe_actions_put(struct devlink_dpipe_table
*table
,
1762 struct sk_buff
*skb
)
1764 struct nlattr
*actions_attr
;
1766 actions_attr
= nla_nest_start_noflag(skb
,
1767 DEVLINK_ATTR_DPIPE_TABLE_ACTIONS
);
1771 if (table
->table_ops
->actions_dump(table
->priv
, skb
))
1772 goto nla_put_failure
;
1774 nla_nest_end(skb
, actions_attr
);
1778 nla_nest_cancel(skb
, actions_attr
);
1782 static int devlink_dpipe_table_put(struct sk_buff
*skb
,
1783 struct devlink_dpipe_table
*table
)
1785 struct nlattr
*table_attr
;
1788 table_size
= table
->table_ops
->size_get(table
->priv
);
1789 table_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_TABLE
);
1793 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_TABLE_NAME
, table
->name
) ||
1794 nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_TABLE_SIZE
, table_size
,
1796 goto nla_put_failure
;
1797 if (nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
,
1798 table
->counters_enabled
))
1799 goto nla_put_failure
;
1801 if (table
->resource_valid
) {
1802 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID
,
1803 table
->resource_id
, DEVLINK_ATTR_PAD
) ||
1804 nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS
,
1805 table
->resource_units
, DEVLINK_ATTR_PAD
))
1806 goto nla_put_failure
;
1808 if (devlink_dpipe_matches_put(table
, skb
))
1809 goto nla_put_failure
;
1811 if (devlink_dpipe_actions_put(table
, skb
))
1812 goto nla_put_failure
;
1814 nla_nest_end(skb
, table_attr
);
1818 nla_nest_cancel(skb
, table_attr
);
1822 static int devlink_dpipe_send_and_alloc_skb(struct sk_buff
**pskb
,
1823 struct genl_info
*info
)
1828 err
= genlmsg_reply(*pskb
, info
);
1832 *pskb
= genlmsg_new(GENLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1838 static int devlink_dpipe_tables_fill(struct genl_info
*info
,
1839 enum devlink_command cmd
, int flags
,
1840 struct list_head
*dpipe_tables
,
1841 const char *table_name
)
1843 struct devlink
*devlink
= info
->user_ptr
[0];
1844 struct devlink_dpipe_table
*table
;
1845 struct nlattr
*tables_attr
;
1846 struct sk_buff
*skb
= NULL
;
1847 struct nlmsghdr
*nlh
;
1853 table
= list_first_entry(dpipe_tables
,
1854 struct devlink_dpipe_table
, list
);
1856 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
1860 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
1861 &devlink_nl_family
, NLM_F_MULTI
, cmd
);
1867 if (devlink_nl_put_handle(skb
, devlink
))
1868 goto nla_put_failure
;
1869 tables_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_TABLES
);
1871 goto nla_put_failure
;
1875 list_for_each_entry_from(table
, dpipe_tables
, list
) {
1877 err
= devlink_dpipe_table_put(skb
, table
);
1885 if (!strcmp(table
->name
, table_name
)) {
1886 err
= devlink_dpipe_table_put(skb
, table
);
1894 nla_nest_end(skb
, tables_attr
);
1895 genlmsg_end(skb
, hdr
);
1900 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
1901 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
1903 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
1909 return genlmsg_reply(skb
, info
);
1918 static int devlink_nl_cmd_dpipe_table_get(struct sk_buff
*skb
,
1919 struct genl_info
*info
)
1921 struct devlink
*devlink
= info
->user_ptr
[0];
1922 const char *table_name
= NULL
;
1924 if (info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
])
1925 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
1927 return devlink_dpipe_tables_fill(info
, DEVLINK_CMD_DPIPE_TABLE_GET
, 0,
1928 &devlink
->dpipe_table_list
,
1932 static int devlink_dpipe_value_put(struct sk_buff
*skb
,
1933 struct devlink_dpipe_value
*value
)
1935 if (nla_put(skb
, DEVLINK_ATTR_DPIPE_VALUE
,
1936 value
->value_size
, value
->value
))
1939 if (nla_put(skb
, DEVLINK_ATTR_DPIPE_VALUE_MASK
,
1940 value
->value_size
, value
->mask
))
1942 if (value
->mapping_valid
)
1943 if (nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_VALUE_MAPPING
,
1944 value
->mapping_value
))
1949 static int devlink_dpipe_action_value_put(struct sk_buff
*skb
,
1950 struct devlink_dpipe_value
*value
)
1954 if (devlink_dpipe_action_put(skb
, value
->action
))
1956 if (devlink_dpipe_value_put(skb
, value
))
1961 static int devlink_dpipe_action_values_put(struct sk_buff
*skb
,
1962 struct devlink_dpipe_value
*values
,
1963 unsigned int values_count
)
1965 struct nlattr
*action_attr
;
1969 for (i
= 0; i
< values_count
; i
++) {
1970 action_attr
= nla_nest_start_noflag(skb
,
1971 DEVLINK_ATTR_DPIPE_ACTION_VALUE
);
1974 err
= devlink_dpipe_action_value_put(skb
, &values
[i
]);
1976 goto err_action_value_put
;
1977 nla_nest_end(skb
, action_attr
);
1981 err_action_value_put
:
1982 nla_nest_cancel(skb
, action_attr
);
1986 static int devlink_dpipe_match_value_put(struct sk_buff
*skb
,
1987 struct devlink_dpipe_value
*value
)
1991 if (devlink_dpipe_match_put(skb
, value
->match
))
1993 if (devlink_dpipe_value_put(skb
, value
))
1998 static int devlink_dpipe_match_values_put(struct sk_buff
*skb
,
1999 struct devlink_dpipe_value
*values
,
2000 unsigned int values_count
)
2002 struct nlattr
*match_attr
;
2006 for (i
= 0; i
< values_count
; i
++) {
2007 match_attr
= nla_nest_start_noflag(skb
,
2008 DEVLINK_ATTR_DPIPE_MATCH_VALUE
);
2011 err
= devlink_dpipe_match_value_put(skb
, &values
[i
]);
2013 goto err_match_value_put
;
2014 nla_nest_end(skb
, match_attr
);
2018 err_match_value_put
:
2019 nla_nest_cancel(skb
, match_attr
);
2023 static int devlink_dpipe_entry_put(struct sk_buff
*skb
,
2024 struct devlink_dpipe_entry
*entry
)
2026 struct nlattr
*entry_attr
, *matches_attr
, *actions_attr
;
2029 entry_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_ENTRY
);
2033 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_ENTRY_INDEX
, entry
->index
,
2035 goto nla_put_failure
;
2036 if (entry
->counter_valid
)
2037 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER
,
2038 entry
->counter
, DEVLINK_ATTR_PAD
))
2039 goto nla_put_failure
;
2041 matches_attr
= nla_nest_start_noflag(skb
,
2042 DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES
);
2044 goto nla_put_failure
;
2046 err
= devlink_dpipe_match_values_put(skb
, entry
->match_values
,
2047 entry
->match_values_count
);
2049 nla_nest_cancel(skb
, matches_attr
);
2050 goto err_match_values_put
;
2052 nla_nest_end(skb
, matches_attr
);
2054 actions_attr
= nla_nest_start_noflag(skb
,
2055 DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES
);
2057 goto nla_put_failure
;
2059 err
= devlink_dpipe_action_values_put(skb
, entry
->action_values
,
2060 entry
->action_values_count
);
2062 nla_nest_cancel(skb
, actions_attr
);
2063 goto err_action_values_put
;
2065 nla_nest_end(skb
, actions_attr
);
2067 nla_nest_end(skb
, entry_attr
);
2072 err_match_values_put
:
2073 err_action_values_put
:
2074 nla_nest_cancel(skb
, entry_attr
);
2078 static struct devlink_dpipe_table
*
2079 devlink_dpipe_table_find(struct list_head
*dpipe_tables
,
2080 const char *table_name
)
2082 struct devlink_dpipe_table
*table
;
2084 list_for_each_entry_rcu(table
, dpipe_tables
, list
) {
2085 if (!strcmp(table
->name
, table_name
))
2091 int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx
*dump_ctx
)
2093 struct devlink
*devlink
;
2096 err
= devlink_dpipe_send_and_alloc_skb(&dump_ctx
->skb
,
2101 dump_ctx
->hdr
= genlmsg_put(dump_ctx
->skb
,
2102 dump_ctx
->info
->snd_portid
,
2103 dump_ctx
->info
->snd_seq
,
2104 &devlink_nl_family
, NLM_F_MULTI
,
2107 goto nla_put_failure
;
2109 devlink
= dump_ctx
->info
->user_ptr
[0];
2110 if (devlink_nl_put_handle(dump_ctx
->skb
, devlink
))
2111 goto nla_put_failure
;
2112 dump_ctx
->nest
= nla_nest_start_noflag(dump_ctx
->skb
,
2113 DEVLINK_ATTR_DPIPE_ENTRIES
);
2114 if (!dump_ctx
->nest
)
2115 goto nla_put_failure
;
2119 nlmsg_free(dump_ctx
->skb
);
2122 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare
);
2124 int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx
*dump_ctx
,
2125 struct devlink_dpipe_entry
*entry
)
2127 return devlink_dpipe_entry_put(dump_ctx
->skb
, entry
);
2129 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append
);
2131 int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx
*dump_ctx
)
2133 nla_nest_end(dump_ctx
->skb
, dump_ctx
->nest
);
2134 genlmsg_end(dump_ctx
->skb
, dump_ctx
->hdr
);
2137 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close
);
2139 void devlink_dpipe_entry_clear(struct devlink_dpipe_entry
*entry
)
2142 unsigned int value_count
, value_index
;
2143 struct devlink_dpipe_value
*value
;
2145 value
= entry
->action_values
;
2146 value_count
= entry
->action_values_count
;
2147 for (value_index
= 0; value_index
< value_count
; value_index
++) {
2148 kfree(value
[value_index
].value
);
2149 kfree(value
[value_index
].mask
);
2152 value
= entry
->match_values
;
2153 value_count
= entry
->match_values_count
;
2154 for (value_index
= 0; value_index
< value_count
; value_index
++) {
2155 kfree(value
[value_index
].value
);
2156 kfree(value
[value_index
].mask
);
2159 EXPORT_SYMBOL(devlink_dpipe_entry_clear
);
2161 static int devlink_dpipe_entries_fill(struct genl_info
*info
,
2162 enum devlink_command cmd
, int flags
,
2163 struct devlink_dpipe_table
*table
)
2165 struct devlink_dpipe_dump_ctx dump_ctx
;
2166 struct nlmsghdr
*nlh
;
2169 dump_ctx
.skb
= NULL
;
2171 dump_ctx
.info
= info
;
2173 err
= table
->table_ops
->entries_dump(table
->priv
,
2174 table
->counters_enabled
,
2180 nlh
= nlmsg_put(dump_ctx
.skb
, info
->snd_portid
, info
->snd_seq
,
2181 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
2183 err
= devlink_dpipe_send_and_alloc_skb(&dump_ctx
.skb
, info
);
2188 return genlmsg_reply(dump_ctx
.skb
, info
);
2191 static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff
*skb
,
2192 struct genl_info
*info
)
2194 struct devlink
*devlink
= info
->user_ptr
[0];
2195 struct devlink_dpipe_table
*table
;
2196 const char *table_name
;
2198 if (!info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
])
2201 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
2202 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
2207 if (!table
->table_ops
->entries_dump
)
2210 return devlink_dpipe_entries_fill(info
, DEVLINK_CMD_DPIPE_ENTRIES_GET
,
2214 static int devlink_dpipe_fields_put(struct sk_buff
*skb
,
2215 const struct devlink_dpipe_header
*header
)
2217 struct devlink_dpipe_field
*field
;
2218 struct nlattr
*field_attr
;
2221 for (i
= 0; i
< header
->fields_count
; i
++) {
2222 field
= &header
->fields
[i
];
2223 field_attr
= nla_nest_start_noflag(skb
,
2224 DEVLINK_ATTR_DPIPE_FIELD
);
2227 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_FIELD_NAME
, field
->name
) ||
2228 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_ID
, field
->id
) ||
2229 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH
, field
->bitwidth
) ||
2230 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE
, field
->mapping_type
))
2231 goto nla_put_failure
;
2232 nla_nest_end(skb
, field_attr
);
2237 nla_nest_cancel(skb
, field_attr
);
2241 static int devlink_dpipe_header_put(struct sk_buff
*skb
,
2242 struct devlink_dpipe_header
*header
)
2244 struct nlattr
*fields_attr
, *header_attr
;
2247 header_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_HEADER
);
2251 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_HEADER_NAME
, header
->name
) ||
2252 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_ID
, header
->id
) ||
2253 nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL
, header
->global
))
2254 goto nla_put_failure
;
2256 fields_attr
= nla_nest_start_noflag(skb
,
2257 DEVLINK_ATTR_DPIPE_HEADER_FIELDS
);
2259 goto nla_put_failure
;
2261 err
= devlink_dpipe_fields_put(skb
, header
);
2263 nla_nest_cancel(skb
, fields_attr
);
2264 goto nla_put_failure
;
2266 nla_nest_end(skb
, fields_attr
);
2267 nla_nest_end(skb
, header_attr
);
2272 nla_nest_cancel(skb
, header_attr
);
2276 static int devlink_dpipe_headers_fill(struct genl_info
*info
,
2277 enum devlink_command cmd
, int flags
,
2278 struct devlink_dpipe_headers
*
2281 struct devlink
*devlink
= info
->user_ptr
[0];
2282 struct nlattr
*headers_attr
;
2283 struct sk_buff
*skb
= NULL
;
2284 struct nlmsghdr
*nlh
;
2291 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2295 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2296 &devlink_nl_family
, NLM_F_MULTI
, cmd
);
2302 if (devlink_nl_put_handle(skb
, devlink
))
2303 goto nla_put_failure
;
2304 headers_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_HEADERS
);
2306 goto nla_put_failure
;
2309 for (; i
< dpipe_headers
->headers_count
; i
++) {
2310 err
= devlink_dpipe_header_put(skb
, dpipe_headers
->headers
[i
]);
2318 nla_nest_end(skb
, headers_attr
);
2319 genlmsg_end(skb
, hdr
);
2320 if (i
!= dpipe_headers
->headers_count
)
2324 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2325 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
2327 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2332 return genlmsg_reply(skb
, info
);
2341 static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff
*skb
,
2342 struct genl_info
*info
)
2344 struct devlink
*devlink
= info
->user_ptr
[0];
2346 if (!devlink
->dpipe_headers
)
2348 return devlink_dpipe_headers_fill(info
, DEVLINK_CMD_DPIPE_HEADERS_GET
,
2349 0, devlink
->dpipe_headers
);
2352 static int devlink_dpipe_table_counters_set(struct devlink
*devlink
,
2353 const char *table_name
,
2356 struct devlink_dpipe_table
*table
;
2358 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
2363 if (table
->counter_control_extern
)
2366 if (!(table
->counters_enabled
^ enable
))
2369 table
->counters_enabled
= enable
;
2370 if (table
->table_ops
->counters_set_update
)
2371 table
->table_ops
->counters_set_update(table
->priv
, enable
);
2375 static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff
*skb
,
2376 struct genl_info
*info
)
2378 struct devlink
*devlink
= info
->user_ptr
[0];
2379 const char *table_name
;
2380 bool counters_enable
;
2382 if (!info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
] ||
2383 !info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
])
2386 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
2387 counters_enable
= !!nla_get_u8(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
]);
2389 return devlink_dpipe_table_counters_set(devlink
, table_name
,
2393 static struct devlink_resource
*
2394 devlink_resource_find(struct devlink
*devlink
,
2395 struct devlink_resource
*resource
, u64 resource_id
)
2397 struct list_head
*resource_list
;
2400 resource_list
= &resource
->resource_list
;
2402 resource_list
= &devlink
->resource_list
;
2404 list_for_each_entry(resource
, resource_list
, list
) {
2405 struct devlink_resource
*child_resource
;
2407 if (resource
->id
== resource_id
)
2410 child_resource
= devlink_resource_find(devlink
, resource
,
2413 return child_resource
;
2419 devlink_resource_validate_children(struct devlink_resource
*resource
)
2421 struct devlink_resource
*child_resource
;
2422 bool size_valid
= true;
2425 if (list_empty(&resource
->resource_list
))
2428 list_for_each_entry(child_resource
, &resource
->resource_list
, list
)
2429 parts_size
+= child_resource
->size_new
;
2431 if (parts_size
> resource
->size_new
)
2434 resource
->size_valid
= size_valid
;
2438 devlink_resource_validate_size(struct devlink_resource
*resource
, u64 size
,
2439 struct netlink_ext_ack
*extack
)
2444 if (size
> resource
->size_params
.size_max
) {
2445 NL_SET_ERR_MSG_MOD(extack
, "Size larger than maximum");
2449 if (size
< resource
->size_params
.size_min
) {
2450 NL_SET_ERR_MSG_MOD(extack
, "Size smaller than minimum");
2454 div64_u64_rem(size
, resource
->size_params
.size_granularity
, &reminder
);
2456 NL_SET_ERR_MSG_MOD(extack
, "Wrong granularity");
2463 static int devlink_nl_cmd_resource_set(struct sk_buff
*skb
,
2464 struct genl_info
*info
)
2466 struct devlink
*devlink
= info
->user_ptr
[0];
2467 struct devlink_resource
*resource
;
2472 if (!info
->attrs
[DEVLINK_ATTR_RESOURCE_ID
] ||
2473 !info
->attrs
[DEVLINK_ATTR_RESOURCE_SIZE
])
2475 resource_id
= nla_get_u64(info
->attrs
[DEVLINK_ATTR_RESOURCE_ID
]);
2477 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
2481 size
= nla_get_u64(info
->attrs
[DEVLINK_ATTR_RESOURCE_SIZE
]);
2482 err
= devlink_resource_validate_size(resource
, size
, info
->extack
);
2486 resource
->size_new
= size
;
2487 devlink_resource_validate_children(resource
);
2488 if (resource
->parent
)
2489 devlink_resource_validate_children(resource
->parent
);
2494 devlink_resource_size_params_put(struct devlink_resource
*resource
,
2495 struct sk_buff
*skb
)
2497 struct devlink_resource_size_params
*size_params
;
2499 size_params
= &resource
->size_params
;
2500 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_GRAN
,
2501 size_params
->size_granularity
, DEVLINK_ATTR_PAD
) ||
2502 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_MAX
,
2503 size_params
->size_max
, DEVLINK_ATTR_PAD
) ||
2504 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_MIN
,
2505 size_params
->size_min
, DEVLINK_ATTR_PAD
) ||
2506 nla_put_u8(skb
, DEVLINK_ATTR_RESOURCE_UNIT
, size_params
->unit
))
2511 static int devlink_resource_occ_put(struct devlink_resource
*resource
,
2512 struct sk_buff
*skb
)
2514 if (!resource
->occ_get
)
2516 return nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_OCC
,
2517 resource
->occ_get(resource
->occ_get_priv
),
2521 static int devlink_resource_put(struct devlink
*devlink
, struct sk_buff
*skb
,
2522 struct devlink_resource
*resource
)
2524 struct devlink_resource
*child_resource
;
2525 struct nlattr
*child_resource_attr
;
2526 struct nlattr
*resource_attr
;
2528 resource_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_RESOURCE
);
2532 if (nla_put_string(skb
, DEVLINK_ATTR_RESOURCE_NAME
, resource
->name
) ||
2533 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE
, resource
->size
,
2534 DEVLINK_ATTR_PAD
) ||
2535 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_ID
, resource
->id
,
2537 goto nla_put_failure
;
2538 if (resource
->size
!= resource
->size_new
)
2539 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_NEW
,
2540 resource
->size_new
, DEVLINK_ATTR_PAD
);
2541 if (devlink_resource_occ_put(resource
, skb
))
2542 goto nla_put_failure
;
2543 if (devlink_resource_size_params_put(resource
, skb
))
2544 goto nla_put_failure
;
2545 if (list_empty(&resource
->resource_list
))
2548 if (nla_put_u8(skb
, DEVLINK_ATTR_RESOURCE_SIZE_VALID
,
2549 resource
->size_valid
))
2550 goto nla_put_failure
;
2552 child_resource_attr
= nla_nest_start_noflag(skb
,
2553 DEVLINK_ATTR_RESOURCE_LIST
);
2554 if (!child_resource_attr
)
2555 goto nla_put_failure
;
2557 list_for_each_entry(child_resource
, &resource
->resource_list
, list
) {
2558 if (devlink_resource_put(devlink
, skb
, child_resource
))
2559 goto resource_put_failure
;
2562 nla_nest_end(skb
, child_resource_attr
);
2564 nla_nest_end(skb
, resource_attr
);
2567 resource_put_failure
:
2568 nla_nest_cancel(skb
, child_resource_attr
);
2570 nla_nest_cancel(skb
, resource_attr
);
2574 static int devlink_resource_fill(struct genl_info
*info
,
2575 enum devlink_command cmd
, int flags
)
2577 struct devlink
*devlink
= info
->user_ptr
[0];
2578 struct devlink_resource
*resource
;
2579 struct nlattr
*resources_attr
;
2580 struct sk_buff
*skb
= NULL
;
2581 struct nlmsghdr
*nlh
;
2587 resource
= list_first_entry(&devlink
->resource_list
,
2588 struct devlink_resource
, list
);
2590 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2594 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2595 &devlink_nl_family
, NLM_F_MULTI
, cmd
);
2601 if (devlink_nl_put_handle(skb
, devlink
))
2602 goto nla_put_failure
;
2604 resources_attr
= nla_nest_start_noflag(skb
,
2605 DEVLINK_ATTR_RESOURCE_LIST
);
2606 if (!resources_attr
)
2607 goto nla_put_failure
;
2611 list_for_each_entry_from(resource
, &devlink
->resource_list
, list
) {
2612 err
= devlink_resource_put(devlink
, skb
, resource
);
2615 goto err_resource_put
;
2621 nla_nest_end(skb
, resources_attr
);
2622 genlmsg_end(skb
, hdr
);
2626 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2627 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
2629 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2634 return genlmsg_reply(skb
, info
);
2643 static int devlink_nl_cmd_resource_dump(struct sk_buff
*skb
,
2644 struct genl_info
*info
)
2646 struct devlink
*devlink
= info
->user_ptr
[0];
2648 if (list_empty(&devlink
->resource_list
))
2651 return devlink_resource_fill(info
, DEVLINK_CMD_RESOURCE_DUMP
, 0);
2655 devlink_resources_validate(struct devlink
*devlink
,
2656 struct devlink_resource
*resource
,
2657 struct genl_info
*info
)
2659 struct list_head
*resource_list
;
2663 resource_list
= &resource
->resource_list
;
2665 resource_list
= &devlink
->resource_list
;
2667 list_for_each_entry(resource
, resource_list
, list
) {
2668 if (!resource
->size_valid
)
2670 err
= devlink_resources_validate(devlink
, resource
, info
);
2677 static bool devlink_reload_supported(struct devlink
*devlink
)
2679 return devlink
->ops
->reload_down
&& devlink
->ops
->reload_up
;
2682 static void devlink_reload_failed_set(struct devlink
*devlink
,
2685 if (devlink
->reload_failed
== reload_failed
)
2687 devlink
->reload_failed
= reload_failed
;
2688 devlink_notify(devlink
, DEVLINK_CMD_NEW
);
2691 bool devlink_is_reload_failed(const struct devlink
*devlink
)
2693 return devlink
->reload_failed
;
2695 EXPORT_SYMBOL_GPL(devlink_is_reload_failed
);
2697 static int devlink_nl_cmd_reload(struct sk_buff
*skb
, struct genl_info
*info
)
2699 struct devlink
*devlink
= info
->user_ptr
[0];
2702 if (!devlink_reload_supported(devlink
) || !devlink
->reload_enabled
)
2705 err
= devlink_resources_validate(devlink
, NULL
, info
);
2707 NL_SET_ERR_MSG_MOD(info
->extack
, "resources size validation failed");
2710 err
= devlink
->ops
->reload_down(devlink
, info
->extack
);
2713 err
= devlink
->ops
->reload_up(devlink
, info
->extack
);
2714 devlink_reload_failed_set(devlink
, !!err
);
2718 static int devlink_nl_flash_update_fill(struct sk_buff
*msg
,
2719 struct devlink
*devlink
,
2720 enum devlink_command cmd
,
2721 const char *status_msg
,
2722 const char *component
,
2723 unsigned long done
, unsigned long total
)
2727 hdr
= genlmsg_put(msg
, 0, 0, &devlink_nl_family
, 0, cmd
);
2731 if (devlink_nl_put_handle(msg
, devlink
))
2732 goto nla_put_failure
;
2734 if (cmd
!= DEVLINK_CMD_FLASH_UPDATE_STATUS
)
2738 nla_put_string(msg
, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG
,
2740 goto nla_put_failure
;
2742 nla_put_string(msg
, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT
,
2744 goto nla_put_failure
;
2745 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE
,
2746 done
, DEVLINK_ATTR_PAD
))
2747 goto nla_put_failure
;
2748 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL
,
2749 total
, DEVLINK_ATTR_PAD
))
2750 goto nla_put_failure
;
2753 genlmsg_end(msg
, hdr
);
2757 genlmsg_cancel(msg
, hdr
);
2761 static void __devlink_flash_update_notify(struct devlink
*devlink
,
2762 enum devlink_command cmd
,
2763 const char *status_msg
,
2764 const char *component
,
2766 unsigned long total
)
2768 struct sk_buff
*msg
;
2771 WARN_ON(cmd
!= DEVLINK_CMD_FLASH_UPDATE
&&
2772 cmd
!= DEVLINK_CMD_FLASH_UPDATE_END
&&
2773 cmd
!= DEVLINK_CMD_FLASH_UPDATE_STATUS
);
2775 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
2779 err
= devlink_nl_flash_update_fill(msg
, devlink
, cmd
, status_msg
,
2780 component
, done
, total
);
2784 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
2785 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
2792 void devlink_flash_update_begin_notify(struct devlink
*devlink
)
2794 __devlink_flash_update_notify(devlink
,
2795 DEVLINK_CMD_FLASH_UPDATE
,
2798 EXPORT_SYMBOL_GPL(devlink_flash_update_begin_notify
);
2800 void devlink_flash_update_end_notify(struct devlink
*devlink
)
2802 __devlink_flash_update_notify(devlink
,
2803 DEVLINK_CMD_FLASH_UPDATE_END
,
2806 EXPORT_SYMBOL_GPL(devlink_flash_update_end_notify
);
2808 void devlink_flash_update_status_notify(struct devlink
*devlink
,
2809 const char *status_msg
,
2810 const char *component
,
2812 unsigned long total
)
2814 __devlink_flash_update_notify(devlink
,
2815 DEVLINK_CMD_FLASH_UPDATE_STATUS
,
2816 status_msg
, component
, done
, total
);
2818 EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify
);
2820 static int devlink_nl_cmd_flash_update(struct sk_buff
*skb
,
2821 struct genl_info
*info
)
2823 struct devlink
*devlink
= info
->user_ptr
[0];
2824 const char *file_name
, *component
;
2825 struct nlattr
*nla_component
;
2827 if (!devlink
->ops
->flash_update
)
2830 if (!info
->attrs
[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME
])
2832 file_name
= nla_data(info
->attrs
[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME
]);
2834 nla_component
= info
->attrs
[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT
];
2835 component
= nla_component
? nla_data(nla_component
) : NULL
;
2837 return devlink
->ops
->flash_update(devlink
, file_name
, component
,
2841 static const struct devlink_param devlink_param_generic
[] = {
2843 .id
= DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET
,
2844 .name
= DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME
,
2845 .type
= DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE
,
2848 .id
= DEVLINK_PARAM_GENERIC_ID_MAX_MACS
,
2849 .name
= DEVLINK_PARAM_GENERIC_MAX_MACS_NAME
,
2850 .type
= DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE
,
2853 .id
= DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV
,
2854 .name
= DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME
,
2855 .type
= DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE
,
2858 .id
= DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT
,
2859 .name
= DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME
,
2860 .type
= DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE
,
2863 .id
= DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI
,
2864 .name
= DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME
,
2865 .type
= DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE
,
2868 .id
= DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX
,
2869 .name
= DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME
,
2870 .type
= DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE
,
2873 .id
= DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN
,
2874 .name
= DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME
,
2875 .type
= DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE
,
2878 .id
= DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY
,
2879 .name
= DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME
,
2880 .type
= DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE
,
2883 .id
= DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE
,
2884 .name
= DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME
,
2885 .type
= DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE
,
2889 static int devlink_param_generic_verify(const struct devlink_param
*param
)
2891 /* verify it match generic parameter by id and name */
2892 if (param
->id
> DEVLINK_PARAM_GENERIC_ID_MAX
)
2894 if (strcmp(param
->name
, devlink_param_generic
[param
->id
].name
))
2897 WARN_ON(param
->type
!= devlink_param_generic
[param
->id
].type
);
2902 static int devlink_param_driver_verify(const struct devlink_param
*param
)
2906 if (param
->id
<= DEVLINK_PARAM_GENERIC_ID_MAX
)
2908 /* verify no such name in generic params */
2909 for (i
= 0; i
<= DEVLINK_PARAM_GENERIC_ID_MAX
; i
++)
2910 if (!strcmp(param
->name
, devlink_param_generic
[i
].name
))
2916 static struct devlink_param_item
*
2917 devlink_param_find_by_name(struct list_head
*param_list
,
2918 const char *param_name
)
2920 struct devlink_param_item
*param_item
;
2922 list_for_each_entry(param_item
, param_list
, list
)
2923 if (!strcmp(param_item
->param
->name
, param_name
))
2928 static struct devlink_param_item
*
2929 devlink_param_find_by_id(struct list_head
*param_list
, u32 param_id
)
2931 struct devlink_param_item
*param_item
;
2933 list_for_each_entry(param_item
, param_list
, list
)
2934 if (param_item
->param
->id
== param_id
)
2940 devlink_param_cmode_is_supported(const struct devlink_param
*param
,
2941 enum devlink_param_cmode cmode
)
2943 return test_bit(cmode
, ¶m
->supported_cmodes
);
2946 static int devlink_param_get(struct devlink
*devlink
,
2947 const struct devlink_param
*param
,
2948 struct devlink_param_gset_ctx
*ctx
)
2952 return param
->get(devlink
, param
->id
, ctx
);
2955 static int devlink_param_set(struct devlink
*devlink
,
2956 const struct devlink_param
*param
,
2957 struct devlink_param_gset_ctx
*ctx
)
2961 return param
->set(devlink
, param
->id
, ctx
);
2965 devlink_param_type_to_nla_type(enum devlink_param_type param_type
)
2967 switch (param_type
) {
2968 case DEVLINK_PARAM_TYPE_U8
:
2970 case DEVLINK_PARAM_TYPE_U16
:
2972 case DEVLINK_PARAM_TYPE_U32
:
2974 case DEVLINK_PARAM_TYPE_STRING
:
2976 case DEVLINK_PARAM_TYPE_BOOL
:
2984 devlink_nl_param_value_fill_one(struct sk_buff
*msg
,
2985 enum devlink_param_type type
,
2986 enum devlink_param_cmode cmode
,
2987 union devlink_param_value val
)
2989 struct nlattr
*param_value_attr
;
2991 param_value_attr
= nla_nest_start_noflag(msg
,
2992 DEVLINK_ATTR_PARAM_VALUE
);
2993 if (!param_value_attr
)
2994 goto nla_put_failure
;
2996 if (nla_put_u8(msg
, DEVLINK_ATTR_PARAM_VALUE_CMODE
, cmode
))
2997 goto value_nest_cancel
;
3000 case DEVLINK_PARAM_TYPE_U8
:
3001 if (nla_put_u8(msg
, DEVLINK_ATTR_PARAM_VALUE_DATA
, val
.vu8
))
3002 goto value_nest_cancel
;
3004 case DEVLINK_PARAM_TYPE_U16
:
3005 if (nla_put_u16(msg
, DEVLINK_ATTR_PARAM_VALUE_DATA
, val
.vu16
))
3006 goto value_nest_cancel
;
3008 case DEVLINK_PARAM_TYPE_U32
:
3009 if (nla_put_u32(msg
, DEVLINK_ATTR_PARAM_VALUE_DATA
, val
.vu32
))
3010 goto value_nest_cancel
;
3012 case DEVLINK_PARAM_TYPE_STRING
:
3013 if (nla_put_string(msg
, DEVLINK_ATTR_PARAM_VALUE_DATA
,
3015 goto value_nest_cancel
;
3017 case DEVLINK_PARAM_TYPE_BOOL
:
3019 nla_put_flag(msg
, DEVLINK_ATTR_PARAM_VALUE_DATA
))
3020 goto value_nest_cancel
;
3024 nla_nest_end(msg
, param_value_attr
);
3028 nla_nest_cancel(msg
, param_value_attr
);
3033 static int devlink_nl_param_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
3034 unsigned int port_index
,
3035 struct devlink_param_item
*param_item
,
3036 enum devlink_command cmd
,
3037 u32 portid
, u32 seq
, int flags
)
3039 union devlink_param_value param_value
[DEVLINK_PARAM_CMODE_MAX
+ 1];
3040 bool param_value_set
[DEVLINK_PARAM_CMODE_MAX
+ 1] = {};
3041 const struct devlink_param
*param
= param_item
->param
;
3042 struct devlink_param_gset_ctx ctx
;
3043 struct nlattr
*param_values_list
;
3044 struct nlattr
*param_attr
;
3050 /* Get value from driver part to driverinit configuration mode */
3051 for (i
= 0; i
<= DEVLINK_PARAM_CMODE_MAX
; i
++) {
3052 if (!devlink_param_cmode_is_supported(param
, i
))
3054 if (i
== DEVLINK_PARAM_CMODE_DRIVERINIT
) {
3055 if (!param_item
->driverinit_value_valid
)
3057 param_value
[i
] = param_item
->driverinit_value
;
3059 if (!param_item
->published
)
3062 err
= devlink_param_get(devlink
, param
, &ctx
);
3065 param_value
[i
] = ctx
.val
;
3067 param_value_set
[i
] = true;
3070 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
3074 if (devlink_nl_put_handle(msg
, devlink
))
3075 goto genlmsg_cancel
;
3077 if (cmd
== DEVLINK_CMD_PORT_PARAM_GET
||
3078 cmd
== DEVLINK_CMD_PORT_PARAM_NEW
||
3079 cmd
== DEVLINK_CMD_PORT_PARAM_DEL
)
3080 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, port_index
))
3081 goto genlmsg_cancel
;
3083 param_attr
= nla_nest_start_noflag(msg
, DEVLINK_ATTR_PARAM
);
3085 goto genlmsg_cancel
;
3086 if (nla_put_string(msg
, DEVLINK_ATTR_PARAM_NAME
, param
->name
))
3087 goto param_nest_cancel
;
3088 if (param
->generic
&& nla_put_flag(msg
, DEVLINK_ATTR_PARAM_GENERIC
))
3089 goto param_nest_cancel
;
3091 nla_type
= devlink_param_type_to_nla_type(param
->type
);
3093 goto param_nest_cancel
;
3094 if (nla_put_u8(msg
, DEVLINK_ATTR_PARAM_TYPE
, nla_type
))
3095 goto param_nest_cancel
;
3097 param_values_list
= nla_nest_start_noflag(msg
,
3098 DEVLINK_ATTR_PARAM_VALUES_LIST
);
3099 if (!param_values_list
)
3100 goto param_nest_cancel
;
3102 for (i
= 0; i
<= DEVLINK_PARAM_CMODE_MAX
; i
++) {
3103 if (!param_value_set
[i
])
3105 err
= devlink_nl_param_value_fill_one(msg
, param
->type
,
3108 goto values_list_nest_cancel
;
3111 nla_nest_end(msg
, param_values_list
);
3112 nla_nest_end(msg
, param_attr
);
3113 genlmsg_end(msg
, hdr
);
3116 values_list_nest_cancel
:
3117 nla_nest_end(msg
, param_values_list
);
3119 nla_nest_cancel(msg
, param_attr
);
3121 genlmsg_cancel(msg
, hdr
);
3125 static void devlink_param_notify(struct devlink
*devlink
,
3126 unsigned int port_index
,
3127 struct devlink_param_item
*param_item
,
3128 enum devlink_command cmd
)
3130 struct sk_buff
*msg
;
3133 WARN_ON(cmd
!= DEVLINK_CMD_PARAM_NEW
&& cmd
!= DEVLINK_CMD_PARAM_DEL
&&
3134 cmd
!= DEVLINK_CMD_PORT_PARAM_NEW
&&
3135 cmd
!= DEVLINK_CMD_PORT_PARAM_DEL
);
3137 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
3140 err
= devlink_nl_param_fill(msg
, devlink
, port_index
, param_item
, cmd
,
3147 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
3148 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
3151 static int devlink_nl_cmd_param_get_dumpit(struct sk_buff
*msg
,
3152 struct netlink_callback
*cb
)
3154 struct devlink_param_item
*param_item
;
3155 struct devlink
*devlink
;
3156 int start
= cb
->args
[0];
3160 mutex_lock(&devlink_mutex
);
3161 list_for_each_entry(devlink
, &devlink_list
, list
) {
3162 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
3164 mutex_lock(&devlink
->lock
);
3165 list_for_each_entry(param_item
, &devlink
->param_list
, list
) {
3170 err
= devlink_nl_param_fill(msg
, devlink
, 0, param_item
,
3171 DEVLINK_CMD_PARAM_GET
,
3172 NETLINK_CB(cb
->skb
).portid
,
3175 if (err
&& err
!= -EOPNOTSUPP
) {
3176 mutex_unlock(&devlink
->lock
);
3181 mutex_unlock(&devlink
->lock
);
3184 mutex_unlock(&devlink_mutex
);
3191 devlink_param_type_get_from_info(struct genl_info
*info
,
3192 enum devlink_param_type
*param_type
)
3194 if (!info
->attrs
[DEVLINK_ATTR_PARAM_TYPE
])
3197 switch (nla_get_u8(info
->attrs
[DEVLINK_ATTR_PARAM_TYPE
])) {
3199 *param_type
= DEVLINK_PARAM_TYPE_U8
;
3202 *param_type
= DEVLINK_PARAM_TYPE_U16
;
3205 *param_type
= DEVLINK_PARAM_TYPE_U32
;
3208 *param_type
= DEVLINK_PARAM_TYPE_STRING
;
3211 *param_type
= DEVLINK_PARAM_TYPE_BOOL
;
3221 devlink_param_value_get_from_info(const struct devlink_param
*param
,
3222 struct genl_info
*info
,
3223 union devlink_param_value
*value
)
3225 struct nlattr
*param_data
;
3228 param_data
= info
->attrs
[DEVLINK_ATTR_PARAM_VALUE_DATA
];
3230 if (param
->type
!= DEVLINK_PARAM_TYPE_BOOL
&& !param_data
)
3233 switch (param
->type
) {
3234 case DEVLINK_PARAM_TYPE_U8
:
3235 if (nla_len(param_data
) != sizeof(u8
))
3237 value
->vu8
= nla_get_u8(param_data
);
3239 case DEVLINK_PARAM_TYPE_U16
:
3240 if (nla_len(param_data
) != sizeof(u16
))
3242 value
->vu16
= nla_get_u16(param_data
);
3244 case DEVLINK_PARAM_TYPE_U32
:
3245 if (nla_len(param_data
) != sizeof(u32
))
3247 value
->vu32
= nla_get_u32(param_data
);
3249 case DEVLINK_PARAM_TYPE_STRING
:
3250 len
= strnlen(nla_data(param_data
), nla_len(param_data
));
3251 if (len
== nla_len(param_data
) ||
3252 len
>= __DEVLINK_PARAM_MAX_STRING_VALUE
)
3254 strcpy(value
->vstr
, nla_data(param_data
));
3256 case DEVLINK_PARAM_TYPE_BOOL
:
3257 if (param_data
&& nla_len(param_data
))
3259 value
->vbool
= nla_get_flag(param_data
);
3265 static struct devlink_param_item
*
3266 devlink_param_get_from_info(struct list_head
*param_list
,
3267 struct genl_info
*info
)
3271 if (!info
->attrs
[DEVLINK_ATTR_PARAM_NAME
])
3274 param_name
= nla_data(info
->attrs
[DEVLINK_ATTR_PARAM_NAME
]);
3275 return devlink_param_find_by_name(param_list
, param_name
);
3278 static int devlink_nl_cmd_param_get_doit(struct sk_buff
*skb
,
3279 struct genl_info
*info
)
3281 struct devlink
*devlink
= info
->user_ptr
[0];
3282 struct devlink_param_item
*param_item
;
3283 struct sk_buff
*msg
;
3286 param_item
= devlink_param_get_from_info(&devlink
->param_list
, info
);
3290 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
3294 err
= devlink_nl_param_fill(msg
, devlink
, 0, param_item
,
3295 DEVLINK_CMD_PARAM_GET
,
3296 info
->snd_portid
, info
->snd_seq
, 0);
3302 return genlmsg_reply(msg
, info
);
3305 static int __devlink_nl_cmd_param_set_doit(struct devlink
*devlink
,
3306 unsigned int port_index
,
3307 struct list_head
*param_list
,
3308 struct genl_info
*info
,
3309 enum devlink_command cmd
)
3311 enum devlink_param_type param_type
;
3312 struct devlink_param_gset_ctx ctx
;
3313 enum devlink_param_cmode cmode
;
3314 struct devlink_param_item
*param_item
;
3315 const struct devlink_param
*param
;
3316 union devlink_param_value value
;
3319 param_item
= devlink_param_get_from_info(param_list
, info
);
3322 param
= param_item
->param
;
3323 err
= devlink_param_type_get_from_info(info
, ¶m_type
);
3326 if (param_type
!= param
->type
)
3328 err
= devlink_param_value_get_from_info(param
, info
, &value
);
3331 if (param
->validate
) {
3332 err
= param
->validate(devlink
, param
->id
, value
, info
->extack
);
3337 if (!info
->attrs
[DEVLINK_ATTR_PARAM_VALUE_CMODE
])
3339 cmode
= nla_get_u8(info
->attrs
[DEVLINK_ATTR_PARAM_VALUE_CMODE
]);
3340 if (!devlink_param_cmode_is_supported(param
, cmode
))
3343 if (cmode
== DEVLINK_PARAM_CMODE_DRIVERINIT
) {
3344 if (param
->type
== DEVLINK_PARAM_TYPE_STRING
)
3345 strcpy(param_item
->driverinit_value
.vstr
, value
.vstr
);
3347 param_item
->driverinit_value
= value
;
3348 param_item
->driverinit_value_valid
= true;
3354 err
= devlink_param_set(devlink
, param
, &ctx
);
3359 devlink_param_notify(devlink
, port_index
, param_item
, cmd
);
3363 static int devlink_nl_cmd_param_set_doit(struct sk_buff
*skb
,
3364 struct genl_info
*info
)
3366 struct devlink
*devlink
= info
->user_ptr
[0];
3368 return __devlink_nl_cmd_param_set_doit(devlink
, 0, &devlink
->param_list
,
3369 info
, DEVLINK_CMD_PARAM_NEW
);
3372 static int devlink_param_register_one(struct devlink
*devlink
,
3373 unsigned int port_index
,
3374 struct list_head
*param_list
,
3375 const struct devlink_param
*param
,
3376 enum devlink_command cmd
)
3378 struct devlink_param_item
*param_item
;
3380 if (devlink_param_find_by_name(param_list
, param
->name
))
3383 if (param
->supported_cmodes
== BIT(DEVLINK_PARAM_CMODE_DRIVERINIT
))
3384 WARN_ON(param
->get
|| param
->set
);
3386 WARN_ON(!param
->get
|| !param
->set
);
3388 param_item
= kzalloc(sizeof(*param_item
), GFP_KERNEL
);
3391 param_item
->param
= param
;
3393 list_add_tail(¶m_item
->list
, param_list
);
3394 devlink_param_notify(devlink
, port_index
, param_item
, cmd
);
3398 static void devlink_param_unregister_one(struct devlink
*devlink
,
3399 unsigned int port_index
,
3400 struct list_head
*param_list
,
3401 const struct devlink_param
*param
,
3402 enum devlink_command cmd
)
3404 struct devlink_param_item
*param_item
;
3406 param_item
= devlink_param_find_by_name(param_list
, param
->name
);
3407 WARN_ON(!param_item
);
3408 devlink_param_notify(devlink
, port_index
, param_item
, cmd
);
3409 list_del(¶m_item
->list
);
3413 static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff
*msg
,
3414 struct netlink_callback
*cb
)
3416 struct devlink_param_item
*param_item
;
3417 struct devlink_port
*devlink_port
;
3418 struct devlink
*devlink
;
3419 int start
= cb
->args
[0];
3423 mutex_lock(&devlink_mutex
);
3424 list_for_each_entry(devlink
, &devlink_list
, list
) {
3425 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
3427 mutex_lock(&devlink
->lock
);
3428 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
3429 list_for_each_entry(param_item
,
3430 &devlink_port
->param_list
, list
) {
3435 err
= devlink_nl_param_fill(msg
,
3436 devlink_port
->devlink
,
3437 devlink_port
->index
, param_item
,
3438 DEVLINK_CMD_PORT_PARAM_GET
,
3439 NETLINK_CB(cb
->skb
).portid
,
3442 if (err
&& err
!= -EOPNOTSUPP
) {
3443 mutex_unlock(&devlink
->lock
);
3449 mutex_unlock(&devlink
->lock
);
3452 mutex_unlock(&devlink_mutex
);
3458 static int devlink_nl_cmd_port_param_get_doit(struct sk_buff
*skb
,
3459 struct genl_info
*info
)
3461 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
3462 struct devlink_param_item
*param_item
;
3463 struct sk_buff
*msg
;
3466 param_item
= devlink_param_get_from_info(&devlink_port
->param_list
,
3471 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
3475 err
= devlink_nl_param_fill(msg
, devlink_port
->devlink
,
3476 devlink_port
->index
, param_item
,
3477 DEVLINK_CMD_PORT_PARAM_GET
,
3478 info
->snd_portid
, info
->snd_seq
, 0);
3484 return genlmsg_reply(msg
, info
);
3487 static int devlink_nl_cmd_port_param_set_doit(struct sk_buff
*skb
,
3488 struct genl_info
*info
)
3490 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
3492 return __devlink_nl_cmd_param_set_doit(devlink_port
->devlink
,
3493 devlink_port
->index
,
3494 &devlink_port
->param_list
, info
,
3495 DEVLINK_CMD_PORT_PARAM_NEW
);
3498 static int devlink_nl_region_snapshot_id_put(struct sk_buff
*msg
,
3499 struct devlink
*devlink
,
3500 struct devlink_snapshot
*snapshot
)
3502 struct nlattr
*snap_attr
;
3505 snap_attr
= nla_nest_start_noflag(msg
, DEVLINK_ATTR_REGION_SNAPSHOT
);
3509 err
= nla_put_u32(msg
, DEVLINK_ATTR_REGION_SNAPSHOT_ID
, snapshot
->id
);
3511 goto nla_put_failure
;
3513 nla_nest_end(msg
, snap_attr
);
3517 nla_nest_cancel(msg
, snap_attr
);
3521 static int devlink_nl_region_snapshots_id_put(struct sk_buff
*msg
,
3522 struct devlink
*devlink
,
3523 struct devlink_region
*region
)
3525 struct devlink_snapshot
*snapshot
;
3526 struct nlattr
*snapshots_attr
;
3529 snapshots_attr
= nla_nest_start_noflag(msg
,
3530 DEVLINK_ATTR_REGION_SNAPSHOTS
);
3531 if (!snapshots_attr
)
3534 list_for_each_entry(snapshot
, ®ion
->snapshot_list
, list
) {
3535 err
= devlink_nl_region_snapshot_id_put(msg
, devlink
, snapshot
);
3537 goto nla_put_failure
;
3540 nla_nest_end(msg
, snapshots_attr
);
3544 nla_nest_cancel(msg
, snapshots_attr
);
3548 static int devlink_nl_region_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
3549 enum devlink_command cmd
, u32 portid
,
3551 struct devlink_region
*region
)
3556 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
3560 err
= devlink_nl_put_handle(msg
, devlink
);
3562 goto nla_put_failure
;
3564 err
= nla_put_string(msg
, DEVLINK_ATTR_REGION_NAME
, region
->name
);
3566 goto nla_put_failure
;
3568 err
= nla_put_u64_64bit(msg
, DEVLINK_ATTR_REGION_SIZE
,
3572 goto nla_put_failure
;
3574 err
= devlink_nl_region_snapshots_id_put(msg
, devlink
, region
);
3576 goto nla_put_failure
;
3578 genlmsg_end(msg
, hdr
);
3582 genlmsg_cancel(msg
, hdr
);
3586 static void devlink_nl_region_notify(struct devlink_region
*region
,
3587 struct devlink_snapshot
*snapshot
,
3588 enum devlink_command cmd
)
3590 struct devlink
*devlink
= region
->devlink
;
3591 struct sk_buff
*msg
;
3595 WARN_ON(cmd
!= DEVLINK_CMD_REGION_NEW
&& cmd
!= DEVLINK_CMD_REGION_DEL
);
3597 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
3601 hdr
= genlmsg_put(msg
, 0, 0, &devlink_nl_family
, 0, cmd
);
3605 err
= devlink_nl_put_handle(msg
, devlink
);
3607 goto out_cancel_msg
;
3609 err
= nla_put_string(msg
, DEVLINK_ATTR_REGION_NAME
,
3612 goto out_cancel_msg
;
3615 err
= nla_put_u32(msg
, DEVLINK_ATTR_REGION_SNAPSHOT_ID
,
3618 goto out_cancel_msg
;
3620 err
= nla_put_u64_64bit(msg
, DEVLINK_ATTR_REGION_SIZE
,
3621 region
->size
, DEVLINK_ATTR_PAD
);
3623 goto out_cancel_msg
;
3625 genlmsg_end(msg
, hdr
);
3627 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
3628 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
3633 genlmsg_cancel(msg
, hdr
);
3638 static void devlink_region_snapshot_del(struct devlink_region
*region
,
3639 struct devlink_snapshot
*snapshot
)
3641 devlink_nl_region_notify(region
, snapshot
, DEVLINK_CMD_REGION_DEL
);
3642 region
->cur_snapshots
--;
3643 list_del(&snapshot
->list
);
3644 (*snapshot
->data_destructor
)(snapshot
->data
);
3648 static int devlink_nl_cmd_region_get_doit(struct sk_buff
*skb
,
3649 struct genl_info
*info
)
3651 struct devlink
*devlink
= info
->user_ptr
[0];
3652 struct devlink_region
*region
;
3653 const char *region_name
;
3654 struct sk_buff
*msg
;
3657 if (!info
->attrs
[DEVLINK_ATTR_REGION_NAME
])
3660 region_name
= nla_data(info
->attrs
[DEVLINK_ATTR_REGION_NAME
]);
3661 region
= devlink_region_get_by_name(devlink
, region_name
);
3665 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
3669 err
= devlink_nl_region_fill(msg
, devlink
, DEVLINK_CMD_REGION_GET
,
3670 info
->snd_portid
, info
->snd_seq
, 0,
3677 return genlmsg_reply(msg
, info
);
3680 static int devlink_nl_cmd_region_get_dumpit(struct sk_buff
*msg
,
3681 struct netlink_callback
*cb
)
3683 struct devlink_region
*region
;
3684 struct devlink
*devlink
;
3685 int start
= cb
->args
[0];
3689 mutex_lock(&devlink_mutex
);
3690 list_for_each_entry(devlink
, &devlink_list
, list
) {
3691 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
3694 mutex_lock(&devlink
->lock
);
3695 list_for_each_entry(region
, &devlink
->region_list
, list
) {
3700 err
= devlink_nl_region_fill(msg
, devlink
,
3701 DEVLINK_CMD_REGION_GET
,
3702 NETLINK_CB(cb
->skb
).portid
,
3704 NLM_F_MULTI
, region
);
3706 mutex_unlock(&devlink
->lock
);
3711 mutex_unlock(&devlink
->lock
);
3714 mutex_unlock(&devlink_mutex
);
3719 static int devlink_nl_cmd_region_del(struct sk_buff
*skb
,
3720 struct genl_info
*info
)
3722 struct devlink
*devlink
= info
->user_ptr
[0];
3723 struct devlink_snapshot
*snapshot
;
3724 struct devlink_region
*region
;
3725 const char *region_name
;
3728 if (!info
->attrs
[DEVLINK_ATTR_REGION_NAME
] ||
3729 !info
->attrs
[DEVLINK_ATTR_REGION_SNAPSHOT_ID
])
3732 region_name
= nla_data(info
->attrs
[DEVLINK_ATTR_REGION_NAME
]);
3733 snapshot_id
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_REGION_SNAPSHOT_ID
]);
3735 region
= devlink_region_get_by_name(devlink
, region_name
);
3739 snapshot
= devlink_region_snapshot_get_by_id(region
, snapshot_id
);
3743 devlink_region_snapshot_del(region
, snapshot
);
3747 static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff
*msg
,
3748 struct devlink
*devlink
,
3749 u8
*chunk
, u32 chunk_size
,
3752 struct nlattr
*chunk_attr
;
3755 chunk_attr
= nla_nest_start_noflag(msg
, DEVLINK_ATTR_REGION_CHUNK
);
3759 err
= nla_put(msg
, DEVLINK_ATTR_REGION_CHUNK_DATA
, chunk_size
, chunk
);
3761 goto nla_put_failure
;
3763 err
= nla_put_u64_64bit(msg
, DEVLINK_ATTR_REGION_CHUNK_ADDR
, addr
,
3766 goto nla_put_failure
;
3768 nla_nest_end(msg
, chunk_attr
);
3772 nla_nest_cancel(msg
, chunk_attr
);
3776 #define DEVLINK_REGION_READ_CHUNK_SIZE 256
3778 static int devlink_nl_region_read_snapshot_fill(struct sk_buff
*skb
,
3779 struct devlink
*devlink
,
3780 struct devlink_region
*region
,
3781 struct nlattr
**attrs
,
3787 struct devlink_snapshot
*snapshot
;
3788 u64 curr_offset
= start_offset
;
3792 *new_offset
= start_offset
;
3794 snapshot_id
= nla_get_u32(attrs
[DEVLINK_ATTR_REGION_SNAPSHOT_ID
]);
3795 snapshot
= devlink_region_snapshot_get_by_id(region
, snapshot_id
);
3799 if (end_offset
> region
->size
|| dump
)
3800 end_offset
= region
->size
;
3802 while (curr_offset
< end_offset
) {
3806 if (end_offset
- curr_offset
< DEVLINK_REGION_READ_CHUNK_SIZE
)
3807 data_size
= end_offset
- curr_offset
;
3809 data_size
= DEVLINK_REGION_READ_CHUNK_SIZE
;
3811 data
= &snapshot
->data
[curr_offset
];
3812 err
= devlink_nl_cmd_region_read_chunk_fill(skb
, devlink
,
3818 curr_offset
+= data_size
;
3820 *new_offset
= curr_offset
;
3825 static int devlink_nl_cmd_region_read_dumpit(struct sk_buff
*skb
,
3826 struct netlink_callback
*cb
)
3828 u64 ret_offset
, start_offset
, end_offset
= 0;
3829 struct devlink_region
*region
;
3830 struct nlattr
*chunks_attr
;
3831 const char *region_name
;
3832 struct devlink
*devlink
;
3833 struct nlattr
**attrs
;
3838 start_offset
= *((u64
*)&cb
->args
[0]);
3840 attrs
= kmalloc_array(DEVLINK_ATTR_MAX
+ 1, sizeof(*attrs
), GFP_KERNEL
);
3844 err
= nlmsg_parse_deprecated(cb
->nlh
,
3845 GENL_HDRLEN
+ devlink_nl_family
.hdrsize
,
3846 attrs
, DEVLINK_ATTR_MAX
,
3847 devlink_nl_family
.policy
, cb
->extack
);
3851 mutex_lock(&devlink_mutex
);
3852 devlink
= devlink_get_from_attrs(sock_net(cb
->skb
->sk
), attrs
);
3853 if (IS_ERR(devlink
)) {
3854 err
= PTR_ERR(devlink
);
3858 mutex_lock(&devlink
->lock
);
3860 if (!attrs
[DEVLINK_ATTR_REGION_NAME
] ||
3861 !attrs
[DEVLINK_ATTR_REGION_SNAPSHOT_ID
]) {
3866 region_name
= nla_data(attrs
[DEVLINK_ATTR_REGION_NAME
]);
3867 region
= devlink_region_get_by_name(devlink
, region_name
);
3873 /* return 0 if there is no further data to read */
3874 if (start_offset
>= region
->size
) {
3879 hdr
= genlmsg_put(skb
, NETLINK_CB(cb
->skb
).portid
, cb
->nlh
->nlmsg_seq
,
3880 &devlink_nl_family
, NLM_F_ACK
| NLM_F_MULTI
,
3881 DEVLINK_CMD_REGION_READ
);
3887 err
= devlink_nl_put_handle(skb
, devlink
);
3889 goto nla_put_failure
;
3891 err
= nla_put_string(skb
, DEVLINK_ATTR_REGION_NAME
, region_name
);
3893 goto nla_put_failure
;
3895 chunks_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_REGION_CHUNKS
);
3898 goto nla_put_failure
;
3901 if (attrs
[DEVLINK_ATTR_REGION_CHUNK_ADDR
] &&
3902 attrs
[DEVLINK_ATTR_REGION_CHUNK_LEN
]) {
3905 nla_get_u64(attrs
[DEVLINK_ATTR_REGION_CHUNK_ADDR
]);
3907 end_offset
= nla_get_u64(attrs
[DEVLINK_ATTR_REGION_CHUNK_ADDR
]);
3908 end_offset
+= nla_get_u64(attrs
[DEVLINK_ATTR_REGION_CHUNK_LEN
]);
3911 if (start_offset
== end_offset
) {
3913 goto nla_put_failure
;
3917 err
= devlink_nl_region_read_snapshot_fill(skb
, devlink
,
3923 if (err
&& err
!= -EMSGSIZE
)
3924 goto nla_put_failure
;
3926 /* Check if there was any progress done to prevent infinite loop */
3927 if (ret_offset
== start_offset
) {
3929 goto nla_put_failure
;
3932 *((u64
*)&cb
->args
[0]) = ret_offset
;
3934 nla_nest_end(skb
, chunks_attr
);
3935 genlmsg_end(skb
, hdr
);
3936 mutex_unlock(&devlink
->lock
);
3937 mutex_unlock(&devlink_mutex
);
3943 genlmsg_cancel(skb
, hdr
);
3945 mutex_unlock(&devlink
->lock
);
3947 mutex_unlock(&devlink_mutex
);
3953 struct devlink_info_req
{
3954 struct sk_buff
*msg
;
3957 int devlink_info_driver_name_put(struct devlink_info_req
*req
, const char *name
)
3959 return nla_put_string(req
->msg
, DEVLINK_ATTR_INFO_DRIVER_NAME
, name
);
3961 EXPORT_SYMBOL_GPL(devlink_info_driver_name_put
);
3963 int devlink_info_serial_number_put(struct devlink_info_req
*req
, const char *sn
)
3965 return nla_put_string(req
->msg
, DEVLINK_ATTR_INFO_SERIAL_NUMBER
, sn
);
3967 EXPORT_SYMBOL_GPL(devlink_info_serial_number_put
);
3969 static int devlink_info_version_put(struct devlink_info_req
*req
, int attr
,
3970 const char *version_name
,
3971 const char *version_value
)
3973 struct nlattr
*nest
;
3976 nest
= nla_nest_start_noflag(req
->msg
, attr
);
3980 err
= nla_put_string(req
->msg
, DEVLINK_ATTR_INFO_VERSION_NAME
,
3983 goto nla_put_failure
;
3985 err
= nla_put_string(req
->msg
, DEVLINK_ATTR_INFO_VERSION_VALUE
,
3988 goto nla_put_failure
;
3990 nla_nest_end(req
->msg
, nest
);
3995 nla_nest_cancel(req
->msg
, nest
);
3999 int devlink_info_version_fixed_put(struct devlink_info_req
*req
,
4000 const char *version_name
,
4001 const char *version_value
)
4003 return devlink_info_version_put(req
, DEVLINK_ATTR_INFO_VERSION_FIXED
,
4004 version_name
, version_value
);
4006 EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put
);
4008 int devlink_info_version_stored_put(struct devlink_info_req
*req
,
4009 const char *version_name
,
4010 const char *version_value
)
4012 return devlink_info_version_put(req
, DEVLINK_ATTR_INFO_VERSION_STORED
,
4013 version_name
, version_value
);
4015 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put
);
4017 int devlink_info_version_running_put(struct devlink_info_req
*req
,
4018 const char *version_name
,
4019 const char *version_value
)
4021 return devlink_info_version_put(req
, DEVLINK_ATTR_INFO_VERSION_RUNNING
,
4022 version_name
, version_value
);
4024 EXPORT_SYMBOL_GPL(devlink_info_version_running_put
);
4027 devlink_nl_info_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
4028 enum devlink_command cmd
, u32 portid
,
4029 u32 seq
, int flags
, struct netlink_ext_ack
*extack
)
4031 struct devlink_info_req req
;
4035 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
4040 if (devlink_nl_put_handle(msg
, devlink
))
4041 goto err_cancel_msg
;
4044 err
= devlink
->ops
->info_get(devlink
, &req
, extack
);
4046 goto err_cancel_msg
;
4048 genlmsg_end(msg
, hdr
);
4052 genlmsg_cancel(msg
, hdr
);
4056 static int devlink_nl_cmd_info_get_doit(struct sk_buff
*skb
,
4057 struct genl_info
*info
)
4059 struct devlink
*devlink
= info
->user_ptr
[0];
4060 struct sk_buff
*msg
;
4063 if (!devlink
->ops
->info_get
)
4066 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
4070 err
= devlink_nl_info_fill(msg
, devlink
, DEVLINK_CMD_INFO_GET
,
4071 info
->snd_portid
, info
->snd_seq
, 0,
4078 return genlmsg_reply(msg
, info
);
4081 static int devlink_nl_cmd_info_get_dumpit(struct sk_buff
*msg
,
4082 struct netlink_callback
*cb
)
4084 struct devlink
*devlink
;
4085 int start
= cb
->args
[0];
4089 mutex_lock(&devlink_mutex
);
4090 list_for_each_entry(devlink
, &devlink_list
, list
) {
4091 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
4098 if (!devlink
->ops
->info_get
) {
4103 mutex_lock(&devlink
->lock
);
4104 err
= devlink_nl_info_fill(msg
, devlink
, DEVLINK_CMD_INFO_GET
,
4105 NETLINK_CB(cb
->skb
).portid
,
4106 cb
->nlh
->nlmsg_seq
, NLM_F_MULTI
,
4108 mutex_unlock(&devlink
->lock
);
4109 if (err
&& err
!= -EOPNOTSUPP
)
4113 mutex_unlock(&devlink_mutex
);
4119 struct devlink_fmsg_item
{
4120 struct list_head list
;
4127 struct devlink_fmsg
{
4128 struct list_head item_list
;
4131 static struct devlink_fmsg
*devlink_fmsg_alloc(void)
4133 struct devlink_fmsg
*fmsg
;
4135 fmsg
= kzalloc(sizeof(*fmsg
), GFP_KERNEL
);
4139 INIT_LIST_HEAD(&fmsg
->item_list
);
4144 static void devlink_fmsg_free(struct devlink_fmsg
*fmsg
)
4146 struct devlink_fmsg_item
*item
, *tmp
;
4148 list_for_each_entry_safe(item
, tmp
, &fmsg
->item_list
, list
) {
4149 list_del(&item
->list
);
4155 static int devlink_fmsg_nest_common(struct devlink_fmsg
*fmsg
,
4158 struct devlink_fmsg_item
*item
;
4160 item
= kzalloc(sizeof(*item
), GFP_KERNEL
);
4164 item
->attrtype
= attrtype
;
4165 list_add_tail(&item
->list
, &fmsg
->item_list
);
4170 int devlink_fmsg_obj_nest_start(struct devlink_fmsg
*fmsg
)
4172 return devlink_fmsg_nest_common(fmsg
, DEVLINK_ATTR_FMSG_OBJ_NEST_START
);
4174 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start
);
4176 static int devlink_fmsg_nest_end(struct devlink_fmsg
*fmsg
)
4178 return devlink_fmsg_nest_common(fmsg
, DEVLINK_ATTR_FMSG_NEST_END
);
4181 int devlink_fmsg_obj_nest_end(struct devlink_fmsg
*fmsg
)
4183 return devlink_fmsg_nest_end(fmsg
);
4185 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end
);
4187 #define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN)
4189 static int devlink_fmsg_put_name(struct devlink_fmsg
*fmsg
, const char *name
)
4191 struct devlink_fmsg_item
*item
;
4193 if (strlen(name
) + 1 > DEVLINK_FMSG_MAX_SIZE
)
4196 item
= kzalloc(sizeof(*item
) + strlen(name
) + 1, GFP_KERNEL
);
4200 item
->nla_type
= NLA_NUL_STRING
;
4201 item
->len
= strlen(name
) + 1;
4202 item
->attrtype
= DEVLINK_ATTR_FMSG_OBJ_NAME
;
4203 memcpy(&item
->value
, name
, item
->len
);
4204 list_add_tail(&item
->list
, &fmsg
->item_list
);
4209 int devlink_fmsg_pair_nest_start(struct devlink_fmsg
*fmsg
, const char *name
)
4213 err
= devlink_fmsg_nest_common(fmsg
, DEVLINK_ATTR_FMSG_PAIR_NEST_START
);
4217 err
= devlink_fmsg_put_name(fmsg
, name
);
4223 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start
);
4225 int devlink_fmsg_pair_nest_end(struct devlink_fmsg
*fmsg
)
4227 return devlink_fmsg_nest_end(fmsg
);
4229 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end
);
4231 int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg
*fmsg
,
4236 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
4240 err
= devlink_fmsg_nest_common(fmsg
, DEVLINK_ATTR_FMSG_ARR_NEST_START
);
4246 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start
);
4248 int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg
*fmsg
)
4252 err
= devlink_fmsg_nest_end(fmsg
);
4256 err
= devlink_fmsg_nest_end(fmsg
);
4262 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end
);
4264 static int devlink_fmsg_put_value(struct devlink_fmsg
*fmsg
,
4265 const void *value
, u16 value_len
,
4268 struct devlink_fmsg_item
*item
;
4270 if (value_len
> DEVLINK_FMSG_MAX_SIZE
)
4273 item
= kzalloc(sizeof(*item
) + value_len
, GFP_KERNEL
);
4277 item
->nla_type
= value_nla_type
;
4278 item
->len
= value_len
;
4279 item
->attrtype
= DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA
;
4280 memcpy(&item
->value
, value
, item
->len
);
4281 list_add_tail(&item
->list
, &fmsg
->item_list
);
4286 int devlink_fmsg_bool_put(struct devlink_fmsg
*fmsg
, bool value
)
4288 return devlink_fmsg_put_value(fmsg
, &value
, sizeof(value
), NLA_FLAG
);
4290 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_put
);
4292 int devlink_fmsg_u8_put(struct devlink_fmsg
*fmsg
, u8 value
)
4294 return devlink_fmsg_put_value(fmsg
, &value
, sizeof(value
), NLA_U8
);
4296 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_put
);
4298 int devlink_fmsg_u32_put(struct devlink_fmsg
*fmsg
, u32 value
)
4300 return devlink_fmsg_put_value(fmsg
, &value
, sizeof(value
), NLA_U32
);
4302 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put
);
4304 int devlink_fmsg_u64_put(struct devlink_fmsg
*fmsg
, u64 value
)
4306 return devlink_fmsg_put_value(fmsg
, &value
, sizeof(value
), NLA_U64
);
4308 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_put
);
4310 int devlink_fmsg_string_put(struct devlink_fmsg
*fmsg
, const char *value
)
4312 return devlink_fmsg_put_value(fmsg
, value
, strlen(value
) + 1,
4315 EXPORT_SYMBOL_GPL(devlink_fmsg_string_put
);
4317 int devlink_fmsg_binary_put(struct devlink_fmsg
*fmsg
, const void *value
,
4320 return devlink_fmsg_put_value(fmsg
, value
, value_len
, NLA_BINARY
);
4322 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put
);
4324 int devlink_fmsg_bool_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
4329 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
4333 err
= devlink_fmsg_bool_put(fmsg
, value
);
4337 err
= devlink_fmsg_pair_nest_end(fmsg
);
4343 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put
);
4345 int devlink_fmsg_u8_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
4350 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
4354 err
= devlink_fmsg_u8_put(fmsg
, value
);
4358 err
= devlink_fmsg_pair_nest_end(fmsg
);
4364 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put
);
4366 int devlink_fmsg_u32_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
4371 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
4375 err
= devlink_fmsg_u32_put(fmsg
, value
);
4379 err
= devlink_fmsg_pair_nest_end(fmsg
);
4385 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put
);
4387 int devlink_fmsg_u64_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
4392 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
4396 err
= devlink_fmsg_u64_put(fmsg
, value
);
4400 err
= devlink_fmsg_pair_nest_end(fmsg
);
4406 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put
);
4408 int devlink_fmsg_string_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
4413 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
4417 err
= devlink_fmsg_string_put(fmsg
, value
);
4421 err
= devlink_fmsg_pair_nest_end(fmsg
);
4427 EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put
);
4429 int devlink_fmsg_binary_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
4430 const void *value
, u16 value_len
)
4434 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
4438 err
= devlink_fmsg_binary_put(fmsg
, value
, value_len
);
4442 err
= devlink_fmsg_pair_nest_end(fmsg
);
4448 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put
);
4451 devlink_fmsg_item_fill_type(struct devlink_fmsg_item
*msg
, struct sk_buff
*skb
)
4453 switch (msg
->nla_type
) {
4458 case NLA_NUL_STRING
:
4460 return nla_put_u8(skb
, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE
,
4468 devlink_fmsg_item_fill_data(struct devlink_fmsg_item
*msg
, struct sk_buff
*skb
)
4470 int attrtype
= DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA
;
4473 switch (msg
->nla_type
) {
4475 /* Always provide flag data, regardless of its value */
4476 tmp
= *(bool *) msg
->value
;
4478 return nla_put_u8(skb
, attrtype
, tmp
);
4480 return nla_put_u8(skb
, attrtype
, *(u8
*) msg
->value
);
4482 return nla_put_u32(skb
, attrtype
, *(u32
*) msg
->value
);
4484 return nla_put_u64_64bit(skb
, attrtype
, *(u64
*) msg
->value
,
4486 case NLA_NUL_STRING
:
4487 return nla_put_string(skb
, attrtype
, (char *) &msg
->value
);
4489 return nla_put(skb
, attrtype
, msg
->len
, (void *) &msg
->value
);
4496 devlink_fmsg_prepare_skb(struct devlink_fmsg
*fmsg
, struct sk_buff
*skb
,
4499 struct devlink_fmsg_item
*item
;
4500 struct nlattr
*fmsg_nlattr
;
4504 fmsg_nlattr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_FMSG
);
4508 list_for_each_entry(item
, &fmsg
->item_list
, list
) {
4514 switch (item
->attrtype
) {
4515 case DEVLINK_ATTR_FMSG_OBJ_NEST_START
:
4516 case DEVLINK_ATTR_FMSG_PAIR_NEST_START
:
4517 case DEVLINK_ATTR_FMSG_ARR_NEST_START
:
4518 case DEVLINK_ATTR_FMSG_NEST_END
:
4519 err
= nla_put_flag(skb
, item
->attrtype
);
4521 case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA
:
4522 err
= devlink_fmsg_item_fill_type(item
, skb
);
4525 err
= devlink_fmsg_item_fill_data(item
, skb
);
4527 case DEVLINK_ATTR_FMSG_OBJ_NAME
:
4528 err
= nla_put_string(skb
, item
->attrtype
,
4529 (char *) &item
->value
);
4541 nla_nest_end(skb
, fmsg_nlattr
);
4545 static int devlink_fmsg_snd(struct devlink_fmsg
*fmsg
,
4546 struct genl_info
*info
,
4547 enum devlink_command cmd
, int flags
)
4549 struct nlmsghdr
*nlh
;
4550 struct sk_buff
*skb
;
4557 int tmp_index
= index
;
4559 skb
= genlmsg_new(GENLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
4563 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
4564 &devlink_nl_family
, flags
| NLM_F_MULTI
, cmd
);
4567 goto nla_put_failure
;
4570 err
= devlink_fmsg_prepare_skb(fmsg
, skb
, &index
);
4573 else if (err
!= -EMSGSIZE
|| tmp_index
== index
)
4574 goto nla_put_failure
;
4576 genlmsg_end(skb
, hdr
);
4577 err
= genlmsg_reply(skb
, info
);
4582 skb
= genlmsg_new(GENLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
4585 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
4586 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
4589 goto nla_put_failure
;
4592 return genlmsg_reply(skb
, info
);
4599 static int devlink_fmsg_dumpit(struct devlink_fmsg
*fmsg
, struct sk_buff
*skb
,
4600 struct netlink_callback
*cb
,
4601 enum devlink_command cmd
)
4603 int index
= cb
->args
[0];
4604 int tmp_index
= index
;
4608 hdr
= genlmsg_put(skb
, NETLINK_CB(cb
->skb
).portid
, cb
->nlh
->nlmsg_seq
,
4609 &devlink_nl_family
, NLM_F_ACK
| NLM_F_MULTI
, cmd
);
4612 goto nla_put_failure
;
4615 err
= devlink_fmsg_prepare_skb(fmsg
, skb
, &index
);
4616 if ((err
&& err
!= -EMSGSIZE
) || tmp_index
== index
)
4617 goto nla_put_failure
;
4619 cb
->args
[0] = index
;
4620 genlmsg_end(skb
, hdr
);
4624 genlmsg_cancel(skb
, hdr
);
4628 struct devlink_health_reporter
{
4629 struct list_head list
;
4631 const struct devlink_health_reporter_ops
*ops
;
4632 struct devlink
*devlink
;
4633 struct devlink_fmsg
*dump_fmsg
;
4634 struct mutex dump_lock
; /* lock parallel read/write from dump buffers */
4635 u64 graceful_period
;
4642 u64 last_recovery_ts
;
4643 refcount_t refcount
;
4647 devlink_health_reporter_priv(struct devlink_health_reporter
*reporter
)
4649 return reporter
->priv
;
4651 EXPORT_SYMBOL_GPL(devlink_health_reporter_priv
);
4653 static struct devlink_health_reporter
*
4654 devlink_health_reporter_find_by_name(struct devlink
*devlink
,
4655 const char *reporter_name
)
4657 struct devlink_health_reporter
*reporter
;
4659 lockdep_assert_held(&devlink
->reporters_lock
);
4660 list_for_each_entry(reporter
, &devlink
->reporter_list
, list
)
4661 if (!strcmp(reporter
->ops
->name
, reporter_name
))
4667 * devlink_health_reporter_create - create devlink health reporter
4671 * @graceful_period: to avoid recovery loops, in msecs
4672 * @auto_recover: auto recover when error occurs
4675 struct devlink_health_reporter
*
4676 devlink_health_reporter_create(struct devlink
*devlink
,
4677 const struct devlink_health_reporter_ops
*ops
,
4678 u64 graceful_period
, bool auto_recover
,
4681 struct devlink_health_reporter
*reporter
;
4683 mutex_lock(&devlink
->reporters_lock
);
4684 if (devlink_health_reporter_find_by_name(devlink
, ops
->name
)) {
4685 reporter
= ERR_PTR(-EEXIST
);
4689 if (WARN_ON(auto_recover
&& !ops
->recover
) ||
4690 WARN_ON(graceful_period
&& !ops
->recover
)) {
4691 reporter
= ERR_PTR(-EINVAL
);
4695 reporter
= kzalloc(sizeof(*reporter
), GFP_KERNEL
);
4697 reporter
= ERR_PTR(-ENOMEM
);
4701 reporter
->priv
= priv
;
4702 reporter
->ops
= ops
;
4703 reporter
->devlink
= devlink
;
4704 reporter
->graceful_period
= graceful_period
;
4705 reporter
->auto_recover
= auto_recover
;
4706 mutex_init(&reporter
->dump_lock
);
4707 refcount_set(&reporter
->refcount
, 1);
4708 list_add_tail(&reporter
->list
, &devlink
->reporter_list
);
4710 mutex_unlock(&devlink
->reporters_lock
);
4713 EXPORT_SYMBOL_GPL(devlink_health_reporter_create
);
4716 * devlink_health_reporter_destroy - destroy devlink health reporter
4718 * @reporter: devlink health reporter to destroy
4721 devlink_health_reporter_destroy(struct devlink_health_reporter
*reporter
)
4723 mutex_lock(&reporter
->devlink
->reporters_lock
);
4724 list_del(&reporter
->list
);
4725 mutex_unlock(&reporter
->devlink
->reporters_lock
);
4726 while (refcount_read(&reporter
->refcount
) > 1)
4728 mutex_destroy(&reporter
->dump_lock
);
4729 if (reporter
->dump_fmsg
)
4730 devlink_fmsg_free(reporter
->dump_fmsg
);
4733 EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy
);
4736 devlink_health_reporter_state_update(struct devlink_health_reporter
*reporter
,
4737 enum devlink_health_reporter_state state
)
4739 if (WARN_ON(state
!= DEVLINK_HEALTH_REPORTER_STATE_HEALTHY
&&
4740 state
!= DEVLINK_HEALTH_REPORTER_STATE_ERROR
))
4743 if (reporter
->health_state
== state
)
4746 reporter
->health_state
= state
;
4747 trace_devlink_health_reporter_state_update(reporter
->devlink
,
4748 reporter
->ops
->name
, state
);
4750 EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update
);
4753 devlink_health_reporter_recover(struct devlink_health_reporter
*reporter
,
4758 if (!reporter
->ops
->recover
)
4761 err
= reporter
->ops
->recover(reporter
, priv_ctx
);
4765 reporter
->recovery_count
++;
4766 reporter
->health_state
= DEVLINK_HEALTH_REPORTER_STATE_HEALTHY
;
4767 reporter
->last_recovery_ts
= jiffies
;
4773 devlink_health_dump_clear(struct devlink_health_reporter
*reporter
)
4775 if (!reporter
->dump_fmsg
)
4777 devlink_fmsg_free(reporter
->dump_fmsg
);
4778 reporter
->dump_fmsg
= NULL
;
4781 static int devlink_health_do_dump(struct devlink_health_reporter
*reporter
,
4786 if (!reporter
->ops
->dump
)
4789 if (reporter
->dump_fmsg
)
4792 reporter
->dump_fmsg
= devlink_fmsg_alloc();
4793 if (!reporter
->dump_fmsg
) {
4798 err
= devlink_fmsg_obj_nest_start(reporter
->dump_fmsg
);
4802 err
= reporter
->ops
->dump(reporter
, reporter
->dump_fmsg
,
4807 err
= devlink_fmsg_obj_nest_end(reporter
->dump_fmsg
);
4811 reporter
->dump_ts
= jiffies
;
4812 reporter
->dump_real_ts
= ktime_get_real_ns();
4817 devlink_health_dump_clear(reporter
);
4821 int devlink_health_report(struct devlink_health_reporter
*reporter
,
4822 const char *msg
, void *priv_ctx
)
4824 enum devlink_health_reporter_state prev_health_state
;
4825 struct devlink
*devlink
= reporter
->devlink
;
4827 /* write a log message of the current error */
4829 trace_devlink_health_report(devlink
, reporter
->ops
->name
, msg
);
4830 reporter
->error_count
++;
4831 prev_health_state
= reporter
->health_state
;
4832 reporter
->health_state
= DEVLINK_HEALTH_REPORTER_STATE_ERROR
;
4834 /* abort if the previous error wasn't recovered */
4835 if (reporter
->auto_recover
&&
4836 (prev_health_state
!= DEVLINK_HEALTH_REPORTER_STATE_HEALTHY
||
4837 jiffies
- reporter
->last_recovery_ts
<
4838 msecs_to_jiffies(reporter
->graceful_period
))) {
4839 trace_devlink_health_recover_aborted(devlink
,
4840 reporter
->ops
->name
,
4841 reporter
->health_state
,
4843 reporter
->last_recovery_ts
);
4847 reporter
->health_state
= DEVLINK_HEALTH_REPORTER_STATE_ERROR
;
4849 mutex_lock(&reporter
->dump_lock
);
4850 /* store current dump of current error, for later analysis */
4851 devlink_health_do_dump(reporter
, priv_ctx
);
4852 mutex_unlock(&reporter
->dump_lock
);
4854 if (reporter
->auto_recover
)
4855 return devlink_health_reporter_recover(reporter
, priv_ctx
);
4859 EXPORT_SYMBOL_GPL(devlink_health_report
);
4861 static struct devlink_health_reporter
*
4862 devlink_health_reporter_get_from_attrs(struct devlink
*devlink
,
4863 struct nlattr
**attrs
)
4865 struct devlink_health_reporter
*reporter
;
4866 char *reporter_name
;
4868 if (!attrs
[DEVLINK_ATTR_HEALTH_REPORTER_NAME
])
4871 reporter_name
= nla_data(attrs
[DEVLINK_ATTR_HEALTH_REPORTER_NAME
]);
4872 mutex_lock(&devlink
->reporters_lock
);
4873 reporter
= devlink_health_reporter_find_by_name(devlink
, reporter_name
);
4875 refcount_inc(&reporter
->refcount
);
4876 mutex_unlock(&devlink
->reporters_lock
);
4880 static struct devlink_health_reporter
*
4881 devlink_health_reporter_get_from_info(struct devlink
*devlink
,
4882 struct genl_info
*info
)
4884 return devlink_health_reporter_get_from_attrs(devlink
, info
->attrs
);
4887 static struct devlink_health_reporter
*
4888 devlink_health_reporter_get_from_cb(struct netlink_callback
*cb
)
4890 struct devlink_health_reporter
*reporter
;
4891 struct devlink
*devlink
;
4892 struct nlattr
**attrs
;
4895 attrs
= kmalloc_array(DEVLINK_ATTR_MAX
+ 1, sizeof(*attrs
), GFP_KERNEL
);
4899 err
= nlmsg_parse_deprecated(cb
->nlh
,
4900 GENL_HDRLEN
+ devlink_nl_family
.hdrsize
,
4901 attrs
, DEVLINK_ATTR_MAX
,
4902 devlink_nl_family
.policy
, cb
->extack
);
4906 mutex_lock(&devlink_mutex
);
4907 devlink
= devlink_get_from_attrs(sock_net(cb
->skb
->sk
), attrs
);
4908 if (IS_ERR(devlink
))
4911 reporter
= devlink_health_reporter_get_from_attrs(devlink
, attrs
);
4912 mutex_unlock(&devlink_mutex
);
4916 mutex_unlock(&devlink_mutex
);
4923 devlink_health_reporter_put(struct devlink_health_reporter
*reporter
)
4925 refcount_dec(&reporter
->refcount
);
4929 devlink_nl_health_reporter_fill(struct sk_buff
*msg
,
4930 struct devlink
*devlink
,
4931 struct devlink_health_reporter
*reporter
,
4932 enum devlink_command cmd
, u32 portid
,
4935 struct nlattr
*reporter_attr
;
4938 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
4942 if (devlink_nl_put_handle(msg
, devlink
))
4943 goto genlmsg_cancel
;
4945 reporter_attr
= nla_nest_start_noflag(msg
,
4946 DEVLINK_ATTR_HEALTH_REPORTER
);
4948 goto genlmsg_cancel
;
4949 if (nla_put_string(msg
, DEVLINK_ATTR_HEALTH_REPORTER_NAME
,
4950 reporter
->ops
->name
))
4951 goto reporter_nest_cancel
;
4952 if (nla_put_u8(msg
, DEVLINK_ATTR_HEALTH_REPORTER_STATE
,
4953 reporter
->health_state
))
4954 goto reporter_nest_cancel
;
4955 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT
,
4956 reporter
->error_count
, DEVLINK_ATTR_PAD
))
4957 goto reporter_nest_cancel
;
4958 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT
,
4959 reporter
->recovery_count
, DEVLINK_ATTR_PAD
))
4960 goto reporter_nest_cancel
;
4961 if (reporter
->ops
->recover
&&
4962 nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
,
4963 reporter
->graceful_period
,
4965 goto reporter_nest_cancel
;
4966 if (reporter
->ops
->recover
&&
4967 nla_put_u8(msg
, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
,
4968 reporter
->auto_recover
))
4969 goto reporter_nest_cancel
;
4970 if (reporter
->dump_fmsg
&&
4971 nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS
,
4972 jiffies_to_msecs(reporter
->dump_ts
),
4974 goto reporter_nest_cancel
;
4975 if (reporter
->dump_fmsg
&&
4976 nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS
,
4977 reporter
->dump_real_ts
, DEVLINK_ATTR_PAD
))
4978 goto reporter_nest_cancel
;
4980 nla_nest_end(msg
, reporter_attr
);
4981 genlmsg_end(msg
, hdr
);
4984 reporter_nest_cancel
:
4985 nla_nest_end(msg
, reporter_attr
);
4987 genlmsg_cancel(msg
, hdr
);
4991 static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff
*skb
,
4992 struct genl_info
*info
)
4994 struct devlink
*devlink
= info
->user_ptr
[0];
4995 struct devlink_health_reporter
*reporter
;
4996 struct sk_buff
*msg
;
4999 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5003 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
5009 err
= devlink_nl_health_reporter_fill(msg
, devlink
, reporter
,
5010 DEVLINK_CMD_HEALTH_REPORTER_GET
,
5011 info
->snd_portid
, info
->snd_seq
,
5018 err
= genlmsg_reply(msg
, info
);
5020 devlink_health_reporter_put(reporter
);
5025 devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff
*msg
,
5026 struct netlink_callback
*cb
)
5028 struct devlink_health_reporter
*reporter
;
5029 struct devlink
*devlink
;
5030 int start
= cb
->args
[0];
5034 mutex_lock(&devlink_mutex
);
5035 list_for_each_entry(devlink
, &devlink_list
, list
) {
5036 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
5038 mutex_lock(&devlink
->reporters_lock
);
5039 list_for_each_entry(reporter
, &devlink
->reporter_list
,
5045 err
= devlink_nl_health_reporter_fill(msg
, devlink
,
5047 DEVLINK_CMD_HEALTH_REPORTER_GET
,
5048 NETLINK_CB(cb
->skb
).portid
,
5052 mutex_unlock(&devlink
->reporters_lock
);
5057 mutex_unlock(&devlink
->reporters_lock
);
5060 mutex_unlock(&devlink_mutex
);
5067 devlink_nl_cmd_health_reporter_set_doit(struct sk_buff
*skb
,
5068 struct genl_info
*info
)
5070 struct devlink
*devlink
= info
->user_ptr
[0];
5071 struct devlink_health_reporter
*reporter
;
5074 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5078 if (!reporter
->ops
->recover
&&
5079 (info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
] ||
5080 info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
])) {
5085 if (info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
])
5086 reporter
->graceful_period
=
5087 nla_get_u64(info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
]);
5089 if (info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
])
5090 reporter
->auto_recover
=
5091 nla_get_u8(info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
]);
5093 devlink_health_reporter_put(reporter
);
5096 devlink_health_reporter_put(reporter
);
5100 static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff
*skb
,
5101 struct genl_info
*info
)
5103 struct devlink
*devlink
= info
->user_ptr
[0];
5104 struct devlink_health_reporter
*reporter
;
5107 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5111 err
= devlink_health_reporter_recover(reporter
, NULL
);
5113 devlink_health_reporter_put(reporter
);
5117 static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff
*skb
,
5118 struct genl_info
*info
)
5120 struct devlink
*devlink
= info
->user_ptr
[0];
5121 struct devlink_health_reporter
*reporter
;
5122 struct devlink_fmsg
*fmsg
;
5125 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5129 if (!reporter
->ops
->diagnose
) {
5130 devlink_health_reporter_put(reporter
);
5134 fmsg
= devlink_fmsg_alloc();
5136 devlink_health_reporter_put(reporter
);
5140 err
= devlink_fmsg_obj_nest_start(fmsg
);
5144 err
= reporter
->ops
->diagnose(reporter
, fmsg
);
5148 err
= devlink_fmsg_obj_nest_end(fmsg
);
5152 err
= devlink_fmsg_snd(fmsg
, info
,
5153 DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE
, 0);
5156 devlink_fmsg_free(fmsg
);
5157 devlink_health_reporter_put(reporter
);
5162 devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff
*skb
,
5163 struct netlink_callback
*cb
)
5165 struct devlink_health_reporter
*reporter
;
5166 u64 start
= cb
->args
[0];
5169 reporter
= devlink_health_reporter_get_from_cb(cb
);
5173 if (!reporter
->ops
->dump
) {
5177 mutex_lock(&reporter
->dump_lock
);
5179 err
= devlink_health_do_dump(reporter
, NULL
);
5182 cb
->args
[1] = reporter
->dump_ts
;
5184 if (!reporter
->dump_fmsg
|| cb
->args
[1] != reporter
->dump_ts
) {
5185 NL_SET_ERR_MSG_MOD(cb
->extack
, "Dump trampled, please retry");
5190 err
= devlink_fmsg_dumpit(reporter
->dump_fmsg
, skb
, cb
,
5191 DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET
);
5193 mutex_unlock(&reporter
->dump_lock
);
5195 devlink_health_reporter_put(reporter
);
5200 devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff
*skb
,
5201 struct genl_info
*info
)
5203 struct devlink
*devlink
= info
->user_ptr
[0];
5204 struct devlink_health_reporter
*reporter
;
5206 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5210 if (!reporter
->ops
->dump
) {
5211 devlink_health_reporter_put(reporter
);
5215 mutex_lock(&reporter
->dump_lock
);
5216 devlink_health_dump_clear(reporter
);
5217 mutex_unlock(&reporter
->dump_lock
);
5218 devlink_health_reporter_put(reporter
);
5222 struct devlink_stats
{
5225 struct u64_stats_sync syncp
;
5229 * struct devlink_trap_group_item - Packet trap group attributes.
5230 * @group: Immutable packet trap group attributes.
5231 * @refcount: Number of trap items using the group.
5232 * @list: trap_group_list member.
5233 * @stats: Trap group statistics.
5235 * Describes packet trap group attributes. Created by devlink during trap
5238 struct devlink_trap_group_item
{
5239 const struct devlink_trap_group
*group
;
5240 refcount_t refcount
;
5241 struct list_head list
;
5242 struct devlink_stats __percpu
*stats
;
5246 * struct devlink_trap_item - Packet trap attributes.
5247 * @trap: Immutable packet trap attributes.
5248 * @group_item: Associated group item.
5249 * @list: trap_list member.
5250 * @action: Trap action.
5251 * @stats: Trap statistics.
5252 * @priv: Driver private information.
5254 * Describes both mutable and immutable packet trap attributes. Created by
5255 * devlink during trap registration and used for all trap related operations.
5257 struct devlink_trap_item
{
5258 const struct devlink_trap
*trap
;
5259 struct devlink_trap_group_item
*group_item
;
5260 struct list_head list
;
5261 enum devlink_trap_action action
;
5262 struct devlink_stats __percpu
*stats
;
5266 static struct devlink_trap_item
*
5267 devlink_trap_item_lookup(struct devlink
*devlink
, const char *name
)
5269 struct devlink_trap_item
*trap_item
;
5271 list_for_each_entry(trap_item
, &devlink
->trap_list
, list
) {
5272 if (!strcmp(trap_item
->trap
->name
, name
))
5279 static struct devlink_trap_item
*
5280 devlink_trap_item_get_from_info(struct devlink
*devlink
,
5281 struct genl_info
*info
)
5283 struct nlattr
*attr
;
5285 if (!info
->attrs
[DEVLINK_ATTR_TRAP_NAME
])
5287 attr
= info
->attrs
[DEVLINK_ATTR_TRAP_NAME
];
5289 return devlink_trap_item_lookup(devlink
, nla_data(attr
));
5293 devlink_trap_action_get_from_info(struct genl_info
*info
,
5294 enum devlink_trap_action
*p_trap_action
)
5298 val
= nla_get_u8(info
->attrs
[DEVLINK_ATTR_TRAP_ACTION
]);
5300 case DEVLINK_TRAP_ACTION_DROP
: /* fall-through */
5301 case DEVLINK_TRAP_ACTION_TRAP
:
5302 *p_trap_action
= val
;
5311 static int devlink_trap_metadata_put(struct sk_buff
*msg
,
5312 const struct devlink_trap
*trap
)
5314 struct nlattr
*attr
;
5316 attr
= nla_nest_start(msg
, DEVLINK_ATTR_TRAP_METADATA
);
5320 if ((trap
->metadata_cap
& DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT
) &&
5321 nla_put_flag(msg
, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT
))
5322 goto nla_put_failure
;
5324 nla_nest_end(msg
, attr
);
5329 nla_nest_cancel(msg
, attr
);
5333 static void devlink_trap_stats_read(struct devlink_stats __percpu
*trap_stats
,
5334 struct devlink_stats
*stats
)
5338 memset(stats
, 0, sizeof(*stats
));
5339 for_each_possible_cpu(i
) {
5340 struct devlink_stats
*cpu_stats
;
5341 u64 rx_packets
, rx_bytes
;
5344 cpu_stats
= per_cpu_ptr(trap_stats
, i
);
5346 start
= u64_stats_fetch_begin_irq(&cpu_stats
->syncp
);
5347 rx_packets
= cpu_stats
->rx_packets
;
5348 rx_bytes
= cpu_stats
->rx_bytes
;
5349 } while (u64_stats_fetch_retry_irq(&cpu_stats
->syncp
, start
));
5351 stats
->rx_packets
+= rx_packets
;
5352 stats
->rx_bytes
+= rx_bytes
;
5356 static int devlink_trap_stats_put(struct sk_buff
*msg
,
5357 struct devlink_stats __percpu
*trap_stats
)
5359 struct devlink_stats stats
;
5360 struct nlattr
*attr
;
5362 devlink_trap_stats_read(trap_stats
, &stats
);
5364 attr
= nla_nest_start(msg
, DEVLINK_ATTR_STATS
);
5368 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_STATS_RX_PACKETS
,
5369 stats
.rx_packets
, DEVLINK_ATTR_PAD
))
5370 goto nla_put_failure
;
5372 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_STATS_RX_BYTES
,
5373 stats
.rx_bytes
, DEVLINK_ATTR_PAD
))
5374 goto nla_put_failure
;
5376 nla_nest_end(msg
, attr
);
5381 nla_nest_cancel(msg
, attr
);
5385 static int devlink_nl_trap_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
5386 const struct devlink_trap_item
*trap_item
,
5387 enum devlink_command cmd
, u32 portid
, u32 seq
,
5390 struct devlink_trap_group_item
*group_item
= trap_item
->group_item
;
5394 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
5398 if (devlink_nl_put_handle(msg
, devlink
))
5399 goto nla_put_failure
;
5401 if (nla_put_string(msg
, DEVLINK_ATTR_TRAP_GROUP_NAME
,
5402 group_item
->group
->name
))
5403 goto nla_put_failure
;
5405 if (nla_put_string(msg
, DEVLINK_ATTR_TRAP_NAME
, trap_item
->trap
->name
))
5406 goto nla_put_failure
;
5408 if (nla_put_u8(msg
, DEVLINK_ATTR_TRAP_TYPE
, trap_item
->trap
->type
))
5409 goto nla_put_failure
;
5411 if (trap_item
->trap
->generic
&&
5412 nla_put_flag(msg
, DEVLINK_ATTR_TRAP_GENERIC
))
5413 goto nla_put_failure
;
5415 if (nla_put_u8(msg
, DEVLINK_ATTR_TRAP_ACTION
, trap_item
->action
))
5416 goto nla_put_failure
;
5418 err
= devlink_trap_metadata_put(msg
, trap_item
->trap
);
5420 goto nla_put_failure
;
5422 err
= devlink_trap_stats_put(msg
, trap_item
->stats
);
5424 goto nla_put_failure
;
5426 genlmsg_end(msg
, hdr
);
5431 genlmsg_cancel(msg
, hdr
);
5435 static int devlink_nl_cmd_trap_get_doit(struct sk_buff
*skb
,
5436 struct genl_info
*info
)
5438 struct netlink_ext_ack
*extack
= info
->extack
;
5439 struct devlink
*devlink
= info
->user_ptr
[0];
5440 struct devlink_trap_item
*trap_item
;
5441 struct sk_buff
*msg
;
5444 if (list_empty(&devlink
->trap_list
))
5447 trap_item
= devlink_trap_item_get_from_info(devlink
, info
);
5449 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap");
5453 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
5457 err
= devlink_nl_trap_fill(msg
, devlink
, trap_item
,
5458 DEVLINK_CMD_TRAP_NEW
, info
->snd_portid
,
5463 return genlmsg_reply(msg
, info
);
5470 static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff
*msg
,
5471 struct netlink_callback
*cb
)
5473 struct devlink_trap_item
*trap_item
;
5474 struct devlink
*devlink
;
5475 int start
= cb
->args
[0];
5479 mutex_lock(&devlink_mutex
);
5480 list_for_each_entry(devlink
, &devlink_list
, list
) {
5481 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
5483 mutex_lock(&devlink
->lock
);
5484 list_for_each_entry(trap_item
, &devlink
->trap_list
, list
) {
5489 err
= devlink_nl_trap_fill(msg
, devlink
, trap_item
,
5490 DEVLINK_CMD_TRAP_NEW
,
5491 NETLINK_CB(cb
->skb
).portid
,
5495 mutex_unlock(&devlink
->lock
);
5500 mutex_unlock(&devlink
->lock
);
5503 mutex_unlock(&devlink_mutex
);
5509 static int __devlink_trap_action_set(struct devlink
*devlink
,
5510 struct devlink_trap_item
*trap_item
,
5511 enum devlink_trap_action trap_action
,
5512 struct netlink_ext_ack
*extack
)
5516 if (trap_item
->action
!= trap_action
&&
5517 trap_item
->trap
->type
!= DEVLINK_TRAP_TYPE_DROP
) {
5518 NL_SET_ERR_MSG_MOD(extack
, "Cannot change action of non-drop traps. Skipping");
5522 err
= devlink
->ops
->trap_action_set(devlink
, trap_item
->trap
,
5527 trap_item
->action
= trap_action
;
5532 static int devlink_trap_action_set(struct devlink
*devlink
,
5533 struct devlink_trap_item
*trap_item
,
5534 struct genl_info
*info
)
5536 enum devlink_trap_action trap_action
;
5539 if (!info
->attrs
[DEVLINK_ATTR_TRAP_ACTION
])
5542 err
= devlink_trap_action_get_from_info(info
, &trap_action
);
5544 NL_SET_ERR_MSG_MOD(info
->extack
, "Invalid trap action");
5548 return __devlink_trap_action_set(devlink
, trap_item
, trap_action
,
5552 static int devlink_nl_cmd_trap_set_doit(struct sk_buff
*skb
,
5553 struct genl_info
*info
)
5555 struct netlink_ext_ack
*extack
= info
->extack
;
5556 struct devlink
*devlink
= info
->user_ptr
[0];
5557 struct devlink_trap_item
*trap_item
;
5560 if (list_empty(&devlink
->trap_list
))
5563 trap_item
= devlink_trap_item_get_from_info(devlink
, info
);
5565 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap");
5569 err
= devlink_trap_action_set(devlink
, trap_item
, info
);
5576 static struct devlink_trap_group_item
*
5577 devlink_trap_group_item_lookup(struct devlink
*devlink
, const char *name
)
5579 struct devlink_trap_group_item
*group_item
;
5581 list_for_each_entry(group_item
, &devlink
->trap_group_list
, list
) {
5582 if (!strcmp(group_item
->group
->name
, name
))
5589 static struct devlink_trap_group_item
*
5590 devlink_trap_group_item_get_from_info(struct devlink
*devlink
,
5591 struct genl_info
*info
)
5595 if (!info
->attrs
[DEVLINK_ATTR_TRAP_GROUP_NAME
])
5597 name
= nla_data(info
->attrs
[DEVLINK_ATTR_TRAP_GROUP_NAME
]);
5599 return devlink_trap_group_item_lookup(devlink
, name
);
5603 devlink_nl_trap_group_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
5604 const struct devlink_trap_group_item
*group_item
,
5605 enum devlink_command cmd
, u32 portid
, u32 seq
,
5611 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
5615 if (devlink_nl_put_handle(msg
, devlink
))
5616 goto nla_put_failure
;
5618 if (nla_put_string(msg
, DEVLINK_ATTR_TRAP_GROUP_NAME
,
5619 group_item
->group
->name
))
5620 goto nla_put_failure
;
5622 if (group_item
->group
->generic
&&
5623 nla_put_flag(msg
, DEVLINK_ATTR_TRAP_GENERIC
))
5624 goto nla_put_failure
;
5626 err
= devlink_trap_stats_put(msg
, group_item
->stats
);
5628 goto nla_put_failure
;
5630 genlmsg_end(msg
, hdr
);
5635 genlmsg_cancel(msg
, hdr
);
5639 static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff
*skb
,
5640 struct genl_info
*info
)
5642 struct netlink_ext_ack
*extack
= info
->extack
;
5643 struct devlink
*devlink
= info
->user_ptr
[0];
5644 struct devlink_trap_group_item
*group_item
;
5645 struct sk_buff
*msg
;
5648 if (list_empty(&devlink
->trap_group_list
))
5651 group_item
= devlink_trap_group_item_get_from_info(devlink
, info
);
5653 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap group");
5657 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
5661 err
= devlink_nl_trap_group_fill(msg
, devlink
, group_item
,
5662 DEVLINK_CMD_TRAP_GROUP_NEW
,
5663 info
->snd_portid
, info
->snd_seq
, 0);
5665 goto err_trap_group_fill
;
5667 return genlmsg_reply(msg
, info
);
5669 err_trap_group_fill
:
5674 static int devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff
*msg
,
5675 struct netlink_callback
*cb
)
5677 enum devlink_command cmd
= DEVLINK_CMD_TRAP_GROUP_NEW
;
5678 struct devlink_trap_group_item
*group_item
;
5679 u32 portid
= NETLINK_CB(cb
->skb
).portid
;
5680 struct devlink
*devlink
;
5681 int start
= cb
->args
[0];
5685 mutex_lock(&devlink_mutex
);
5686 list_for_each_entry(devlink
, &devlink_list
, list
) {
5687 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
5689 mutex_lock(&devlink
->lock
);
5690 list_for_each_entry(group_item
, &devlink
->trap_group_list
,
5696 err
= devlink_nl_trap_group_fill(msg
, devlink
,
5702 mutex_unlock(&devlink
->lock
);
5707 mutex_unlock(&devlink
->lock
);
5710 mutex_unlock(&devlink_mutex
);
5717 __devlink_trap_group_action_set(struct devlink
*devlink
,
5718 struct devlink_trap_group_item
*group_item
,
5719 enum devlink_trap_action trap_action
,
5720 struct netlink_ext_ack
*extack
)
5722 const char *group_name
= group_item
->group
->name
;
5723 struct devlink_trap_item
*trap_item
;
5726 list_for_each_entry(trap_item
, &devlink
->trap_list
, list
) {
5727 if (strcmp(trap_item
->trap
->group
.name
, group_name
))
5729 err
= __devlink_trap_action_set(devlink
, trap_item
,
5730 trap_action
, extack
);
5739 devlink_trap_group_action_set(struct devlink
*devlink
,
5740 struct devlink_trap_group_item
*group_item
,
5741 struct genl_info
*info
)
5743 enum devlink_trap_action trap_action
;
5746 if (!info
->attrs
[DEVLINK_ATTR_TRAP_ACTION
])
5749 err
= devlink_trap_action_get_from_info(info
, &trap_action
);
5751 NL_SET_ERR_MSG_MOD(info
->extack
, "Invalid trap action");
5755 err
= __devlink_trap_group_action_set(devlink
, group_item
, trap_action
,
5763 static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff
*skb
,
5764 struct genl_info
*info
)
5766 struct netlink_ext_ack
*extack
= info
->extack
;
5767 struct devlink
*devlink
= info
->user_ptr
[0];
5768 struct devlink_trap_group_item
*group_item
;
5771 if (list_empty(&devlink
->trap_group_list
))
5774 group_item
= devlink_trap_group_item_get_from_info(devlink
, info
);
5776 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap group");
5780 err
= devlink_trap_group_action_set(devlink
, group_item
, info
);
5787 static const struct nla_policy devlink_nl_policy
[DEVLINK_ATTR_MAX
+ 1] = {
5788 [DEVLINK_ATTR_BUS_NAME
] = { .type
= NLA_NUL_STRING
},
5789 [DEVLINK_ATTR_DEV_NAME
] = { .type
= NLA_NUL_STRING
},
5790 [DEVLINK_ATTR_PORT_INDEX
] = { .type
= NLA_U32
},
5791 [DEVLINK_ATTR_PORT_TYPE
] = { .type
= NLA_U16
},
5792 [DEVLINK_ATTR_PORT_SPLIT_COUNT
] = { .type
= NLA_U32
},
5793 [DEVLINK_ATTR_SB_INDEX
] = { .type
= NLA_U32
},
5794 [DEVLINK_ATTR_SB_POOL_INDEX
] = { .type
= NLA_U16
},
5795 [DEVLINK_ATTR_SB_POOL_TYPE
] = { .type
= NLA_U8
},
5796 [DEVLINK_ATTR_SB_POOL_SIZE
] = { .type
= NLA_U32
},
5797 [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
] = { .type
= NLA_U8
},
5798 [DEVLINK_ATTR_SB_THRESHOLD
] = { .type
= NLA_U32
},
5799 [DEVLINK_ATTR_SB_TC_INDEX
] = { .type
= NLA_U16
},
5800 [DEVLINK_ATTR_ESWITCH_MODE
] = { .type
= NLA_U16
},
5801 [DEVLINK_ATTR_ESWITCH_INLINE_MODE
] = { .type
= NLA_U8
},
5802 [DEVLINK_ATTR_ESWITCH_ENCAP_MODE
] = { .type
= NLA_U8
},
5803 [DEVLINK_ATTR_DPIPE_TABLE_NAME
] = { .type
= NLA_NUL_STRING
},
5804 [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
] = { .type
= NLA_U8
},
5805 [DEVLINK_ATTR_RESOURCE_ID
] = { .type
= NLA_U64
},
5806 [DEVLINK_ATTR_RESOURCE_SIZE
] = { .type
= NLA_U64
},
5807 [DEVLINK_ATTR_PARAM_NAME
] = { .type
= NLA_NUL_STRING
},
5808 [DEVLINK_ATTR_PARAM_TYPE
] = { .type
= NLA_U8
},
5809 [DEVLINK_ATTR_PARAM_VALUE_CMODE
] = { .type
= NLA_U8
},
5810 [DEVLINK_ATTR_REGION_NAME
] = { .type
= NLA_NUL_STRING
},
5811 [DEVLINK_ATTR_REGION_SNAPSHOT_ID
] = { .type
= NLA_U32
},
5812 [DEVLINK_ATTR_REGION_CHUNK_ADDR
] = { .type
= NLA_U64
},
5813 [DEVLINK_ATTR_REGION_CHUNK_LEN
] = { .type
= NLA_U64
},
5814 [DEVLINK_ATTR_HEALTH_REPORTER_NAME
] = { .type
= NLA_NUL_STRING
},
5815 [DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
] = { .type
= NLA_U64
},
5816 [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
] = { .type
= NLA_U8
},
5817 [DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME
] = { .type
= NLA_NUL_STRING
},
5818 [DEVLINK_ATTR_FLASH_UPDATE_COMPONENT
] = { .type
= NLA_NUL_STRING
},
5819 [DEVLINK_ATTR_TRAP_NAME
] = { .type
= NLA_NUL_STRING
},
5820 [DEVLINK_ATTR_TRAP_ACTION
] = { .type
= NLA_U8
},
5821 [DEVLINK_ATTR_TRAP_GROUP_NAME
] = { .type
= NLA_NUL_STRING
},
5824 static const struct genl_ops devlink_nl_ops
[] = {
5826 .cmd
= DEVLINK_CMD_GET
,
5827 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5828 .doit
= devlink_nl_cmd_get_doit
,
5829 .dumpit
= devlink_nl_cmd_get_dumpit
,
5830 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
5831 /* can be retrieved by unprivileged users */
5834 .cmd
= DEVLINK_CMD_PORT_GET
,
5835 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5836 .doit
= devlink_nl_cmd_port_get_doit
,
5837 .dumpit
= devlink_nl_cmd_port_get_dumpit
,
5838 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
5839 /* can be retrieved by unprivileged users */
5842 .cmd
= DEVLINK_CMD_PORT_SET
,
5843 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5844 .doit
= devlink_nl_cmd_port_set_doit
,
5845 .flags
= GENL_ADMIN_PERM
,
5846 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
5849 .cmd
= DEVLINK_CMD_PORT_SPLIT
,
5850 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5851 .doit
= devlink_nl_cmd_port_split_doit
,
5852 .flags
= GENL_ADMIN_PERM
,
5853 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
5854 DEVLINK_NL_FLAG_NO_LOCK
,
5857 .cmd
= DEVLINK_CMD_PORT_UNSPLIT
,
5858 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5859 .doit
= devlink_nl_cmd_port_unsplit_doit
,
5860 .flags
= GENL_ADMIN_PERM
,
5861 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
5862 DEVLINK_NL_FLAG_NO_LOCK
,
5865 .cmd
= DEVLINK_CMD_SB_GET
,
5866 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5867 .doit
= devlink_nl_cmd_sb_get_doit
,
5868 .dumpit
= devlink_nl_cmd_sb_get_dumpit
,
5869 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
5870 DEVLINK_NL_FLAG_NEED_SB
,
5871 /* can be retrieved by unprivileged users */
5874 .cmd
= DEVLINK_CMD_SB_POOL_GET
,
5875 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5876 .doit
= devlink_nl_cmd_sb_pool_get_doit
,
5877 .dumpit
= devlink_nl_cmd_sb_pool_get_dumpit
,
5878 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
5879 DEVLINK_NL_FLAG_NEED_SB
,
5880 /* can be retrieved by unprivileged users */
5883 .cmd
= DEVLINK_CMD_SB_POOL_SET
,
5884 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5885 .doit
= devlink_nl_cmd_sb_pool_set_doit
,
5886 .flags
= GENL_ADMIN_PERM
,
5887 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
5888 DEVLINK_NL_FLAG_NEED_SB
,
5891 .cmd
= DEVLINK_CMD_SB_PORT_POOL_GET
,
5892 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5893 .doit
= devlink_nl_cmd_sb_port_pool_get_doit
,
5894 .dumpit
= devlink_nl_cmd_sb_port_pool_get_dumpit
,
5895 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
5896 DEVLINK_NL_FLAG_NEED_SB
,
5897 /* can be retrieved by unprivileged users */
5900 .cmd
= DEVLINK_CMD_SB_PORT_POOL_SET
,
5901 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5902 .doit
= devlink_nl_cmd_sb_port_pool_set_doit
,
5903 .flags
= GENL_ADMIN_PERM
,
5904 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
5905 DEVLINK_NL_FLAG_NEED_SB
,
5908 .cmd
= DEVLINK_CMD_SB_TC_POOL_BIND_GET
,
5909 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5910 .doit
= devlink_nl_cmd_sb_tc_pool_bind_get_doit
,
5911 .dumpit
= devlink_nl_cmd_sb_tc_pool_bind_get_dumpit
,
5912 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
5913 DEVLINK_NL_FLAG_NEED_SB
,
5914 /* can be retrieved by unprivileged users */
5917 .cmd
= DEVLINK_CMD_SB_TC_POOL_BIND_SET
,
5918 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5919 .doit
= devlink_nl_cmd_sb_tc_pool_bind_set_doit
,
5920 .flags
= GENL_ADMIN_PERM
,
5921 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
5922 DEVLINK_NL_FLAG_NEED_SB
,
5925 .cmd
= DEVLINK_CMD_SB_OCC_SNAPSHOT
,
5926 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5927 .doit
= devlink_nl_cmd_sb_occ_snapshot_doit
,
5928 .flags
= GENL_ADMIN_PERM
,
5929 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
5930 DEVLINK_NL_FLAG_NEED_SB
,
5933 .cmd
= DEVLINK_CMD_SB_OCC_MAX_CLEAR
,
5934 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5935 .doit
= devlink_nl_cmd_sb_occ_max_clear_doit
,
5936 .flags
= GENL_ADMIN_PERM
,
5937 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
5938 DEVLINK_NL_FLAG_NEED_SB
,
5941 .cmd
= DEVLINK_CMD_ESWITCH_GET
,
5942 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5943 .doit
= devlink_nl_cmd_eswitch_get_doit
,
5944 .flags
= GENL_ADMIN_PERM
,
5945 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
5948 .cmd
= DEVLINK_CMD_ESWITCH_SET
,
5949 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5950 .doit
= devlink_nl_cmd_eswitch_set_doit
,
5951 .flags
= GENL_ADMIN_PERM
,
5952 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
5953 DEVLINK_NL_FLAG_NO_LOCK
,
5956 .cmd
= DEVLINK_CMD_DPIPE_TABLE_GET
,
5957 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5958 .doit
= devlink_nl_cmd_dpipe_table_get
,
5959 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
5960 /* can be retrieved by unprivileged users */
5963 .cmd
= DEVLINK_CMD_DPIPE_ENTRIES_GET
,
5964 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5965 .doit
= devlink_nl_cmd_dpipe_entries_get
,
5966 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
5967 /* can be retrieved by unprivileged users */
5970 .cmd
= DEVLINK_CMD_DPIPE_HEADERS_GET
,
5971 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5972 .doit
= devlink_nl_cmd_dpipe_headers_get
,
5973 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
5974 /* can be retrieved by unprivileged users */
5977 .cmd
= DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET
,
5978 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5979 .doit
= devlink_nl_cmd_dpipe_table_counters_set
,
5980 .flags
= GENL_ADMIN_PERM
,
5981 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
5984 .cmd
= DEVLINK_CMD_RESOURCE_SET
,
5985 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5986 .doit
= devlink_nl_cmd_resource_set
,
5987 .flags
= GENL_ADMIN_PERM
,
5988 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
5991 .cmd
= DEVLINK_CMD_RESOURCE_DUMP
,
5992 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5993 .doit
= devlink_nl_cmd_resource_dump
,
5994 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
5995 /* can be retrieved by unprivileged users */
5998 .cmd
= DEVLINK_CMD_RELOAD
,
5999 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6000 .doit
= devlink_nl_cmd_reload
,
6001 .flags
= GENL_ADMIN_PERM
,
6002 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6003 DEVLINK_NL_FLAG_NO_LOCK
,
6006 .cmd
= DEVLINK_CMD_PARAM_GET
,
6007 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6008 .doit
= devlink_nl_cmd_param_get_doit
,
6009 .dumpit
= devlink_nl_cmd_param_get_dumpit
,
6010 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6011 /* can be retrieved by unprivileged users */
6014 .cmd
= DEVLINK_CMD_PARAM_SET
,
6015 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6016 .doit
= devlink_nl_cmd_param_set_doit
,
6017 .flags
= GENL_ADMIN_PERM
,
6018 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6021 .cmd
= DEVLINK_CMD_PORT_PARAM_GET
,
6022 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6023 .doit
= devlink_nl_cmd_port_param_get_doit
,
6024 .dumpit
= devlink_nl_cmd_port_param_get_dumpit
,
6025 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
6026 /* can be retrieved by unprivileged users */
6029 .cmd
= DEVLINK_CMD_PORT_PARAM_SET
,
6030 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6031 .doit
= devlink_nl_cmd_port_param_set_doit
,
6032 .flags
= GENL_ADMIN_PERM
,
6033 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
6036 .cmd
= DEVLINK_CMD_REGION_GET
,
6037 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6038 .doit
= devlink_nl_cmd_region_get_doit
,
6039 .dumpit
= devlink_nl_cmd_region_get_dumpit
,
6040 .flags
= GENL_ADMIN_PERM
,
6041 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6044 .cmd
= DEVLINK_CMD_REGION_DEL
,
6045 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6046 .doit
= devlink_nl_cmd_region_del
,
6047 .flags
= GENL_ADMIN_PERM
,
6048 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6051 .cmd
= DEVLINK_CMD_REGION_READ
,
6052 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6053 .dumpit
= devlink_nl_cmd_region_read_dumpit
,
6054 .flags
= GENL_ADMIN_PERM
,
6055 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6058 .cmd
= DEVLINK_CMD_INFO_GET
,
6059 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6060 .doit
= devlink_nl_cmd_info_get_doit
,
6061 .dumpit
= devlink_nl_cmd_info_get_dumpit
,
6062 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6063 /* can be retrieved by unprivileged users */
6066 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_GET
,
6067 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6068 .doit
= devlink_nl_cmd_health_reporter_get_doit
,
6069 .dumpit
= devlink_nl_cmd_health_reporter_get_dumpit
,
6070 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6071 DEVLINK_NL_FLAG_NO_LOCK
,
6072 /* can be retrieved by unprivileged users */
6075 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_SET
,
6076 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6077 .doit
= devlink_nl_cmd_health_reporter_set_doit
,
6078 .flags
= GENL_ADMIN_PERM
,
6079 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6080 DEVLINK_NL_FLAG_NO_LOCK
,
6083 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_RECOVER
,
6084 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6085 .doit
= devlink_nl_cmd_health_reporter_recover_doit
,
6086 .flags
= GENL_ADMIN_PERM
,
6087 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6088 DEVLINK_NL_FLAG_NO_LOCK
,
6091 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE
,
6092 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6093 .doit
= devlink_nl_cmd_health_reporter_diagnose_doit
,
6094 .flags
= GENL_ADMIN_PERM
,
6095 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6096 DEVLINK_NL_FLAG_NO_LOCK
,
6099 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET
,
6100 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6101 .dumpit
= devlink_nl_cmd_health_reporter_dump_get_dumpit
,
6102 .flags
= GENL_ADMIN_PERM
,
6103 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6104 DEVLINK_NL_FLAG_NO_LOCK
,
6107 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR
,
6108 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6109 .doit
= devlink_nl_cmd_health_reporter_dump_clear_doit
,
6110 .flags
= GENL_ADMIN_PERM
,
6111 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6112 DEVLINK_NL_FLAG_NO_LOCK
,
6115 .cmd
= DEVLINK_CMD_FLASH_UPDATE
,
6116 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6117 .doit
= devlink_nl_cmd_flash_update
,
6118 .flags
= GENL_ADMIN_PERM
,
6119 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6122 .cmd
= DEVLINK_CMD_TRAP_GET
,
6123 .doit
= devlink_nl_cmd_trap_get_doit
,
6124 .dumpit
= devlink_nl_cmd_trap_get_dumpit
,
6125 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6126 /* can be retrieved by unprivileged users */
6129 .cmd
= DEVLINK_CMD_TRAP_SET
,
6130 .doit
= devlink_nl_cmd_trap_set_doit
,
6131 .flags
= GENL_ADMIN_PERM
,
6132 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6135 .cmd
= DEVLINK_CMD_TRAP_GROUP_GET
,
6136 .doit
= devlink_nl_cmd_trap_group_get_doit
,
6137 .dumpit
= devlink_nl_cmd_trap_group_get_dumpit
,
6138 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6139 /* can be retrieved by unprivileged users */
6142 .cmd
= DEVLINK_CMD_TRAP_GROUP_SET
,
6143 .doit
= devlink_nl_cmd_trap_group_set_doit
,
6144 .flags
= GENL_ADMIN_PERM
,
6145 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6149 static struct genl_family devlink_nl_family __ro_after_init
= {
6150 .name
= DEVLINK_GENL_NAME
,
6151 .version
= DEVLINK_GENL_VERSION
,
6152 .maxattr
= DEVLINK_ATTR_MAX
,
6153 .policy
= devlink_nl_policy
,
6155 .pre_doit
= devlink_nl_pre_doit
,
6156 .post_doit
= devlink_nl_post_doit
,
6157 .module
= THIS_MODULE
,
6158 .ops
= devlink_nl_ops
,
6159 .n_ops
= ARRAY_SIZE(devlink_nl_ops
),
6160 .mcgrps
= devlink_nl_mcgrps
,
6161 .n_mcgrps
= ARRAY_SIZE(devlink_nl_mcgrps
),
6165 * devlink_alloc - Allocate new devlink instance resources
6168 * @priv_size: size of user private data
6170 * Allocate new devlink instance resources, including devlink index
6173 struct devlink
*devlink_alloc(const struct devlink_ops
*ops
, size_t priv_size
)
6175 struct devlink
*devlink
;
6180 devlink
= kzalloc(sizeof(*devlink
) + priv_size
, GFP_KERNEL
);
6184 devlink_net_set(devlink
, &init_net
);
6185 INIT_LIST_HEAD(&devlink
->port_list
);
6186 INIT_LIST_HEAD(&devlink
->sb_list
);
6187 INIT_LIST_HEAD_RCU(&devlink
->dpipe_table_list
);
6188 INIT_LIST_HEAD(&devlink
->resource_list
);
6189 INIT_LIST_HEAD(&devlink
->param_list
);
6190 INIT_LIST_HEAD(&devlink
->region_list
);
6191 INIT_LIST_HEAD(&devlink
->reporter_list
);
6192 INIT_LIST_HEAD(&devlink
->trap_list
);
6193 INIT_LIST_HEAD(&devlink
->trap_group_list
);
6194 mutex_init(&devlink
->lock
);
6195 mutex_init(&devlink
->reporters_lock
);
6198 EXPORT_SYMBOL_GPL(devlink_alloc
);
6201 * devlink_register - Register devlink instance
6204 * @dev: parent device
6206 int devlink_register(struct devlink
*devlink
, struct device
*dev
)
6208 mutex_lock(&devlink_mutex
);
6210 list_add_tail(&devlink
->list
, &devlink_list
);
6211 devlink_notify(devlink
, DEVLINK_CMD_NEW
);
6212 mutex_unlock(&devlink_mutex
);
6215 EXPORT_SYMBOL_GPL(devlink_register
);
6218 * devlink_unregister - Unregister devlink instance
6222 void devlink_unregister(struct devlink
*devlink
)
6224 mutex_lock(&devlink_mutex
);
6225 WARN_ON(devlink_reload_supported(devlink
) &&
6226 devlink
->reload_enabled
);
6227 devlink_notify(devlink
, DEVLINK_CMD_DEL
);
6228 list_del(&devlink
->list
);
6229 mutex_unlock(&devlink_mutex
);
6231 EXPORT_SYMBOL_GPL(devlink_unregister
);
6234 * devlink_reload_enable - Enable reload of devlink instance
6238 * Should be called at end of device initialization
6239 * process when reload operation is supported.
6241 void devlink_reload_enable(struct devlink
*devlink
)
6243 mutex_lock(&devlink_mutex
);
6244 devlink
->reload_enabled
= true;
6245 mutex_unlock(&devlink_mutex
);
6247 EXPORT_SYMBOL_GPL(devlink_reload_enable
);
6250 * devlink_reload_disable - Disable reload of devlink instance
6254 * Should be called at the beginning of device cleanup
6255 * process when reload operation is supported.
6257 void devlink_reload_disable(struct devlink
*devlink
)
6259 mutex_lock(&devlink_mutex
);
6260 /* Mutex is taken which ensures that no reload operation is in
6261 * progress while setting up forbidded flag.
6263 devlink
->reload_enabled
= false;
6264 mutex_unlock(&devlink_mutex
);
6266 EXPORT_SYMBOL_GPL(devlink_reload_disable
);
6269 * devlink_free - Free devlink instance resources
6273 void devlink_free(struct devlink
*devlink
)
6275 mutex_destroy(&devlink
->reporters_lock
);
6276 mutex_destroy(&devlink
->lock
);
6277 WARN_ON(!list_empty(&devlink
->trap_group_list
));
6278 WARN_ON(!list_empty(&devlink
->trap_list
));
6279 WARN_ON(!list_empty(&devlink
->reporter_list
));
6280 WARN_ON(!list_empty(&devlink
->region_list
));
6281 WARN_ON(!list_empty(&devlink
->param_list
));
6282 WARN_ON(!list_empty(&devlink
->resource_list
));
6283 WARN_ON(!list_empty(&devlink
->dpipe_table_list
));
6284 WARN_ON(!list_empty(&devlink
->sb_list
));
6285 WARN_ON(!list_empty(&devlink
->port_list
));
6289 EXPORT_SYMBOL_GPL(devlink_free
);
6291 static void devlink_port_type_warn(struct work_struct
*work
)
6293 WARN(true, "Type was not set for devlink port.");
6296 static bool devlink_port_type_should_warn(struct devlink_port
*devlink_port
)
6298 /* Ignore CPU and DSA flavours. */
6299 return devlink_port
->attrs
.flavour
!= DEVLINK_PORT_FLAVOUR_CPU
&&
6300 devlink_port
->attrs
.flavour
!= DEVLINK_PORT_FLAVOUR_DSA
;
6303 #define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 3600)
6305 static void devlink_port_type_warn_schedule(struct devlink_port
*devlink_port
)
6307 if (!devlink_port_type_should_warn(devlink_port
))
6309 /* Schedule a work to WARN in case driver does not set port
6310 * type within timeout.
6312 schedule_delayed_work(&devlink_port
->type_warn_dw
,
6313 DEVLINK_PORT_TYPE_WARN_TIMEOUT
);
6316 static void devlink_port_type_warn_cancel(struct devlink_port
*devlink_port
)
6318 if (!devlink_port_type_should_warn(devlink_port
))
6320 cancel_delayed_work_sync(&devlink_port
->type_warn_dw
);
6324 * devlink_port_register - Register devlink port
6327 * @devlink_port: devlink port
6328 * @port_index: driver-specific numerical identifier of the port
6330 * Register devlink port with provided port index. User can use
6331 * any indexing, even hw-related one. devlink_port structure
6332 * is convenient to be embedded inside user driver private structure.
6333 * Note that the caller should take care of zeroing the devlink_port
6336 int devlink_port_register(struct devlink
*devlink
,
6337 struct devlink_port
*devlink_port
,
6338 unsigned int port_index
)
6340 mutex_lock(&devlink
->lock
);
6341 if (devlink_port_index_exists(devlink
, port_index
)) {
6342 mutex_unlock(&devlink
->lock
);
6345 devlink_port
->devlink
= devlink
;
6346 devlink_port
->index
= port_index
;
6347 devlink_port
->registered
= true;
6348 spin_lock_init(&devlink_port
->type_lock
);
6349 list_add_tail(&devlink_port
->list
, &devlink
->port_list
);
6350 INIT_LIST_HEAD(&devlink_port
->param_list
);
6351 mutex_unlock(&devlink
->lock
);
6352 INIT_DELAYED_WORK(&devlink_port
->type_warn_dw
, &devlink_port_type_warn
);
6353 devlink_port_type_warn_schedule(devlink_port
);
6354 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
6357 EXPORT_SYMBOL_GPL(devlink_port_register
);
6360 * devlink_port_unregister - Unregister devlink port
6362 * @devlink_port: devlink port
6364 void devlink_port_unregister(struct devlink_port
*devlink_port
)
6366 struct devlink
*devlink
= devlink_port
->devlink
;
6368 devlink_port_type_warn_cancel(devlink_port
);
6369 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_DEL
);
6370 mutex_lock(&devlink
->lock
);
6371 list_del(&devlink_port
->list
);
6372 mutex_unlock(&devlink
->lock
);
6374 EXPORT_SYMBOL_GPL(devlink_port_unregister
);
6376 static void __devlink_port_type_set(struct devlink_port
*devlink_port
,
6377 enum devlink_port_type type
,
6380 if (WARN_ON(!devlink_port
->registered
))
6382 devlink_port_type_warn_cancel(devlink_port
);
6383 spin_lock_bh(&devlink_port
->type_lock
);
6384 devlink_port
->type
= type
;
6385 devlink_port
->type_dev
= type_dev
;
6386 spin_unlock_bh(&devlink_port
->type_lock
);
6387 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
6391 * devlink_port_type_eth_set - Set port type to Ethernet
6393 * @devlink_port: devlink port
6394 * @netdev: related netdevice
6396 void devlink_port_type_eth_set(struct devlink_port
*devlink_port
,
6397 struct net_device
*netdev
)
6399 const struct net_device_ops
*ops
= netdev
->netdev_ops
;
6401 /* If driver registers devlink port, it should set devlink port
6402 * attributes accordingly so the compat functions are called
6403 * and the original ops are not used.
6405 if (ops
->ndo_get_phys_port_name
) {
6406 /* Some drivers use the same set of ndos for netdevs
6407 * that have devlink_port registered and also for
6408 * those who don't. Make sure that ndo_get_phys_port_name
6409 * returns -EOPNOTSUPP here in case it is defined.
6412 char name
[IFNAMSIZ
];
6415 err
= ops
->ndo_get_phys_port_name(netdev
, name
, sizeof(name
));
6416 WARN_ON(err
!= -EOPNOTSUPP
);
6418 if (ops
->ndo_get_port_parent_id
) {
6419 /* Some drivers use the same set of ndos for netdevs
6420 * that have devlink_port registered and also for
6421 * those who don't. Make sure that ndo_get_port_parent_id
6422 * returns -EOPNOTSUPP here in case it is defined.
6425 struct netdev_phys_item_id ppid
;
6428 err
= ops
->ndo_get_port_parent_id(netdev
, &ppid
);
6429 WARN_ON(err
!= -EOPNOTSUPP
);
6431 __devlink_port_type_set(devlink_port
, DEVLINK_PORT_TYPE_ETH
, netdev
);
6433 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set
);
6436 * devlink_port_type_ib_set - Set port type to InfiniBand
6438 * @devlink_port: devlink port
6439 * @ibdev: related IB device
6441 void devlink_port_type_ib_set(struct devlink_port
*devlink_port
,
6442 struct ib_device
*ibdev
)
6444 __devlink_port_type_set(devlink_port
, DEVLINK_PORT_TYPE_IB
, ibdev
);
6446 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set
);
6449 * devlink_port_type_clear - Clear port type
6451 * @devlink_port: devlink port
6453 void devlink_port_type_clear(struct devlink_port
*devlink_port
)
6455 __devlink_port_type_set(devlink_port
, DEVLINK_PORT_TYPE_NOTSET
, NULL
);
6456 devlink_port_type_warn_schedule(devlink_port
);
6458 EXPORT_SYMBOL_GPL(devlink_port_type_clear
);
6460 static int __devlink_port_attrs_set(struct devlink_port
*devlink_port
,
6461 enum devlink_port_flavour flavour
,
6462 const unsigned char *switch_id
,
6463 unsigned char switch_id_len
)
6465 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
6467 if (WARN_ON(devlink_port
->registered
))
6470 attrs
->flavour
= flavour
;
6472 attrs
->switch_port
= true;
6473 if (WARN_ON(switch_id_len
> MAX_PHYS_ITEM_ID_LEN
))
6474 switch_id_len
= MAX_PHYS_ITEM_ID_LEN
;
6475 memcpy(attrs
->switch_id
.id
, switch_id
, switch_id_len
);
6476 attrs
->switch_id
.id_len
= switch_id_len
;
6478 attrs
->switch_port
= false;
6484 * devlink_port_attrs_set - Set port attributes
6486 * @devlink_port: devlink port
6487 * @flavour: flavour of the port
6488 * @port_number: number of the port that is facing user, for example
6489 * the front panel port number
6490 * @split: indicates if this is split port
6491 * @split_subport_number: if the port is split, this is the number
6493 * @switch_id: if the port is part of switch, this is buffer with ID,
6494 * otwerwise this is NULL
6495 * @switch_id_len: length of the switch_id buffer
6497 void devlink_port_attrs_set(struct devlink_port
*devlink_port
,
6498 enum devlink_port_flavour flavour
,
6499 u32 port_number
, bool split
,
6500 u32 split_subport_number
,
6501 const unsigned char *switch_id
,
6502 unsigned char switch_id_len
)
6504 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
6507 ret
= __devlink_port_attrs_set(devlink_port
, flavour
,
6508 switch_id
, switch_id_len
);
6511 attrs
->split
= split
;
6512 attrs
->phys
.port_number
= port_number
;
6513 attrs
->phys
.split_subport_number
= split_subport_number
;
6515 EXPORT_SYMBOL_GPL(devlink_port_attrs_set
);
6518 * devlink_port_attrs_pci_pf_set - Set PCI PF port attributes
6520 * @devlink_port: devlink port
6521 * @pf: associated PF for the devlink port instance
6522 * @switch_id: if the port is part of switch, this is buffer with ID,
6523 * otherwise this is NULL
6524 * @switch_id_len: length of the switch_id buffer
6526 void devlink_port_attrs_pci_pf_set(struct devlink_port
*devlink_port
,
6527 const unsigned char *switch_id
,
6528 unsigned char switch_id_len
, u16 pf
)
6530 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
6533 ret
= __devlink_port_attrs_set(devlink_port
,
6534 DEVLINK_PORT_FLAVOUR_PCI_PF
,
6535 switch_id
, switch_id_len
);
6539 attrs
->pci_pf
.pf
= pf
;
6541 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set
);
6544 * devlink_port_attrs_pci_vf_set - Set PCI VF port attributes
6546 * @devlink_port: devlink port
6547 * @pf: associated PF for the devlink port instance
6548 * @vf: associated VF of a PF for the devlink port instance
6549 * @switch_id: if the port is part of switch, this is buffer with ID,
6550 * otherwise this is NULL
6551 * @switch_id_len: length of the switch_id buffer
6553 void devlink_port_attrs_pci_vf_set(struct devlink_port
*devlink_port
,
6554 const unsigned char *switch_id
,
6555 unsigned char switch_id_len
,
6558 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
6561 ret
= __devlink_port_attrs_set(devlink_port
,
6562 DEVLINK_PORT_FLAVOUR_PCI_VF
,
6563 switch_id
, switch_id_len
);
6566 attrs
->pci_vf
.pf
= pf
;
6567 attrs
->pci_vf
.vf
= vf
;
6569 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set
);
6571 static int __devlink_port_phys_port_name_get(struct devlink_port
*devlink_port
,
6572 char *name
, size_t len
)
6574 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
6580 switch (attrs
->flavour
) {
6581 case DEVLINK_PORT_FLAVOUR_PHYSICAL
:
6583 n
= snprintf(name
, len
, "p%u", attrs
->phys
.port_number
);
6585 n
= snprintf(name
, len
, "p%us%u",
6586 attrs
->phys
.port_number
,
6587 attrs
->phys
.split_subport_number
);
6589 case DEVLINK_PORT_FLAVOUR_CPU
:
6590 case DEVLINK_PORT_FLAVOUR_DSA
:
6591 /* As CPU and DSA ports do not have a netdevice associated
6592 * case should not ever happen.
6596 case DEVLINK_PORT_FLAVOUR_PCI_PF
:
6597 n
= snprintf(name
, len
, "pf%u", attrs
->pci_pf
.pf
);
6599 case DEVLINK_PORT_FLAVOUR_PCI_VF
:
6600 n
= snprintf(name
, len
, "pf%uvf%u",
6601 attrs
->pci_vf
.pf
, attrs
->pci_vf
.vf
);
6611 int devlink_sb_register(struct devlink
*devlink
, unsigned int sb_index
,
6612 u32 size
, u16 ingress_pools_count
,
6613 u16 egress_pools_count
, u16 ingress_tc_count
,
6614 u16 egress_tc_count
)
6616 struct devlink_sb
*devlink_sb
;
6619 mutex_lock(&devlink
->lock
);
6620 if (devlink_sb_index_exists(devlink
, sb_index
)) {
6625 devlink_sb
= kzalloc(sizeof(*devlink_sb
), GFP_KERNEL
);
6630 devlink_sb
->index
= sb_index
;
6631 devlink_sb
->size
= size
;
6632 devlink_sb
->ingress_pools_count
= ingress_pools_count
;
6633 devlink_sb
->egress_pools_count
= egress_pools_count
;
6634 devlink_sb
->ingress_tc_count
= ingress_tc_count
;
6635 devlink_sb
->egress_tc_count
= egress_tc_count
;
6636 list_add_tail(&devlink_sb
->list
, &devlink
->sb_list
);
6638 mutex_unlock(&devlink
->lock
);
6641 EXPORT_SYMBOL_GPL(devlink_sb_register
);
6643 void devlink_sb_unregister(struct devlink
*devlink
, unsigned int sb_index
)
6645 struct devlink_sb
*devlink_sb
;
6647 mutex_lock(&devlink
->lock
);
6648 devlink_sb
= devlink_sb_get_by_index(devlink
, sb_index
);
6649 WARN_ON(!devlink_sb
);
6650 list_del(&devlink_sb
->list
);
6651 mutex_unlock(&devlink
->lock
);
6654 EXPORT_SYMBOL_GPL(devlink_sb_unregister
);
6657 * devlink_dpipe_headers_register - register dpipe headers
6660 * @dpipe_headers: dpipe header array
6662 * Register the headers supported by hardware.
6664 int devlink_dpipe_headers_register(struct devlink
*devlink
,
6665 struct devlink_dpipe_headers
*dpipe_headers
)
6667 mutex_lock(&devlink
->lock
);
6668 devlink
->dpipe_headers
= dpipe_headers
;
6669 mutex_unlock(&devlink
->lock
);
6672 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register
);
6675 * devlink_dpipe_headers_unregister - unregister dpipe headers
6679 * Unregister the headers supported by hardware.
6681 void devlink_dpipe_headers_unregister(struct devlink
*devlink
)
6683 mutex_lock(&devlink
->lock
);
6684 devlink
->dpipe_headers
= NULL
;
6685 mutex_unlock(&devlink
->lock
);
6687 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister
);
6690 * devlink_dpipe_table_counter_enabled - check if counter allocation
6693 * @table_name: tables name
6695 * Used by driver to check if counter allocation is required.
6696 * After counter allocation is turned on the table entries
6697 * are updated to include counter statistics.
6699 * After that point on the driver must respect the counter
6700 * state so that each entry added to the table is added
6703 bool devlink_dpipe_table_counter_enabled(struct devlink
*devlink
,
6704 const char *table_name
)
6706 struct devlink_dpipe_table
*table
;
6710 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
6714 enabled
= table
->counters_enabled
;
6718 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled
);
6721 * devlink_dpipe_table_register - register dpipe table
6724 * @table_name: table name
6725 * @table_ops: table ops
6727 * @counter_control_extern: external control for counters
6729 int devlink_dpipe_table_register(struct devlink
*devlink
,
6730 const char *table_name
,
6731 struct devlink_dpipe_table_ops
*table_ops
,
6732 void *priv
, bool counter_control_extern
)
6734 struct devlink_dpipe_table
*table
;
6736 if (devlink_dpipe_table_find(&devlink
->dpipe_table_list
, table_name
))
6739 if (WARN_ON(!table_ops
->size_get
))
6742 table
= kzalloc(sizeof(*table
), GFP_KERNEL
);
6746 table
->name
= table_name
;
6747 table
->table_ops
= table_ops
;
6749 table
->counter_control_extern
= counter_control_extern
;
6751 mutex_lock(&devlink
->lock
);
6752 list_add_tail_rcu(&table
->list
, &devlink
->dpipe_table_list
);
6753 mutex_unlock(&devlink
->lock
);
6756 EXPORT_SYMBOL_GPL(devlink_dpipe_table_register
);
6759 * devlink_dpipe_table_unregister - unregister dpipe table
6762 * @table_name: table name
6764 void devlink_dpipe_table_unregister(struct devlink
*devlink
,
6765 const char *table_name
)
6767 struct devlink_dpipe_table
*table
;
6769 mutex_lock(&devlink
->lock
);
6770 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
6774 list_del_rcu(&table
->list
);
6775 mutex_unlock(&devlink
->lock
);
6776 kfree_rcu(table
, rcu
);
6779 mutex_unlock(&devlink
->lock
);
6781 EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister
);
6784 * devlink_resource_register - devlink resource register
6787 * @resource_name: resource's name
6788 * @resource_size: resource's size
6789 * @resource_id: resource's id
6790 * @parent_resource_id: resource's parent id
6791 * @size_params: size parameters
6793 int devlink_resource_register(struct devlink
*devlink
,
6794 const char *resource_name
,
6797 u64 parent_resource_id
,
6798 const struct devlink_resource_size_params
*size_params
)
6800 struct devlink_resource
*resource
;
6801 struct list_head
*resource_list
;
6805 top_hierarchy
= parent_resource_id
== DEVLINK_RESOURCE_ID_PARENT_TOP
;
6807 mutex_lock(&devlink
->lock
);
6808 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
6814 resource
= kzalloc(sizeof(*resource
), GFP_KERNEL
);
6820 if (top_hierarchy
) {
6821 resource_list
= &devlink
->resource_list
;
6823 struct devlink_resource
*parent_resource
;
6825 parent_resource
= devlink_resource_find(devlink
, NULL
,
6826 parent_resource_id
);
6827 if (parent_resource
) {
6828 resource_list
= &parent_resource
->resource_list
;
6829 resource
->parent
= parent_resource
;
6837 resource
->name
= resource_name
;
6838 resource
->size
= resource_size
;
6839 resource
->size_new
= resource_size
;
6840 resource
->id
= resource_id
;
6841 resource
->size_valid
= true;
6842 memcpy(&resource
->size_params
, size_params
,
6843 sizeof(resource
->size_params
));
6844 INIT_LIST_HEAD(&resource
->resource_list
);
6845 list_add_tail(&resource
->list
, resource_list
);
6847 mutex_unlock(&devlink
->lock
);
6850 EXPORT_SYMBOL_GPL(devlink_resource_register
);
6853 * devlink_resources_unregister - free all resources
6856 * @resource: resource
6858 void devlink_resources_unregister(struct devlink
*devlink
,
6859 struct devlink_resource
*resource
)
6861 struct devlink_resource
*tmp
, *child_resource
;
6862 struct list_head
*resource_list
;
6865 resource_list
= &resource
->resource_list
;
6867 resource_list
= &devlink
->resource_list
;
6870 mutex_lock(&devlink
->lock
);
6872 list_for_each_entry_safe(child_resource
, tmp
, resource_list
, list
) {
6873 devlink_resources_unregister(devlink
, child_resource
);
6874 list_del(&child_resource
->list
);
6875 kfree(child_resource
);
6879 mutex_unlock(&devlink
->lock
);
6881 EXPORT_SYMBOL_GPL(devlink_resources_unregister
);
6884 * devlink_resource_size_get - get and update size
6887 * @resource_id: the requested resource id
6888 * @p_resource_size: ptr to update
6890 int devlink_resource_size_get(struct devlink
*devlink
,
6892 u64
*p_resource_size
)
6894 struct devlink_resource
*resource
;
6897 mutex_lock(&devlink
->lock
);
6898 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
6903 *p_resource_size
= resource
->size_new
;
6904 resource
->size
= resource
->size_new
;
6906 mutex_unlock(&devlink
->lock
);
6909 EXPORT_SYMBOL_GPL(devlink_resource_size_get
);
6912 * devlink_dpipe_table_resource_set - set the resource id
6915 * @table_name: table name
6916 * @resource_id: resource id
6917 * @resource_units: number of resource's units consumed per table's entry
6919 int devlink_dpipe_table_resource_set(struct devlink
*devlink
,
6920 const char *table_name
, u64 resource_id
,
6923 struct devlink_dpipe_table
*table
;
6926 mutex_lock(&devlink
->lock
);
6927 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
6933 table
->resource_id
= resource_id
;
6934 table
->resource_units
= resource_units
;
6935 table
->resource_valid
= true;
6937 mutex_unlock(&devlink
->lock
);
6940 EXPORT_SYMBOL_GPL(devlink_dpipe_table_resource_set
);
6943 * devlink_resource_occ_get_register - register occupancy getter
6946 * @resource_id: resource id
6947 * @occ_get: occupancy getter callback
6948 * @occ_get_priv: occupancy getter callback priv
6950 void devlink_resource_occ_get_register(struct devlink
*devlink
,
6952 devlink_resource_occ_get_t
*occ_get
,
6955 struct devlink_resource
*resource
;
6957 mutex_lock(&devlink
->lock
);
6958 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
6959 if (WARN_ON(!resource
))
6961 WARN_ON(resource
->occ_get
);
6963 resource
->occ_get
= occ_get
;
6964 resource
->occ_get_priv
= occ_get_priv
;
6966 mutex_unlock(&devlink
->lock
);
6968 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register
);
6971 * devlink_resource_occ_get_unregister - unregister occupancy getter
6974 * @resource_id: resource id
6976 void devlink_resource_occ_get_unregister(struct devlink
*devlink
,
6979 struct devlink_resource
*resource
;
6981 mutex_lock(&devlink
->lock
);
6982 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
6983 if (WARN_ON(!resource
))
6985 WARN_ON(!resource
->occ_get
);
6987 resource
->occ_get
= NULL
;
6988 resource
->occ_get_priv
= NULL
;
6990 mutex_unlock(&devlink
->lock
);
6992 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister
);
6994 static int devlink_param_verify(const struct devlink_param
*param
)
6996 if (!param
|| !param
->name
|| !param
->supported_cmodes
)
6999 return devlink_param_generic_verify(param
);
7001 return devlink_param_driver_verify(param
);
7004 static int __devlink_params_register(struct devlink
*devlink
,
7005 unsigned int port_index
,
7006 struct list_head
*param_list
,
7007 const struct devlink_param
*params
,
7008 size_t params_count
,
7009 enum devlink_command reg_cmd
,
7010 enum devlink_command unreg_cmd
)
7012 const struct devlink_param
*param
= params
;
7016 mutex_lock(&devlink
->lock
);
7017 for (i
= 0; i
< params_count
; i
++, param
++) {
7018 err
= devlink_param_verify(param
);
7022 err
= devlink_param_register_one(devlink
, port_index
,
7023 param_list
, param
, reg_cmd
);
7028 mutex_unlock(&devlink
->lock
);
7034 for (param
--; i
> 0; i
--, param
--)
7035 devlink_param_unregister_one(devlink
, port_index
, param_list
,
7038 mutex_unlock(&devlink
->lock
);
7042 static void __devlink_params_unregister(struct devlink
*devlink
,
7043 unsigned int port_index
,
7044 struct list_head
*param_list
,
7045 const struct devlink_param
*params
,
7046 size_t params_count
,
7047 enum devlink_command cmd
)
7049 const struct devlink_param
*param
= params
;
7052 mutex_lock(&devlink
->lock
);
7053 for (i
= 0; i
< params_count
; i
++, param
++)
7054 devlink_param_unregister_one(devlink
, 0, param_list
, param
,
7056 mutex_unlock(&devlink
->lock
);
7060 * devlink_params_register - register configuration parameters
7063 * @params: configuration parameters array
7064 * @params_count: number of parameters provided
7066 * Register the configuration parameters supported by the driver.
7068 int devlink_params_register(struct devlink
*devlink
,
7069 const struct devlink_param
*params
,
7070 size_t params_count
)
7072 return __devlink_params_register(devlink
, 0, &devlink
->param_list
,
7073 params
, params_count
,
7074 DEVLINK_CMD_PARAM_NEW
,
7075 DEVLINK_CMD_PARAM_DEL
);
7077 EXPORT_SYMBOL_GPL(devlink_params_register
);
7080 * devlink_params_unregister - unregister configuration parameters
7082 * @params: configuration parameters to unregister
7083 * @params_count: number of parameters provided
7085 void devlink_params_unregister(struct devlink
*devlink
,
7086 const struct devlink_param
*params
,
7087 size_t params_count
)
7089 return __devlink_params_unregister(devlink
, 0, &devlink
->param_list
,
7090 params
, params_count
,
7091 DEVLINK_CMD_PARAM_DEL
);
7093 EXPORT_SYMBOL_GPL(devlink_params_unregister
);
7096 * devlink_params_publish - publish configuration parameters
7100 * Publish previously registered configuration parameters.
7102 void devlink_params_publish(struct devlink
*devlink
)
7104 struct devlink_param_item
*param_item
;
7106 list_for_each_entry(param_item
, &devlink
->param_list
, list
) {
7107 if (param_item
->published
)
7109 param_item
->published
= true;
7110 devlink_param_notify(devlink
, 0, param_item
,
7111 DEVLINK_CMD_PARAM_NEW
);
7114 EXPORT_SYMBOL_GPL(devlink_params_publish
);
7117 * devlink_params_unpublish - unpublish configuration parameters
7121 * Unpublish previously registered configuration parameters.
7123 void devlink_params_unpublish(struct devlink
*devlink
)
7125 struct devlink_param_item
*param_item
;
7127 list_for_each_entry(param_item
, &devlink
->param_list
, list
) {
7128 if (!param_item
->published
)
7130 param_item
->published
= false;
7131 devlink_param_notify(devlink
, 0, param_item
,
7132 DEVLINK_CMD_PARAM_DEL
);
7135 EXPORT_SYMBOL_GPL(devlink_params_unpublish
);
7138 * devlink_port_params_register - register port configuration parameters
7140 * @devlink_port: devlink port
7141 * @params: configuration parameters array
7142 * @params_count: number of parameters provided
7144 * Register the configuration parameters supported by the port.
7146 int devlink_port_params_register(struct devlink_port
*devlink_port
,
7147 const struct devlink_param
*params
,
7148 size_t params_count
)
7150 return __devlink_params_register(devlink_port
->devlink
,
7151 devlink_port
->index
,
7152 &devlink_port
->param_list
, params
,
7154 DEVLINK_CMD_PORT_PARAM_NEW
,
7155 DEVLINK_CMD_PORT_PARAM_DEL
);
7157 EXPORT_SYMBOL_GPL(devlink_port_params_register
);
7160 * devlink_port_params_unregister - unregister port configuration
7163 * @devlink_port: devlink port
7164 * @params: configuration parameters array
7165 * @params_count: number of parameters provided
7167 void devlink_port_params_unregister(struct devlink_port
*devlink_port
,
7168 const struct devlink_param
*params
,
7169 size_t params_count
)
7171 return __devlink_params_unregister(devlink_port
->devlink
,
7172 devlink_port
->index
,
7173 &devlink_port
->param_list
,
7174 params
, params_count
,
7175 DEVLINK_CMD_PORT_PARAM_DEL
);
7177 EXPORT_SYMBOL_GPL(devlink_port_params_unregister
);
7180 __devlink_param_driverinit_value_get(struct list_head
*param_list
, u32 param_id
,
7181 union devlink_param_value
*init_val
)
7183 struct devlink_param_item
*param_item
;
7185 param_item
= devlink_param_find_by_id(param_list
, param_id
);
7189 if (!param_item
->driverinit_value_valid
||
7190 !devlink_param_cmode_is_supported(param_item
->param
,
7191 DEVLINK_PARAM_CMODE_DRIVERINIT
))
7194 if (param_item
->param
->type
== DEVLINK_PARAM_TYPE_STRING
)
7195 strcpy(init_val
->vstr
, param_item
->driverinit_value
.vstr
);
7197 *init_val
= param_item
->driverinit_value
;
7203 __devlink_param_driverinit_value_set(struct devlink
*devlink
,
7204 unsigned int port_index
,
7205 struct list_head
*param_list
, u32 param_id
,
7206 union devlink_param_value init_val
,
7207 enum devlink_command cmd
)
7209 struct devlink_param_item
*param_item
;
7211 param_item
= devlink_param_find_by_id(param_list
, param_id
);
7215 if (!devlink_param_cmode_is_supported(param_item
->param
,
7216 DEVLINK_PARAM_CMODE_DRIVERINIT
))
7219 if (param_item
->param
->type
== DEVLINK_PARAM_TYPE_STRING
)
7220 strcpy(param_item
->driverinit_value
.vstr
, init_val
.vstr
);
7222 param_item
->driverinit_value
= init_val
;
7223 param_item
->driverinit_value_valid
= true;
7225 devlink_param_notify(devlink
, port_index
, param_item
, cmd
);
7230 * devlink_param_driverinit_value_get - get configuration parameter
7231 * value for driver initializing
7234 * @param_id: parameter ID
7235 * @init_val: value of parameter in driverinit configuration mode
7237 * This function should be used by the driver to get driverinit
7238 * configuration for initialization after reload command.
7240 int devlink_param_driverinit_value_get(struct devlink
*devlink
, u32 param_id
,
7241 union devlink_param_value
*init_val
)
7243 if (!devlink_reload_supported(devlink
))
7246 return __devlink_param_driverinit_value_get(&devlink
->param_list
,
7247 param_id
, init_val
);
7249 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_get
);
7252 * devlink_param_driverinit_value_set - set value of configuration
7253 * parameter for driverinit
7254 * configuration mode
7257 * @param_id: parameter ID
7258 * @init_val: value of parameter to set for driverinit configuration mode
7260 * This function should be used by the driver to set driverinit
7261 * configuration mode default value.
7263 int devlink_param_driverinit_value_set(struct devlink
*devlink
, u32 param_id
,
7264 union devlink_param_value init_val
)
7266 return __devlink_param_driverinit_value_set(devlink
, 0,
7267 &devlink
->param_list
,
7269 DEVLINK_CMD_PARAM_NEW
);
7271 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set
);
7274 * devlink_port_param_driverinit_value_get - get configuration parameter
7275 * value for driver initializing
7277 * @devlink_port: devlink_port
7278 * @param_id: parameter ID
7279 * @init_val: value of parameter in driverinit configuration mode
7281 * This function should be used by the driver to get driverinit
7282 * configuration for initialization after reload command.
7284 int devlink_port_param_driverinit_value_get(struct devlink_port
*devlink_port
,
7286 union devlink_param_value
*init_val
)
7288 struct devlink
*devlink
= devlink_port
->devlink
;
7290 if (!devlink_reload_supported(devlink
))
7293 return __devlink_param_driverinit_value_get(&devlink_port
->param_list
,
7294 param_id
, init_val
);
7296 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_get
);
7299 * devlink_port_param_driverinit_value_set - set value of configuration
7300 * parameter for driverinit
7301 * configuration mode
7303 * @devlink_port: devlink_port
7304 * @param_id: parameter ID
7305 * @init_val: value of parameter to set for driverinit configuration mode
7307 * This function should be used by the driver to set driverinit
7308 * configuration mode default value.
7310 int devlink_port_param_driverinit_value_set(struct devlink_port
*devlink_port
,
7312 union devlink_param_value init_val
)
7314 return __devlink_param_driverinit_value_set(devlink_port
->devlink
,
7315 devlink_port
->index
,
7316 &devlink_port
->param_list
,
7318 DEVLINK_CMD_PORT_PARAM_NEW
);
7320 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_set
);
7323 * devlink_param_value_changed - notify devlink on a parameter's value
7324 * change. Should be called by the driver
7325 * right after the change.
7328 * @param_id: parameter ID
7330 * This function should be used by the driver to notify devlink on value
7331 * change, excluding driverinit configuration mode.
7332 * For driverinit configuration mode driver should use the function
7334 void devlink_param_value_changed(struct devlink
*devlink
, u32 param_id
)
7336 struct devlink_param_item
*param_item
;
7338 param_item
= devlink_param_find_by_id(&devlink
->param_list
, param_id
);
7339 WARN_ON(!param_item
);
7341 devlink_param_notify(devlink
, 0, param_item
, DEVLINK_CMD_PARAM_NEW
);
7343 EXPORT_SYMBOL_GPL(devlink_param_value_changed
);
7346 * devlink_port_param_value_changed - notify devlink on a parameter's value
7347 * change. Should be called by the driver
7348 * right after the change.
7350 * @devlink_port: devlink_port
7351 * @param_id: parameter ID
7353 * This function should be used by the driver to notify devlink on value
7354 * change, excluding driverinit configuration mode.
7355 * For driverinit configuration mode driver should use the function
7356 * devlink_port_param_driverinit_value_set() instead.
7358 void devlink_port_param_value_changed(struct devlink_port
*devlink_port
,
7361 struct devlink_param_item
*param_item
;
7363 param_item
= devlink_param_find_by_id(&devlink_port
->param_list
,
7365 WARN_ON(!param_item
);
7367 devlink_param_notify(devlink_port
->devlink
, devlink_port
->index
,
7368 param_item
, DEVLINK_CMD_PORT_PARAM_NEW
);
7370 EXPORT_SYMBOL_GPL(devlink_port_param_value_changed
);
7373 * devlink_param_value_str_fill - Safely fill-up the string preventing
7374 * from overflow of the preallocated buffer
7376 * @dst_val: destination devlink_param_value
7377 * @src: source buffer
7379 void devlink_param_value_str_fill(union devlink_param_value
*dst_val
,
7384 len
= strlcpy(dst_val
->vstr
, src
, __DEVLINK_PARAM_MAX_STRING_VALUE
);
7385 WARN_ON(len
>= __DEVLINK_PARAM_MAX_STRING_VALUE
);
7387 EXPORT_SYMBOL_GPL(devlink_param_value_str_fill
);
7390 * devlink_region_create - create a new address region
7393 * @region_name: region name
7394 * @region_max_snapshots: Maximum supported number of snapshots for region
7395 * @region_size: size of region
7397 struct devlink_region
*devlink_region_create(struct devlink
*devlink
,
7398 const char *region_name
,
7399 u32 region_max_snapshots
,
7402 struct devlink_region
*region
;
7405 mutex_lock(&devlink
->lock
);
7407 if (devlink_region_get_by_name(devlink
, region_name
)) {
7412 region
= kzalloc(sizeof(*region
), GFP_KERNEL
);
7418 region
->devlink
= devlink
;
7419 region
->max_snapshots
= region_max_snapshots
;
7420 region
->name
= region_name
;
7421 region
->size
= region_size
;
7422 INIT_LIST_HEAD(®ion
->snapshot_list
);
7423 list_add_tail(®ion
->list
, &devlink
->region_list
);
7424 devlink_nl_region_notify(region
, NULL
, DEVLINK_CMD_REGION_NEW
);
7426 mutex_unlock(&devlink
->lock
);
7430 mutex_unlock(&devlink
->lock
);
7431 return ERR_PTR(err
);
7433 EXPORT_SYMBOL_GPL(devlink_region_create
);
7436 * devlink_region_destroy - destroy address region
7438 * @region: devlink region to destroy
7440 void devlink_region_destroy(struct devlink_region
*region
)
7442 struct devlink
*devlink
= region
->devlink
;
7443 struct devlink_snapshot
*snapshot
, *ts
;
7445 mutex_lock(&devlink
->lock
);
7447 /* Free all snapshots of region */
7448 list_for_each_entry_safe(snapshot
, ts
, ®ion
->snapshot_list
, list
)
7449 devlink_region_snapshot_del(region
, snapshot
);
7451 list_del(®ion
->list
);
7453 devlink_nl_region_notify(region
, NULL
, DEVLINK_CMD_REGION_DEL
);
7454 mutex_unlock(&devlink
->lock
);
7457 EXPORT_SYMBOL_GPL(devlink_region_destroy
);
7460 * devlink_region_shapshot_id_get - get snapshot ID
7462 * This callback should be called when adding a new snapshot,
7463 * Driver should use the same id for multiple snapshots taken
7464 * on multiple regions at the same time/by the same trigger.
7468 u32
devlink_region_shapshot_id_get(struct devlink
*devlink
)
7472 mutex_lock(&devlink
->lock
);
7473 id
= ++devlink
->snapshot_id
;
7474 mutex_unlock(&devlink
->lock
);
7478 EXPORT_SYMBOL_GPL(devlink_region_shapshot_id_get
);
7481 * devlink_region_snapshot_create - create a new snapshot
7482 * This will add a new snapshot of a region. The snapshot
7483 * will be stored on the region struct and can be accessed
7484 * from devlink. This is useful for future analyses of snapshots.
7485 * Multiple snapshots can be created on a region.
7486 * The @snapshot_id should be obtained using the getter function.
7488 * @region: devlink region of the snapshot
7489 * @data: snapshot data
7490 * @snapshot_id: snapshot id to be created
7491 * @data_destructor: pointer to destructor function to free data
7493 int devlink_region_snapshot_create(struct devlink_region
*region
,
7494 u8
*data
, u32 snapshot_id
,
7495 devlink_snapshot_data_dest_t
*data_destructor
)
7497 struct devlink
*devlink
= region
->devlink
;
7498 struct devlink_snapshot
*snapshot
;
7501 mutex_lock(&devlink
->lock
);
7503 /* check if region can hold one more snapshot */
7504 if (region
->cur_snapshots
== region
->max_snapshots
) {
7509 if (devlink_region_snapshot_get_by_id(region
, snapshot_id
)) {
7514 snapshot
= kzalloc(sizeof(*snapshot
), GFP_KERNEL
);
7520 snapshot
->id
= snapshot_id
;
7521 snapshot
->region
= region
;
7522 snapshot
->data
= data
;
7523 snapshot
->data_destructor
= data_destructor
;
7525 list_add_tail(&snapshot
->list
, ®ion
->snapshot_list
);
7527 region
->cur_snapshots
++;
7529 devlink_nl_region_notify(region
, snapshot
, DEVLINK_CMD_REGION_NEW
);
7530 mutex_unlock(&devlink
->lock
);
7534 mutex_unlock(&devlink
->lock
);
7537 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create
);
7539 #define DEVLINK_TRAP(_id, _type) \
7541 .type = DEVLINK_TRAP_TYPE_##_type, \
7542 .id = DEVLINK_TRAP_GENERIC_ID_##_id, \
7543 .name = DEVLINK_TRAP_GENERIC_NAME_##_id, \
7546 static const struct devlink_trap devlink_trap_generic
[] = {
7547 DEVLINK_TRAP(SMAC_MC
, DROP
),
7548 DEVLINK_TRAP(VLAN_TAG_MISMATCH
, DROP
),
7549 DEVLINK_TRAP(INGRESS_VLAN_FILTER
, DROP
),
7550 DEVLINK_TRAP(INGRESS_STP_FILTER
, DROP
),
7551 DEVLINK_TRAP(EMPTY_TX_LIST
, DROP
),
7552 DEVLINK_TRAP(PORT_LOOPBACK_FILTER
, DROP
),
7553 DEVLINK_TRAP(BLACKHOLE_ROUTE
, DROP
),
7554 DEVLINK_TRAP(TTL_ERROR
, EXCEPTION
),
7555 DEVLINK_TRAP(TAIL_DROP
, DROP
),
7558 #define DEVLINK_TRAP_GROUP(_id) \
7560 .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \
7561 .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \
7564 static const struct devlink_trap_group devlink_trap_group_generic
[] = {
7565 DEVLINK_TRAP_GROUP(L2_DROPS
),
7566 DEVLINK_TRAP_GROUP(L3_DROPS
),
7567 DEVLINK_TRAP_GROUP(BUFFER_DROPS
),
7570 static int devlink_trap_generic_verify(const struct devlink_trap
*trap
)
7572 if (trap
->id
> DEVLINK_TRAP_GENERIC_ID_MAX
)
7575 if (strcmp(trap
->name
, devlink_trap_generic
[trap
->id
].name
))
7578 if (trap
->type
!= devlink_trap_generic
[trap
->id
].type
)
7584 static int devlink_trap_driver_verify(const struct devlink_trap
*trap
)
7588 if (trap
->id
<= DEVLINK_TRAP_GENERIC_ID_MAX
)
7591 for (i
= 0; i
< ARRAY_SIZE(devlink_trap_generic
); i
++) {
7592 if (!strcmp(trap
->name
, devlink_trap_generic
[i
].name
))
7599 static int devlink_trap_verify(const struct devlink_trap
*trap
)
7601 if (!trap
|| !trap
->name
|| !trap
->group
.name
)
7605 return devlink_trap_generic_verify(trap
);
7607 return devlink_trap_driver_verify(trap
);
7611 devlink_trap_group_generic_verify(const struct devlink_trap_group
*group
)
7613 if (group
->id
> DEVLINK_TRAP_GROUP_GENERIC_ID_MAX
)
7616 if (strcmp(group
->name
, devlink_trap_group_generic
[group
->id
].name
))
7623 devlink_trap_group_driver_verify(const struct devlink_trap_group
*group
)
7627 if (group
->id
<= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX
)
7630 for (i
= 0; i
< ARRAY_SIZE(devlink_trap_group_generic
); i
++) {
7631 if (!strcmp(group
->name
, devlink_trap_group_generic
[i
].name
))
7638 static int devlink_trap_group_verify(const struct devlink_trap_group
*group
)
7641 return devlink_trap_group_generic_verify(group
);
7643 return devlink_trap_group_driver_verify(group
);
7647 devlink_trap_group_notify(struct devlink
*devlink
,
7648 const struct devlink_trap_group_item
*group_item
,
7649 enum devlink_command cmd
)
7651 struct sk_buff
*msg
;
7654 WARN_ON_ONCE(cmd
!= DEVLINK_CMD_TRAP_GROUP_NEW
&&
7655 cmd
!= DEVLINK_CMD_TRAP_GROUP_DEL
);
7657 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
7661 err
= devlink_nl_trap_group_fill(msg
, devlink
, group_item
, cmd
, 0, 0,
7668 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
7669 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
7672 static struct devlink_trap_group_item
*
7673 devlink_trap_group_item_create(struct devlink
*devlink
,
7674 const struct devlink_trap_group
*group
)
7676 struct devlink_trap_group_item
*group_item
;
7679 err
= devlink_trap_group_verify(group
);
7681 return ERR_PTR(err
);
7683 group_item
= kzalloc(sizeof(*group_item
), GFP_KERNEL
);
7685 return ERR_PTR(-ENOMEM
);
7687 group_item
->stats
= netdev_alloc_pcpu_stats(struct devlink_stats
);
7688 if (!group_item
->stats
) {
7690 goto err_stats_alloc
;
7693 group_item
->group
= group
;
7694 refcount_set(&group_item
->refcount
, 1);
7696 if (devlink
->ops
->trap_group_init
) {
7697 err
= devlink
->ops
->trap_group_init(devlink
, group
);
7699 goto err_group_init
;
7702 list_add_tail(&group_item
->list
, &devlink
->trap_group_list
);
7703 devlink_trap_group_notify(devlink
, group_item
,
7704 DEVLINK_CMD_TRAP_GROUP_NEW
);
7709 free_percpu(group_item
->stats
);
7712 return ERR_PTR(err
);
7716 devlink_trap_group_item_destroy(struct devlink
*devlink
,
7717 struct devlink_trap_group_item
*group_item
)
7719 devlink_trap_group_notify(devlink
, group_item
,
7720 DEVLINK_CMD_TRAP_GROUP_DEL
);
7721 list_del(&group_item
->list
);
7722 free_percpu(group_item
->stats
);
7726 static struct devlink_trap_group_item
*
7727 devlink_trap_group_item_get(struct devlink
*devlink
,
7728 const struct devlink_trap_group
*group
)
7730 struct devlink_trap_group_item
*group_item
;
7732 group_item
= devlink_trap_group_item_lookup(devlink
, group
->name
);
7734 refcount_inc(&group_item
->refcount
);
7738 return devlink_trap_group_item_create(devlink
, group
);
7742 devlink_trap_group_item_put(struct devlink
*devlink
,
7743 struct devlink_trap_group_item
*group_item
)
7745 if (!refcount_dec_and_test(&group_item
->refcount
))
7748 devlink_trap_group_item_destroy(devlink
, group_item
);
7752 devlink_trap_item_group_link(struct devlink
*devlink
,
7753 struct devlink_trap_item
*trap_item
)
7755 struct devlink_trap_group_item
*group_item
;
7757 group_item
= devlink_trap_group_item_get(devlink
,
7758 &trap_item
->trap
->group
);
7759 if (IS_ERR(group_item
))
7760 return PTR_ERR(group_item
);
7762 trap_item
->group_item
= group_item
;
7768 devlink_trap_item_group_unlink(struct devlink
*devlink
,
7769 struct devlink_trap_item
*trap_item
)
7771 devlink_trap_group_item_put(devlink
, trap_item
->group_item
);
7774 static void devlink_trap_notify(struct devlink
*devlink
,
7775 const struct devlink_trap_item
*trap_item
,
7776 enum devlink_command cmd
)
7778 struct sk_buff
*msg
;
7781 WARN_ON_ONCE(cmd
!= DEVLINK_CMD_TRAP_NEW
&&
7782 cmd
!= DEVLINK_CMD_TRAP_DEL
);
7784 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
7788 err
= devlink_nl_trap_fill(msg
, devlink
, trap_item
, cmd
, 0, 0, 0);
7794 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
7795 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
7799 devlink_trap_register(struct devlink
*devlink
,
7800 const struct devlink_trap
*trap
, void *priv
)
7802 struct devlink_trap_item
*trap_item
;
7805 if (devlink_trap_item_lookup(devlink
, trap
->name
))
7808 trap_item
= kzalloc(sizeof(*trap_item
), GFP_KERNEL
);
7812 trap_item
->stats
= netdev_alloc_pcpu_stats(struct devlink_stats
);
7813 if (!trap_item
->stats
) {
7815 goto err_stats_alloc
;
7818 trap_item
->trap
= trap
;
7819 trap_item
->action
= trap
->init_action
;
7820 trap_item
->priv
= priv
;
7822 err
= devlink_trap_item_group_link(devlink
, trap_item
);
7824 goto err_group_link
;
7826 err
= devlink
->ops
->trap_init(devlink
, trap
, trap_item
);
7830 list_add_tail(&trap_item
->list
, &devlink
->trap_list
);
7831 devlink_trap_notify(devlink
, trap_item
, DEVLINK_CMD_TRAP_NEW
);
7836 devlink_trap_item_group_unlink(devlink
, trap_item
);
7838 free_percpu(trap_item
->stats
);
7844 static void devlink_trap_unregister(struct devlink
*devlink
,
7845 const struct devlink_trap
*trap
)
7847 struct devlink_trap_item
*trap_item
;
7849 trap_item
= devlink_trap_item_lookup(devlink
, trap
->name
);
7850 if (WARN_ON_ONCE(!trap_item
))
7853 devlink_trap_notify(devlink
, trap_item
, DEVLINK_CMD_TRAP_DEL
);
7854 list_del(&trap_item
->list
);
7855 if (devlink
->ops
->trap_fini
)
7856 devlink
->ops
->trap_fini(devlink
, trap
, trap_item
);
7857 devlink_trap_item_group_unlink(devlink
, trap_item
);
7858 free_percpu(trap_item
->stats
);
7862 static void devlink_trap_disable(struct devlink
*devlink
,
7863 const struct devlink_trap
*trap
)
7865 struct devlink_trap_item
*trap_item
;
7867 trap_item
= devlink_trap_item_lookup(devlink
, trap
->name
);
7868 if (WARN_ON_ONCE(!trap_item
))
7871 devlink
->ops
->trap_action_set(devlink
, trap
, DEVLINK_TRAP_ACTION_DROP
);
7872 trap_item
->action
= DEVLINK_TRAP_ACTION_DROP
;
7876 * devlink_traps_register - Register packet traps with devlink.
7877 * @devlink: devlink.
7878 * @traps: Packet traps.
7879 * @traps_count: Count of provided packet traps.
7880 * @priv: Driver private information.
7882 * Return: Non-zero value on failure.
7884 int devlink_traps_register(struct devlink
*devlink
,
7885 const struct devlink_trap
*traps
,
7886 size_t traps_count
, void *priv
)
7890 if (!devlink
->ops
->trap_init
|| !devlink
->ops
->trap_action_set
)
7893 mutex_lock(&devlink
->lock
);
7894 for (i
= 0; i
< traps_count
; i
++) {
7895 const struct devlink_trap
*trap
= &traps
[i
];
7897 err
= devlink_trap_verify(trap
);
7899 goto err_trap_verify
;
7901 err
= devlink_trap_register(devlink
, trap
, priv
);
7903 goto err_trap_register
;
7905 mutex_unlock(&devlink
->lock
);
7911 for (i
--; i
>= 0; i
--)
7912 devlink_trap_unregister(devlink
, &traps
[i
]);
7913 mutex_unlock(&devlink
->lock
);
7916 EXPORT_SYMBOL_GPL(devlink_traps_register
);
7919 * devlink_traps_unregister - Unregister packet traps from devlink.
7920 * @devlink: devlink.
7921 * @traps: Packet traps.
7922 * @traps_count: Count of provided packet traps.
7924 void devlink_traps_unregister(struct devlink
*devlink
,
7925 const struct devlink_trap
*traps
,
7930 mutex_lock(&devlink
->lock
);
7931 /* Make sure we do not have any packets in-flight while unregistering
7932 * traps by disabling all of them and waiting for a grace period.
7934 for (i
= traps_count
- 1; i
>= 0; i
--)
7935 devlink_trap_disable(devlink
, &traps
[i
]);
7937 for (i
= traps_count
- 1; i
>= 0; i
--)
7938 devlink_trap_unregister(devlink
, &traps
[i
]);
7939 mutex_unlock(&devlink
->lock
);
7941 EXPORT_SYMBOL_GPL(devlink_traps_unregister
);
7944 devlink_trap_stats_update(struct devlink_stats __percpu
*trap_stats
,
7947 struct devlink_stats
*stats
;
7949 stats
= this_cpu_ptr(trap_stats
);
7950 u64_stats_update_begin(&stats
->syncp
);
7951 stats
->rx_bytes
+= skb_len
;
7952 stats
->rx_packets
++;
7953 u64_stats_update_end(&stats
->syncp
);
7957 devlink_trap_report_metadata_fill(struct net_dm_hw_metadata
*hw_metadata
,
7958 const struct devlink_trap_item
*trap_item
,
7959 struct devlink_port
*in_devlink_port
)
7961 struct devlink_trap_group_item
*group_item
= trap_item
->group_item
;
7963 hw_metadata
->trap_group_name
= group_item
->group
->name
;
7964 hw_metadata
->trap_name
= trap_item
->trap
->name
;
7966 spin_lock(&in_devlink_port
->type_lock
);
7967 if (in_devlink_port
->type
== DEVLINK_PORT_TYPE_ETH
)
7968 hw_metadata
->input_dev
= in_devlink_port
->type_dev
;
7969 spin_unlock(&in_devlink_port
->type_lock
);
7973 * devlink_trap_report - Report trapped packet to drop monitor.
7974 * @devlink: devlink.
7975 * @skb: Trapped packet.
7976 * @trap_ctx: Trap context.
7977 * @in_devlink_port: Input devlink port.
7979 void devlink_trap_report(struct devlink
*devlink
, struct sk_buff
*skb
,
7980 void *trap_ctx
, struct devlink_port
*in_devlink_port
)
7982 struct devlink_trap_item
*trap_item
= trap_ctx
;
7983 struct net_dm_hw_metadata hw_metadata
= {};
7985 devlink_trap_stats_update(trap_item
->stats
, skb
->len
);
7986 devlink_trap_stats_update(trap_item
->group_item
->stats
, skb
->len
);
7988 devlink_trap_report_metadata_fill(&hw_metadata
, trap_item
,
7990 net_dm_hw_report(skb
, &hw_metadata
);
7992 EXPORT_SYMBOL_GPL(devlink_trap_report
);
7995 * devlink_trap_ctx_priv - Trap context to driver private information.
7996 * @trap_ctx: Trap context.
7998 * Return: Driver private information passed during registration.
8000 void *devlink_trap_ctx_priv(void *trap_ctx
)
8002 struct devlink_trap_item
*trap_item
= trap_ctx
;
8004 return trap_item
->priv
;
8006 EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv
);
8008 static void __devlink_compat_running_version(struct devlink
*devlink
,
8009 char *buf
, size_t len
)
8011 const struct nlattr
*nlattr
;
8012 struct devlink_info_req req
;
8013 struct sk_buff
*msg
;
8016 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
8021 err
= devlink
->ops
->info_get(devlink
, &req
, NULL
);
8025 nla_for_each_attr(nlattr
, (void *)msg
->data
, msg
->len
, rem
) {
8026 const struct nlattr
*kv
;
8029 if (nla_type(nlattr
) != DEVLINK_ATTR_INFO_VERSION_RUNNING
)
8032 nla_for_each_nested(kv
, nlattr
, rem_kv
) {
8033 if (nla_type(kv
) != DEVLINK_ATTR_INFO_VERSION_VALUE
)
8036 strlcat(buf
, nla_data(kv
), len
);
8037 strlcat(buf
, " ", len
);
8044 void devlink_compat_running_version(struct net_device
*dev
,
8045 char *buf
, size_t len
)
8047 struct devlink
*devlink
;
8052 devlink
= netdev_to_devlink(dev
);
8053 if (!devlink
|| !devlink
->ops
->info_get
)
8056 mutex_lock(&devlink
->lock
);
8057 __devlink_compat_running_version(devlink
, buf
, len
);
8058 mutex_unlock(&devlink
->lock
);
8065 int devlink_compat_flash_update(struct net_device
*dev
, const char *file_name
)
8067 struct devlink
*devlink
;
8073 devlink
= netdev_to_devlink(dev
);
8074 if (!devlink
|| !devlink
->ops
->flash_update
) {
8079 mutex_lock(&devlink
->lock
);
8080 ret
= devlink
->ops
->flash_update(devlink
, file_name
, NULL
, NULL
);
8081 mutex_unlock(&devlink
->lock
);
8090 int devlink_compat_phys_port_name_get(struct net_device
*dev
,
8091 char *name
, size_t len
)
8093 struct devlink_port
*devlink_port
;
8095 /* RTNL mutex is held here which ensures that devlink_port
8096 * instance cannot disappear in the middle. No need to take
8097 * any devlink lock as only permanent values are accessed.
8101 devlink_port
= netdev_to_devlink_port(dev
);
8105 return __devlink_port_phys_port_name_get(devlink_port
, name
, len
);
8108 int devlink_compat_switch_id_get(struct net_device
*dev
,
8109 struct netdev_phys_item_id
*ppid
)
8111 struct devlink_port
*devlink_port
;
8113 /* Caller must hold RTNL mutex or reference to dev, which ensures that
8114 * devlink_port instance cannot disappear in the middle. No need to take
8115 * any devlink lock as only permanent values are accessed.
8117 devlink_port
= netdev_to_devlink_port(dev
);
8118 if (!devlink_port
|| !devlink_port
->attrs
.switch_port
)
8121 memcpy(ppid
, &devlink_port
->attrs
.switch_id
, sizeof(*ppid
));
8126 static int __init
devlink_init(void)
8128 return genl_register_family(&devlink_nl_family
);
8131 subsys_initcall(devlink_init
);