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 struct net
*devlink_net(const struct devlink
*devlink
)
100 return read_pnet(&devlink
->_net
);
102 EXPORT_SYMBOL_GPL(devlink_net
);
104 static void __devlink_net_set(struct devlink
*devlink
, struct net
*net
)
106 write_pnet(&devlink
->_net
, net
);
109 void devlink_net_set(struct devlink
*devlink
, struct net
*net
)
111 if (WARN_ON(devlink
->registered
))
113 __devlink_net_set(devlink
, net
);
115 EXPORT_SYMBOL_GPL(devlink_net_set
);
117 static struct devlink
*devlink_get_from_attrs(struct net
*net
,
118 struct nlattr
**attrs
)
120 struct devlink
*devlink
;
124 if (!attrs
[DEVLINK_ATTR_BUS_NAME
] || !attrs
[DEVLINK_ATTR_DEV_NAME
])
125 return ERR_PTR(-EINVAL
);
127 busname
= nla_data(attrs
[DEVLINK_ATTR_BUS_NAME
]);
128 devname
= nla_data(attrs
[DEVLINK_ATTR_DEV_NAME
]);
130 lockdep_assert_held(&devlink_mutex
);
132 list_for_each_entry(devlink
, &devlink_list
, list
) {
133 if (strcmp(devlink
->dev
->bus
->name
, busname
) == 0 &&
134 strcmp(dev_name(devlink
->dev
), devname
) == 0 &&
135 net_eq(devlink_net(devlink
), net
))
139 return ERR_PTR(-ENODEV
);
142 static struct devlink
*devlink_get_from_info(struct genl_info
*info
)
144 return devlink_get_from_attrs(genl_info_net(info
), info
->attrs
);
147 static struct devlink_port
*devlink_port_get_by_index(struct devlink
*devlink
,
148 unsigned int port_index
)
150 struct devlink_port
*devlink_port
;
152 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
153 if (devlink_port
->index
== port_index
)
159 static bool devlink_port_index_exists(struct devlink
*devlink
,
160 unsigned int port_index
)
162 return devlink_port_get_by_index(devlink
, port_index
);
165 static struct devlink_port
*devlink_port_get_from_attrs(struct devlink
*devlink
,
166 struct nlattr
**attrs
)
168 if (attrs
[DEVLINK_ATTR_PORT_INDEX
]) {
169 u32 port_index
= nla_get_u32(attrs
[DEVLINK_ATTR_PORT_INDEX
]);
170 struct devlink_port
*devlink_port
;
172 devlink_port
= devlink_port_get_by_index(devlink
, port_index
);
174 return ERR_PTR(-ENODEV
);
177 return ERR_PTR(-EINVAL
);
180 static struct devlink_port
*devlink_port_get_from_info(struct devlink
*devlink
,
181 struct genl_info
*info
)
183 return devlink_port_get_from_attrs(devlink
, info
->attrs
);
187 struct list_head list
;
190 u16 ingress_pools_count
;
191 u16 egress_pools_count
;
192 u16 ingress_tc_count
;
196 static u16
devlink_sb_pool_count(struct devlink_sb
*devlink_sb
)
198 return devlink_sb
->ingress_pools_count
+ devlink_sb
->egress_pools_count
;
201 static struct devlink_sb
*devlink_sb_get_by_index(struct devlink
*devlink
,
202 unsigned int sb_index
)
204 struct devlink_sb
*devlink_sb
;
206 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
207 if (devlink_sb
->index
== sb_index
)
213 static bool devlink_sb_index_exists(struct devlink
*devlink
,
214 unsigned int sb_index
)
216 return devlink_sb_get_by_index(devlink
, sb_index
);
219 static struct devlink_sb
*devlink_sb_get_from_attrs(struct devlink
*devlink
,
220 struct nlattr
**attrs
)
222 if (attrs
[DEVLINK_ATTR_SB_INDEX
]) {
223 u32 sb_index
= nla_get_u32(attrs
[DEVLINK_ATTR_SB_INDEX
]);
224 struct devlink_sb
*devlink_sb
;
226 devlink_sb
= devlink_sb_get_by_index(devlink
, sb_index
);
228 return ERR_PTR(-ENODEV
);
231 return ERR_PTR(-EINVAL
);
234 static struct devlink_sb
*devlink_sb_get_from_info(struct devlink
*devlink
,
235 struct genl_info
*info
)
237 return devlink_sb_get_from_attrs(devlink
, info
->attrs
);
240 static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb
*devlink_sb
,
241 struct nlattr
**attrs
,
246 if (!attrs
[DEVLINK_ATTR_SB_POOL_INDEX
])
249 val
= nla_get_u16(attrs
[DEVLINK_ATTR_SB_POOL_INDEX
]);
250 if (val
>= devlink_sb_pool_count(devlink_sb
))
256 static int devlink_sb_pool_index_get_from_info(struct devlink_sb
*devlink_sb
,
257 struct genl_info
*info
,
260 return devlink_sb_pool_index_get_from_attrs(devlink_sb
, info
->attrs
,
265 devlink_sb_pool_type_get_from_attrs(struct nlattr
**attrs
,
266 enum devlink_sb_pool_type
*p_pool_type
)
270 if (!attrs
[DEVLINK_ATTR_SB_POOL_TYPE
])
273 val
= nla_get_u8(attrs
[DEVLINK_ATTR_SB_POOL_TYPE
]);
274 if (val
!= DEVLINK_SB_POOL_TYPE_INGRESS
&&
275 val
!= DEVLINK_SB_POOL_TYPE_EGRESS
)
282 devlink_sb_pool_type_get_from_info(struct genl_info
*info
,
283 enum devlink_sb_pool_type
*p_pool_type
)
285 return devlink_sb_pool_type_get_from_attrs(info
->attrs
, p_pool_type
);
289 devlink_sb_th_type_get_from_attrs(struct nlattr
**attrs
,
290 enum devlink_sb_threshold_type
*p_th_type
)
294 if (!attrs
[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
])
297 val
= nla_get_u8(attrs
[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
]);
298 if (val
!= DEVLINK_SB_THRESHOLD_TYPE_STATIC
&&
299 val
!= DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC
)
306 devlink_sb_th_type_get_from_info(struct genl_info
*info
,
307 enum devlink_sb_threshold_type
*p_th_type
)
309 return devlink_sb_th_type_get_from_attrs(info
->attrs
, p_th_type
);
313 devlink_sb_tc_index_get_from_attrs(struct devlink_sb
*devlink_sb
,
314 struct nlattr
**attrs
,
315 enum devlink_sb_pool_type pool_type
,
320 if (!attrs
[DEVLINK_ATTR_SB_TC_INDEX
])
323 val
= nla_get_u16(attrs
[DEVLINK_ATTR_SB_TC_INDEX
]);
324 if (pool_type
== DEVLINK_SB_POOL_TYPE_INGRESS
&&
325 val
>= devlink_sb
->ingress_tc_count
)
327 if (pool_type
== DEVLINK_SB_POOL_TYPE_EGRESS
&&
328 val
>= devlink_sb
->egress_tc_count
)
335 devlink_sb_tc_index_get_from_info(struct devlink_sb
*devlink_sb
,
336 struct genl_info
*info
,
337 enum devlink_sb_pool_type pool_type
,
340 return devlink_sb_tc_index_get_from_attrs(devlink_sb
, info
->attrs
,
341 pool_type
, p_tc_index
);
344 struct devlink_region
{
345 struct devlink
*devlink
;
346 struct list_head list
;
347 const struct devlink_region_ops
*ops
;
348 struct list_head snapshot_list
;
354 struct devlink_snapshot
{
355 struct list_head list
;
356 struct devlink_region
*region
;
361 static struct devlink_region
*
362 devlink_region_get_by_name(struct devlink
*devlink
, const char *region_name
)
364 struct devlink_region
*region
;
366 list_for_each_entry(region
, &devlink
->region_list
, list
)
367 if (!strcmp(region
->ops
->name
, region_name
))
373 static struct devlink_snapshot
*
374 devlink_region_snapshot_get_by_id(struct devlink_region
*region
, u32 id
)
376 struct devlink_snapshot
*snapshot
;
378 list_for_each_entry(snapshot
, ®ion
->snapshot_list
, list
)
379 if (snapshot
->id
== id
)
385 #define DEVLINK_NL_FLAG_NEED_DEVLINK BIT(0)
386 #define DEVLINK_NL_FLAG_NEED_PORT BIT(1)
387 #define DEVLINK_NL_FLAG_NEED_SB BIT(2)
389 /* The per devlink instance lock is taken by default in the pre-doit
390 * operation, yet several commands do not require this. The global
391 * devlink lock is taken and protects from disruption by user-calls.
393 #define DEVLINK_NL_FLAG_NO_LOCK BIT(3)
395 static int devlink_nl_pre_doit(const struct genl_ops
*ops
,
396 struct sk_buff
*skb
, struct genl_info
*info
)
398 struct devlink
*devlink
;
401 mutex_lock(&devlink_mutex
);
402 devlink
= devlink_get_from_info(info
);
403 if (IS_ERR(devlink
)) {
404 mutex_unlock(&devlink_mutex
);
405 return PTR_ERR(devlink
);
407 if (~ops
->internal_flags
& DEVLINK_NL_FLAG_NO_LOCK
)
408 mutex_lock(&devlink
->lock
);
409 if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_DEVLINK
) {
410 info
->user_ptr
[0] = devlink
;
411 } else if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_PORT
) {
412 struct devlink_port
*devlink_port
;
414 devlink_port
= devlink_port_get_from_info(devlink
, info
);
415 if (IS_ERR(devlink_port
)) {
416 err
= PTR_ERR(devlink_port
);
419 info
->user_ptr
[0] = devlink_port
;
421 if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_SB
) {
422 struct devlink_sb
*devlink_sb
;
424 devlink_sb
= devlink_sb_get_from_info(devlink
, info
);
425 if (IS_ERR(devlink_sb
)) {
426 err
= PTR_ERR(devlink_sb
);
429 info
->user_ptr
[1] = devlink_sb
;
434 if (~ops
->internal_flags
& DEVLINK_NL_FLAG_NO_LOCK
)
435 mutex_unlock(&devlink
->lock
);
436 mutex_unlock(&devlink_mutex
);
440 static void devlink_nl_post_doit(const struct genl_ops
*ops
,
441 struct sk_buff
*skb
, struct genl_info
*info
)
443 struct devlink
*devlink
;
445 /* When devlink changes netns, it would not be found
446 * by devlink_get_from_info(). So try if it is stored first.
448 if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_DEVLINK
) {
449 devlink
= info
->user_ptr
[0];
451 devlink
= devlink_get_from_info(info
);
452 WARN_ON(IS_ERR(devlink
));
454 if (!IS_ERR(devlink
) && ~ops
->internal_flags
& DEVLINK_NL_FLAG_NO_LOCK
)
455 mutex_unlock(&devlink
->lock
);
456 mutex_unlock(&devlink_mutex
);
459 static struct genl_family devlink_nl_family
;
461 enum devlink_multicast_groups
{
462 DEVLINK_MCGRP_CONFIG
,
465 static const struct genl_multicast_group devlink_nl_mcgrps
[] = {
466 [DEVLINK_MCGRP_CONFIG
] = { .name
= DEVLINK_GENL_MCGRP_CONFIG_NAME
},
469 static int devlink_nl_put_handle(struct sk_buff
*msg
, struct devlink
*devlink
)
471 if (nla_put_string(msg
, DEVLINK_ATTR_BUS_NAME
, devlink
->dev
->bus
->name
))
473 if (nla_put_string(msg
, DEVLINK_ATTR_DEV_NAME
, dev_name(devlink
->dev
)))
478 static int devlink_nl_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
479 enum devlink_command cmd
, u32 portid
,
484 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
488 if (devlink_nl_put_handle(msg
, devlink
))
489 goto nla_put_failure
;
490 if (nla_put_u8(msg
, DEVLINK_ATTR_RELOAD_FAILED
, devlink
->reload_failed
))
491 goto nla_put_failure
;
493 genlmsg_end(msg
, hdr
);
497 genlmsg_cancel(msg
, hdr
);
501 static void devlink_notify(struct devlink
*devlink
, enum devlink_command cmd
)
506 WARN_ON(cmd
!= DEVLINK_CMD_NEW
&& cmd
!= DEVLINK_CMD_DEL
);
508 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
512 err
= devlink_nl_fill(msg
, devlink
, cmd
, 0, 0, 0);
518 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
519 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
522 static int devlink_nl_port_attrs_put(struct sk_buff
*msg
,
523 struct devlink_port
*devlink_port
)
525 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
529 if (nla_put_u16(msg
, DEVLINK_ATTR_PORT_FLAVOUR
, attrs
->flavour
))
531 switch (devlink_port
->attrs
.flavour
) {
532 case DEVLINK_PORT_FLAVOUR_PCI_PF
:
533 if (nla_put_u16(msg
, DEVLINK_ATTR_PORT_PCI_PF_NUMBER
,
537 case DEVLINK_PORT_FLAVOUR_PCI_VF
:
538 if (nla_put_u16(msg
, DEVLINK_ATTR_PORT_PCI_PF_NUMBER
,
540 nla_put_u16(msg
, DEVLINK_ATTR_PORT_PCI_VF_NUMBER
,
544 case DEVLINK_PORT_FLAVOUR_PHYSICAL
:
545 case DEVLINK_PORT_FLAVOUR_CPU
:
546 case DEVLINK_PORT_FLAVOUR_DSA
:
547 case DEVLINK_PORT_FLAVOUR_VIRTUAL
:
548 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_NUMBER
,
549 attrs
->phys
.port_number
))
553 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_SPLIT_GROUP
,
554 attrs
->phys
.port_number
))
556 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER
,
557 attrs
->phys
.split_subport_number
))
566 static int devlink_nl_port_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
567 struct devlink_port
*devlink_port
,
568 enum devlink_command cmd
, u32 portid
,
570 struct netlink_ext_ack
*extack
)
574 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
578 if (devlink_nl_put_handle(msg
, devlink
))
579 goto nla_put_failure
;
580 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, devlink_port
->index
))
581 goto nla_put_failure
;
583 spin_lock_bh(&devlink_port
->type_lock
);
584 if (nla_put_u16(msg
, DEVLINK_ATTR_PORT_TYPE
, devlink_port
->type
))
585 goto nla_put_failure_type_locked
;
586 if (devlink_port
->desired_type
!= DEVLINK_PORT_TYPE_NOTSET
&&
587 nla_put_u16(msg
, DEVLINK_ATTR_PORT_DESIRED_TYPE
,
588 devlink_port
->desired_type
))
589 goto nla_put_failure_type_locked
;
590 if (devlink_port
->type
== DEVLINK_PORT_TYPE_ETH
) {
591 struct net_device
*netdev
= devlink_port
->type_dev
;
594 (nla_put_u32(msg
, DEVLINK_ATTR_PORT_NETDEV_IFINDEX
,
596 nla_put_string(msg
, DEVLINK_ATTR_PORT_NETDEV_NAME
,
598 goto nla_put_failure_type_locked
;
600 if (devlink_port
->type
== DEVLINK_PORT_TYPE_IB
) {
601 struct ib_device
*ibdev
= devlink_port
->type_dev
;
604 nla_put_string(msg
, DEVLINK_ATTR_PORT_IBDEV_NAME
,
606 goto nla_put_failure_type_locked
;
608 spin_unlock_bh(&devlink_port
->type_lock
);
609 if (devlink_nl_port_attrs_put(msg
, devlink_port
))
610 goto nla_put_failure
;
612 genlmsg_end(msg
, hdr
);
615 nla_put_failure_type_locked
:
616 spin_unlock_bh(&devlink_port
->type_lock
);
618 genlmsg_cancel(msg
, hdr
);
622 static void devlink_port_notify(struct devlink_port
*devlink_port
,
623 enum devlink_command cmd
)
625 struct devlink
*devlink
= devlink_port
->devlink
;
629 if (!devlink_port
->registered
)
632 WARN_ON(cmd
!= DEVLINK_CMD_PORT_NEW
&& cmd
!= DEVLINK_CMD_PORT_DEL
);
634 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
638 err
= devlink_nl_port_fill(msg
, devlink
, devlink_port
, cmd
, 0, 0, 0,
645 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
646 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
649 static int devlink_nl_cmd_get_doit(struct sk_buff
*skb
, struct genl_info
*info
)
651 struct devlink
*devlink
= info
->user_ptr
[0];
655 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
659 err
= devlink_nl_fill(msg
, devlink
, DEVLINK_CMD_NEW
,
660 info
->snd_portid
, info
->snd_seq
, 0);
666 return genlmsg_reply(msg
, info
);
669 static int devlink_nl_cmd_get_dumpit(struct sk_buff
*msg
,
670 struct netlink_callback
*cb
)
672 struct devlink
*devlink
;
673 int start
= cb
->args
[0];
677 mutex_lock(&devlink_mutex
);
678 list_for_each_entry(devlink
, &devlink_list
, list
) {
679 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
685 err
= devlink_nl_fill(msg
, devlink
, DEVLINK_CMD_NEW
,
686 NETLINK_CB(cb
->skb
).portid
,
687 cb
->nlh
->nlmsg_seq
, NLM_F_MULTI
);
693 mutex_unlock(&devlink_mutex
);
699 static int devlink_nl_cmd_port_get_doit(struct sk_buff
*skb
,
700 struct genl_info
*info
)
702 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
703 struct devlink
*devlink
= devlink_port
->devlink
;
707 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
711 err
= devlink_nl_port_fill(msg
, devlink
, devlink_port
,
712 DEVLINK_CMD_PORT_NEW
,
713 info
->snd_portid
, info
->snd_seq
, 0,
720 return genlmsg_reply(msg
, info
);
723 static int devlink_nl_cmd_port_get_dumpit(struct sk_buff
*msg
,
724 struct netlink_callback
*cb
)
726 struct devlink
*devlink
;
727 struct devlink_port
*devlink_port
;
728 int start
= cb
->args
[0];
732 mutex_lock(&devlink_mutex
);
733 list_for_each_entry(devlink
, &devlink_list
, list
) {
734 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
736 mutex_lock(&devlink
->lock
);
737 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
742 err
= devlink_nl_port_fill(msg
, devlink
, devlink_port
,
744 NETLINK_CB(cb
->skb
).portid
,
749 mutex_unlock(&devlink
->lock
);
754 mutex_unlock(&devlink
->lock
);
757 mutex_unlock(&devlink_mutex
);
763 static int devlink_port_type_set(struct devlink
*devlink
,
764 struct devlink_port
*devlink_port
,
765 enum devlink_port_type port_type
)
770 if (devlink
->ops
->port_type_set
) {
771 if (port_type
== DEVLINK_PORT_TYPE_NOTSET
)
773 if (port_type
== devlink_port
->type
)
775 err
= devlink
->ops
->port_type_set(devlink_port
, port_type
);
778 devlink_port
->desired_type
= port_type
;
779 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
785 static int devlink_nl_cmd_port_set_doit(struct sk_buff
*skb
,
786 struct genl_info
*info
)
788 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
789 struct devlink
*devlink
= devlink_port
->devlink
;
792 if (info
->attrs
[DEVLINK_ATTR_PORT_TYPE
]) {
793 enum devlink_port_type port_type
;
795 port_type
= nla_get_u16(info
->attrs
[DEVLINK_ATTR_PORT_TYPE
]);
796 err
= devlink_port_type_set(devlink
, devlink_port
, port_type
);
803 static int devlink_port_split(struct devlink
*devlink
, u32 port_index
,
804 u32 count
, struct netlink_ext_ack
*extack
)
807 if (devlink
->ops
->port_split
)
808 return devlink
->ops
->port_split(devlink
, port_index
, count
,
813 static int devlink_nl_cmd_port_split_doit(struct sk_buff
*skb
,
814 struct genl_info
*info
)
816 struct devlink
*devlink
= info
->user_ptr
[0];
820 if (!info
->attrs
[DEVLINK_ATTR_PORT_INDEX
] ||
821 !info
->attrs
[DEVLINK_ATTR_PORT_SPLIT_COUNT
])
824 port_index
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_PORT_INDEX
]);
825 count
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_PORT_SPLIT_COUNT
]);
826 return devlink_port_split(devlink
, port_index
, count
, info
->extack
);
829 static int devlink_port_unsplit(struct devlink
*devlink
, u32 port_index
,
830 struct netlink_ext_ack
*extack
)
833 if (devlink
->ops
->port_unsplit
)
834 return devlink
->ops
->port_unsplit(devlink
, port_index
, extack
);
838 static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff
*skb
,
839 struct genl_info
*info
)
841 struct devlink
*devlink
= info
->user_ptr
[0];
844 if (!info
->attrs
[DEVLINK_ATTR_PORT_INDEX
])
847 port_index
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_PORT_INDEX
]);
848 return devlink_port_unsplit(devlink
, port_index
, info
->extack
);
851 static int devlink_nl_sb_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
852 struct devlink_sb
*devlink_sb
,
853 enum devlink_command cmd
, u32 portid
,
858 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
862 if (devlink_nl_put_handle(msg
, devlink
))
863 goto nla_put_failure
;
864 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
865 goto nla_put_failure
;
866 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_SIZE
, devlink_sb
->size
))
867 goto nla_put_failure
;
868 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT
,
869 devlink_sb
->ingress_pools_count
))
870 goto nla_put_failure
;
871 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT
,
872 devlink_sb
->egress_pools_count
))
873 goto nla_put_failure
;
874 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_INGRESS_TC_COUNT
,
875 devlink_sb
->ingress_tc_count
))
876 goto nla_put_failure
;
877 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_EGRESS_TC_COUNT
,
878 devlink_sb
->egress_tc_count
))
879 goto nla_put_failure
;
881 genlmsg_end(msg
, hdr
);
885 genlmsg_cancel(msg
, hdr
);
889 static int devlink_nl_cmd_sb_get_doit(struct sk_buff
*skb
,
890 struct genl_info
*info
)
892 struct devlink
*devlink
= info
->user_ptr
[0];
893 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
897 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
901 err
= devlink_nl_sb_fill(msg
, devlink
, devlink_sb
,
903 info
->snd_portid
, info
->snd_seq
, 0);
909 return genlmsg_reply(msg
, info
);
912 static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff
*msg
,
913 struct netlink_callback
*cb
)
915 struct devlink
*devlink
;
916 struct devlink_sb
*devlink_sb
;
917 int start
= cb
->args
[0];
921 mutex_lock(&devlink_mutex
);
922 list_for_each_entry(devlink
, &devlink_list
, list
) {
923 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
925 mutex_lock(&devlink
->lock
);
926 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
931 err
= devlink_nl_sb_fill(msg
, devlink
, devlink_sb
,
933 NETLINK_CB(cb
->skb
).portid
,
937 mutex_unlock(&devlink
->lock
);
942 mutex_unlock(&devlink
->lock
);
945 mutex_unlock(&devlink_mutex
);
951 static int devlink_nl_sb_pool_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
952 struct devlink_sb
*devlink_sb
,
953 u16 pool_index
, enum devlink_command cmd
,
954 u32 portid
, u32 seq
, int flags
)
956 struct devlink_sb_pool_info pool_info
;
960 err
= devlink
->ops
->sb_pool_get(devlink
, devlink_sb
->index
,
961 pool_index
, &pool_info
);
965 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
969 if (devlink_nl_put_handle(msg
, devlink
))
970 goto nla_put_failure
;
971 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
972 goto nla_put_failure
;
973 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_POOL_INDEX
, pool_index
))
974 goto nla_put_failure
;
975 if (nla_put_u8(msg
, DEVLINK_ATTR_SB_POOL_TYPE
, pool_info
.pool_type
))
976 goto nla_put_failure
;
977 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_POOL_SIZE
, pool_info
.size
))
978 goto nla_put_failure
;
979 if (nla_put_u8(msg
, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
,
980 pool_info
.threshold_type
))
981 goto nla_put_failure
;
982 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_POOL_CELL_SIZE
,
983 pool_info
.cell_size
))
984 goto nla_put_failure
;
986 genlmsg_end(msg
, hdr
);
990 genlmsg_cancel(msg
, hdr
);
994 static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff
*skb
,
995 struct genl_info
*info
)
997 struct devlink
*devlink
= info
->user_ptr
[0];
998 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1003 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1008 if (!devlink
->ops
->sb_pool_get
)
1011 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1015 err
= devlink_nl_sb_pool_fill(msg
, devlink
, devlink_sb
, pool_index
,
1016 DEVLINK_CMD_SB_POOL_NEW
,
1017 info
->snd_portid
, info
->snd_seq
, 0);
1023 return genlmsg_reply(msg
, info
);
1026 static int __sb_pool_get_dumpit(struct sk_buff
*msg
, int start
, int *p_idx
,
1027 struct devlink
*devlink
,
1028 struct devlink_sb
*devlink_sb
,
1029 u32 portid
, u32 seq
)
1031 u16 pool_count
= devlink_sb_pool_count(devlink_sb
);
1035 for (pool_index
= 0; pool_index
< pool_count
; pool_index
++) {
1036 if (*p_idx
< start
) {
1040 err
= devlink_nl_sb_pool_fill(msg
, devlink
,
1043 DEVLINK_CMD_SB_POOL_NEW
,
1044 portid
, seq
, NLM_F_MULTI
);
1052 static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff
*msg
,
1053 struct netlink_callback
*cb
)
1055 struct devlink
*devlink
;
1056 struct devlink_sb
*devlink_sb
;
1057 int start
= cb
->args
[0];
1061 mutex_lock(&devlink_mutex
);
1062 list_for_each_entry(devlink
, &devlink_list
, list
) {
1063 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)) ||
1064 !devlink
->ops
->sb_pool_get
)
1066 mutex_lock(&devlink
->lock
);
1067 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
1068 err
= __sb_pool_get_dumpit(msg
, start
, &idx
, devlink
,
1070 NETLINK_CB(cb
->skb
).portid
,
1071 cb
->nlh
->nlmsg_seq
);
1072 if (err
&& err
!= -EOPNOTSUPP
) {
1073 mutex_unlock(&devlink
->lock
);
1077 mutex_unlock(&devlink
->lock
);
1080 mutex_unlock(&devlink_mutex
);
1082 if (err
!= -EMSGSIZE
)
1089 static int devlink_sb_pool_set(struct devlink
*devlink
, unsigned int sb_index
,
1090 u16 pool_index
, u32 size
,
1091 enum devlink_sb_threshold_type threshold_type
,
1092 struct netlink_ext_ack
*extack
)
1095 const struct devlink_ops
*ops
= devlink
->ops
;
1097 if (ops
->sb_pool_set
)
1098 return ops
->sb_pool_set(devlink
, sb_index
, pool_index
,
1099 size
, threshold_type
, extack
);
1103 static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff
*skb
,
1104 struct genl_info
*info
)
1106 struct devlink
*devlink
= info
->user_ptr
[0];
1107 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1108 enum devlink_sb_threshold_type threshold_type
;
1113 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1118 err
= devlink_sb_th_type_get_from_info(info
, &threshold_type
);
1122 if (!info
->attrs
[DEVLINK_ATTR_SB_POOL_SIZE
])
1125 size
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_SB_POOL_SIZE
]);
1126 return devlink_sb_pool_set(devlink
, devlink_sb
->index
,
1127 pool_index
, size
, threshold_type
,
1131 static int devlink_nl_sb_port_pool_fill(struct sk_buff
*msg
,
1132 struct devlink
*devlink
,
1133 struct devlink_port
*devlink_port
,
1134 struct devlink_sb
*devlink_sb
,
1136 enum devlink_command cmd
,
1137 u32 portid
, u32 seq
, int flags
)
1139 const struct devlink_ops
*ops
= devlink
->ops
;
1144 err
= ops
->sb_port_pool_get(devlink_port
, devlink_sb
->index
,
1145 pool_index
, &threshold
);
1149 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
1153 if (devlink_nl_put_handle(msg
, devlink
))
1154 goto nla_put_failure
;
1155 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, devlink_port
->index
))
1156 goto nla_put_failure
;
1157 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
1158 goto nla_put_failure
;
1159 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_POOL_INDEX
, pool_index
))
1160 goto nla_put_failure
;
1161 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_THRESHOLD
, threshold
))
1162 goto nla_put_failure
;
1164 if (ops
->sb_occ_port_pool_get
) {
1168 err
= ops
->sb_occ_port_pool_get(devlink_port
, devlink_sb
->index
,
1169 pool_index
, &cur
, &max
);
1170 if (err
&& err
!= -EOPNOTSUPP
)
1173 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_CUR
, cur
))
1174 goto nla_put_failure
;
1175 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_MAX
, max
))
1176 goto nla_put_failure
;
1180 genlmsg_end(msg
, hdr
);
1184 genlmsg_cancel(msg
, hdr
);
1188 static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff
*skb
,
1189 struct genl_info
*info
)
1191 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1192 struct devlink
*devlink
= devlink_port
->devlink
;
1193 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1194 struct sk_buff
*msg
;
1198 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1203 if (!devlink
->ops
->sb_port_pool_get
)
1206 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1210 err
= devlink_nl_sb_port_pool_fill(msg
, devlink
, devlink_port
,
1211 devlink_sb
, pool_index
,
1212 DEVLINK_CMD_SB_PORT_POOL_NEW
,
1213 info
->snd_portid
, info
->snd_seq
, 0);
1219 return genlmsg_reply(msg
, info
);
1222 static int __sb_port_pool_get_dumpit(struct sk_buff
*msg
, int start
, int *p_idx
,
1223 struct devlink
*devlink
,
1224 struct devlink_sb
*devlink_sb
,
1225 u32 portid
, u32 seq
)
1227 struct devlink_port
*devlink_port
;
1228 u16 pool_count
= devlink_sb_pool_count(devlink_sb
);
1232 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
1233 for (pool_index
= 0; pool_index
< pool_count
; pool_index
++) {
1234 if (*p_idx
< start
) {
1238 err
= devlink_nl_sb_port_pool_fill(msg
, devlink
,
1242 DEVLINK_CMD_SB_PORT_POOL_NEW
,
1253 static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff
*msg
,
1254 struct netlink_callback
*cb
)
1256 struct devlink
*devlink
;
1257 struct devlink_sb
*devlink_sb
;
1258 int start
= cb
->args
[0];
1262 mutex_lock(&devlink_mutex
);
1263 list_for_each_entry(devlink
, &devlink_list
, list
) {
1264 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)) ||
1265 !devlink
->ops
->sb_port_pool_get
)
1267 mutex_lock(&devlink
->lock
);
1268 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
1269 err
= __sb_port_pool_get_dumpit(msg
, start
, &idx
,
1270 devlink
, devlink_sb
,
1271 NETLINK_CB(cb
->skb
).portid
,
1272 cb
->nlh
->nlmsg_seq
);
1273 if (err
&& err
!= -EOPNOTSUPP
) {
1274 mutex_unlock(&devlink
->lock
);
1278 mutex_unlock(&devlink
->lock
);
1281 mutex_unlock(&devlink_mutex
);
1283 if (err
!= -EMSGSIZE
)
1290 static int devlink_sb_port_pool_set(struct devlink_port
*devlink_port
,
1291 unsigned int sb_index
, u16 pool_index
,
1293 struct netlink_ext_ack
*extack
)
1296 const struct devlink_ops
*ops
= devlink_port
->devlink
->ops
;
1298 if (ops
->sb_port_pool_set
)
1299 return ops
->sb_port_pool_set(devlink_port
, sb_index
,
1300 pool_index
, threshold
, extack
);
1304 static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff
*skb
,
1305 struct genl_info
*info
)
1307 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1308 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1313 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1318 if (!info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
])
1321 threshold
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
]);
1322 return devlink_sb_port_pool_set(devlink_port
, devlink_sb
->index
,
1323 pool_index
, threshold
, info
->extack
);
1327 devlink_nl_sb_tc_pool_bind_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
1328 struct devlink_port
*devlink_port
,
1329 struct devlink_sb
*devlink_sb
, u16 tc_index
,
1330 enum devlink_sb_pool_type pool_type
,
1331 enum devlink_command cmd
,
1332 u32 portid
, u32 seq
, int flags
)
1334 const struct devlink_ops
*ops
= devlink
->ops
;
1340 err
= ops
->sb_tc_pool_bind_get(devlink_port
, devlink_sb
->index
,
1341 tc_index
, pool_type
,
1342 &pool_index
, &threshold
);
1346 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
1350 if (devlink_nl_put_handle(msg
, devlink
))
1351 goto nla_put_failure
;
1352 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, devlink_port
->index
))
1353 goto nla_put_failure
;
1354 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
1355 goto nla_put_failure
;
1356 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_TC_INDEX
, tc_index
))
1357 goto nla_put_failure
;
1358 if (nla_put_u8(msg
, DEVLINK_ATTR_SB_POOL_TYPE
, pool_type
))
1359 goto nla_put_failure
;
1360 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_POOL_INDEX
, pool_index
))
1361 goto nla_put_failure
;
1362 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_THRESHOLD
, threshold
))
1363 goto nla_put_failure
;
1365 if (ops
->sb_occ_tc_port_bind_get
) {
1369 err
= ops
->sb_occ_tc_port_bind_get(devlink_port
,
1371 tc_index
, pool_type
,
1373 if (err
&& err
!= -EOPNOTSUPP
)
1376 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_CUR
, cur
))
1377 goto nla_put_failure
;
1378 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_MAX
, max
))
1379 goto nla_put_failure
;
1383 genlmsg_end(msg
, hdr
);
1387 genlmsg_cancel(msg
, hdr
);
1391 static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff
*skb
,
1392 struct genl_info
*info
)
1394 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1395 struct devlink
*devlink
= devlink_port
->devlink
;
1396 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1397 struct sk_buff
*msg
;
1398 enum devlink_sb_pool_type pool_type
;
1402 err
= devlink_sb_pool_type_get_from_info(info
, &pool_type
);
1406 err
= devlink_sb_tc_index_get_from_info(devlink_sb
, info
,
1407 pool_type
, &tc_index
);
1411 if (!devlink
->ops
->sb_tc_pool_bind_get
)
1414 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1418 err
= devlink_nl_sb_tc_pool_bind_fill(msg
, devlink
, devlink_port
,
1419 devlink_sb
, tc_index
, pool_type
,
1420 DEVLINK_CMD_SB_TC_POOL_BIND_NEW
,
1428 return genlmsg_reply(msg
, info
);
1431 static int __sb_tc_pool_bind_get_dumpit(struct sk_buff
*msg
,
1432 int start
, int *p_idx
,
1433 struct devlink
*devlink
,
1434 struct devlink_sb
*devlink_sb
,
1435 u32 portid
, u32 seq
)
1437 struct devlink_port
*devlink_port
;
1441 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
1443 tc_index
< devlink_sb
->ingress_tc_count
; tc_index
++) {
1444 if (*p_idx
< start
) {
1448 err
= devlink_nl_sb_tc_pool_bind_fill(msg
, devlink
,
1452 DEVLINK_SB_POOL_TYPE_INGRESS
,
1453 DEVLINK_CMD_SB_TC_POOL_BIND_NEW
,
1461 tc_index
< devlink_sb
->egress_tc_count
; tc_index
++) {
1462 if (*p_idx
< start
) {
1466 err
= devlink_nl_sb_tc_pool_bind_fill(msg
, devlink
,
1470 DEVLINK_SB_POOL_TYPE_EGRESS
,
1471 DEVLINK_CMD_SB_TC_POOL_BIND_NEW
,
1483 devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff
*msg
,
1484 struct netlink_callback
*cb
)
1486 struct devlink
*devlink
;
1487 struct devlink_sb
*devlink_sb
;
1488 int start
= cb
->args
[0];
1492 mutex_lock(&devlink_mutex
);
1493 list_for_each_entry(devlink
, &devlink_list
, list
) {
1494 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)) ||
1495 !devlink
->ops
->sb_tc_pool_bind_get
)
1498 mutex_lock(&devlink
->lock
);
1499 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
1500 err
= __sb_tc_pool_bind_get_dumpit(msg
, start
, &idx
,
1503 NETLINK_CB(cb
->skb
).portid
,
1504 cb
->nlh
->nlmsg_seq
);
1505 if (err
&& err
!= -EOPNOTSUPP
) {
1506 mutex_unlock(&devlink
->lock
);
1510 mutex_unlock(&devlink
->lock
);
1513 mutex_unlock(&devlink_mutex
);
1515 if (err
!= -EMSGSIZE
)
1522 static int devlink_sb_tc_pool_bind_set(struct devlink_port
*devlink_port
,
1523 unsigned int sb_index
, u16 tc_index
,
1524 enum devlink_sb_pool_type pool_type
,
1525 u16 pool_index
, u32 threshold
,
1526 struct netlink_ext_ack
*extack
)
1529 const struct devlink_ops
*ops
= devlink_port
->devlink
->ops
;
1531 if (ops
->sb_tc_pool_bind_set
)
1532 return ops
->sb_tc_pool_bind_set(devlink_port
, sb_index
,
1533 tc_index
, pool_type
,
1534 pool_index
, threshold
, extack
);
1538 static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff
*skb
,
1539 struct genl_info
*info
)
1541 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1542 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1543 enum devlink_sb_pool_type pool_type
;
1549 err
= devlink_sb_pool_type_get_from_info(info
, &pool_type
);
1553 err
= devlink_sb_tc_index_get_from_info(devlink_sb
, info
,
1554 pool_type
, &tc_index
);
1558 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1563 if (!info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
])
1566 threshold
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
]);
1567 return devlink_sb_tc_pool_bind_set(devlink_port
, devlink_sb
->index
,
1568 tc_index
, pool_type
,
1569 pool_index
, threshold
, info
->extack
);
1572 static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff
*skb
,
1573 struct genl_info
*info
)
1575 struct devlink
*devlink
= info
->user_ptr
[0];
1576 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1577 const struct devlink_ops
*ops
= devlink
->ops
;
1579 if (ops
->sb_occ_snapshot
)
1580 return ops
->sb_occ_snapshot(devlink
, devlink_sb
->index
);
1584 static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff
*skb
,
1585 struct genl_info
*info
)
1587 struct devlink
*devlink
= info
->user_ptr
[0];
1588 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1589 const struct devlink_ops
*ops
= devlink
->ops
;
1591 if (ops
->sb_occ_max_clear
)
1592 return ops
->sb_occ_max_clear(devlink
, devlink_sb
->index
);
1596 static int devlink_nl_eswitch_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
1597 enum devlink_command cmd
, u32 portid
,
1600 const struct devlink_ops
*ops
= devlink
->ops
;
1601 enum devlink_eswitch_encap_mode encap_mode
;
1607 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
1611 err
= devlink_nl_put_handle(msg
, devlink
);
1613 goto nla_put_failure
;
1615 if (ops
->eswitch_mode_get
) {
1616 err
= ops
->eswitch_mode_get(devlink
, &mode
);
1618 goto nla_put_failure
;
1619 err
= nla_put_u16(msg
, DEVLINK_ATTR_ESWITCH_MODE
, mode
);
1621 goto nla_put_failure
;
1624 if (ops
->eswitch_inline_mode_get
) {
1625 err
= ops
->eswitch_inline_mode_get(devlink
, &inline_mode
);
1627 goto nla_put_failure
;
1628 err
= nla_put_u8(msg
, DEVLINK_ATTR_ESWITCH_INLINE_MODE
,
1631 goto nla_put_failure
;
1634 if (ops
->eswitch_encap_mode_get
) {
1635 err
= ops
->eswitch_encap_mode_get(devlink
, &encap_mode
);
1637 goto nla_put_failure
;
1638 err
= nla_put_u8(msg
, DEVLINK_ATTR_ESWITCH_ENCAP_MODE
, encap_mode
);
1640 goto nla_put_failure
;
1643 genlmsg_end(msg
, hdr
);
1647 genlmsg_cancel(msg
, hdr
);
1651 static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff
*skb
,
1652 struct genl_info
*info
)
1654 struct devlink
*devlink
= info
->user_ptr
[0];
1655 struct sk_buff
*msg
;
1658 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1662 err
= devlink_nl_eswitch_fill(msg
, devlink
, DEVLINK_CMD_ESWITCH_GET
,
1663 info
->snd_portid
, info
->snd_seq
, 0);
1670 return genlmsg_reply(msg
, info
);
1673 static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff
*skb
,
1674 struct genl_info
*info
)
1676 struct devlink
*devlink
= info
->user_ptr
[0];
1677 const struct devlink_ops
*ops
= devlink
->ops
;
1678 enum devlink_eswitch_encap_mode encap_mode
;
1683 if (info
->attrs
[DEVLINK_ATTR_ESWITCH_MODE
]) {
1684 if (!ops
->eswitch_mode_set
)
1686 mode
= nla_get_u16(info
->attrs
[DEVLINK_ATTR_ESWITCH_MODE
]);
1687 err
= ops
->eswitch_mode_set(devlink
, mode
, info
->extack
);
1692 if (info
->attrs
[DEVLINK_ATTR_ESWITCH_INLINE_MODE
]) {
1693 if (!ops
->eswitch_inline_mode_set
)
1695 inline_mode
= nla_get_u8(
1696 info
->attrs
[DEVLINK_ATTR_ESWITCH_INLINE_MODE
]);
1697 err
= ops
->eswitch_inline_mode_set(devlink
, inline_mode
,
1703 if (info
->attrs
[DEVLINK_ATTR_ESWITCH_ENCAP_MODE
]) {
1704 if (!ops
->eswitch_encap_mode_set
)
1706 encap_mode
= nla_get_u8(info
->attrs
[DEVLINK_ATTR_ESWITCH_ENCAP_MODE
]);
1707 err
= ops
->eswitch_encap_mode_set(devlink
, encap_mode
,
1716 int devlink_dpipe_match_put(struct sk_buff
*skb
,
1717 struct devlink_dpipe_match
*match
)
1719 struct devlink_dpipe_header
*header
= match
->header
;
1720 struct devlink_dpipe_field
*field
= &header
->fields
[match
->field_id
];
1721 struct nlattr
*match_attr
;
1723 match_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_MATCH
);
1727 if (nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_MATCH_TYPE
, match
->type
) ||
1728 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_INDEX
, match
->header_index
) ||
1729 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_ID
, header
->id
) ||
1730 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_ID
, field
->id
) ||
1731 nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL
, header
->global
))
1732 goto nla_put_failure
;
1734 nla_nest_end(skb
, match_attr
);
1738 nla_nest_cancel(skb
, match_attr
);
1741 EXPORT_SYMBOL_GPL(devlink_dpipe_match_put
);
1743 static int devlink_dpipe_matches_put(struct devlink_dpipe_table
*table
,
1744 struct sk_buff
*skb
)
1746 struct nlattr
*matches_attr
;
1748 matches_attr
= nla_nest_start_noflag(skb
,
1749 DEVLINK_ATTR_DPIPE_TABLE_MATCHES
);
1753 if (table
->table_ops
->matches_dump(table
->priv
, skb
))
1754 goto nla_put_failure
;
1756 nla_nest_end(skb
, matches_attr
);
1760 nla_nest_cancel(skb
, matches_attr
);
1764 int devlink_dpipe_action_put(struct sk_buff
*skb
,
1765 struct devlink_dpipe_action
*action
)
1767 struct devlink_dpipe_header
*header
= action
->header
;
1768 struct devlink_dpipe_field
*field
= &header
->fields
[action
->field_id
];
1769 struct nlattr
*action_attr
;
1771 action_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_ACTION
);
1775 if (nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_ACTION_TYPE
, action
->type
) ||
1776 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_INDEX
, action
->header_index
) ||
1777 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_ID
, header
->id
) ||
1778 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_ID
, field
->id
) ||
1779 nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL
, header
->global
))
1780 goto nla_put_failure
;
1782 nla_nest_end(skb
, action_attr
);
1786 nla_nest_cancel(skb
, action_attr
);
1789 EXPORT_SYMBOL_GPL(devlink_dpipe_action_put
);
1791 static int devlink_dpipe_actions_put(struct devlink_dpipe_table
*table
,
1792 struct sk_buff
*skb
)
1794 struct nlattr
*actions_attr
;
1796 actions_attr
= nla_nest_start_noflag(skb
,
1797 DEVLINK_ATTR_DPIPE_TABLE_ACTIONS
);
1801 if (table
->table_ops
->actions_dump(table
->priv
, skb
))
1802 goto nla_put_failure
;
1804 nla_nest_end(skb
, actions_attr
);
1808 nla_nest_cancel(skb
, actions_attr
);
1812 static int devlink_dpipe_table_put(struct sk_buff
*skb
,
1813 struct devlink_dpipe_table
*table
)
1815 struct nlattr
*table_attr
;
1818 table_size
= table
->table_ops
->size_get(table
->priv
);
1819 table_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_TABLE
);
1823 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_TABLE_NAME
, table
->name
) ||
1824 nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_TABLE_SIZE
, table_size
,
1826 goto nla_put_failure
;
1827 if (nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
,
1828 table
->counters_enabled
))
1829 goto nla_put_failure
;
1831 if (table
->resource_valid
) {
1832 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID
,
1833 table
->resource_id
, DEVLINK_ATTR_PAD
) ||
1834 nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS
,
1835 table
->resource_units
, DEVLINK_ATTR_PAD
))
1836 goto nla_put_failure
;
1838 if (devlink_dpipe_matches_put(table
, skb
))
1839 goto nla_put_failure
;
1841 if (devlink_dpipe_actions_put(table
, skb
))
1842 goto nla_put_failure
;
1844 nla_nest_end(skb
, table_attr
);
1848 nla_nest_cancel(skb
, table_attr
);
1852 static int devlink_dpipe_send_and_alloc_skb(struct sk_buff
**pskb
,
1853 struct genl_info
*info
)
1858 err
= genlmsg_reply(*pskb
, info
);
1862 *pskb
= genlmsg_new(GENLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1868 static int devlink_dpipe_tables_fill(struct genl_info
*info
,
1869 enum devlink_command cmd
, int flags
,
1870 struct list_head
*dpipe_tables
,
1871 const char *table_name
)
1873 struct devlink
*devlink
= info
->user_ptr
[0];
1874 struct devlink_dpipe_table
*table
;
1875 struct nlattr
*tables_attr
;
1876 struct sk_buff
*skb
= NULL
;
1877 struct nlmsghdr
*nlh
;
1883 table
= list_first_entry(dpipe_tables
,
1884 struct devlink_dpipe_table
, list
);
1886 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
1890 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
1891 &devlink_nl_family
, NLM_F_MULTI
, cmd
);
1897 if (devlink_nl_put_handle(skb
, devlink
))
1898 goto nla_put_failure
;
1899 tables_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_TABLES
);
1901 goto nla_put_failure
;
1905 list_for_each_entry_from(table
, dpipe_tables
, list
) {
1907 err
= devlink_dpipe_table_put(skb
, table
);
1915 if (!strcmp(table
->name
, table_name
)) {
1916 err
= devlink_dpipe_table_put(skb
, table
);
1924 nla_nest_end(skb
, tables_attr
);
1925 genlmsg_end(skb
, hdr
);
1930 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
1931 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
1933 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
1939 return genlmsg_reply(skb
, info
);
1948 static int devlink_nl_cmd_dpipe_table_get(struct sk_buff
*skb
,
1949 struct genl_info
*info
)
1951 struct devlink
*devlink
= info
->user_ptr
[0];
1952 const char *table_name
= NULL
;
1954 if (info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
])
1955 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
1957 return devlink_dpipe_tables_fill(info
, DEVLINK_CMD_DPIPE_TABLE_GET
, 0,
1958 &devlink
->dpipe_table_list
,
1962 static int devlink_dpipe_value_put(struct sk_buff
*skb
,
1963 struct devlink_dpipe_value
*value
)
1965 if (nla_put(skb
, DEVLINK_ATTR_DPIPE_VALUE
,
1966 value
->value_size
, value
->value
))
1969 if (nla_put(skb
, DEVLINK_ATTR_DPIPE_VALUE_MASK
,
1970 value
->value_size
, value
->mask
))
1972 if (value
->mapping_valid
)
1973 if (nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_VALUE_MAPPING
,
1974 value
->mapping_value
))
1979 static int devlink_dpipe_action_value_put(struct sk_buff
*skb
,
1980 struct devlink_dpipe_value
*value
)
1984 if (devlink_dpipe_action_put(skb
, value
->action
))
1986 if (devlink_dpipe_value_put(skb
, value
))
1991 static int devlink_dpipe_action_values_put(struct sk_buff
*skb
,
1992 struct devlink_dpipe_value
*values
,
1993 unsigned int values_count
)
1995 struct nlattr
*action_attr
;
1999 for (i
= 0; i
< values_count
; i
++) {
2000 action_attr
= nla_nest_start_noflag(skb
,
2001 DEVLINK_ATTR_DPIPE_ACTION_VALUE
);
2004 err
= devlink_dpipe_action_value_put(skb
, &values
[i
]);
2006 goto err_action_value_put
;
2007 nla_nest_end(skb
, action_attr
);
2011 err_action_value_put
:
2012 nla_nest_cancel(skb
, action_attr
);
2016 static int devlink_dpipe_match_value_put(struct sk_buff
*skb
,
2017 struct devlink_dpipe_value
*value
)
2021 if (devlink_dpipe_match_put(skb
, value
->match
))
2023 if (devlink_dpipe_value_put(skb
, value
))
2028 static int devlink_dpipe_match_values_put(struct sk_buff
*skb
,
2029 struct devlink_dpipe_value
*values
,
2030 unsigned int values_count
)
2032 struct nlattr
*match_attr
;
2036 for (i
= 0; i
< values_count
; i
++) {
2037 match_attr
= nla_nest_start_noflag(skb
,
2038 DEVLINK_ATTR_DPIPE_MATCH_VALUE
);
2041 err
= devlink_dpipe_match_value_put(skb
, &values
[i
]);
2043 goto err_match_value_put
;
2044 nla_nest_end(skb
, match_attr
);
2048 err_match_value_put
:
2049 nla_nest_cancel(skb
, match_attr
);
2053 static int devlink_dpipe_entry_put(struct sk_buff
*skb
,
2054 struct devlink_dpipe_entry
*entry
)
2056 struct nlattr
*entry_attr
, *matches_attr
, *actions_attr
;
2059 entry_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_ENTRY
);
2063 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_ENTRY_INDEX
, entry
->index
,
2065 goto nla_put_failure
;
2066 if (entry
->counter_valid
)
2067 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER
,
2068 entry
->counter
, DEVLINK_ATTR_PAD
))
2069 goto nla_put_failure
;
2071 matches_attr
= nla_nest_start_noflag(skb
,
2072 DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES
);
2074 goto nla_put_failure
;
2076 err
= devlink_dpipe_match_values_put(skb
, entry
->match_values
,
2077 entry
->match_values_count
);
2079 nla_nest_cancel(skb
, matches_attr
);
2080 goto err_match_values_put
;
2082 nla_nest_end(skb
, matches_attr
);
2084 actions_attr
= nla_nest_start_noflag(skb
,
2085 DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES
);
2087 goto nla_put_failure
;
2089 err
= devlink_dpipe_action_values_put(skb
, entry
->action_values
,
2090 entry
->action_values_count
);
2092 nla_nest_cancel(skb
, actions_attr
);
2093 goto err_action_values_put
;
2095 nla_nest_end(skb
, actions_attr
);
2097 nla_nest_end(skb
, entry_attr
);
2102 err_match_values_put
:
2103 err_action_values_put
:
2104 nla_nest_cancel(skb
, entry_attr
);
2108 static struct devlink_dpipe_table
*
2109 devlink_dpipe_table_find(struct list_head
*dpipe_tables
,
2110 const char *table_name
, struct devlink
*devlink
)
2112 struct devlink_dpipe_table
*table
;
2113 list_for_each_entry_rcu(table
, dpipe_tables
, list
,
2114 lockdep_is_held(&devlink
->lock
)) {
2115 if (!strcmp(table
->name
, table_name
))
2121 int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx
*dump_ctx
)
2123 struct devlink
*devlink
;
2126 err
= devlink_dpipe_send_and_alloc_skb(&dump_ctx
->skb
,
2131 dump_ctx
->hdr
= genlmsg_put(dump_ctx
->skb
,
2132 dump_ctx
->info
->snd_portid
,
2133 dump_ctx
->info
->snd_seq
,
2134 &devlink_nl_family
, NLM_F_MULTI
,
2137 goto nla_put_failure
;
2139 devlink
= dump_ctx
->info
->user_ptr
[0];
2140 if (devlink_nl_put_handle(dump_ctx
->skb
, devlink
))
2141 goto nla_put_failure
;
2142 dump_ctx
->nest
= nla_nest_start_noflag(dump_ctx
->skb
,
2143 DEVLINK_ATTR_DPIPE_ENTRIES
);
2144 if (!dump_ctx
->nest
)
2145 goto nla_put_failure
;
2149 nlmsg_free(dump_ctx
->skb
);
2152 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare
);
2154 int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx
*dump_ctx
,
2155 struct devlink_dpipe_entry
*entry
)
2157 return devlink_dpipe_entry_put(dump_ctx
->skb
, entry
);
2159 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append
);
2161 int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx
*dump_ctx
)
2163 nla_nest_end(dump_ctx
->skb
, dump_ctx
->nest
);
2164 genlmsg_end(dump_ctx
->skb
, dump_ctx
->hdr
);
2167 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close
);
2169 void devlink_dpipe_entry_clear(struct devlink_dpipe_entry
*entry
)
2172 unsigned int value_count
, value_index
;
2173 struct devlink_dpipe_value
*value
;
2175 value
= entry
->action_values
;
2176 value_count
= entry
->action_values_count
;
2177 for (value_index
= 0; value_index
< value_count
; value_index
++) {
2178 kfree(value
[value_index
].value
);
2179 kfree(value
[value_index
].mask
);
2182 value
= entry
->match_values
;
2183 value_count
= entry
->match_values_count
;
2184 for (value_index
= 0; value_index
< value_count
; value_index
++) {
2185 kfree(value
[value_index
].value
);
2186 kfree(value
[value_index
].mask
);
2189 EXPORT_SYMBOL(devlink_dpipe_entry_clear
);
2191 static int devlink_dpipe_entries_fill(struct genl_info
*info
,
2192 enum devlink_command cmd
, int flags
,
2193 struct devlink_dpipe_table
*table
)
2195 struct devlink_dpipe_dump_ctx dump_ctx
;
2196 struct nlmsghdr
*nlh
;
2199 dump_ctx
.skb
= NULL
;
2201 dump_ctx
.info
= info
;
2203 err
= table
->table_ops
->entries_dump(table
->priv
,
2204 table
->counters_enabled
,
2210 nlh
= nlmsg_put(dump_ctx
.skb
, info
->snd_portid
, info
->snd_seq
,
2211 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
2213 err
= devlink_dpipe_send_and_alloc_skb(&dump_ctx
.skb
, info
);
2218 return genlmsg_reply(dump_ctx
.skb
, info
);
2221 static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff
*skb
,
2222 struct genl_info
*info
)
2224 struct devlink
*devlink
= info
->user_ptr
[0];
2225 struct devlink_dpipe_table
*table
;
2226 const char *table_name
;
2228 if (!info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
])
2231 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
2232 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
2233 table_name
, devlink
);
2237 if (!table
->table_ops
->entries_dump
)
2240 return devlink_dpipe_entries_fill(info
, DEVLINK_CMD_DPIPE_ENTRIES_GET
,
2244 static int devlink_dpipe_fields_put(struct sk_buff
*skb
,
2245 const struct devlink_dpipe_header
*header
)
2247 struct devlink_dpipe_field
*field
;
2248 struct nlattr
*field_attr
;
2251 for (i
= 0; i
< header
->fields_count
; i
++) {
2252 field
= &header
->fields
[i
];
2253 field_attr
= nla_nest_start_noflag(skb
,
2254 DEVLINK_ATTR_DPIPE_FIELD
);
2257 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_FIELD_NAME
, field
->name
) ||
2258 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_ID
, field
->id
) ||
2259 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH
, field
->bitwidth
) ||
2260 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE
, field
->mapping_type
))
2261 goto nla_put_failure
;
2262 nla_nest_end(skb
, field_attr
);
2267 nla_nest_cancel(skb
, field_attr
);
2271 static int devlink_dpipe_header_put(struct sk_buff
*skb
,
2272 struct devlink_dpipe_header
*header
)
2274 struct nlattr
*fields_attr
, *header_attr
;
2277 header_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_HEADER
);
2281 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_HEADER_NAME
, header
->name
) ||
2282 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_ID
, header
->id
) ||
2283 nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL
, header
->global
))
2284 goto nla_put_failure
;
2286 fields_attr
= nla_nest_start_noflag(skb
,
2287 DEVLINK_ATTR_DPIPE_HEADER_FIELDS
);
2289 goto nla_put_failure
;
2291 err
= devlink_dpipe_fields_put(skb
, header
);
2293 nla_nest_cancel(skb
, fields_attr
);
2294 goto nla_put_failure
;
2296 nla_nest_end(skb
, fields_attr
);
2297 nla_nest_end(skb
, header_attr
);
2302 nla_nest_cancel(skb
, header_attr
);
2306 static int devlink_dpipe_headers_fill(struct genl_info
*info
,
2307 enum devlink_command cmd
, int flags
,
2308 struct devlink_dpipe_headers
*
2311 struct devlink
*devlink
= info
->user_ptr
[0];
2312 struct nlattr
*headers_attr
;
2313 struct sk_buff
*skb
= NULL
;
2314 struct nlmsghdr
*nlh
;
2321 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2325 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2326 &devlink_nl_family
, NLM_F_MULTI
, cmd
);
2332 if (devlink_nl_put_handle(skb
, devlink
))
2333 goto nla_put_failure
;
2334 headers_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_HEADERS
);
2336 goto nla_put_failure
;
2339 for (; i
< dpipe_headers
->headers_count
; i
++) {
2340 err
= devlink_dpipe_header_put(skb
, dpipe_headers
->headers
[i
]);
2348 nla_nest_end(skb
, headers_attr
);
2349 genlmsg_end(skb
, hdr
);
2350 if (i
!= dpipe_headers
->headers_count
)
2354 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2355 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
2357 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2362 return genlmsg_reply(skb
, info
);
2371 static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff
*skb
,
2372 struct genl_info
*info
)
2374 struct devlink
*devlink
= info
->user_ptr
[0];
2376 if (!devlink
->dpipe_headers
)
2378 return devlink_dpipe_headers_fill(info
, DEVLINK_CMD_DPIPE_HEADERS_GET
,
2379 0, devlink
->dpipe_headers
);
2382 static int devlink_dpipe_table_counters_set(struct devlink
*devlink
,
2383 const char *table_name
,
2386 struct devlink_dpipe_table
*table
;
2388 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
2389 table_name
, devlink
);
2393 if (table
->counter_control_extern
)
2396 if (!(table
->counters_enabled
^ enable
))
2399 table
->counters_enabled
= enable
;
2400 if (table
->table_ops
->counters_set_update
)
2401 table
->table_ops
->counters_set_update(table
->priv
, enable
);
2405 static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff
*skb
,
2406 struct genl_info
*info
)
2408 struct devlink
*devlink
= info
->user_ptr
[0];
2409 const char *table_name
;
2410 bool counters_enable
;
2412 if (!info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
] ||
2413 !info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
])
2416 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
2417 counters_enable
= !!nla_get_u8(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
]);
2419 return devlink_dpipe_table_counters_set(devlink
, table_name
,
2423 static struct devlink_resource
*
2424 devlink_resource_find(struct devlink
*devlink
,
2425 struct devlink_resource
*resource
, u64 resource_id
)
2427 struct list_head
*resource_list
;
2430 resource_list
= &resource
->resource_list
;
2432 resource_list
= &devlink
->resource_list
;
2434 list_for_each_entry(resource
, resource_list
, list
) {
2435 struct devlink_resource
*child_resource
;
2437 if (resource
->id
== resource_id
)
2440 child_resource
= devlink_resource_find(devlink
, resource
,
2443 return child_resource
;
2449 devlink_resource_validate_children(struct devlink_resource
*resource
)
2451 struct devlink_resource
*child_resource
;
2452 bool size_valid
= true;
2455 if (list_empty(&resource
->resource_list
))
2458 list_for_each_entry(child_resource
, &resource
->resource_list
, list
)
2459 parts_size
+= child_resource
->size_new
;
2461 if (parts_size
> resource
->size_new
)
2464 resource
->size_valid
= size_valid
;
2468 devlink_resource_validate_size(struct devlink_resource
*resource
, u64 size
,
2469 struct netlink_ext_ack
*extack
)
2474 if (size
> resource
->size_params
.size_max
) {
2475 NL_SET_ERR_MSG_MOD(extack
, "Size larger than maximum");
2479 if (size
< resource
->size_params
.size_min
) {
2480 NL_SET_ERR_MSG_MOD(extack
, "Size smaller than minimum");
2484 div64_u64_rem(size
, resource
->size_params
.size_granularity
, &reminder
);
2486 NL_SET_ERR_MSG_MOD(extack
, "Wrong granularity");
2493 static int devlink_nl_cmd_resource_set(struct sk_buff
*skb
,
2494 struct genl_info
*info
)
2496 struct devlink
*devlink
= info
->user_ptr
[0];
2497 struct devlink_resource
*resource
;
2502 if (!info
->attrs
[DEVLINK_ATTR_RESOURCE_ID
] ||
2503 !info
->attrs
[DEVLINK_ATTR_RESOURCE_SIZE
])
2505 resource_id
= nla_get_u64(info
->attrs
[DEVLINK_ATTR_RESOURCE_ID
]);
2507 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
2511 size
= nla_get_u64(info
->attrs
[DEVLINK_ATTR_RESOURCE_SIZE
]);
2512 err
= devlink_resource_validate_size(resource
, size
, info
->extack
);
2516 resource
->size_new
= size
;
2517 devlink_resource_validate_children(resource
);
2518 if (resource
->parent
)
2519 devlink_resource_validate_children(resource
->parent
);
2524 devlink_resource_size_params_put(struct devlink_resource
*resource
,
2525 struct sk_buff
*skb
)
2527 struct devlink_resource_size_params
*size_params
;
2529 size_params
= &resource
->size_params
;
2530 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_GRAN
,
2531 size_params
->size_granularity
, DEVLINK_ATTR_PAD
) ||
2532 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_MAX
,
2533 size_params
->size_max
, DEVLINK_ATTR_PAD
) ||
2534 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_MIN
,
2535 size_params
->size_min
, DEVLINK_ATTR_PAD
) ||
2536 nla_put_u8(skb
, DEVLINK_ATTR_RESOURCE_UNIT
, size_params
->unit
))
2541 static int devlink_resource_occ_put(struct devlink_resource
*resource
,
2542 struct sk_buff
*skb
)
2544 if (!resource
->occ_get
)
2546 return nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_OCC
,
2547 resource
->occ_get(resource
->occ_get_priv
),
2551 static int devlink_resource_put(struct devlink
*devlink
, struct sk_buff
*skb
,
2552 struct devlink_resource
*resource
)
2554 struct devlink_resource
*child_resource
;
2555 struct nlattr
*child_resource_attr
;
2556 struct nlattr
*resource_attr
;
2558 resource_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_RESOURCE
);
2562 if (nla_put_string(skb
, DEVLINK_ATTR_RESOURCE_NAME
, resource
->name
) ||
2563 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE
, resource
->size
,
2564 DEVLINK_ATTR_PAD
) ||
2565 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_ID
, resource
->id
,
2567 goto nla_put_failure
;
2568 if (resource
->size
!= resource
->size_new
)
2569 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_NEW
,
2570 resource
->size_new
, DEVLINK_ATTR_PAD
);
2571 if (devlink_resource_occ_put(resource
, skb
))
2572 goto nla_put_failure
;
2573 if (devlink_resource_size_params_put(resource
, skb
))
2574 goto nla_put_failure
;
2575 if (list_empty(&resource
->resource_list
))
2578 if (nla_put_u8(skb
, DEVLINK_ATTR_RESOURCE_SIZE_VALID
,
2579 resource
->size_valid
))
2580 goto nla_put_failure
;
2582 child_resource_attr
= nla_nest_start_noflag(skb
,
2583 DEVLINK_ATTR_RESOURCE_LIST
);
2584 if (!child_resource_attr
)
2585 goto nla_put_failure
;
2587 list_for_each_entry(child_resource
, &resource
->resource_list
, list
) {
2588 if (devlink_resource_put(devlink
, skb
, child_resource
))
2589 goto resource_put_failure
;
2592 nla_nest_end(skb
, child_resource_attr
);
2594 nla_nest_end(skb
, resource_attr
);
2597 resource_put_failure
:
2598 nla_nest_cancel(skb
, child_resource_attr
);
2600 nla_nest_cancel(skb
, resource_attr
);
2604 static int devlink_resource_fill(struct genl_info
*info
,
2605 enum devlink_command cmd
, int flags
)
2607 struct devlink
*devlink
= info
->user_ptr
[0];
2608 struct devlink_resource
*resource
;
2609 struct nlattr
*resources_attr
;
2610 struct sk_buff
*skb
= NULL
;
2611 struct nlmsghdr
*nlh
;
2617 resource
= list_first_entry(&devlink
->resource_list
,
2618 struct devlink_resource
, list
);
2620 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2624 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2625 &devlink_nl_family
, NLM_F_MULTI
, cmd
);
2631 if (devlink_nl_put_handle(skb
, devlink
))
2632 goto nla_put_failure
;
2634 resources_attr
= nla_nest_start_noflag(skb
,
2635 DEVLINK_ATTR_RESOURCE_LIST
);
2636 if (!resources_attr
)
2637 goto nla_put_failure
;
2641 list_for_each_entry_from(resource
, &devlink
->resource_list
, list
) {
2642 err
= devlink_resource_put(devlink
, skb
, resource
);
2645 goto err_resource_put
;
2651 nla_nest_end(skb
, resources_attr
);
2652 genlmsg_end(skb
, hdr
);
2656 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2657 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
2659 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2664 return genlmsg_reply(skb
, info
);
2673 static int devlink_nl_cmd_resource_dump(struct sk_buff
*skb
,
2674 struct genl_info
*info
)
2676 struct devlink
*devlink
= info
->user_ptr
[0];
2678 if (list_empty(&devlink
->resource_list
))
2681 return devlink_resource_fill(info
, DEVLINK_CMD_RESOURCE_DUMP
, 0);
2685 devlink_resources_validate(struct devlink
*devlink
,
2686 struct devlink_resource
*resource
,
2687 struct genl_info
*info
)
2689 struct list_head
*resource_list
;
2693 resource_list
= &resource
->resource_list
;
2695 resource_list
= &devlink
->resource_list
;
2697 list_for_each_entry(resource
, resource_list
, list
) {
2698 if (!resource
->size_valid
)
2700 err
= devlink_resources_validate(devlink
, resource
, info
);
2707 static struct net
*devlink_netns_get(struct sk_buff
*skb
,
2708 struct genl_info
*info
)
2710 struct nlattr
*netns_pid_attr
= info
->attrs
[DEVLINK_ATTR_NETNS_PID
];
2711 struct nlattr
*netns_fd_attr
= info
->attrs
[DEVLINK_ATTR_NETNS_FD
];
2712 struct nlattr
*netns_id_attr
= info
->attrs
[DEVLINK_ATTR_NETNS_ID
];
2715 if (!!netns_pid_attr
+ !!netns_fd_attr
+ !!netns_id_attr
> 1) {
2716 NL_SET_ERR_MSG_MOD(info
->extack
, "multiple netns identifying attributes specified");
2717 return ERR_PTR(-EINVAL
);
2720 if (netns_pid_attr
) {
2721 net
= get_net_ns_by_pid(nla_get_u32(netns_pid_attr
));
2722 } else if (netns_fd_attr
) {
2723 net
= get_net_ns_by_fd(nla_get_u32(netns_fd_attr
));
2724 } else if (netns_id_attr
) {
2725 net
= get_net_ns_by_id(sock_net(skb
->sk
),
2726 nla_get_u32(netns_id_attr
));
2728 net
= ERR_PTR(-EINVAL
);
2731 net
= ERR_PTR(-EINVAL
);
2734 NL_SET_ERR_MSG_MOD(info
->extack
, "Unknown network namespace");
2735 return ERR_PTR(-EINVAL
);
2737 if (!netlink_ns_capable(skb
, net
->user_ns
, CAP_NET_ADMIN
)) {
2739 return ERR_PTR(-EPERM
);
2744 static void devlink_param_notify(struct devlink
*devlink
,
2745 unsigned int port_index
,
2746 struct devlink_param_item
*param_item
,
2747 enum devlink_command cmd
);
2749 static void devlink_reload_netns_change(struct devlink
*devlink
,
2750 struct net
*dest_net
)
2752 struct devlink_param_item
*param_item
;
2754 /* Userspace needs to be notified about devlink objects
2755 * removed from original and entering new network namespace.
2756 * The rest of the devlink objects are re-created during
2757 * reload process so the notifications are generated separatelly.
2760 list_for_each_entry(param_item
, &devlink
->param_list
, list
)
2761 devlink_param_notify(devlink
, 0, param_item
,
2762 DEVLINK_CMD_PARAM_DEL
);
2763 devlink_notify(devlink
, DEVLINK_CMD_DEL
);
2765 __devlink_net_set(devlink
, dest_net
);
2767 devlink_notify(devlink
, DEVLINK_CMD_NEW
);
2768 list_for_each_entry(param_item
, &devlink
->param_list
, list
)
2769 devlink_param_notify(devlink
, 0, param_item
,
2770 DEVLINK_CMD_PARAM_NEW
);
2773 static bool devlink_reload_supported(struct devlink
*devlink
)
2775 return devlink
->ops
->reload_down
&& devlink
->ops
->reload_up
;
2778 static void devlink_reload_failed_set(struct devlink
*devlink
,
2781 if (devlink
->reload_failed
== reload_failed
)
2783 devlink
->reload_failed
= reload_failed
;
2784 devlink_notify(devlink
, DEVLINK_CMD_NEW
);
2787 bool devlink_is_reload_failed(const struct devlink
*devlink
)
2789 return devlink
->reload_failed
;
2791 EXPORT_SYMBOL_GPL(devlink_is_reload_failed
);
2793 static int devlink_reload(struct devlink
*devlink
, struct net
*dest_net
,
2794 struct netlink_ext_ack
*extack
)
2798 if (!devlink
->reload_enabled
)
2801 err
= devlink
->ops
->reload_down(devlink
, !!dest_net
, extack
);
2805 if (dest_net
&& !net_eq(dest_net
, devlink_net(devlink
)))
2806 devlink_reload_netns_change(devlink
, dest_net
);
2808 err
= devlink
->ops
->reload_up(devlink
, extack
);
2809 devlink_reload_failed_set(devlink
, !!err
);
2813 static int devlink_nl_cmd_reload(struct sk_buff
*skb
, struct genl_info
*info
)
2815 struct devlink
*devlink
= info
->user_ptr
[0];
2816 struct net
*dest_net
= NULL
;
2819 if (!devlink_reload_supported(devlink
) || !devlink
->reload_enabled
)
2822 err
= devlink_resources_validate(devlink
, NULL
, info
);
2824 NL_SET_ERR_MSG_MOD(info
->extack
, "resources size validation failed");
2828 if (info
->attrs
[DEVLINK_ATTR_NETNS_PID
] ||
2829 info
->attrs
[DEVLINK_ATTR_NETNS_FD
] ||
2830 info
->attrs
[DEVLINK_ATTR_NETNS_ID
]) {
2831 dest_net
= devlink_netns_get(skb
, info
);
2832 if (IS_ERR(dest_net
))
2833 return PTR_ERR(dest_net
);
2836 err
= devlink_reload(devlink
, dest_net
, info
->extack
);
2844 static int devlink_nl_flash_update_fill(struct sk_buff
*msg
,
2845 struct devlink
*devlink
,
2846 enum devlink_command cmd
,
2847 const char *status_msg
,
2848 const char *component
,
2849 unsigned long done
, unsigned long total
)
2853 hdr
= genlmsg_put(msg
, 0, 0, &devlink_nl_family
, 0, cmd
);
2857 if (devlink_nl_put_handle(msg
, devlink
))
2858 goto nla_put_failure
;
2860 if (cmd
!= DEVLINK_CMD_FLASH_UPDATE_STATUS
)
2864 nla_put_string(msg
, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG
,
2866 goto nla_put_failure
;
2868 nla_put_string(msg
, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT
,
2870 goto nla_put_failure
;
2871 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE
,
2872 done
, DEVLINK_ATTR_PAD
))
2873 goto nla_put_failure
;
2874 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL
,
2875 total
, DEVLINK_ATTR_PAD
))
2876 goto nla_put_failure
;
2879 genlmsg_end(msg
, hdr
);
2883 genlmsg_cancel(msg
, hdr
);
2887 static void __devlink_flash_update_notify(struct devlink
*devlink
,
2888 enum devlink_command cmd
,
2889 const char *status_msg
,
2890 const char *component
,
2892 unsigned long total
)
2894 struct sk_buff
*msg
;
2897 WARN_ON(cmd
!= DEVLINK_CMD_FLASH_UPDATE
&&
2898 cmd
!= DEVLINK_CMD_FLASH_UPDATE_END
&&
2899 cmd
!= DEVLINK_CMD_FLASH_UPDATE_STATUS
);
2901 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
2905 err
= devlink_nl_flash_update_fill(msg
, devlink
, cmd
, status_msg
,
2906 component
, done
, total
);
2910 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
2911 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
2918 void devlink_flash_update_begin_notify(struct devlink
*devlink
)
2920 __devlink_flash_update_notify(devlink
,
2921 DEVLINK_CMD_FLASH_UPDATE
,
2924 EXPORT_SYMBOL_GPL(devlink_flash_update_begin_notify
);
2926 void devlink_flash_update_end_notify(struct devlink
*devlink
)
2928 __devlink_flash_update_notify(devlink
,
2929 DEVLINK_CMD_FLASH_UPDATE_END
,
2932 EXPORT_SYMBOL_GPL(devlink_flash_update_end_notify
);
2934 void devlink_flash_update_status_notify(struct devlink
*devlink
,
2935 const char *status_msg
,
2936 const char *component
,
2938 unsigned long total
)
2940 __devlink_flash_update_notify(devlink
,
2941 DEVLINK_CMD_FLASH_UPDATE_STATUS
,
2942 status_msg
, component
, done
, total
);
2944 EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify
);
2946 static int devlink_nl_cmd_flash_update(struct sk_buff
*skb
,
2947 struct genl_info
*info
)
2949 struct devlink
*devlink
= info
->user_ptr
[0];
2950 const char *file_name
, *component
;
2951 struct nlattr
*nla_component
;
2953 if (!devlink
->ops
->flash_update
)
2956 if (!info
->attrs
[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME
])
2958 file_name
= nla_data(info
->attrs
[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME
]);
2960 nla_component
= info
->attrs
[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT
];
2961 component
= nla_component
? nla_data(nla_component
) : NULL
;
2963 return devlink
->ops
->flash_update(devlink
, file_name
, component
,
2967 static const struct devlink_param devlink_param_generic
[] = {
2969 .id
= DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET
,
2970 .name
= DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME
,
2971 .type
= DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE
,
2974 .id
= DEVLINK_PARAM_GENERIC_ID_MAX_MACS
,
2975 .name
= DEVLINK_PARAM_GENERIC_MAX_MACS_NAME
,
2976 .type
= DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE
,
2979 .id
= DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV
,
2980 .name
= DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME
,
2981 .type
= DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE
,
2984 .id
= DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT
,
2985 .name
= DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME
,
2986 .type
= DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE
,
2989 .id
= DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI
,
2990 .name
= DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME
,
2991 .type
= DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE
,
2994 .id
= DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX
,
2995 .name
= DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME
,
2996 .type
= DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE
,
2999 .id
= DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN
,
3000 .name
= DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME
,
3001 .type
= DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE
,
3004 .id
= DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY
,
3005 .name
= DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME
,
3006 .type
= DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE
,
3009 .id
= DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE
,
3010 .name
= DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME
,
3011 .type
= DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE
,
3014 .id
= DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE
,
3015 .name
= DEVLINK_PARAM_GENERIC_ENABLE_ROCE_NAME
,
3016 .type
= DEVLINK_PARAM_GENERIC_ENABLE_ROCE_TYPE
,
3020 static int devlink_param_generic_verify(const struct devlink_param
*param
)
3022 /* verify it match generic parameter by id and name */
3023 if (param
->id
> DEVLINK_PARAM_GENERIC_ID_MAX
)
3025 if (strcmp(param
->name
, devlink_param_generic
[param
->id
].name
))
3028 WARN_ON(param
->type
!= devlink_param_generic
[param
->id
].type
);
3033 static int devlink_param_driver_verify(const struct devlink_param
*param
)
3037 if (param
->id
<= DEVLINK_PARAM_GENERIC_ID_MAX
)
3039 /* verify no such name in generic params */
3040 for (i
= 0; i
<= DEVLINK_PARAM_GENERIC_ID_MAX
; i
++)
3041 if (!strcmp(param
->name
, devlink_param_generic
[i
].name
))
3047 static struct devlink_param_item
*
3048 devlink_param_find_by_name(struct list_head
*param_list
,
3049 const char *param_name
)
3051 struct devlink_param_item
*param_item
;
3053 list_for_each_entry(param_item
, param_list
, list
)
3054 if (!strcmp(param_item
->param
->name
, param_name
))
3059 static struct devlink_param_item
*
3060 devlink_param_find_by_id(struct list_head
*param_list
, u32 param_id
)
3062 struct devlink_param_item
*param_item
;
3064 list_for_each_entry(param_item
, param_list
, list
)
3065 if (param_item
->param
->id
== param_id
)
3071 devlink_param_cmode_is_supported(const struct devlink_param
*param
,
3072 enum devlink_param_cmode cmode
)
3074 return test_bit(cmode
, ¶m
->supported_cmodes
);
3077 static int devlink_param_get(struct devlink
*devlink
,
3078 const struct devlink_param
*param
,
3079 struct devlink_param_gset_ctx
*ctx
)
3083 return param
->get(devlink
, param
->id
, ctx
);
3086 static int devlink_param_set(struct devlink
*devlink
,
3087 const struct devlink_param
*param
,
3088 struct devlink_param_gset_ctx
*ctx
)
3092 return param
->set(devlink
, param
->id
, ctx
);
3096 devlink_param_type_to_nla_type(enum devlink_param_type param_type
)
3098 switch (param_type
) {
3099 case DEVLINK_PARAM_TYPE_U8
:
3101 case DEVLINK_PARAM_TYPE_U16
:
3103 case DEVLINK_PARAM_TYPE_U32
:
3105 case DEVLINK_PARAM_TYPE_STRING
:
3107 case DEVLINK_PARAM_TYPE_BOOL
:
3115 devlink_nl_param_value_fill_one(struct sk_buff
*msg
,
3116 enum devlink_param_type type
,
3117 enum devlink_param_cmode cmode
,
3118 union devlink_param_value val
)
3120 struct nlattr
*param_value_attr
;
3122 param_value_attr
= nla_nest_start_noflag(msg
,
3123 DEVLINK_ATTR_PARAM_VALUE
);
3124 if (!param_value_attr
)
3125 goto nla_put_failure
;
3127 if (nla_put_u8(msg
, DEVLINK_ATTR_PARAM_VALUE_CMODE
, cmode
))
3128 goto value_nest_cancel
;
3131 case DEVLINK_PARAM_TYPE_U8
:
3132 if (nla_put_u8(msg
, DEVLINK_ATTR_PARAM_VALUE_DATA
, val
.vu8
))
3133 goto value_nest_cancel
;
3135 case DEVLINK_PARAM_TYPE_U16
:
3136 if (nla_put_u16(msg
, DEVLINK_ATTR_PARAM_VALUE_DATA
, val
.vu16
))
3137 goto value_nest_cancel
;
3139 case DEVLINK_PARAM_TYPE_U32
:
3140 if (nla_put_u32(msg
, DEVLINK_ATTR_PARAM_VALUE_DATA
, val
.vu32
))
3141 goto value_nest_cancel
;
3143 case DEVLINK_PARAM_TYPE_STRING
:
3144 if (nla_put_string(msg
, DEVLINK_ATTR_PARAM_VALUE_DATA
,
3146 goto value_nest_cancel
;
3148 case DEVLINK_PARAM_TYPE_BOOL
:
3150 nla_put_flag(msg
, DEVLINK_ATTR_PARAM_VALUE_DATA
))
3151 goto value_nest_cancel
;
3155 nla_nest_end(msg
, param_value_attr
);
3159 nla_nest_cancel(msg
, param_value_attr
);
3164 static int devlink_nl_param_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
3165 unsigned int port_index
,
3166 struct devlink_param_item
*param_item
,
3167 enum devlink_command cmd
,
3168 u32 portid
, u32 seq
, int flags
)
3170 union devlink_param_value param_value
[DEVLINK_PARAM_CMODE_MAX
+ 1];
3171 bool param_value_set
[DEVLINK_PARAM_CMODE_MAX
+ 1] = {};
3172 const struct devlink_param
*param
= param_item
->param
;
3173 struct devlink_param_gset_ctx ctx
;
3174 struct nlattr
*param_values_list
;
3175 struct nlattr
*param_attr
;
3181 /* Get value from driver part to driverinit configuration mode */
3182 for (i
= 0; i
<= DEVLINK_PARAM_CMODE_MAX
; i
++) {
3183 if (!devlink_param_cmode_is_supported(param
, i
))
3185 if (i
== DEVLINK_PARAM_CMODE_DRIVERINIT
) {
3186 if (!param_item
->driverinit_value_valid
)
3188 param_value
[i
] = param_item
->driverinit_value
;
3190 if (!param_item
->published
)
3193 err
= devlink_param_get(devlink
, param
, &ctx
);
3196 param_value
[i
] = ctx
.val
;
3198 param_value_set
[i
] = true;
3201 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
3205 if (devlink_nl_put_handle(msg
, devlink
))
3206 goto genlmsg_cancel
;
3208 if (cmd
== DEVLINK_CMD_PORT_PARAM_GET
||
3209 cmd
== DEVLINK_CMD_PORT_PARAM_NEW
||
3210 cmd
== DEVLINK_CMD_PORT_PARAM_DEL
)
3211 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, port_index
))
3212 goto genlmsg_cancel
;
3214 param_attr
= nla_nest_start_noflag(msg
, DEVLINK_ATTR_PARAM
);
3216 goto genlmsg_cancel
;
3217 if (nla_put_string(msg
, DEVLINK_ATTR_PARAM_NAME
, param
->name
))
3218 goto param_nest_cancel
;
3219 if (param
->generic
&& nla_put_flag(msg
, DEVLINK_ATTR_PARAM_GENERIC
))
3220 goto param_nest_cancel
;
3222 nla_type
= devlink_param_type_to_nla_type(param
->type
);
3224 goto param_nest_cancel
;
3225 if (nla_put_u8(msg
, DEVLINK_ATTR_PARAM_TYPE
, nla_type
))
3226 goto param_nest_cancel
;
3228 param_values_list
= nla_nest_start_noflag(msg
,
3229 DEVLINK_ATTR_PARAM_VALUES_LIST
);
3230 if (!param_values_list
)
3231 goto param_nest_cancel
;
3233 for (i
= 0; i
<= DEVLINK_PARAM_CMODE_MAX
; i
++) {
3234 if (!param_value_set
[i
])
3236 err
= devlink_nl_param_value_fill_one(msg
, param
->type
,
3239 goto values_list_nest_cancel
;
3242 nla_nest_end(msg
, param_values_list
);
3243 nla_nest_end(msg
, param_attr
);
3244 genlmsg_end(msg
, hdr
);
3247 values_list_nest_cancel
:
3248 nla_nest_end(msg
, param_values_list
);
3250 nla_nest_cancel(msg
, param_attr
);
3252 genlmsg_cancel(msg
, hdr
);
3256 static void devlink_param_notify(struct devlink
*devlink
,
3257 unsigned int port_index
,
3258 struct devlink_param_item
*param_item
,
3259 enum devlink_command cmd
)
3261 struct sk_buff
*msg
;
3264 WARN_ON(cmd
!= DEVLINK_CMD_PARAM_NEW
&& cmd
!= DEVLINK_CMD_PARAM_DEL
&&
3265 cmd
!= DEVLINK_CMD_PORT_PARAM_NEW
&&
3266 cmd
!= DEVLINK_CMD_PORT_PARAM_DEL
);
3268 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
3271 err
= devlink_nl_param_fill(msg
, devlink
, port_index
, param_item
, cmd
,
3278 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
3279 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
3282 static int devlink_nl_cmd_param_get_dumpit(struct sk_buff
*msg
,
3283 struct netlink_callback
*cb
)
3285 struct devlink_param_item
*param_item
;
3286 struct devlink
*devlink
;
3287 int start
= cb
->args
[0];
3291 mutex_lock(&devlink_mutex
);
3292 list_for_each_entry(devlink
, &devlink_list
, list
) {
3293 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
3295 mutex_lock(&devlink
->lock
);
3296 list_for_each_entry(param_item
, &devlink
->param_list
, list
) {
3301 err
= devlink_nl_param_fill(msg
, devlink
, 0, param_item
,
3302 DEVLINK_CMD_PARAM_GET
,
3303 NETLINK_CB(cb
->skb
).portid
,
3306 if (err
&& err
!= -EOPNOTSUPP
) {
3307 mutex_unlock(&devlink
->lock
);
3312 mutex_unlock(&devlink
->lock
);
3315 mutex_unlock(&devlink_mutex
);
3317 if (err
!= -EMSGSIZE
)
3325 devlink_param_type_get_from_info(struct genl_info
*info
,
3326 enum devlink_param_type
*param_type
)
3328 if (!info
->attrs
[DEVLINK_ATTR_PARAM_TYPE
])
3331 switch (nla_get_u8(info
->attrs
[DEVLINK_ATTR_PARAM_TYPE
])) {
3333 *param_type
= DEVLINK_PARAM_TYPE_U8
;
3336 *param_type
= DEVLINK_PARAM_TYPE_U16
;
3339 *param_type
= DEVLINK_PARAM_TYPE_U32
;
3342 *param_type
= DEVLINK_PARAM_TYPE_STRING
;
3345 *param_type
= DEVLINK_PARAM_TYPE_BOOL
;
3355 devlink_param_value_get_from_info(const struct devlink_param
*param
,
3356 struct genl_info
*info
,
3357 union devlink_param_value
*value
)
3359 struct nlattr
*param_data
;
3362 param_data
= info
->attrs
[DEVLINK_ATTR_PARAM_VALUE_DATA
];
3364 if (param
->type
!= DEVLINK_PARAM_TYPE_BOOL
&& !param_data
)
3367 switch (param
->type
) {
3368 case DEVLINK_PARAM_TYPE_U8
:
3369 if (nla_len(param_data
) != sizeof(u8
))
3371 value
->vu8
= nla_get_u8(param_data
);
3373 case DEVLINK_PARAM_TYPE_U16
:
3374 if (nla_len(param_data
) != sizeof(u16
))
3376 value
->vu16
= nla_get_u16(param_data
);
3378 case DEVLINK_PARAM_TYPE_U32
:
3379 if (nla_len(param_data
) != sizeof(u32
))
3381 value
->vu32
= nla_get_u32(param_data
);
3383 case DEVLINK_PARAM_TYPE_STRING
:
3384 len
= strnlen(nla_data(param_data
), nla_len(param_data
));
3385 if (len
== nla_len(param_data
) ||
3386 len
>= __DEVLINK_PARAM_MAX_STRING_VALUE
)
3388 strcpy(value
->vstr
, nla_data(param_data
));
3390 case DEVLINK_PARAM_TYPE_BOOL
:
3391 if (param_data
&& nla_len(param_data
))
3393 value
->vbool
= nla_get_flag(param_data
);
3399 static struct devlink_param_item
*
3400 devlink_param_get_from_info(struct list_head
*param_list
,
3401 struct genl_info
*info
)
3405 if (!info
->attrs
[DEVLINK_ATTR_PARAM_NAME
])
3408 param_name
= nla_data(info
->attrs
[DEVLINK_ATTR_PARAM_NAME
]);
3409 return devlink_param_find_by_name(param_list
, param_name
);
3412 static int devlink_nl_cmd_param_get_doit(struct sk_buff
*skb
,
3413 struct genl_info
*info
)
3415 struct devlink
*devlink
= info
->user_ptr
[0];
3416 struct devlink_param_item
*param_item
;
3417 struct sk_buff
*msg
;
3420 param_item
= devlink_param_get_from_info(&devlink
->param_list
, info
);
3424 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
3428 err
= devlink_nl_param_fill(msg
, devlink
, 0, param_item
,
3429 DEVLINK_CMD_PARAM_GET
,
3430 info
->snd_portid
, info
->snd_seq
, 0);
3436 return genlmsg_reply(msg
, info
);
3439 static int __devlink_nl_cmd_param_set_doit(struct devlink
*devlink
,
3440 unsigned int port_index
,
3441 struct list_head
*param_list
,
3442 struct genl_info
*info
,
3443 enum devlink_command cmd
)
3445 enum devlink_param_type param_type
;
3446 struct devlink_param_gset_ctx ctx
;
3447 enum devlink_param_cmode cmode
;
3448 struct devlink_param_item
*param_item
;
3449 const struct devlink_param
*param
;
3450 union devlink_param_value value
;
3453 param_item
= devlink_param_get_from_info(param_list
, info
);
3456 param
= param_item
->param
;
3457 err
= devlink_param_type_get_from_info(info
, ¶m_type
);
3460 if (param_type
!= param
->type
)
3462 err
= devlink_param_value_get_from_info(param
, info
, &value
);
3465 if (param
->validate
) {
3466 err
= param
->validate(devlink
, param
->id
, value
, info
->extack
);
3471 if (!info
->attrs
[DEVLINK_ATTR_PARAM_VALUE_CMODE
])
3473 cmode
= nla_get_u8(info
->attrs
[DEVLINK_ATTR_PARAM_VALUE_CMODE
]);
3474 if (!devlink_param_cmode_is_supported(param
, cmode
))
3477 if (cmode
== DEVLINK_PARAM_CMODE_DRIVERINIT
) {
3478 if (param
->type
== DEVLINK_PARAM_TYPE_STRING
)
3479 strcpy(param_item
->driverinit_value
.vstr
, value
.vstr
);
3481 param_item
->driverinit_value
= value
;
3482 param_item
->driverinit_value_valid
= true;
3488 err
= devlink_param_set(devlink
, param
, &ctx
);
3493 devlink_param_notify(devlink
, port_index
, param_item
, cmd
);
3497 static int devlink_nl_cmd_param_set_doit(struct sk_buff
*skb
,
3498 struct genl_info
*info
)
3500 struct devlink
*devlink
= info
->user_ptr
[0];
3502 return __devlink_nl_cmd_param_set_doit(devlink
, 0, &devlink
->param_list
,
3503 info
, DEVLINK_CMD_PARAM_NEW
);
3506 static int devlink_param_register_one(struct devlink
*devlink
,
3507 unsigned int port_index
,
3508 struct list_head
*param_list
,
3509 const struct devlink_param
*param
,
3510 enum devlink_command cmd
)
3512 struct devlink_param_item
*param_item
;
3514 if (devlink_param_find_by_name(param_list
, param
->name
))
3517 if (param
->supported_cmodes
== BIT(DEVLINK_PARAM_CMODE_DRIVERINIT
))
3518 WARN_ON(param
->get
|| param
->set
);
3520 WARN_ON(!param
->get
|| !param
->set
);
3522 param_item
= kzalloc(sizeof(*param_item
), GFP_KERNEL
);
3525 param_item
->param
= param
;
3527 list_add_tail(¶m_item
->list
, param_list
);
3528 devlink_param_notify(devlink
, port_index
, param_item
, cmd
);
3532 static void devlink_param_unregister_one(struct devlink
*devlink
,
3533 unsigned int port_index
,
3534 struct list_head
*param_list
,
3535 const struct devlink_param
*param
,
3536 enum devlink_command cmd
)
3538 struct devlink_param_item
*param_item
;
3540 param_item
= devlink_param_find_by_name(param_list
, param
->name
);
3541 WARN_ON(!param_item
);
3542 devlink_param_notify(devlink
, port_index
, param_item
, cmd
);
3543 list_del(¶m_item
->list
);
3547 static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff
*msg
,
3548 struct netlink_callback
*cb
)
3550 struct devlink_param_item
*param_item
;
3551 struct devlink_port
*devlink_port
;
3552 struct devlink
*devlink
;
3553 int start
= cb
->args
[0];
3557 mutex_lock(&devlink_mutex
);
3558 list_for_each_entry(devlink
, &devlink_list
, list
) {
3559 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
3561 mutex_lock(&devlink
->lock
);
3562 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
3563 list_for_each_entry(param_item
,
3564 &devlink_port
->param_list
, list
) {
3569 err
= devlink_nl_param_fill(msg
,
3570 devlink_port
->devlink
,
3571 devlink_port
->index
, param_item
,
3572 DEVLINK_CMD_PORT_PARAM_GET
,
3573 NETLINK_CB(cb
->skb
).portid
,
3576 if (err
&& err
!= -EOPNOTSUPP
) {
3577 mutex_unlock(&devlink
->lock
);
3583 mutex_unlock(&devlink
->lock
);
3586 mutex_unlock(&devlink_mutex
);
3588 if (err
!= -EMSGSIZE
)
3595 static int devlink_nl_cmd_port_param_get_doit(struct sk_buff
*skb
,
3596 struct genl_info
*info
)
3598 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
3599 struct devlink_param_item
*param_item
;
3600 struct sk_buff
*msg
;
3603 param_item
= devlink_param_get_from_info(&devlink_port
->param_list
,
3608 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
3612 err
= devlink_nl_param_fill(msg
, devlink_port
->devlink
,
3613 devlink_port
->index
, param_item
,
3614 DEVLINK_CMD_PORT_PARAM_GET
,
3615 info
->snd_portid
, info
->snd_seq
, 0);
3621 return genlmsg_reply(msg
, info
);
3624 static int devlink_nl_cmd_port_param_set_doit(struct sk_buff
*skb
,
3625 struct genl_info
*info
)
3627 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
3629 return __devlink_nl_cmd_param_set_doit(devlink_port
->devlink
,
3630 devlink_port
->index
,
3631 &devlink_port
->param_list
, info
,
3632 DEVLINK_CMD_PORT_PARAM_NEW
);
3635 static int devlink_nl_region_snapshot_id_put(struct sk_buff
*msg
,
3636 struct devlink
*devlink
,
3637 struct devlink_snapshot
*snapshot
)
3639 struct nlattr
*snap_attr
;
3642 snap_attr
= nla_nest_start_noflag(msg
, DEVLINK_ATTR_REGION_SNAPSHOT
);
3646 err
= nla_put_u32(msg
, DEVLINK_ATTR_REGION_SNAPSHOT_ID
, snapshot
->id
);
3648 goto nla_put_failure
;
3650 nla_nest_end(msg
, snap_attr
);
3654 nla_nest_cancel(msg
, snap_attr
);
3658 static int devlink_nl_region_snapshots_id_put(struct sk_buff
*msg
,
3659 struct devlink
*devlink
,
3660 struct devlink_region
*region
)
3662 struct devlink_snapshot
*snapshot
;
3663 struct nlattr
*snapshots_attr
;
3666 snapshots_attr
= nla_nest_start_noflag(msg
,
3667 DEVLINK_ATTR_REGION_SNAPSHOTS
);
3668 if (!snapshots_attr
)
3671 list_for_each_entry(snapshot
, ®ion
->snapshot_list
, list
) {
3672 err
= devlink_nl_region_snapshot_id_put(msg
, devlink
, snapshot
);
3674 goto nla_put_failure
;
3677 nla_nest_end(msg
, snapshots_attr
);
3681 nla_nest_cancel(msg
, snapshots_attr
);
3685 static int devlink_nl_region_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
3686 enum devlink_command cmd
, u32 portid
,
3688 struct devlink_region
*region
)
3693 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
3697 err
= devlink_nl_put_handle(msg
, devlink
);
3699 goto nla_put_failure
;
3701 err
= nla_put_string(msg
, DEVLINK_ATTR_REGION_NAME
, region
->ops
->name
);
3703 goto nla_put_failure
;
3705 err
= nla_put_u64_64bit(msg
, DEVLINK_ATTR_REGION_SIZE
,
3709 goto nla_put_failure
;
3711 err
= devlink_nl_region_snapshots_id_put(msg
, devlink
, region
);
3713 goto nla_put_failure
;
3715 genlmsg_end(msg
, hdr
);
3719 genlmsg_cancel(msg
, hdr
);
3723 static struct sk_buff
*
3724 devlink_nl_region_notify_build(struct devlink_region
*region
,
3725 struct devlink_snapshot
*snapshot
,
3726 enum devlink_command cmd
, u32 portid
, u32 seq
)
3728 struct devlink
*devlink
= region
->devlink
;
3729 struct sk_buff
*msg
;
3734 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
3736 return ERR_PTR(-ENOMEM
);
3738 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, 0, cmd
);
3744 err
= devlink_nl_put_handle(msg
, devlink
);
3746 goto out_cancel_msg
;
3748 err
= nla_put_string(msg
, DEVLINK_ATTR_REGION_NAME
,
3751 goto out_cancel_msg
;
3754 err
= nla_put_u32(msg
, DEVLINK_ATTR_REGION_SNAPSHOT_ID
,
3757 goto out_cancel_msg
;
3759 err
= nla_put_u64_64bit(msg
, DEVLINK_ATTR_REGION_SIZE
,
3760 region
->size
, DEVLINK_ATTR_PAD
);
3762 goto out_cancel_msg
;
3764 genlmsg_end(msg
, hdr
);
3769 genlmsg_cancel(msg
, hdr
);
3772 return ERR_PTR(err
);
3775 static void devlink_nl_region_notify(struct devlink_region
*region
,
3776 struct devlink_snapshot
*snapshot
,
3777 enum devlink_command cmd
)
3779 struct devlink
*devlink
= region
->devlink
;
3780 struct sk_buff
*msg
;
3782 WARN_ON(cmd
!= DEVLINK_CMD_REGION_NEW
&& cmd
!= DEVLINK_CMD_REGION_DEL
);
3784 msg
= devlink_nl_region_notify_build(region
, snapshot
, cmd
, 0, 0);
3788 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
3789 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
3793 * __devlink_snapshot_id_increment - Increment number of snapshots using an id
3794 * @devlink: devlink instance
3795 * @id: the snapshot id
3797 * Track when a new snapshot begins using an id. Load the count for the
3798 * given id from the snapshot xarray, increment it, and store it back.
3800 * Called when a new snapshot is created with the given id.
3802 * The id *must* have been previously allocated by
3803 * devlink_region_snapshot_id_get().
3805 * Returns 0 on success, or an error on failure.
3807 static int __devlink_snapshot_id_increment(struct devlink
*devlink
, u32 id
)
3809 unsigned long count
;
3812 lockdep_assert_held(&devlink
->lock
);
3814 p
= xa_load(&devlink
->snapshot_ids
, id
);
3818 if (WARN_ON(!xa_is_value(p
)))
3821 count
= xa_to_value(p
);
3824 return xa_err(xa_store(&devlink
->snapshot_ids
, id
, xa_mk_value(count
),
3829 * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id
3830 * @devlink: devlink instance
3831 * @id: the snapshot id
3833 * Track when a snapshot is deleted and stops using an id. Load the count
3834 * for the given id from the snapshot xarray, decrement it, and store it
3837 * If the count reaches zero, erase this id from the xarray, freeing it
3838 * up for future re-use by devlink_region_snapshot_id_get().
3840 * Called when a snapshot using the given id is deleted, and when the
3841 * initial allocator of the id is finished using it.
3843 static void __devlink_snapshot_id_decrement(struct devlink
*devlink
, u32 id
)
3845 unsigned long count
;
3848 lockdep_assert_held(&devlink
->lock
);
3850 p
= xa_load(&devlink
->snapshot_ids
, id
);
3854 if (WARN_ON(!xa_is_value(p
)))
3857 count
= xa_to_value(p
);
3861 xa_store(&devlink
->snapshot_ids
, id
, xa_mk_value(count
),
3864 /* If this was the last user, we can erase this id */
3865 xa_erase(&devlink
->snapshot_ids
, id
);
3870 * __devlink_snapshot_id_insert - Insert a specific snapshot ID
3871 * @devlink: devlink instance
3872 * @id: the snapshot id
3874 * Mark the given snapshot id as used by inserting a zero value into the
3877 * This must be called while holding the devlink instance lock. Unlike
3878 * devlink_snapshot_id_get, the initial reference count is zero, not one.
3879 * It is expected that the id will immediately be used before
3880 * releasing the devlink instance lock.
3882 * Returns zero on success, or an error code if the snapshot id could not
3885 static int __devlink_snapshot_id_insert(struct devlink
*devlink
, u32 id
)
3887 lockdep_assert_held(&devlink
->lock
);
3889 if (WARN_ON(xa_load(&devlink
->snapshot_ids
, id
)))
3892 return xa_err(xa_store(&devlink
->snapshot_ids
, id
, xa_mk_value(0),
3897 * __devlink_region_snapshot_id_get - get snapshot ID
3898 * @devlink: devlink instance
3899 * @id: storage to return snapshot id
3901 * Allocates a new snapshot id. Returns zero on success, or a negative
3902 * error on failure. Must be called while holding the devlink instance
3905 * Snapshot IDs are tracked using an xarray which stores the number of
3906 * users of the snapshot id.
3908 * Note that the caller of this function counts as a 'user', in order to
3909 * avoid race conditions. The caller must release its hold on the
3910 * snapshot by using devlink_region_snapshot_id_put.
3912 static int __devlink_region_snapshot_id_get(struct devlink
*devlink
, u32
*id
)
3914 lockdep_assert_held(&devlink
->lock
);
3916 return xa_alloc(&devlink
->snapshot_ids
, id
, xa_mk_value(1),
3917 xa_limit_32b
, GFP_KERNEL
);
3921 * __devlink_region_snapshot_create - create a new snapshot
3922 * This will add a new snapshot of a region. The snapshot
3923 * will be stored on the region struct and can be accessed
3924 * from devlink. This is useful for future analyses of snapshots.
3925 * Multiple snapshots can be created on a region.
3926 * The @snapshot_id should be obtained using the getter function.
3928 * Must be called only while holding the devlink instance lock.
3930 * @region: devlink region of the snapshot
3931 * @data: snapshot data
3932 * @snapshot_id: snapshot id to be created
3935 __devlink_region_snapshot_create(struct devlink_region
*region
,
3936 u8
*data
, u32 snapshot_id
)
3938 struct devlink
*devlink
= region
->devlink
;
3939 struct devlink_snapshot
*snapshot
;
3942 lockdep_assert_held(&devlink
->lock
);
3944 /* check if region can hold one more snapshot */
3945 if (region
->cur_snapshots
== region
->max_snapshots
)
3948 if (devlink_region_snapshot_get_by_id(region
, snapshot_id
))
3951 snapshot
= kzalloc(sizeof(*snapshot
), GFP_KERNEL
);
3955 err
= __devlink_snapshot_id_increment(devlink
, snapshot_id
);
3957 goto err_snapshot_id_increment
;
3959 snapshot
->id
= snapshot_id
;
3960 snapshot
->region
= region
;
3961 snapshot
->data
= data
;
3963 list_add_tail(&snapshot
->list
, ®ion
->snapshot_list
);
3965 region
->cur_snapshots
++;
3967 devlink_nl_region_notify(region
, snapshot
, DEVLINK_CMD_REGION_NEW
);
3970 err_snapshot_id_increment
:
3975 static void devlink_region_snapshot_del(struct devlink_region
*region
,
3976 struct devlink_snapshot
*snapshot
)
3978 struct devlink
*devlink
= region
->devlink
;
3980 lockdep_assert_held(&devlink
->lock
);
3982 devlink_nl_region_notify(region
, snapshot
, DEVLINK_CMD_REGION_DEL
);
3983 region
->cur_snapshots
--;
3984 list_del(&snapshot
->list
);
3985 region
->ops
->destructor(snapshot
->data
);
3986 __devlink_snapshot_id_decrement(devlink
, snapshot
->id
);
3990 static int devlink_nl_cmd_region_get_doit(struct sk_buff
*skb
,
3991 struct genl_info
*info
)
3993 struct devlink
*devlink
= info
->user_ptr
[0];
3994 struct devlink_region
*region
;
3995 const char *region_name
;
3996 struct sk_buff
*msg
;
3999 if (!info
->attrs
[DEVLINK_ATTR_REGION_NAME
])
4002 region_name
= nla_data(info
->attrs
[DEVLINK_ATTR_REGION_NAME
]);
4003 region
= devlink_region_get_by_name(devlink
, region_name
);
4007 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
4011 err
= devlink_nl_region_fill(msg
, devlink
, DEVLINK_CMD_REGION_GET
,
4012 info
->snd_portid
, info
->snd_seq
, 0,
4019 return genlmsg_reply(msg
, info
);
4022 static int devlink_nl_cmd_region_get_dumpit(struct sk_buff
*msg
,
4023 struct netlink_callback
*cb
)
4025 struct devlink_region
*region
;
4026 struct devlink
*devlink
;
4027 int start
= cb
->args
[0];
4031 mutex_lock(&devlink_mutex
);
4032 list_for_each_entry(devlink
, &devlink_list
, list
) {
4033 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
4036 mutex_lock(&devlink
->lock
);
4037 list_for_each_entry(region
, &devlink
->region_list
, list
) {
4042 err
= devlink_nl_region_fill(msg
, devlink
,
4043 DEVLINK_CMD_REGION_GET
,
4044 NETLINK_CB(cb
->skb
).portid
,
4046 NLM_F_MULTI
, region
);
4048 mutex_unlock(&devlink
->lock
);
4053 mutex_unlock(&devlink
->lock
);
4056 mutex_unlock(&devlink_mutex
);
4061 static int devlink_nl_cmd_region_del(struct sk_buff
*skb
,
4062 struct genl_info
*info
)
4064 struct devlink
*devlink
= info
->user_ptr
[0];
4065 struct devlink_snapshot
*snapshot
;
4066 struct devlink_region
*region
;
4067 const char *region_name
;
4070 if (!info
->attrs
[DEVLINK_ATTR_REGION_NAME
] ||
4071 !info
->attrs
[DEVLINK_ATTR_REGION_SNAPSHOT_ID
])
4074 region_name
= nla_data(info
->attrs
[DEVLINK_ATTR_REGION_NAME
]);
4075 snapshot_id
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_REGION_SNAPSHOT_ID
]);
4077 region
= devlink_region_get_by_name(devlink
, region_name
);
4081 snapshot
= devlink_region_snapshot_get_by_id(region
, snapshot_id
);
4085 devlink_region_snapshot_del(region
, snapshot
);
4090 devlink_nl_cmd_region_new(struct sk_buff
*skb
, struct genl_info
*info
)
4092 struct devlink
*devlink
= info
->user_ptr
[0];
4093 struct devlink_snapshot
*snapshot
;
4094 struct nlattr
*snapshot_id_attr
;
4095 struct devlink_region
*region
;
4096 const char *region_name
;
4101 if (!info
->attrs
[DEVLINK_ATTR_REGION_NAME
]) {
4102 NL_SET_ERR_MSG_MOD(info
->extack
, "No region name provided");
4106 region_name
= nla_data(info
->attrs
[DEVLINK_ATTR_REGION_NAME
]);
4107 region
= devlink_region_get_by_name(devlink
, region_name
);
4109 NL_SET_ERR_MSG_MOD(info
->extack
, "The requested region does not exist");
4113 if (!region
->ops
->snapshot
) {
4114 NL_SET_ERR_MSG_MOD(info
->extack
, "The requested region does not support taking an immediate snapshot");
4118 if (region
->cur_snapshots
== region
->max_snapshots
) {
4119 NL_SET_ERR_MSG_MOD(info
->extack
, "The region has reached the maximum number of stored snapshots");
4123 snapshot_id_attr
= info
->attrs
[DEVLINK_ATTR_REGION_SNAPSHOT_ID
];
4124 if (snapshot_id_attr
) {
4125 snapshot_id
= nla_get_u32(snapshot_id_attr
);
4127 if (devlink_region_snapshot_get_by_id(region
, snapshot_id
)) {
4128 NL_SET_ERR_MSG_MOD(info
->extack
, "The requested snapshot id is already in use");
4132 err
= __devlink_snapshot_id_insert(devlink
, snapshot_id
);
4136 err
= __devlink_region_snapshot_id_get(devlink
, &snapshot_id
);
4138 NL_SET_ERR_MSG_MOD(info
->extack
, "Failed to allocate a new snapshot id");
4143 err
= region
->ops
->snapshot(devlink
, info
->extack
, &data
);
4145 goto err_snapshot_capture
;
4147 err
= __devlink_region_snapshot_create(region
, data
, snapshot_id
);
4149 goto err_snapshot_create
;
4151 if (!snapshot_id_attr
) {
4152 struct sk_buff
*msg
;
4154 snapshot
= devlink_region_snapshot_get_by_id(region
,
4156 if (WARN_ON(!snapshot
))
4159 msg
= devlink_nl_region_notify_build(region
, snapshot
,
4160 DEVLINK_CMD_REGION_NEW
,
4163 err
= PTR_ERR_OR_ZERO(msg
);
4167 err
= genlmsg_reply(msg
, info
);
4174 err_snapshot_create
:
4175 region
->ops
->destructor(data
);
4176 err_snapshot_capture
:
4177 __devlink_snapshot_id_decrement(devlink
, snapshot_id
);
4181 devlink_region_snapshot_del(region
, snapshot
);
4185 static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff
*msg
,
4186 struct devlink
*devlink
,
4187 u8
*chunk
, u32 chunk_size
,
4190 struct nlattr
*chunk_attr
;
4193 chunk_attr
= nla_nest_start_noflag(msg
, DEVLINK_ATTR_REGION_CHUNK
);
4197 err
= nla_put(msg
, DEVLINK_ATTR_REGION_CHUNK_DATA
, chunk_size
, chunk
);
4199 goto nla_put_failure
;
4201 err
= nla_put_u64_64bit(msg
, DEVLINK_ATTR_REGION_CHUNK_ADDR
, addr
,
4204 goto nla_put_failure
;
4206 nla_nest_end(msg
, chunk_attr
);
4210 nla_nest_cancel(msg
, chunk_attr
);
4214 #define DEVLINK_REGION_READ_CHUNK_SIZE 256
4216 static int devlink_nl_region_read_snapshot_fill(struct sk_buff
*skb
,
4217 struct devlink
*devlink
,
4218 struct devlink_region
*region
,
4219 struct nlattr
**attrs
,
4224 struct devlink_snapshot
*snapshot
;
4225 u64 curr_offset
= start_offset
;
4229 *new_offset
= start_offset
;
4231 snapshot_id
= nla_get_u32(attrs
[DEVLINK_ATTR_REGION_SNAPSHOT_ID
]);
4232 snapshot
= devlink_region_snapshot_get_by_id(region
, snapshot_id
);
4236 while (curr_offset
< end_offset
) {
4240 if (end_offset
- curr_offset
< DEVLINK_REGION_READ_CHUNK_SIZE
)
4241 data_size
= end_offset
- curr_offset
;
4243 data_size
= DEVLINK_REGION_READ_CHUNK_SIZE
;
4245 data
= &snapshot
->data
[curr_offset
];
4246 err
= devlink_nl_cmd_region_read_chunk_fill(skb
, devlink
,
4252 curr_offset
+= data_size
;
4254 *new_offset
= curr_offset
;
4259 static int devlink_nl_cmd_region_read_dumpit(struct sk_buff
*skb
,
4260 struct netlink_callback
*cb
)
4262 const struct genl_dumpit_info
*info
= genl_dumpit_info(cb
);
4263 u64 ret_offset
, start_offset
, end_offset
= U64_MAX
;
4264 struct nlattr
**attrs
= info
->attrs
;
4265 struct devlink_region
*region
;
4266 struct nlattr
*chunks_attr
;
4267 const char *region_name
;
4268 struct devlink
*devlink
;
4272 start_offset
= *((u64
*)&cb
->args
[0]);
4274 mutex_lock(&devlink_mutex
);
4275 devlink
= devlink_get_from_attrs(sock_net(cb
->skb
->sk
), attrs
);
4276 if (IS_ERR(devlink
)) {
4277 err
= PTR_ERR(devlink
);
4281 mutex_lock(&devlink
->lock
);
4283 if (!attrs
[DEVLINK_ATTR_REGION_NAME
] ||
4284 !attrs
[DEVLINK_ATTR_REGION_SNAPSHOT_ID
]) {
4289 region_name
= nla_data(attrs
[DEVLINK_ATTR_REGION_NAME
]);
4290 region
= devlink_region_get_by_name(devlink
, region_name
);
4296 if (attrs
[DEVLINK_ATTR_REGION_CHUNK_ADDR
] &&
4297 attrs
[DEVLINK_ATTR_REGION_CHUNK_LEN
]) {
4300 nla_get_u64(attrs
[DEVLINK_ATTR_REGION_CHUNK_ADDR
]);
4302 end_offset
= nla_get_u64(attrs
[DEVLINK_ATTR_REGION_CHUNK_ADDR
]);
4303 end_offset
+= nla_get_u64(attrs
[DEVLINK_ATTR_REGION_CHUNK_LEN
]);
4306 if (end_offset
> region
->size
)
4307 end_offset
= region
->size
;
4309 /* return 0 if there is no further data to read */
4310 if (start_offset
== end_offset
) {
4315 hdr
= genlmsg_put(skb
, NETLINK_CB(cb
->skb
).portid
, cb
->nlh
->nlmsg_seq
,
4316 &devlink_nl_family
, NLM_F_ACK
| NLM_F_MULTI
,
4317 DEVLINK_CMD_REGION_READ
);
4323 err
= devlink_nl_put_handle(skb
, devlink
);
4325 goto nla_put_failure
;
4327 err
= nla_put_string(skb
, DEVLINK_ATTR_REGION_NAME
, region_name
);
4329 goto nla_put_failure
;
4331 chunks_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_REGION_CHUNKS
);
4334 goto nla_put_failure
;
4337 err
= devlink_nl_region_read_snapshot_fill(skb
, devlink
,
4340 end_offset
, &ret_offset
);
4342 if (err
&& err
!= -EMSGSIZE
)
4343 goto nla_put_failure
;
4345 /* Check if there was any progress done to prevent infinite loop */
4346 if (ret_offset
== start_offset
) {
4348 goto nla_put_failure
;
4351 *((u64
*)&cb
->args
[0]) = ret_offset
;
4353 nla_nest_end(skb
, chunks_attr
);
4354 genlmsg_end(skb
, hdr
);
4355 mutex_unlock(&devlink
->lock
);
4356 mutex_unlock(&devlink_mutex
);
4361 genlmsg_cancel(skb
, hdr
);
4363 mutex_unlock(&devlink
->lock
);
4365 mutex_unlock(&devlink_mutex
);
4369 struct devlink_info_req
{
4370 struct sk_buff
*msg
;
4373 int devlink_info_driver_name_put(struct devlink_info_req
*req
, const char *name
)
4375 return nla_put_string(req
->msg
, DEVLINK_ATTR_INFO_DRIVER_NAME
, name
);
4377 EXPORT_SYMBOL_GPL(devlink_info_driver_name_put
);
4379 int devlink_info_serial_number_put(struct devlink_info_req
*req
, const char *sn
)
4381 return nla_put_string(req
->msg
, DEVLINK_ATTR_INFO_SERIAL_NUMBER
, sn
);
4383 EXPORT_SYMBOL_GPL(devlink_info_serial_number_put
);
4385 static int devlink_info_version_put(struct devlink_info_req
*req
, int attr
,
4386 const char *version_name
,
4387 const char *version_value
)
4389 struct nlattr
*nest
;
4392 nest
= nla_nest_start_noflag(req
->msg
, attr
);
4396 err
= nla_put_string(req
->msg
, DEVLINK_ATTR_INFO_VERSION_NAME
,
4399 goto nla_put_failure
;
4401 err
= nla_put_string(req
->msg
, DEVLINK_ATTR_INFO_VERSION_VALUE
,
4404 goto nla_put_failure
;
4406 nla_nest_end(req
->msg
, nest
);
4411 nla_nest_cancel(req
->msg
, nest
);
4415 int devlink_info_version_fixed_put(struct devlink_info_req
*req
,
4416 const char *version_name
,
4417 const char *version_value
)
4419 return devlink_info_version_put(req
, DEVLINK_ATTR_INFO_VERSION_FIXED
,
4420 version_name
, version_value
);
4422 EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put
);
4424 int devlink_info_version_stored_put(struct devlink_info_req
*req
,
4425 const char *version_name
,
4426 const char *version_value
)
4428 return devlink_info_version_put(req
, DEVLINK_ATTR_INFO_VERSION_STORED
,
4429 version_name
, version_value
);
4431 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put
);
4433 int devlink_info_version_running_put(struct devlink_info_req
*req
,
4434 const char *version_name
,
4435 const char *version_value
)
4437 return devlink_info_version_put(req
, DEVLINK_ATTR_INFO_VERSION_RUNNING
,
4438 version_name
, version_value
);
4440 EXPORT_SYMBOL_GPL(devlink_info_version_running_put
);
4443 devlink_nl_info_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
4444 enum devlink_command cmd
, u32 portid
,
4445 u32 seq
, int flags
, struct netlink_ext_ack
*extack
)
4447 struct devlink_info_req req
;
4451 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
4456 if (devlink_nl_put_handle(msg
, devlink
))
4457 goto err_cancel_msg
;
4460 err
= devlink
->ops
->info_get(devlink
, &req
, extack
);
4462 goto err_cancel_msg
;
4464 genlmsg_end(msg
, hdr
);
4468 genlmsg_cancel(msg
, hdr
);
4472 static int devlink_nl_cmd_info_get_doit(struct sk_buff
*skb
,
4473 struct genl_info
*info
)
4475 struct devlink
*devlink
= info
->user_ptr
[0];
4476 struct sk_buff
*msg
;
4479 if (!devlink
->ops
->info_get
)
4482 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
4486 err
= devlink_nl_info_fill(msg
, devlink
, DEVLINK_CMD_INFO_GET
,
4487 info
->snd_portid
, info
->snd_seq
, 0,
4494 return genlmsg_reply(msg
, info
);
4497 static int devlink_nl_cmd_info_get_dumpit(struct sk_buff
*msg
,
4498 struct netlink_callback
*cb
)
4500 struct devlink
*devlink
;
4501 int start
= cb
->args
[0];
4505 mutex_lock(&devlink_mutex
);
4506 list_for_each_entry(devlink
, &devlink_list
, list
) {
4507 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
4514 if (!devlink
->ops
->info_get
) {
4519 mutex_lock(&devlink
->lock
);
4520 err
= devlink_nl_info_fill(msg
, devlink
, DEVLINK_CMD_INFO_GET
,
4521 NETLINK_CB(cb
->skb
).portid
,
4522 cb
->nlh
->nlmsg_seq
, NLM_F_MULTI
,
4524 mutex_unlock(&devlink
->lock
);
4525 if (err
&& err
!= -EOPNOTSUPP
)
4529 mutex_unlock(&devlink_mutex
);
4531 if (err
!= -EMSGSIZE
)
4538 struct devlink_fmsg_item
{
4539 struct list_head list
;
4546 struct devlink_fmsg
{
4547 struct list_head item_list
;
4548 bool putting_binary
; /* This flag forces enclosing of binary data
4549 * in an array brackets. It forces using
4550 * of designated API:
4551 * devlink_fmsg_binary_pair_nest_start()
4552 * devlink_fmsg_binary_pair_nest_end()
4556 static struct devlink_fmsg
*devlink_fmsg_alloc(void)
4558 struct devlink_fmsg
*fmsg
;
4560 fmsg
= kzalloc(sizeof(*fmsg
), GFP_KERNEL
);
4564 INIT_LIST_HEAD(&fmsg
->item_list
);
4569 static void devlink_fmsg_free(struct devlink_fmsg
*fmsg
)
4571 struct devlink_fmsg_item
*item
, *tmp
;
4573 list_for_each_entry_safe(item
, tmp
, &fmsg
->item_list
, list
) {
4574 list_del(&item
->list
);
4580 static int devlink_fmsg_nest_common(struct devlink_fmsg
*fmsg
,
4583 struct devlink_fmsg_item
*item
;
4585 item
= kzalloc(sizeof(*item
), GFP_KERNEL
);
4589 item
->attrtype
= attrtype
;
4590 list_add_tail(&item
->list
, &fmsg
->item_list
);
4595 int devlink_fmsg_obj_nest_start(struct devlink_fmsg
*fmsg
)
4597 if (fmsg
->putting_binary
)
4600 return devlink_fmsg_nest_common(fmsg
, DEVLINK_ATTR_FMSG_OBJ_NEST_START
);
4602 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start
);
4604 static int devlink_fmsg_nest_end(struct devlink_fmsg
*fmsg
)
4606 if (fmsg
->putting_binary
)
4609 return devlink_fmsg_nest_common(fmsg
, DEVLINK_ATTR_FMSG_NEST_END
);
4612 int devlink_fmsg_obj_nest_end(struct devlink_fmsg
*fmsg
)
4614 if (fmsg
->putting_binary
)
4617 return devlink_fmsg_nest_end(fmsg
);
4619 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end
);
4621 #define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN)
4623 static int devlink_fmsg_put_name(struct devlink_fmsg
*fmsg
, const char *name
)
4625 struct devlink_fmsg_item
*item
;
4627 if (fmsg
->putting_binary
)
4630 if (strlen(name
) + 1 > DEVLINK_FMSG_MAX_SIZE
)
4633 item
= kzalloc(sizeof(*item
) + strlen(name
) + 1, GFP_KERNEL
);
4637 item
->nla_type
= NLA_NUL_STRING
;
4638 item
->len
= strlen(name
) + 1;
4639 item
->attrtype
= DEVLINK_ATTR_FMSG_OBJ_NAME
;
4640 memcpy(&item
->value
, name
, item
->len
);
4641 list_add_tail(&item
->list
, &fmsg
->item_list
);
4646 int devlink_fmsg_pair_nest_start(struct devlink_fmsg
*fmsg
, const char *name
)
4650 if (fmsg
->putting_binary
)
4653 err
= devlink_fmsg_nest_common(fmsg
, DEVLINK_ATTR_FMSG_PAIR_NEST_START
);
4657 err
= devlink_fmsg_put_name(fmsg
, name
);
4663 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start
);
4665 int devlink_fmsg_pair_nest_end(struct devlink_fmsg
*fmsg
)
4667 if (fmsg
->putting_binary
)
4670 return devlink_fmsg_nest_end(fmsg
);
4672 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end
);
4674 int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg
*fmsg
,
4679 if (fmsg
->putting_binary
)
4682 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
4686 err
= devlink_fmsg_nest_common(fmsg
, DEVLINK_ATTR_FMSG_ARR_NEST_START
);
4692 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start
);
4694 int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg
*fmsg
)
4698 if (fmsg
->putting_binary
)
4701 err
= devlink_fmsg_nest_end(fmsg
);
4705 err
= devlink_fmsg_nest_end(fmsg
);
4711 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end
);
4713 int devlink_fmsg_binary_pair_nest_start(struct devlink_fmsg
*fmsg
,
4718 err
= devlink_fmsg_arr_pair_nest_start(fmsg
, name
);
4722 fmsg
->putting_binary
= true;
4725 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_start
);
4727 int devlink_fmsg_binary_pair_nest_end(struct devlink_fmsg
*fmsg
)
4729 if (!fmsg
->putting_binary
)
4732 fmsg
->putting_binary
= false;
4733 return devlink_fmsg_arr_pair_nest_end(fmsg
);
4735 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_end
);
4737 static int devlink_fmsg_put_value(struct devlink_fmsg
*fmsg
,
4738 const void *value
, u16 value_len
,
4741 struct devlink_fmsg_item
*item
;
4743 if (value_len
> DEVLINK_FMSG_MAX_SIZE
)
4746 item
= kzalloc(sizeof(*item
) + value_len
, GFP_KERNEL
);
4750 item
->nla_type
= value_nla_type
;
4751 item
->len
= value_len
;
4752 item
->attrtype
= DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA
;
4753 memcpy(&item
->value
, value
, item
->len
);
4754 list_add_tail(&item
->list
, &fmsg
->item_list
);
4759 int devlink_fmsg_bool_put(struct devlink_fmsg
*fmsg
, bool value
)
4761 if (fmsg
->putting_binary
)
4764 return devlink_fmsg_put_value(fmsg
, &value
, sizeof(value
), NLA_FLAG
);
4766 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_put
);
4768 int devlink_fmsg_u8_put(struct devlink_fmsg
*fmsg
, u8 value
)
4770 if (fmsg
->putting_binary
)
4773 return devlink_fmsg_put_value(fmsg
, &value
, sizeof(value
), NLA_U8
);
4775 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_put
);
4777 int devlink_fmsg_u32_put(struct devlink_fmsg
*fmsg
, u32 value
)
4779 if (fmsg
->putting_binary
)
4782 return devlink_fmsg_put_value(fmsg
, &value
, sizeof(value
), NLA_U32
);
4784 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put
);
4786 int devlink_fmsg_u64_put(struct devlink_fmsg
*fmsg
, u64 value
)
4788 if (fmsg
->putting_binary
)
4791 return devlink_fmsg_put_value(fmsg
, &value
, sizeof(value
), NLA_U64
);
4793 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_put
);
4795 int devlink_fmsg_string_put(struct devlink_fmsg
*fmsg
, const char *value
)
4797 if (fmsg
->putting_binary
)
4800 return devlink_fmsg_put_value(fmsg
, value
, strlen(value
) + 1,
4803 EXPORT_SYMBOL_GPL(devlink_fmsg_string_put
);
4805 int devlink_fmsg_binary_put(struct devlink_fmsg
*fmsg
, const void *value
,
4808 if (!fmsg
->putting_binary
)
4811 return devlink_fmsg_put_value(fmsg
, value
, value_len
, NLA_BINARY
);
4813 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put
);
4815 int devlink_fmsg_bool_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
4820 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
4824 err
= devlink_fmsg_bool_put(fmsg
, value
);
4828 err
= devlink_fmsg_pair_nest_end(fmsg
);
4834 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put
);
4836 int devlink_fmsg_u8_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
4841 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
4845 err
= devlink_fmsg_u8_put(fmsg
, value
);
4849 err
= devlink_fmsg_pair_nest_end(fmsg
);
4855 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put
);
4857 int devlink_fmsg_u32_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
4862 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
4866 err
= devlink_fmsg_u32_put(fmsg
, value
);
4870 err
= devlink_fmsg_pair_nest_end(fmsg
);
4876 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put
);
4878 int devlink_fmsg_u64_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
4883 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
4887 err
= devlink_fmsg_u64_put(fmsg
, value
);
4891 err
= devlink_fmsg_pair_nest_end(fmsg
);
4897 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put
);
4899 int devlink_fmsg_string_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
4904 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
4908 err
= devlink_fmsg_string_put(fmsg
, value
);
4912 err
= devlink_fmsg_pair_nest_end(fmsg
);
4918 EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put
);
4920 int devlink_fmsg_binary_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
4921 const void *value
, u32 value_len
)
4928 err
= devlink_fmsg_binary_pair_nest_start(fmsg
, name
);
4932 for (offset
= 0; offset
< value_len
; offset
+= data_size
) {
4933 data_size
= value_len
- offset
;
4934 if (data_size
> DEVLINK_FMSG_MAX_SIZE
)
4935 data_size
= DEVLINK_FMSG_MAX_SIZE
;
4936 err
= devlink_fmsg_binary_put(fmsg
, value
+ offset
, data_size
);
4939 /* Exit from loop with a break (instead of
4940 * return) to make sure putting_binary is turned off in
4941 * devlink_fmsg_binary_pair_nest_end
4945 end_err
= devlink_fmsg_binary_pair_nest_end(fmsg
);
4951 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put
);
4954 devlink_fmsg_item_fill_type(struct devlink_fmsg_item
*msg
, struct sk_buff
*skb
)
4956 switch (msg
->nla_type
) {
4961 case NLA_NUL_STRING
:
4963 return nla_put_u8(skb
, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE
,
4971 devlink_fmsg_item_fill_data(struct devlink_fmsg_item
*msg
, struct sk_buff
*skb
)
4973 int attrtype
= DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA
;
4976 switch (msg
->nla_type
) {
4978 /* Always provide flag data, regardless of its value */
4979 tmp
= *(bool *) msg
->value
;
4981 return nla_put_u8(skb
, attrtype
, tmp
);
4983 return nla_put_u8(skb
, attrtype
, *(u8
*) msg
->value
);
4985 return nla_put_u32(skb
, attrtype
, *(u32
*) msg
->value
);
4987 return nla_put_u64_64bit(skb
, attrtype
, *(u64
*) msg
->value
,
4989 case NLA_NUL_STRING
:
4990 return nla_put_string(skb
, attrtype
, (char *) &msg
->value
);
4992 return nla_put(skb
, attrtype
, msg
->len
, (void *) &msg
->value
);
4999 devlink_fmsg_prepare_skb(struct devlink_fmsg
*fmsg
, struct sk_buff
*skb
,
5002 struct devlink_fmsg_item
*item
;
5003 struct nlattr
*fmsg_nlattr
;
5007 fmsg_nlattr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_FMSG
);
5011 list_for_each_entry(item
, &fmsg
->item_list
, list
) {
5017 switch (item
->attrtype
) {
5018 case DEVLINK_ATTR_FMSG_OBJ_NEST_START
:
5019 case DEVLINK_ATTR_FMSG_PAIR_NEST_START
:
5020 case DEVLINK_ATTR_FMSG_ARR_NEST_START
:
5021 case DEVLINK_ATTR_FMSG_NEST_END
:
5022 err
= nla_put_flag(skb
, item
->attrtype
);
5024 case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA
:
5025 err
= devlink_fmsg_item_fill_type(item
, skb
);
5028 err
= devlink_fmsg_item_fill_data(item
, skb
);
5030 case DEVLINK_ATTR_FMSG_OBJ_NAME
:
5031 err
= nla_put_string(skb
, item
->attrtype
,
5032 (char *) &item
->value
);
5044 nla_nest_end(skb
, fmsg_nlattr
);
5048 static int devlink_fmsg_snd(struct devlink_fmsg
*fmsg
,
5049 struct genl_info
*info
,
5050 enum devlink_command cmd
, int flags
)
5052 struct nlmsghdr
*nlh
;
5053 struct sk_buff
*skb
;
5060 int tmp_index
= index
;
5062 skb
= genlmsg_new(GENLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
5066 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
5067 &devlink_nl_family
, flags
| NLM_F_MULTI
, cmd
);
5070 goto nla_put_failure
;
5073 err
= devlink_fmsg_prepare_skb(fmsg
, skb
, &index
);
5076 else if (err
!= -EMSGSIZE
|| tmp_index
== index
)
5077 goto nla_put_failure
;
5079 genlmsg_end(skb
, hdr
);
5080 err
= genlmsg_reply(skb
, info
);
5085 skb
= genlmsg_new(GENLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
5088 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
5089 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
5092 goto nla_put_failure
;
5095 return genlmsg_reply(skb
, info
);
5102 static int devlink_fmsg_dumpit(struct devlink_fmsg
*fmsg
, struct sk_buff
*skb
,
5103 struct netlink_callback
*cb
,
5104 enum devlink_command cmd
)
5106 int index
= cb
->args
[0];
5107 int tmp_index
= index
;
5111 hdr
= genlmsg_put(skb
, NETLINK_CB(cb
->skb
).portid
, cb
->nlh
->nlmsg_seq
,
5112 &devlink_nl_family
, NLM_F_ACK
| NLM_F_MULTI
, cmd
);
5115 goto nla_put_failure
;
5118 err
= devlink_fmsg_prepare_skb(fmsg
, skb
, &index
);
5119 if ((err
&& err
!= -EMSGSIZE
) || tmp_index
== index
)
5120 goto nla_put_failure
;
5122 cb
->args
[0] = index
;
5123 genlmsg_end(skb
, hdr
);
5127 genlmsg_cancel(skb
, hdr
);
5131 struct devlink_health_reporter
{
5132 struct list_head list
;
5134 const struct devlink_health_reporter_ops
*ops
;
5135 struct devlink
*devlink
;
5136 struct devlink_fmsg
*dump_fmsg
;
5137 struct mutex dump_lock
; /* lock parallel read/write from dump buffers */
5138 u64 graceful_period
;
5146 u64 last_recovery_ts
;
5147 refcount_t refcount
;
5151 devlink_health_reporter_priv(struct devlink_health_reporter
*reporter
)
5153 return reporter
->priv
;
5155 EXPORT_SYMBOL_GPL(devlink_health_reporter_priv
);
5157 static struct devlink_health_reporter
*
5158 devlink_health_reporter_find_by_name(struct devlink
*devlink
,
5159 const char *reporter_name
)
5161 struct devlink_health_reporter
*reporter
;
5163 lockdep_assert_held(&devlink
->reporters_lock
);
5164 list_for_each_entry(reporter
, &devlink
->reporter_list
, list
)
5165 if (!strcmp(reporter
->ops
->name
, reporter_name
))
5171 * devlink_health_reporter_create - create devlink health reporter
5175 * @graceful_period: to avoid recovery loops, in msecs
5178 struct devlink_health_reporter
*
5179 devlink_health_reporter_create(struct devlink
*devlink
,
5180 const struct devlink_health_reporter_ops
*ops
,
5181 u64 graceful_period
, void *priv
)
5183 struct devlink_health_reporter
*reporter
;
5185 mutex_lock(&devlink
->reporters_lock
);
5186 if (devlink_health_reporter_find_by_name(devlink
, ops
->name
)) {
5187 reporter
= ERR_PTR(-EEXIST
);
5191 if (WARN_ON(graceful_period
&& !ops
->recover
)) {
5192 reporter
= ERR_PTR(-EINVAL
);
5196 reporter
= kzalloc(sizeof(*reporter
), GFP_KERNEL
);
5198 reporter
= ERR_PTR(-ENOMEM
);
5202 reporter
->priv
= priv
;
5203 reporter
->ops
= ops
;
5204 reporter
->devlink
= devlink
;
5205 reporter
->graceful_period
= graceful_period
;
5206 reporter
->auto_recover
= !!ops
->recover
;
5207 reporter
->auto_dump
= !!ops
->dump
;
5208 mutex_init(&reporter
->dump_lock
);
5209 refcount_set(&reporter
->refcount
, 1);
5210 list_add_tail(&reporter
->list
, &devlink
->reporter_list
);
5212 mutex_unlock(&devlink
->reporters_lock
);
5215 EXPORT_SYMBOL_GPL(devlink_health_reporter_create
);
5218 * devlink_health_reporter_destroy - destroy devlink health reporter
5220 * @reporter: devlink health reporter to destroy
5223 devlink_health_reporter_destroy(struct devlink_health_reporter
*reporter
)
5225 mutex_lock(&reporter
->devlink
->reporters_lock
);
5226 list_del(&reporter
->list
);
5227 mutex_unlock(&reporter
->devlink
->reporters_lock
);
5228 while (refcount_read(&reporter
->refcount
) > 1)
5230 mutex_destroy(&reporter
->dump_lock
);
5231 if (reporter
->dump_fmsg
)
5232 devlink_fmsg_free(reporter
->dump_fmsg
);
5235 EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy
);
5238 devlink_nl_health_reporter_fill(struct sk_buff
*msg
,
5239 struct devlink
*devlink
,
5240 struct devlink_health_reporter
*reporter
,
5241 enum devlink_command cmd
, u32 portid
,
5244 struct nlattr
*reporter_attr
;
5247 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
5251 if (devlink_nl_put_handle(msg
, devlink
))
5252 goto genlmsg_cancel
;
5254 reporter_attr
= nla_nest_start_noflag(msg
,
5255 DEVLINK_ATTR_HEALTH_REPORTER
);
5257 goto genlmsg_cancel
;
5258 if (nla_put_string(msg
, DEVLINK_ATTR_HEALTH_REPORTER_NAME
,
5259 reporter
->ops
->name
))
5260 goto reporter_nest_cancel
;
5261 if (nla_put_u8(msg
, DEVLINK_ATTR_HEALTH_REPORTER_STATE
,
5262 reporter
->health_state
))
5263 goto reporter_nest_cancel
;
5264 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT
,
5265 reporter
->error_count
, DEVLINK_ATTR_PAD
))
5266 goto reporter_nest_cancel
;
5267 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT
,
5268 reporter
->recovery_count
, DEVLINK_ATTR_PAD
))
5269 goto reporter_nest_cancel
;
5270 if (reporter
->ops
->recover
&&
5271 nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
,
5272 reporter
->graceful_period
,
5274 goto reporter_nest_cancel
;
5275 if (reporter
->ops
->recover
&&
5276 nla_put_u8(msg
, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
,
5277 reporter
->auto_recover
))
5278 goto reporter_nest_cancel
;
5279 if (reporter
->dump_fmsg
&&
5280 nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS
,
5281 jiffies_to_msecs(reporter
->dump_ts
),
5283 goto reporter_nest_cancel
;
5284 if (reporter
->dump_fmsg
&&
5285 nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS
,
5286 reporter
->dump_real_ts
, DEVLINK_ATTR_PAD
))
5287 goto reporter_nest_cancel
;
5288 if (reporter
->ops
->dump
&&
5289 nla_put_u8(msg
, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP
,
5290 reporter
->auto_dump
))
5291 goto reporter_nest_cancel
;
5293 nla_nest_end(msg
, reporter_attr
);
5294 genlmsg_end(msg
, hdr
);
5297 reporter_nest_cancel
:
5298 nla_nest_end(msg
, reporter_attr
);
5300 genlmsg_cancel(msg
, hdr
);
5304 static void devlink_recover_notify(struct devlink_health_reporter
*reporter
,
5305 enum devlink_command cmd
)
5307 struct sk_buff
*msg
;
5310 WARN_ON(cmd
!= DEVLINK_CMD_HEALTH_REPORTER_RECOVER
);
5312 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
5316 err
= devlink_nl_health_reporter_fill(msg
, reporter
->devlink
,
5317 reporter
, cmd
, 0, 0, 0);
5323 genlmsg_multicast_netns(&devlink_nl_family
,
5324 devlink_net(reporter
->devlink
),
5325 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
5329 devlink_health_reporter_recovery_done(struct devlink_health_reporter
*reporter
)
5331 reporter
->recovery_count
++;
5332 reporter
->last_recovery_ts
= jiffies
;
5334 EXPORT_SYMBOL_GPL(devlink_health_reporter_recovery_done
);
5337 devlink_health_reporter_recover(struct devlink_health_reporter
*reporter
,
5338 void *priv_ctx
, struct netlink_ext_ack
*extack
)
5342 if (reporter
->health_state
== DEVLINK_HEALTH_REPORTER_STATE_HEALTHY
)
5345 if (!reporter
->ops
->recover
)
5348 err
= reporter
->ops
->recover(reporter
, priv_ctx
, extack
);
5352 devlink_health_reporter_recovery_done(reporter
);
5353 reporter
->health_state
= DEVLINK_HEALTH_REPORTER_STATE_HEALTHY
;
5354 devlink_recover_notify(reporter
, DEVLINK_CMD_HEALTH_REPORTER_RECOVER
);
5360 devlink_health_dump_clear(struct devlink_health_reporter
*reporter
)
5362 if (!reporter
->dump_fmsg
)
5364 devlink_fmsg_free(reporter
->dump_fmsg
);
5365 reporter
->dump_fmsg
= NULL
;
5368 static int devlink_health_do_dump(struct devlink_health_reporter
*reporter
,
5370 struct netlink_ext_ack
*extack
)
5374 if (!reporter
->ops
->dump
)
5377 if (reporter
->dump_fmsg
)
5380 reporter
->dump_fmsg
= devlink_fmsg_alloc();
5381 if (!reporter
->dump_fmsg
) {
5386 err
= devlink_fmsg_obj_nest_start(reporter
->dump_fmsg
);
5390 err
= reporter
->ops
->dump(reporter
, reporter
->dump_fmsg
,
5395 err
= devlink_fmsg_obj_nest_end(reporter
->dump_fmsg
);
5399 reporter
->dump_ts
= jiffies
;
5400 reporter
->dump_real_ts
= ktime_get_real_ns();
5405 devlink_health_dump_clear(reporter
);
5409 int devlink_health_report(struct devlink_health_reporter
*reporter
,
5410 const char *msg
, void *priv_ctx
)
5412 enum devlink_health_reporter_state prev_health_state
;
5413 struct devlink
*devlink
= reporter
->devlink
;
5414 unsigned long recover_ts_threshold
;
5416 /* write a log message of the current error */
5418 trace_devlink_health_report(devlink
, reporter
->ops
->name
, msg
);
5419 reporter
->error_count
++;
5420 prev_health_state
= reporter
->health_state
;
5421 reporter
->health_state
= DEVLINK_HEALTH_REPORTER_STATE_ERROR
;
5422 devlink_recover_notify(reporter
, DEVLINK_CMD_HEALTH_REPORTER_RECOVER
);
5424 /* abort if the previous error wasn't recovered */
5425 recover_ts_threshold
= reporter
->last_recovery_ts
+
5426 msecs_to_jiffies(reporter
->graceful_period
);
5427 if (reporter
->auto_recover
&&
5428 (prev_health_state
!= DEVLINK_HEALTH_REPORTER_STATE_HEALTHY
||
5429 (reporter
->last_recovery_ts
&& reporter
->recovery_count
&&
5430 time_is_after_jiffies(recover_ts_threshold
)))) {
5431 trace_devlink_health_recover_aborted(devlink
,
5432 reporter
->ops
->name
,
5433 reporter
->health_state
,
5435 reporter
->last_recovery_ts
);
5439 reporter
->health_state
= DEVLINK_HEALTH_REPORTER_STATE_ERROR
;
5441 if (reporter
->auto_dump
) {
5442 mutex_lock(&reporter
->dump_lock
);
5443 /* store current dump of current error, for later analysis */
5444 devlink_health_do_dump(reporter
, priv_ctx
, NULL
);
5445 mutex_unlock(&reporter
->dump_lock
);
5448 if (reporter
->auto_recover
)
5449 return devlink_health_reporter_recover(reporter
,
5454 EXPORT_SYMBOL_GPL(devlink_health_report
);
5456 static struct devlink_health_reporter
*
5457 devlink_health_reporter_get_from_attrs(struct devlink
*devlink
,
5458 struct nlattr
**attrs
)
5460 struct devlink_health_reporter
*reporter
;
5461 char *reporter_name
;
5463 if (!attrs
[DEVLINK_ATTR_HEALTH_REPORTER_NAME
])
5466 reporter_name
= nla_data(attrs
[DEVLINK_ATTR_HEALTH_REPORTER_NAME
]);
5467 mutex_lock(&devlink
->reporters_lock
);
5468 reporter
= devlink_health_reporter_find_by_name(devlink
, reporter_name
);
5470 refcount_inc(&reporter
->refcount
);
5471 mutex_unlock(&devlink
->reporters_lock
);
5475 static struct devlink_health_reporter
*
5476 devlink_health_reporter_get_from_info(struct devlink
*devlink
,
5477 struct genl_info
*info
)
5479 return devlink_health_reporter_get_from_attrs(devlink
, info
->attrs
);
5482 static struct devlink_health_reporter
*
5483 devlink_health_reporter_get_from_cb(struct netlink_callback
*cb
)
5485 const struct genl_dumpit_info
*info
= genl_dumpit_info(cb
);
5486 struct devlink_health_reporter
*reporter
;
5487 struct nlattr
**attrs
= info
->attrs
;
5488 struct devlink
*devlink
;
5490 mutex_lock(&devlink_mutex
);
5491 devlink
= devlink_get_from_attrs(sock_net(cb
->skb
->sk
), attrs
);
5492 if (IS_ERR(devlink
))
5495 reporter
= devlink_health_reporter_get_from_attrs(devlink
, attrs
);
5496 mutex_unlock(&devlink_mutex
);
5499 mutex_unlock(&devlink_mutex
);
5504 devlink_health_reporter_put(struct devlink_health_reporter
*reporter
)
5506 refcount_dec(&reporter
->refcount
);
5510 devlink_health_reporter_state_update(struct devlink_health_reporter
*reporter
,
5511 enum devlink_health_reporter_state state
)
5513 if (WARN_ON(state
!= DEVLINK_HEALTH_REPORTER_STATE_HEALTHY
&&
5514 state
!= DEVLINK_HEALTH_REPORTER_STATE_ERROR
))
5517 if (reporter
->health_state
== state
)
5520 reporter
->health_state
= state
;
5521 trace_devlink_health_reporter_state_update(reporter
->devlink
,
5522 reporter
->ops
->name
, state
);
5523 devlink_recover_notify(reporter
, DEVLINK_CMD_HEALTH_REPORTER_RECOVER
);
5525 EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update
);
5527 static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff
*skb
,
5528 struct genl_info
*info
)
5530 struct devlink
*devlink
= info
->user_ptr
[0];
5531 struct devlink_health_reporter
*reporter
;
5532 struct sk_buff
*msg
;
5535 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5539 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
5545 err
= devlink_nl_health_reporter_fill(msg
, devlink
, reporter
,
5546 DEVLINK_CMD_HEALTH_REPORTER_GET
,
5547 info
->snd_portid
, info
->snd_seq
,
5554 err
= genlmsg_reply(msg
, info
);
5556 devlink_health_reporter_put(reporter
);
5561 devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff
*msg
,
5562 struct netlink_callback
*cb
)
5564 struct devlink_health_reporter
*reporter
;
5565 struct devlink
*devlink
;
5566 int start
= cb
->args
[0];
5570 mutex_lock(&devlink_mutex
);
5571 list_for_each_entry(devlink
, &devlink_list
, list
) {
5572 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
5574 mutex_lock(&devlink
->reporters_lock
);
5575 list_for_each_entry(reporter
, &devlink
->reporter_list
,
5581 err
= devlink_nl_health_reporter_fill(msg
, devlink
,
5583 DEVLINK_CMD_HEALTH_REPORTER_GET
,
5584 NETLINK_CB(cb
->skb
).portid
,
5588 mutex_unlock(&devlink
->reporters_lock
);
5593 mutex_unlock(&devlink
->reporters_lock
);
5596 mutex_unlock(&devlink_mutex
);
5603 devlink_nl_cmd_health_reporter_set_doit(struct sk_buff
*skb
,
5604 struct genl_info
*info
)
5606 struct devlink
*devlink
= info
->user_ptr
[0];
5607 struct devlink_health_reporter
*reporter
;
5610 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5614 if (!reporter
->ops
->recover
&&
5615 (info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
] ||
5616 info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
])) {
5620 if (!reporter
->ops
->dump
&&
5621 info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP
]) {
5626 if (info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
])
5627 reporter
->graceful_period
=
5628 nla_get_u64(info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
]);
5630 if (info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
])
5631 reporter
->auto_recover
=
5632 nla_get_u8(info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
]);
5634 if (info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP
])
5635 reporter
->auto_dump
=
5636 nla_get_u8(info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP
]);
5638 devlink_health_reporter_put(reporter
);
5641 devlink_health_reporter_put(reporter
);
5645 static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff
*skb
,
5646 struct genl_info
*info
)
5648 struct devlink
*devlink
= info
->user_ptr
[0];
5649 struct devlink_health_reporter
*reporter
;
5652 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5656 err
= devlink_health_reporter_recover(reporter
, NULL
, info
->extack
);
5658 devlink_health_reporter_put(reporter
);
5662 static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff
*skb
,
5663 struct genl_info
*info
)
5665 struct devlink
*devlink
= info
->user_ptr
[0];
5666 struct devlink_health_reporter
*reporter
;
5667 struct devlink_fmsg
*fmsg
;
5670 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5674 if (!reporter
->ops
->diagnose
) {
5675 devlink_health_reporter_put(reporter
);
5679 fmsg
= devlink_fmsg_alloc();
5681 devlink_health_reporter_put(reporter
);
5685 err
= devlink_fmsg_obj_nest_start(fmsg
);
5689 err
= reporter
->ops
->diagnose(reporter
, fmsg
, info
->extack
);
5693 err
= devlink_fmsg_obj_nest_end(fmsg
);
5697 err
= devlink_fmsg_snd(fmsg
, info
,
5698 DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE
, 0);
5701 devlink_fmsg_free(fmsg
);
5702 devlink_health_reporter_put(reporter
);
5707 devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff
*skb
,
5708 struct netlink_callback
*cb
)
5710 struct devlink_health_reporter
*reporter
;
5711 u64 start
= cb
->args
[0];
5714 reporter
= devlink_health_reporter_get_from_cb(cb
);
5718 if (!reporter
->ops
->dump
) {
5722 mutex_lock(&reporter
->dump_lock
);
5724 err
= devlink_health_do_dump(reporter
, NULL
, cb
->extack
);
5727 cb
->args
[1] = reporter
->dump_ts
;
5729 if (!reporter
->dump_fmsg
|| cb
->args
[1] != reporter
->dump_ts
) {
5730 NL_SET_ERR_MSG_MOD(cb
->extack
, "Dump trampled, please retry");
5735 err
= devlink_fmsg_dumpit(reporter
->dump_fmsg
, skb
, cb
,
5736 DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET
);
5738 mutex_unlock(&reporter
->dump_lock
);
5740 devlink_health_reporter_put(reporter
);
5745 devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff
*skb
,
5746 struct genl_info
*info
)
5748 struct devlink
*devlink
= info
->user_ptr
[0];
5749 struct devlink_health_reporter
*reporter
;
5751 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5755 if (!reporter
->ops
->dump
) {
5756 devlink_health_reporter_put(reporter
);
5760 mutex_lock(&reporter
->dump_lock
);
5761 devlink_health_dump_clear(reporter
);
5762 mutex_unlock(&reporter
->dump_lock
);
5763 devlink_health_reporter_put(reporter
);
5767 struct devlink_stats
{
5770 struct u64_stats_sync syncp
;
5774 * struct devlink_trap_policer_item - Packet trap policer attributes.
5775 * @policer: Immutable packet trap policer attributes.
5776 * @rate: Rate in packets / sec.
5777 * @burst: Burst size in packets.
5778 * @list: trap_policer_list member.
5780 * Describes packet trap policer attributes. Created by devlink during trap
5781 * policer registration.
5783 struct devlink_trap_policer_item
{
5784 const struct devlink_trap_policer
*policer
;
5787 struct list_head list
;
5791 * struct devlink_trap_group_item - Packet trap group attributes.
5792 * @group: Immutable packet trap group attributes.
5793 * @policer_item: Associated policer item. Can be NULL.
5794 * @list: trap_group_list member.
5795 * @stats: Trap group statistics.
5797 * Describes packet trap group attributes. Created by devlink during trap
5798 * group registration.
5800 struct devlink_trap_group_item
{
5801 const struct devlink_trap_group
*group
;
5802 struct devlink_trap_policer_item
*policer_item
;
5803 struct list_head list
;
5804 struct devlink_stats __percpu
*stats
;
5808 * struct devlink_trap_item - Packet trap attributes.
5809 * @trap: Immutable packet trap attributes.
5810 * @group_item: Associated group item.
5811 * @list: trap_list member.
5812 * @action: Trap action.
5813 * @stats: Trap statistics.
5814 * @priv: Driver private information.
5816 * Describes both mutable and immutable packet trap attributes. Created by
5817 * devlink during trap registration and used for all trap related operations.
5819 struct devlink_trap_item
{
5820 const struct devlink_trap
*trap
;
5821 struct devlink_trap_group_item
*group_item
;
5822 struct list_head list
;
5823 enum devlink_trap_action action
;
5824 struct devlink_stats __percpu
*stats
;
5828 static struct devlink_trap_policer_item
*
5829 devlink_trap_policer_item_lookup(struct devlink
*devlink
, u32 id
)
5831 struct devlink_trap_policer_item
*policer_item
;
5833 list_for_each_entry(policer_item
, &devlink
->trap_policer_list
, list
) {
5834 if (policer_item
->policer
->id
== id
)
5835 return policer_item
;
5841 static struct devlink_trap_item
*
5842 devlink_trap_item_lookup(struct devlink
*devlink
, const char *name
)
5844 struct devlink_trap_item
*trap_item
;
5846 list_for_each_entry(trap_item
, &devlink
->trap_list
, list
) {
5847 if (!strcmp(trap_item
->trap
->name
, name
))
5854 static struct devlink_trap_item
*
5855 devlink_trap_item_get_from_info(struct devlink
*devlink
,
5856 struct genl_info
*info
)
5858 struct nlattr
*attr
;
5860 if (!info
->attrs
[DEVLINK_ATTR_TRAP_NAME
])
5862 attr
= info
->attrs
[DEVLINK_ATTR_TRAP_NAME
];
5864 return devlink_trap_item_lookup(devlink
, nla_data(attr
));
5868 devlink_trap_action_get_from_info(struct genl_info
*info
,
5869 enum devlink_trap_action
*p_trap_action
)
5873 val
= nla_get_u8(info
->attrs
[DEVLINK_ATTR_TRAP_ACTION
]);
5875 case DEVLINK_TRAP_ACTION_DROP
: /* fall-through */
5876 case DEVLINK_TRAP_ACTION_TRAP
: /* fall-through */
5877 case DEVLINK_TRAP_ACTION_MIRROR
:
5878 *p_trap_action
= val
;
5887 static int devlink_trap_metadata_put(struct sk_buff
*msg
,
5888 const struct devlink_trap
*trap
)
5890 struct nlattr
*attr
;
5892 attr
= nla_nest_start(msg
, DEVLINK_ATTR_TRAP_METADATA
);
5896 if ((trap
->metadata_cap
& DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT
) &&
5897 nla_put_flag(msg
, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT
))
5898 goto nla_put_failure
;
5899 if ((trap
->metadata_cap
& DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE
) &&
5900 nla_put_flag(msg
, DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE
))
5901 goto nla_put_failure
;
5903 nla_nest_end(msg
, attr
);
5908 nla_nest_cancel(msg
, attr
);
5912 static void devlink_trap_stats_read(struct devlink_stats __percpu
*trap_stats
,
5913 struct devlink_stats
*stats
)
5917 memset(stats
, 0, sizeof(*stats
));
5918 for_each_possible_cpu(i
) {
5919 struct devlink_stats
*cpu_stats
;
5920 u64 rx_packets
, rx_bytes
;
5923 cpu_stats
= per_cpu_ptr(trap_stats
, i
);
5925 start
= u64_stats_fetch_begin_irq(&cpu_stats
->syncp
);
5926 rx_packets
= cpu_stats
->rx_packets
;
5927 rx_bytes
= cpu_stats
->rx_bytes
;
5928 } while (u64_stats_fetch_retry_irq(&cpu_stats
->syncp
, start
));
5930 stats
->rx_packets
+= rx_packets
;
5931 stats
->rx_bytes
+= rx_bytes
;
5935 static int devlink_trap_stats_put(struct sk_buff
*msg
,
5936 struct devlink_stats __percpu
*trap_stats
)
5938 struct devlink_stats stats
;
5939 struct nlattr
*attr
;
5941 devlink_trap_stats_read(trap_stats
, &stats
);
5943 attr
= nla_nest_start(msg
, DEVLINK_ATTR_STATS
);
5947 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_STATS_RX_PACKETS
,
5948 stats
.rx_packets
, DEVLINK_ATTR_PAD
))
5949 goto nla_put_failure
;
5951 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_STATS_RX_BYTES
,
5952 stats
.rx_bytes
, DEVLINK_ATTR_PAD
))
5953 goto nla_put_failure
;
5955 nla_nest_end(msg
, attr
);
5960 nla_nest_cancel(msg
, attr
);
5964 static int devlink_nl_trap_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
5965 const struct devlink_trap_item
*trap_item
,
5966 enum devlink_command cmd
, u32 portid
, u32 seq
,
5969 struct devlink_trap_group_item
*group_item
= trap_item
->group_item
;
5973 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
5977 if (devlink_nl_put_handle(msg
, devlink
))
5978 goto nla_put_failure
;
5980 if (nla_put_string(msg
, DEVLINK_ATTR_TRAP_GROUP_NAME
,
5981 group_item
->group
->name
))
5982 goto nla_put_failure
;
5984 if (nla_put_string(msg
, DEVLINK_ATTR_TRAP_NAME
, trap_item
->trap
->name
))
5985 goto nla_put_failure
;
5987 if (nla_put_u8(msg
, DEVLINK_ATTR_TRAP_TYPE
, trap_item
->trap
->type
))
5988 goto nla_put_failure
;
5990 if (trap_item
->trap
->generic
&&
5991 nla_put_flag(msg
, DEVLINK_ATTR_TRAP_GENERIC
))
5992 goto nla_put_failure
;
5994 if (nla_put_u8(msg
, DEVLINK_ATTR_TRAP_ACTION
, trap_item
->action
))
5995 goto nla_put_failure
;
5997 err
= devlink_trap_metadata_put(msg
, trap_item
->trap
);
5999 goto nla_put_failure
;
6001 err
= devlink_trap_stats_put(msg
, trap_item
->stats
);
6003 goto nla_put_failure
;
6005 genlmsg_end(msg
, hdr
);
6010 genlmsg_cancel(msg
, hdr
);
6014 static int devlink_nl_cmd_trap_get_doit(struct sk_buff
*skb
,
6015 struct genl_info
*info
)
6017 struct netlink_ext_ack
*extack
= info
->extack
;
6018 struct devlink
*devlink
= info
->user_ptr
[0];
6019 struct devlink_trap_item
*trap_item
;
6020 struct sk_buff
*msg
;
6023 if (list_empty(&devlink
->trap_list
))
6026 trap_item
= devlink_trap_item_get_from_info(devlink
, info
);
6028 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap");
6032 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
6036 err
= devlink_nl_trap_fill(msg
, devlink
, trap_item
,
6037 DEVLINK_CMD_TRAP_NEW
, info
->snd_portid
,
6042 return genlmsg_reply(msg
, info
);
6049 static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff
*msg
,
6050 struct netlink_callback
*cb
)
6052 struct devlink_trap_item
*trap_item
;
6053 struct devlink
*devlink
;
6054 int start
= cb
->args
[0];
6058 mutex_lock(&devlink_mutex
);
6059 list_for_each_entry(devlink
, &devlink_list
, list
) {
6060 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
6062 mutex_lock(&devlink
->lock
);
6063 list_for_each_entry(trap_item
, &devlink
->trap_list
, list
) {
6068 err
= devlink_nl_trap_fill(msg
, devlink
, trap_item
,
6069 DEVLINK_CMD_TRAP_NEW
,
6070 NETLINK_CB(cb
->skb
).portid
,
6074 mutex_unlock(&devlink
->lock
);
6079 mutex_unlock(&devlink
->lock
);
6082 mutex_unlock(&devlink_mutex
);
6088 static int __devlink_trap_action_set(struct devlink
*devlink
,
6089 struct devlink_trap_item
*trap_item
,
6090 enum devlink_trap_action trap_action
,
6091 struct netlink_ext_ack
*extack
)
6095 if (trap_item
->action
!= trap_action
&&
6096 trap_item
->trap
->type
!= DEVLINK_TRAP_TYPE_DROP
) {
6097 NL_SET_ERR_MSG_MOD(extack
, "Cannot change action of non-drop traps. Skipping");
6101 err
= devlink
->ops
->trap_action_set(devlink
, trap_item
->trap
,
6106 trap_item
->action
= trap_action
;
6111 static int devlink_trap_action_set(struct devlink
*devlink
,
6112 struct devlink_trap_item
*trap_item
,
6113 struct genl_info
*info
)
6115 enum devlink_trap_action trap_action
;
6118 if (!info
->attrs
[DEVLINK_ATTR_TRAP_ACTION
])
6121 err
= devlink_trap_action_get_from_info(info
, &trap_action
);
6123 NL_SET_ERR_MSG_MOD(info
->extack
, "Invalid trap action");
6127 return __devlink_trap_action_set(devlink
, trap_item
, trap_action
,
6131 static int devlink_nl_cmd_trap_set_doit(struct sk_buff
*skb
,
6132 struct genl_info
*info
)
6134 struct netlink_ext_ack
*extack
= info
->extack
;
6135 struct devlink
*devlink
= info
->user_ptr
[0];
6136 struct devlink_trap_item
*trap_item
;
6139 if (list_empty(&devlink
->trap_list
))
6142 trap_item
= devlink_trap_item_get_from_info(devlink
, info
);
6144 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap");
6148 err
= devlink_trap_action_set(devlink
, trap_item
, info
);
6155 static struct devlink_trap_group_item
*
6156 devlink_trap_group_item_lookup(struct devlink
*devlink
, const char *name
)
6158 struct devlink_trap_group_item
*group_item
;
6160 list_for_each_entry(group_item
, &devlink
->trap_group_list
, list
) {
6161 if (!strcmp(group_item
->group
->name
, name
))
6168 static struct devlink_trap_group_item
*
6169 devlink_trap_group_item_lookup_by_id(struct devlink
*devlink
, u16 id
)
6171 struct devlink_trap_group_item
*group_item
;
6173 list_for_each_entry(group_item
, &devlink
->trap_group_list
, list
) {
6174 if (group_item
->group
->id
== id
)
6181 static struct devlink_trap_group_item
*
6182 devlink_trap_group_item_get_from_info(struct devlink
*devlink
,
6183 struct genl_info
*info
)
6187 if (!info
->attrs
[DEVLINK_ATTR_TRAP_GROUP_NAME
])
6189 name
= nla_data(info
->attrs
[DEVLINK_ATTR_TRAP_GROUP_NAME
]);
6191 return devlink_trap_group_item_lookup(devlink
, name
);
6195 devlink_nl_trap_group_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
6196 const struct devlink_trap_group_item
*group_item
,
6197 enum devlink_command cmd
, u32 portid
, u32 seq
,
6203 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
6207 if (devlink_nl_put_handle(msg
, devlink
))
6208 goto nla_put_failure
;
6210 if (nla_put_string(msg
, DEVLINK_ATTR_TRAP_GROUP_NAME
,
6211 group_item
->group
->name
))
6212 goto nla_put_failure
;
6214 if (group_item
->group
->generic
&&
6215 nla_put_flag(msg
, DEVLINK_ATTR_TRAP_GENERIC
))
6216 goto nla_put_failure
;
6218 if (group_item
->policer_item
&&
6219 nla_put_u32(msg
, DEVLINK_ATTR_TRAP_POLICER_ID
,
6220 group_item
->policer_item
->policer
->id
))
6221 goto nla_put_failure
;
6223 err
= devlink_trap_stats_put(msg
, group_item
->stats
);
6225 goto nla_put_failure
;
6227 genlmsg_end(msg
, hdr
);
6232 genlmsg_cancel(msg
, hdr
);
6236 static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff
*skb
,
6237 struct genl_info
*info
)
6239 struct netlink_ext_ack
*extack
= info
->extack
;
6240 struct devlink
*devlink
= info
->user_ptr
[0];
6241 struct devlink_trap_group_item
*group_item
;
6242 struct sk_buff
*msg
;
6245 if (list_empty(&devlink
->trap_group_list
))
6248 group_item
= devlink_trap_group_item_get_from_info(devlink
, info
);
6250 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap group");
6254 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
6258 err
= devlink_nl_trap_group_fill(msg
, devlink
, group_item
,
6259 DEVLINK_CMD_TRAP_GROUP_NEW
,
6260 info
->snd_portid
, info
->snd_seq
, 0);
6262 goto err_trap_group_fill
;
6264 return genlmsg_reply(msg
, info
);
6266 err_trap_group_fill
:
6271 static int devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff
*msg
,
6272 struct netlink_callback
*cb
)
6274 enum devlink_command cmd
= DEVLINK_CMD_TRAP_GROUP_NEW
;
6275 struct devlink_trap_group_item
*group_item
;
6276 u32 portid
= NETLINK_CB(cb
->skb
).portid
;
6277 struct devlink
*devlink
;
6278 int start
= cb
->args
[0];
6282 mutex_lock(&devlink_mutex
);
6283 list_for_each_entry(devlink
, &devlink_list
, list
) {
6284 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
6286 mutex_lock(&devlink
->lock
);
6287 list_for_each_entry(group_item
, &devlink
->trap_group_list
,
6293 err
= devlink_nl_trap_group_fill(msg
, devlink
,
6299 mutex_unlock(&devlink
->lock
);
6304 mutex_unlock(&devlink
->lock
);
6307 mutex_unlock(&devlink_mutex
);
6314 __devlink_trap_group_action_set(struct devlink
*devlink
,
6315 struct devlink_trap_group_item
*group_item
,
6316 enum devlink_trap_action trap_action
,
6317 struct netlink_ext_ack
*extack
)
6319 const char *group_name
= group_item
->group
->name
;
6320 struct devlink_trap_item
*trap_item
;
6323 list_for_each_entry(trap_item
, &devlink
->trap_list
, list
) {
6324 if (strcmp(trap_item
->group_item
->group
->name
, group_name
))
6326 err
= __devlink_trap_action_set(devlink
, trap_item
,
6327 trap_action
, extack
);
6336 devlink_trap_group_action_set(struct devlink
*devlink
,
6337 struct devlink_trap_group_item
*group_item
,
6338 struct genl_info
*info
, bool *p_modified
)
6340 enum devlink_trap_action trap_action
;
6343 if (!info
->attrs
[DEVLINK_ATTR_TRAP_ACTION
])
6346 err
= devlink_trap_action_get_from_info(info
, &trap_action
);
6348 NL_SET_ERR_MSG_MOD(info
->extack
, "Invalid trap action");
6352 err
= __devlink_trap_group_action_set(devlink
, group_item
, trap_action
,
6362 static int devlink_trap_group_set(struct devlink
*devlink
,
6363 struct devlink_trap_group_item
*group_item
,
6364 struct genl_info
*info
)
6366 struct devlink_trap_policer_item
*policer_item
;
6367 struct netlink_ext_ack
*extack
= info
->extack
;
6368 const struct devlink_trap_policer
*policer
;
6369 struct nlattr
**attrs
= info
->attrs
;
6372 if (!attrs
[DEVLINK_ATTR_TRAP_POLICER_ID
])
6375 if (!devlink
->ops
->trap_group_set
)
6378 policer_item
= group_item
->policer_item
;
6379 if (attrs
[DEVLINK_ATTR_TRAP_POLICER_ID
]) {
6382 policer_id
= nla_get_u32(attrs
[DEVLINK_ATTR_TRAP_POLICER_ID
]);
6383 policer_item
= devlink_trap_policer_item_lookup(devlink
,
6385 if (policer_id
&& !policer_item
) {
6386 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap policer");
6390 policer
= policer_item
? policer_item
->policer
: NULL
;
6392 err
= devlink
->ops
->trap_group_set(devlink
, group_item
->group
, policer
);
6396 group_item
->policer_item
= policer_item
;
6401 static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff
*skb
,
6402 struct genl_info
*info
)
6404 struct netlink_ext_ack
*extack
= info
->extack
;
6405 struct devlink
*devlink
= info
->user_ptr
[0];
6406 struct devlink_trap_group_item
*group_item
;
6407 bool modified
= false;
6410 if (list_empty(&devlink
->trap_group_list
))
6413 group_item
= devlink_trap_group_item_get_from_info(devlink
, info
);
6415 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap group");
6419 err
= devlink_trap_group_action_set(devlink
, group_item
, info
,
6424 err
= devlink_trap_group_set(devlink
, group_item
, info
);
6426 goto err_trap_group_set
;
6432 NL_SET_ERR_MSG_MOD(extack
, "Trap group set failed, but some changes were committed already");
6436 static struct devlink_trap_policer_item
*
6437 devlink_trap_policer_item_get_from_info(struct devlink
*devlink
,
6438 struct genl_info
*info
)
6442 if (!info
->attrs
[DEVLINK_ATTR_TRAP_POLICER_ID
])
6444 id
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_TRAP_POLICER_ID
]);
6446 return devlink_trap_policer_item_lookup(devlink
, id
);
6450 devlink_trap_policer_stats_put(struct sk_buff
*msg
, struct devlink
*devlink
,
6451 const struct devlink_trap_policer
*policer
)
6453 struct nlattr
*attr
;
6457 if (!devlink
->ops
->trap_policer_counter_get
)
6460 err
= devlink
->ops
->trap_policer_counter_get(devlink
, policer
, &drops
);
6464 attr
= nla_nest_start(msg
, DEVLINK_ATTR_STATS
);
6468 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_STATS_RX_DROPPED
, drops
,
6470 goto nla_put_failure
;
6472 nla_nest_end(msg
, attr
);
6477 nla_nest_cancel(msg
, attr
);
6482 devlink_nl_trap_policer_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
6483 const struct devlink_trap_policer_item
*policer_item
,
6484 enum devlink_command cmd
, u32 portid
, u32 seq
,
6490 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
6494 if (devlink_nl_put_handle(msg
, devlink
))
6495 goto nla_put_failure
;
6497 if (nla_put_u32(msg
, DEVLINK_ATTR_TRAP_POLICER_ID
,
6498 policer_item
->policer
->id
))
6499 goto nla_put_failure
;
6501 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_TRAP_POLICER_RATE
,
6502 policer_item
->rate
, DEVLINK_ATTR_PAD
))
6503 goto nla_put_failure
;
6505 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_TRAP_POLICER_BURST
,
6506 policer_item
->burst
, DEVLINK_ATTR_PAD
))
6507 goto nla_put_failure
;
6509 err
= devlink_trap_policer_stats_put(msg
, devlink
,
6510 policer_item
->policer
);
6512 goto nla_put_failure
;
6514 genlmsg_end(msg
, hdr
);
6519 genlmsg_cancel(msg
, hdr
);
6523 static int devlink_nl_cmd_trap_policer_get_doit(struct sk_buff
*skb
,
6524 struct genl_info
*info
)
6526 struct devlink_trap_policer_item
*policer_item
;
6527 struct netlink_ext_ack
*extack
= info
->extack
;
6528 struct devlink
*devlink
= info
->user_ptr
[0];
6529 struct sk_buff
*msg
;
6532 if (list_empty(&devlink
->trap_policer_list
))
6535 policer_item
= devlink_trap_policer_item_get_from_info(devlink
, info
);
6536 if (!policer_item
) {
6537 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap policer");
6541 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
6545 err
= devlink_nl_trap_policer_fill(msg
, devlink
, policer_item
,
6546 DEVLINK_CMD_TRAP_POLICER_NEW
,
6547 info
->snd_portid
, info
->snd_seq
, 0);
6549 goto err_trap_policer_fill
;
6551 return genlmsg_reply(msg
, info
);
6553 err_trap_policer_fill
:
6558 static int devlink_nl_cmd_trap_policer_get_dumpit(struct sk_buff
*msg
,
6559 struct netlink_callback
*cb
)
6561 enum devlink_command cmd
= DEVLINK_CMD_TRAP_POLICER_NEW
;
6562 struct devlink_trap_policer_item
*policer_item
;
6563 u32 portid
= NETLINK_CB(cb
->skb
).portid
;
6564 struct devlink
*devlink
;
6565 int start
= cb
->args
[0];
6569 mutex_lock(&devlink_mutex
);
6570 list_for_each_entry(devlink
, &devlink_list
, list
) {
6571 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
6573 mutex_lock(&devlink
->lock
);
6574 list_for_each_entry(policer_item
, &devlink
->trap_policer_list
,
6580 err
= devlink_nl_trap_policer_fill(msg
, devlink
,
6586 mutex_unlock(&devlink
->lock
);
6591 mutex_unlock(&devlink
->lock
);
6594 mutex_unlock(&devlink_mutex
);
6601 devlink_trap_policer_set(struct devlink
*devlink
,
6602 struct devlink_trap_policer_item
*policer_item
,
6603 struct genl_info
*info
)
6605 struct netlink_ext_ack
*extack
= info
->extack
;
6606 struct nlattr
**attrs
= info
->attrs
;
6610 rate
= policer_item
->rate
;
6611 burst
= policer_item
->burst
;
6613 if (attrs
[DEVLINK_ATTR_TRAP_POLICER_RATE
])
6614 rate
= nla_get_u64(attrs
[DEVLINK_ATTR_TRAP_POLICER_RATE
]);
6616 if (attrs
[DEVLINK_ATTR_TRAP_POLICER_BURST
])
6617 burst
= nla_get_u64(attrs
[DEVLINK_ATTR_TRAP_POLICER_BURST
]);
6619 if (rate
< policer_item
->policer
->min_rate
) {
6620 NL_SET_ERR_MSG_MOD(extack
, "Policer rate lower than limit");
6624 if (rate
> policer_item
->policer
->max_rate
) {
6625 NL_SET_ERR_MSG_MOD(extack
, "Policer rate higher than limit");
6629 if (burst
< policer_item
->policer
->min_burst
) {
6630 NL_SET_ERR_MSG_MOD(extack
, "Policer burst size lower than limit");
6634 if (burst
> policer_item
->policer
->max_burst
) {
6635 NL_SET_ERR_MSG_MOD(extack
, "Policer burst size higher than limit");
6639 err
= devlink
->ops
->trap_policer_set(devlink
, policer_item
->policer
,
6640 rate
, burst
, info
->extack
);
6644 policer_item
->rate
= rate
;
6645 policer_item
->burst
= burst
;
6650 static int devlink_nl_cmd_trap_policer_set_doit(struct sk_buff
*skb
,
6651 struct genl_info
*info
)
6653 struct devlink_trap_policer_item
*policer_item
;
6654 struct netlink_ext_ack
*extack
= info
->extack
;
6655 struct devlink
*devlink
= info
->user_ptr
[0];
6657 if (list_empty(&devlink
->trap_policer_list
))
6660 if (!devlink
->ops
->trap_policer_set
)
6663 policer_item
= devlink_trap_policer_item_get_from_info(devlink
, info
);
6664 if (!policer_item
) {
6665 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap policer");
6669 return devlink_trap_policer_set(devlink
, policer_item
, info
);
6672 static const struct nla_policy devlink_nl_policy
[DEVLINK_ATTR_MAX
+ 1] = {
6673 [DEVLINK_ATTR_UNSPEC
] = { .strict_start_type
=
6674 DEVLINK_ATTR_TRAP_POLICER_ID
},
6675 [DEVLINK_ATTR_BUS_NAME
] = { .type
= NLA_NUL_STRING
},
6676 [DEVLINK_ATTR_DEV_NAME
] = { .type
= NLA_NUL_STRING
},
6677 [DEVLINK_ATTR_PORT_INDEX
] = { .type
= NLA_U32
},
6678 [DEVLINK_ATTR_PORT_TYPE
] = { .type
= NLA_U16
},
6679 [DEVLINK_ATTR_PORT_SPLIT_COUNT
] = { .type
= NLA_U32
},
6680 [DEVLINK_ATTR_SB_INDEX
] = { .type
= NLA_U32
},
6681 [DEVLINK_ATTR_SB_POOL_INDEX
] = { .type
= NLA_U16
},
6682 [DEVLINK_ATTR_SB_POOL_TYPE
] = { .type
= NLA_U8
},
6683 [DEVLINK_ATTR_SB_POOL_SIZE
] = { .type
= NLA_U32
},
6684 [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
] = { .type
= NLA_U8
},
6685 [DEVLINK_ATTR_SB_THRESHOLD
] = { .type
= NLA_U32
},
6686 [DEVLINK_ATTR_SB_TC_INDEX
] = { .type
= NLA_U16
},
6687 [DEVLINK_ATTR_ESWITCH_MODE
] = { .type
= NLA_U16
},
6688 [DEVLINK_ATTR_ESWITCH_INLINE_MODE
] = { .type
= NLA_U8
},
6689 [DEVLINK_ATTR_ESWITCH_ENCAP_MODE
] = { .type
= NLA_U8
},
6690 [DEVLINK_ATTR_DPIPE_TABLE_NAME
] = { .type
= NLA_NUL_STRING
},
6691 [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
] = { .type
= NLA_U8
},
6692 [DEVLINK_ATTR_RESOURCE_ID
] = { .type
= NLA_U64
},
6693 [DEVLINK_ATTR_RESOURCE_SIZE
] = { .type
= NLA_U64
},
6694 [DEVLINK_ATTR_PARAM_NAME
] = { .type
= NLA_NUL_STRING
},
6695 [DEVLINK_ATTR_PARAM_TYPE
] = { .type
= NLA_U8
},
6696 [DEVLINK_ATTR_PARAM_VALUE_CMODE
] = { .type
= NLA_U8
},
6697 [DEVLINK_ATTR_REGION_NAME
] = { .type
= NLA_NUL_STRING
},
6698 [DEVLINK_ATTR_REGION_SNAPSHOT_ID
] = { .type
= NLA_U32
},
6699 [DEVLINK_ATTR_REGION_CHUNK_ADDR
] = { .type
= NLA_U64
},
6700 [DEVLINK_ATTR_REGION_CHUNK_LEN
] = { .type
= NLA_U64
},
6701 [DEVLINK_ATTR_HEALTH_REPORTER_NAME
] = { .type
= NLA_NUL_STRING
},
6702 [DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
] = { .type
= NLA_U64
},
6703 [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
] = { .type
= NLA_U8
},
6704 [DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME
] = { .type
= NLA_NUL_STRING
},
6705 [DEVLINK_ATTR_FLASH_UPDATE_COMPONENT
] = { .type
= NLA_NUL_STRING
},
6706 [DEVLINK_ATTR_TRAP_NAME
] = { .type
= NLA_NUL_STRING
},
6707 [DEVLINK_ATTR_TRAP_ACTION
] = { .type
= NLA_U8
},
6708 [DEVLINK_ATTR_TRAP_GROUP_NAME
] = { .type
= NLA_NUL_STRING
},
6709 [DEVLINK_ATTR_NETNS_PID
] = { .type
= NLA_U32
},
6710 [DEVLINK_ATTR_NETNS_FD
] = { .type
= NLA_U32
},
6711 [DEVLINK_ATTR_NETNS_ID
] = { .type
= NLA_U32
},
6712 [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP
] = { .type
= NLA_U8
},
6713 [DEVLINK_ATTR_TRAP_POLICER_ID
] = { .type
= NLA_U32
},
6714 [DEVLINK_ATTR_TRAP_POLICER_RATE
] = { .type
= NLA_U64
},
6715 [DEVLINK_ATTR_TRAP_POLICER_BURST
] = { .type
= NLA_U64
},
6718 static const struct genl_ops devlink_nl_ops
[] = {
6720 .cmd
= DEVLINK_CMD_GET
,
6721 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6722 .doit
= devlink_nl_cmd_get_doit
,
6723 .dumpit
= devlink_nl_cmd_get_dumpit
,
6724 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6725 /* can be retrieved by unprivileged users */
6728 .cmd
= DEVLINK_CMD_PORT_GET
,
6729 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6730 .doit
= devlink_nl_cmd_port_get_doit
,
6731 .dumpit
= devlink_nl_cmd_port_get_dumpit
,
6732 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
6733 /* can be retrieved by unprivileged users */
6736 .cmd
= DEVLINK_CMD_PORT_SET
,
6737 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6738 .doit
= devlink_nl_cmd_port_set_doit
,
6739 .flags
= GENL_ADMIN_PERM
,
6740 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
6743 .cmd
= DEVLINK_CMD_PORT_SPLIT
,
6744 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6745 .doit
= devlink_nl_cmd_port_split_doit
,
6746 .flags
= GENL_ADMIN_PERM
,
6747 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6748 DEVLINK_NL_FLAG_NO_LOCK
,
6751 .cmd
= DEVLINK_CMD_PORT_UNSPLIT
,
6752 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6753 .doit
= devlink_nl_cmd_port_unsplit_doit
,
6754 .flags
= GENL_ADMIN_PERM
,
6755 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6756 DEVLINK_NL_FLAG_NO_LOCK
,
6759 .cmd
= DEVLINK_CMD_SB_GET
,
6760 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6761 .doit
= devlink_nl_cmd_sb_get_doit
,
6762 .dumpit
= devlink_nl_cmd_sb_get_dumpit
,
6763 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6764 DEVLINK_NL_FLAG_NEED_SB
,
6765 /* can be retrieved by unprivileged users */
6768 .cmd
= DEVLINK_CMD_SB_POOL_GET
,
6769 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6770 .doit
= devlink_nl_cmd_sb_pool_get_doit
,
6771 .dumpit
= devlink_nl_cmd_sb_pool_get_dumpit
,
6772 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6773 DEVLINK_NL_FLAG_NEED_SB
,
6774 /* can be retrieved by unprivileged users */
6777 .cmd
= DEVLINK_CMD_SB_POOL_SET
,
6778 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6779 .doit
= devlink_nl_cmd_sb_pool_set_doit
,
6780 .flags
= GENL_ADMIN_PERM
,
6781 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6782 DEVLINK_NL_FLAG_NEED_SB
,
6785 .cmd
= DEVLINK_CMD_SB_PORT_POOL_GET
,
6786 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6787 .doit
= devlink_nl_cmd_sb_port_pool_get_doit
,
6788 .dumpit
= devlink_nl_cmd_sb_port_pool_get_dumpit
,
6789 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
6790 DEVLINK_NL_FLAG_NEED_SB
,
6791 /* can be retrieved by unprivileged users */
6794 .cmd
= DEVLINK_CMD_SB_PORT_POOL_SET
,
6795 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6796 .doit
= devlink_nl_cmd_sb_port_pool_set_doit
,
6797 .flags
= GENL_ADMIN_PERM
,
6798 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
6799 DEVLINK_NL_FLAG_NEED_SB
,
6802 .cmd
= DEVLINK_CMD_SB_TC_POOL_BIND_GET
,
6803 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6804 .doit
= devlink_nl_cmd_sb_tc_pool_bind_get_doit
,
6805 .dumpit
= devlink_nl_cmd_sb_tc_pool_bind_get_dumpit
,
6806 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
6807 DEVLINK_NL_FLAG_NEED_SB
,
6808 /* can be retrieved by unprivileged users */
6811 .cmd
= DEVLINK_CMD_SB_TC_POOL_BIND_SET
,
6812 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6813 .doit
= devlink_nl_cmd_sb_tc_pool_bind_set_doit
,
6814 .flags
= GENL_ADMIN_PERM
,
6815 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
6816 DEVLINK_NL_FLAG_NEED_SB
,
6819 .cmd
= DEVLINK_CMD_SB_OCC_SNAPSHOT
,
6820 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6821 .doit
= devlink_nl_cmd_sb_occ_snapshot_doit
,
6822 .flags
= GENL_ADMIN_PERM
,
6823 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6824 DEVLINK_NL_FLAG_NEED_SB
,
6827 .cmd
= DEVLINK_CMD_SB_OCC_MAX_CLEAR
,
6828 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6829 .doit
= devlink_nl_cmd_sb_occ_max_clear_doit
,
6830 .flags
= GENL_ADMIN_PERM
,
6831 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6832 DEVLINK_NL_FLAG_NEED_SB
,
6835 .cmd
= DEVLINK_CMD_ESWITCH_GET
,
6836 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6837 .doit
= devlink_nl_cmd_eswitch_get_doit
,
6838 .flags
= GENL_ADMIN_PERM
,
6839 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6840 DEVLINK_NL_FLAG_NO_LOCK
,
6843 .cmd
= DEVLINK_CMD_ESWITCH_SET
,
6844 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6845 .doit
= devlink_nl_cmd_eswitch_set_doit
,
6846 .flags
= GENL_ADMIN_PERM
,
6847 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6848 DEVLINK_NL_FLAG_NO_LOCK
,
6851 .cmd
= DEVLINK_CMD_DPIPE_TABLE_GET
,
6852 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6853 .doit
= devlink_nl_cmd_dpipe_table_get
,
6854 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6855 /* can be retrieved by unprivileged users */
6858 .cmd
= DEVLINK_CMD_DPIPE_ENTRIES_GET
,
6859 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6860 .doit
= devlink_nl_cmd_dpipe_entries_get
,
6861 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6862 /* can be retrieved by unprivileged users */
6865 .cmd
= DEVLINK_CMD_DPIPE_HEADERS_GET
,
6866 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6867 .doit
= devlink_nl_cmd_dpipe_headers_get
,
6868 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6869 /* can be retrieved by unprivileged users */
6872 .cmd
= DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET
,
6873 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6874 .doit
= devlink_nl_cmd_dpipe_table_counters_set
,
6875 .flags
= GENL_ADMIN_PERM
,
6876 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6879 .cmd
= DEVLINK_CMD_RESOURCE_SET
,
6880 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6881 .doit
= devlink_nl_cmd_resource_set
,
6882 .flags
= GENL_ADMIN_PERM
,
6883 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6886 .cmd
= DEVLINK_CMD_RESOURCE_DUMP
,
6887 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6888 .doit
= devlink_nl_cmd_resource_dump
,
6889 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6890 /* can be retrieved by unprivileged users */
6893 .cmd
= DEVLINK_CMD_RELOAD
,
6894 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6895 .doit
= devlink_nl_cmd_reload
,
6896 .flags
= GENL_ADMIN_PERM
,
6897 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6898 DEVLINK_NL_FLAG_NO_LOCK
,
6901 .cmd
= DEVLINK_CMD_PARAM_GET
,
6902 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6903 .doit
= devlink_nl_cmd_param_get_doit
,
6904 .dumpit
= devlink_nl_cmd_param_get_dumpit
,
6905 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6906 /* can be retrieved by unprivileged users */
6909 .cmd
= DEVLINK_CMD_PARAM_SET
,
6910 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6911 .doit
= devlink_nl_cmd_param_set_doit
,
6912 .flags
= GENL_ADMIN_PERM
,
6913 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6916 .cmd
= DEVLINK_CMD_PORT_PARAM_GET
,
6917 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6918 .doit
= devlink_nl_cmd_port_param_get_doit
,
6919 .dumpit
= devlink_nl_cmd_port_param_get_dumpit
,
6920 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
6921 /* can be retrieved by unprivileged users */
6924 .cmd
= DEVLINK_CMD_PORT_PARAM_SET
,
6925 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6926 .doit
= devlink_nl_cmd_port_param_set_doit
,
6927 .flags
= GENL_ADMIN_PERM
,
6928 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
6931 .cmd
= DEVLINK_CMD_REGION_GET
,
6932 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6933 .doit
= devlink_nl_cmd_region_get_doit
,
6934 .dumpit
= devlink_nl_cmd_region_get_dumpit
,
6935 .flags
= GENL_ADMIN_PERM
,
6936 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6939 .cmd
= DEVLINK_CMD_REGION_NEW
,
6940 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6941 .doit
= devlink_nl_cmd_region_new
,
6942 .flags
= GENL_ADMIN_PERM
,
6943 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6946 .cmd
= DEVLINK_CMD_REGION_DEL
,
6947 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6948 .doit
= devlink_nl_cmd_region_del
,
6949 .flags
= GENL_ADMIN_PERM
,
6950 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6953 .cmd
= DEVLINK_CMD_REGION_READ
,
6954 .validate
= GENL_DONT_VALIDATE_STRICT
|
6955 GENL_DONT_VALIDATE_DUMP_STRICT
,
6956 .dumpit
= devlink_nl_cmd_region_read_dumpit
,
6957 .flags
= GENL_ADMIN_PERM
,
6958 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6961 .cmd
= DEVLINK_CMD_INFO_GET
,
6962 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6963 .doit
= devlink_nl_cmd_info_get_doit
,
6964 .dumpit
= devlink_nl_cmd_info_get_dumpit
,
6965 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6966 /* can be retrieved by unprivileged users */
6969 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_GET
,
6970 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6971 .doit
= devlink_nl_cmd_health_reporter_get_doit
,
6972 .dumpit
= devlink_nl_cmd_health_reporter_get_dumpit
,
6973 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6974 DEVLINK_NL_FLAG_NO_LOCK
,
6975 /* can be retrieved by unprivileged users */
6978 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_SET
,
6979 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6980 .doit
= devlink_nl_cmd_health_reporter_set_doit
,
6981 .flags
= GENL_ADMIN_PERM
,
6982 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6983 DEVLINK_NL_FLAG_NO_LOCK
,
6986 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_RECOVER
,
6987 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6988 .doit
= devlink_nl_cmd_health_reporter_recover_doit
,
6989 .flags
= GENL_ADMIN_PERM
,
6990 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6991 DEVLINK_NL_FLAG_NO_LOCK
,
6994 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE
,
6995 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6996 .doit
= devlink_nl_cmd_health_reporter_diagnose_doit
,
6997 .flags
= GENL_ADMIN_PERM
,
6998 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6999 DEVLINK_NL_FLAG_NO_LOCK
,
7002 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET
,
7003 .validate
= GENL_DONT_VALIDATE_STRICT
|
7004 GENL_DONT_VALIDATE_DUMP_STRICT
,
7005 .dumpit
= devlink_nl_cmd_health_reporter_dump_get_dumpit
,
7006 .flags
= GENL_ADMIN_PERM
,
7007 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
7008 DEVLINK_NL_FLAG_NO_LOCK
,
7011 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR
,
7012 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7013 .doit
= devlink_nl_cmd_health_reporter_dump_clear_doit
,
7014 .flags
= GENL_ADMIN_PERM
,
7015 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
7016 DEVLINK_NL_FLAG_NO_LOCK
,
7019 .cmd
= DEVLINK_CMD_FLASH_UPDATE
,
7020 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7021 .doit
= devlink_nl_cmd_flash_update
,
7022 .flags
= GENL_ADMIN_PERM
,
7023 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7026 .cmd
= DEVLINK_CMD_TRAP_GET
,
7027 .doit
= devlink_nl_cmd_trap_get_doit
,
7028 .dumpit
= devlink_nl_cmd_trap_get_dumpit
,
7029 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7030 /* can be retrieved by unprivileged users */
7033 .cmd
= DEVLINK_CMD_TRAP_SET
,
7034 .doit
= devlink_nl_cmd_trap_set_doit
,
7035 .flags
= GENL_ADMIN_PERM
,
7036 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7039 .cmd
= DEVLINK_CMD_TRAP_GROUP_GET
,
7040 .doit
= devlink_nl_cmd_trap_group_get_doit
,
7041 .dumpit
= devlink_nl_cmd_trap_group_get_dumpit
,
7042 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7043 /* can be retrieved by unprivileged users */
7046 .cmd
= DEVLINK_CMD_TRAP_GROUP_SET
,
7047 .doit
= devlink_nl_cmd_trap_group_set_doit
,
7048 .flags
= GENL_ADMIN_PERM
,
7049 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7052 .cmd
= DEVLINK_CMD_TRAP_POLICER_GET
,
7053 .doit
= devlink_nl_cmd_trap_policer_get_doit
,
7054 .dumpit
= devlink_nl_cmd_trap_policer_get_dumpit
,
7055 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7056 /* can be retrieved by unprivileged users */
7059 .cmd
= DEVLINK_CMD_TRAP_POLICER_SET
,
7060 .doit
= devlink_nl_cmd_trap_policer_set_doit
,
7061 .flags
= GENL_ADMIN_PERM
,
7062 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7066 static struct genl_family devlink_nl_family __ro_after_init
= {
7067 .name
= DEVLINK_GENL_NAME
,
7068 .version
= DEVLINK_GENL_VERSION
,
7069 .maxattr
= DEVLINK_ATTR_MAX
,
7070 .policy
= devlink_nl_policy
,
7072 .pre_doit
= devlink_nl_pre_doit
,
7073 .post_doit
= devlink_nl_post_doit
,
7074 .module
= THIS_MODULE
,
7075 .ops
= devlink_nl_ops
,
7076 .n_ops
= ARRAY_SIZE(devlink_nl_ops
),
7077 .mcgrps
= devlink_nl_mcgrps
,
7078 .n_mcgrps
= ARRAY_SIZE(devlink_nl_mcgrps
),
7082 * devlink_alloc - Allocate new devlink instance resources
7085 * @priv_size: size of user private data
7087 * Allocate new devlink instance resources, including devlink index
7090 struct devlink
*devlink_alloc(const struct devlink_ops
*ops
, size_t priv_size
)
7092 struct devlink
*devlink
;
7097 devlink
= kzalloc(sizeof(*devlink
) + priv_size
, GFP_KERNEL
);
7101 xa_init_flags(&devlink
->snapshot_ids
, XA_FLAGS_ALLOC
);
7102 __devlink_net_set(devlink
, &init_net
);
7103 INIT_LIST_HEAD(&devlink
->port_list
);
7104 INIT_LIST_HEAD(&devlink
->sb_list
);
7105 INIT_LIST_HEAD_RCU(&devlink
->dpipe_table_list
);
7106 INIT_LIST_HEAD(&devlink
->resource_list
);
7107 INIT_LIST_HEAD(&devlink
->param_list
);
7108 INIT_LIST_HEAD(&devlink
->region_list
);
7109 INIT_LIST_HEAD(&devlink
->reporter_list
);
7110 INIT_LIST_HEAD(&devlink
->trap_list
);
7111 INIT_LIST_HEAD(&devlink
->trap_group_list
);
7112 INIT_LIST_HEAD(&devlink
->trap_policer_list
);
7113 mutex_init(&devlink
->lock
);
7114 mutex_init(&devlink
->reporters_lock
);
7117 EXPORT_SYMBOL_GPL(devlink_alloc
);
7120 * devlink_register - Register devlink instance
7123 * @dev: parent device
7125 int devlink_register(struct devlink
*devlink
, struct device
*dev
)
7127 mutex_lock(&devlink_mutex
);
7129 devlink
->registered
= true;
7130 list_add_tail(&devlink
->list
, &devlink_list
);
7131 devlink_notify(devlink
, DEVLINK_CMD_NEW
);
7132 mutex_unlock(&devlink_mutex
);
7135 EXPORT_SYMBOL_GPL(devlink_register
);
7138 * devlink_unregister - Unregister devlink instance
7142 void devlink_unregister(struct devlink
*devlink
)
7144 mutex_lock(&devlink_mutex
);
7145 WARN_ON(devlink_reload_supported(devlink
) &&
7146 devlink
->reload_enabled
);
7147 devlink_notify(devlink
, DEVLINK_CMD_DEL
);
7148 list_del(&devlink
->list
);
7149 mutex_unlock(&devlink_mutex
);
7151 EXPORT_SYMBOL_GPL(devlink_unregister
);
7154 * devlink_reload_enable - Enable reload of devlink instance
7158 * Should be called at end of device initialization
7159 * process when reload operation is supported.
7161 void devlink_reload_enable(struct devlink
*devlink
)
7163 mutex_lock(&devlink_mutex
);
7164 devlink
->reload_enabled
= true;
7165 mutex_unlock(&devlink_mutex
);
7167 EXPORT_SYMBOL_GPL(devlink_reload_enable
);
7170 * devlink_reload_disable - Disable reload of devlink instance
7174 * Should be called at the beginning of device cleanup
7175 * process when reload operation is supported.
7177 void devlink_reload_disable(struct devlink
*devlink
)
7179 mutex_lock(&devlink_mutex
);
7180 /* Mutex is taken which ensures that no reload operation is in
7181 * progress while setting up forbidded flag.
7183 devlink
->reload_enabled
= false;
7184 mutex_unlock(&devlink_mutex
);
7186 EXPORT_SYMBOL_GPL(devlink_reload_disable
);
7189 * devlink_free - Free devlink instance resources
7193 void devlink_free(struct devlink
*devlink
)
7195 mutex_destroy(&devlink
->reporters_lock
);
7196 mutex_destroy(&devlink
->lock
);
7197 WARN_ON(!list_empty(&devlink
->trap_policer_list
));
7198 WARN_ON(!list_empty(&devlink
->trap_group_list
));
7199 WARN_ON(!list_empty(&devlink
->trap_list
));
7200 WARN_ON(!list_empty(&devlink
->reporter_list
));
7201 WARN_ON(!list_empty(&devlink
->region_list
));
7202 WARN_ON(!list_empty(&devlink
->param_list
));
7203 WARN_ON(!list_empty(&devlink
->resource_list
));
7204 WARN_ON(!list_empty(&devlink
->dpipe_table_list
));
7205 WARN_ON(!list_empty(&devlink
->sb_list
));
7206 WARN_ON(!list_empty(&devlink
->port_list
));
7208 xa_destroy(&devlink
->snapshot_ids
);
7212 EXPORT_SYMBOL_GPL(devlink_free
);
7214 static void devlink_port_type_warn(struct work_struct
*work
)
7216 WARN(true, "Type was not set for devlink port.");
7219 static bool devlink_port_type_should_warn(struct devlink_port
*devlink_port
)
7221 /* Ignore CPU and DSA flavours. */
7222 return devlink_port
->attrs
.flavour
!= DEVLINK_PORT_FLAVOUR_CPU
&&
7223 devlink_port
->attrs
.flavour
!= DEVLINK_PORT_FLAVOUR_DSA
;
7226 #define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 3600)
7228 static void devlink_port_type_warn_schedule(struct devlink_port
*devlink_port
)
7230 if (!devlink_port_type_should_warn(devlink_port
))
7232 /* Schedule a work to WARN in case driver does not set port
7233 * type within timeout.
7235 schedule_delayed_work(&devlink_port
->type_warn_dw
,
7236 DEVLINK_PORT_TYPE_WARN_TIMEOUT
);
7239 static void devlink_port_type_warn_cancel(struct devlink_port
*devlink_port
)
7241 if (!devlink_port_type_should_warn(devlink_port
))
7243 cancel_delayed_work_sync(&devlink_port
->type_warn_dw
);
7247 * devlink_port_register - Register devlink port
7250 * @devlink_port: devlink port
7251 * @port_index: driver-specific numerical identifier of the port
7253 * Register devlink port with provided port index. User can use
7254 * any indexing, even hw-related one. devlink_port structure
7255 * is convenient to be embedded inside user driver private structure.
7256 * Note that the caller should take care of zeroing the devlink_port
7259 int devlink_port_register(struct devlink
*devlink
,
7260 struct devlink_port
*devlink_port
,
7261 unsigned int port_index
)
7263 mutex_lock(&devlink
->lock
);
7264 if (devlink_port_index_exists(devlink
, port_index
)) {
7265 mutex_unlock(&devlink
->lock
);
7268 devlink_port
->devlink
= devlink
;
7269 devlink_port
->index
= port_index
;
7270 devlink_port
->registered
= true;
7271 spin_lock_init(&devlink_port
->type_lock
);
7272 list_add_tail(&devlink_port
->list
, &devlink
->port_list
);
7273 INIT_LIST_HEAD(&devlink_port
->param_list
);
7274 mutex_unlock(&devlink
->lock
);
7275 INIT_DELAYED_WORK(&devlink_port
->type_warn_dw
, &devlink_port_type_warn
);
7276 devlink_port_type_warn_schedule(devlink_port
);
7277 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
7280 EXPORT_SYMBOL_GPL(devlink_port_register
);
7283 * devlink_port_unregister - Unregister devlink port
7285 * @devlink_port: devlink port
7287 void devlink_port_unregister(struct devlink_port
*devlink_port
)
7289 struct devlink
*devlink
= devlink_port
->devlink
;
7291 devlink_port_type_warn_cancel(devlink_port
);
7292 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_DEL
);
7293 mutex_lock(&devlink
->lock
);
7294 list_del(&devlink_port
->list
);
7295 mutex_unlock(&devlink
->lock
);
7297 EXPORT_SYMBOL_GPL(devlink_port_unregister
);
7299 static void __devlink_port_type_set(struct devlink_port
*devlink_port
,
7300 enum devlink_port_type type
,
7303 if (WARN_ON(!devlink_port
->registered
))
7305 devlink_port_type_warn_cancel(devlink_port
);
7306 spin_lock_bh(&devlink_port
->type_lock
);
7307 devlink_port
->type
= type
;
7308 devlink_port
->type_dev
= type_dev
;
7309 spin_unlock_bh(&devlink_port
->type_lock
);
7310 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
7314 * devlink_port_type_eth_set - Set port type to Ethernet
7316 * @devlink_port: devlink port
7317 * @netdev: related netdevice
7319 void devlink_port_type_eth_set(struct devlink_port
*devlink_port
,
7320 struct net_device
*netdev
)
7322 const struct net_device_ops
*ops
= netdev
->netdev_ops
;
7324 /* If driver registers devlink port, it should set devlink port
7325 * attributes accordingly so the compat functions are called
7326 * and the original ops are not used.
7328 if (ops
->ndo_get_phys_port_name
) {
7329 /* Some drivers use the same set of ndos for netdevs
7330 * that have devlink_port registered and also for
7331 * those who don't. Make sure that ndo_get_phys_port_name
7332 * returns -EOPNOTSUPP here in case it is defined.
7335 char name
[IFNAMSIZ
];
7338 err
= ops
->ndo_get_phys_port_name(netdev
, name
, sizeof(name
));
7339 WARN_ON(err
!= -EOPNOTSUPP
);
7341 if (ops
->ndo_get_port_parent_id
) {
7342 /* Some drivers use the same set of ndos for netdevs
7343 * that have devlink_port registered and also for
7344 * those who don't. Make sure that ndo_get_port_parent_id
7345 * returns -EOPNOTSUPP here in case it is defined.
7348 struct netdev_phys_item_id ppid
;
7351 err
= ops
->ndo_get_port_parent_id(netdev
, &ppid
);
7352 WARN_ON(err
!= -EOPNOTSUPP
);
7354 __devlink_port_type_set(devlink_port
, DEVLINK_PORT_TYPE_ETH
, netdev
);
7356 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set
);
7359 * devlink_port_type_ib_set - Set port type to InfiniBand
7361 * @devlink_port: devlink port
7362 * @ibdev: related IB device
7364 void devlink_port_type_ib_set(struct devlink_port
*devlink_port
,
7365 struct ib_device
*ibdev
)
7367 __devlink_port_type_set(devlink_port
, DEVLINK_PORT_TYPE_IB
, ibdev
);
7369 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set
);
7372 * devlink_port_type_clear - Clear port type
7374 * @devlink_port: devlink port
7376 void devlink_port_type_clear(struct devlink_port
*devlink_port
)
7378 __devlink_port_type_set(devlink_port
, DEVLINK_PORT_TYPE_NOTSET
, NULL
);
7379 devlink_port_type_warn_schedule(devlink_port
);
7381 EXPORT_SYMBOL_GPL(devlink_port_type_clear
);
7383 static int __devlink_port_attrs_set(struct devlink_port
*devlink_port
,
7384 enum devlink_port_flavour flavour
,
7385 const unsigned char *switch_id
,
7386 unsigned char switch_id_len
)
7388 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
7390 if (WARN_ON(devlink_port
->registered
))
7393 attrs
->flavour
= flavour
;
7395 attrs
->switch_port
= true;
7396 if (WARN_ON(switch_id_len
> MAX_PHYS_ITEM_ID_LEN
))
7397 switch_id_len
= MAX_PHYS_ITEM_ID_LEN
;
7398 memcpy(attrs
->switch_id
.id
, switch_id
, switch_id_len
);
7399 attrs
->switch_id
.id_len
= switch_id_len
;
7401 attrs
->switch_port
= false;
7407 * devlink_port_attrs_set - Set port attributes
7409 * @devlink_port: devlink port
7410 * @flavour: flavour of the port
7411 * @port_number: number of the port that is facing user, for example
7412 * the front panel port number
7413 * @split: indicates if this is split port
7414 * @split_subport_number: if the port is split, this is the number
7416 * @switch_id: if the port is part of switch, this is buffer with ID,
7417 * otwerwise this is NULL
7418 * @switch_id_len: length of the switch_id buffer
7420 void devlink_port_attrs_set(struct devlink_port
*devlink_port
,
7421 enum devlink_port_flavour flavour
,
7422 u32 port_number
, bool split
,
7423 u32 split_subport_number
,
7424 const unsigned char *switch_id
,
7425 unsigned char switch_id_len
)
7427 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
7430 ret
= __devlink_port_attrs_set(devlink_port
, flavour
,
7431 switch_id
, switch_id_len
);
7434 attrs
->split
= split
;
7435 attrs
->phys
.port_number
= port_number
;
7436 attrs
->phys
.split_subport_number
= split_subport_number
;
7438 EXPORT_SYMBOL_GPL(devlink_port_attrs_set
);
7441 * devlink_port_attrs_pci_pf_set - Set PCI PF port attributes
7443 * @devlink_port: devlink port
7444 * @pf: associated PF for the devlink port instance
7445 * @switch_id: if the port is part of switch, this is buffer with ID,
7446 * otherwise this is NULL
7447 * @switch_id_len: length of the switch_id buffer
7449 void devlink_port_attrs_pci_pf_set(struct devlink_port
*devlink_port
,
7450 const unsigned char *switch_id
,
7451 unsigned char switch_id_len
, u16 pf
)
7453 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
7456 ret
= __devlink_port_attrs_set(devlink_port
,
7457 DEVLINK_PORT_FLAVOUR_PCI_PF
,
7458 switch_id
, switch_id_len
);
7462 attrs
->pci_pf
.pf
= pf
;
7464 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set
);
7467 * devlink_port_attrs_pci_vf_set - Set PCI VF port attributes
7469 * @devlink_port: devlink port
7470 * @pf: associated PF for the devlink port instance
7471 * @vf: associated VF of a PF for the devlink port instance
7472 * @switch_id: if the port is part of switch, this is buffer with ID,
7473 * otherwise this is NULL
7474 * @switch_id_len: length of the switch_id buffer
7476 void devlink_port_attrs_pci_vf_set(struct devlink_port
*devlink_port
,
7477 const unsigned char *switch_id
,
7478 unsigned char switch_id_len
,
7481 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
7484 ret
= __devlink_port_attrs_set(devlink_port
,
7485 DEVLINK_PORT_FLAVOUR_PCI_VF
,
7486 switch_id
, switch_id_len
);
7489 attrs
->pci_vf
.pf
= pf
;
7490 attrs
->pci_vf
.vf
= vf
;
7492 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set
);
7494 static int __devlink_port_phys_port_name_get(struct devlink_port
*devlink_port
,
7495 char *name
, size_t len
)
7497 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
7503 switch (attrs
->flavour
) {
7504 case DEVLINK_PORT_FLAVOUR_PHYSICAL
:
7505 case DEVLINK_PORT_FLAVOUR_VIRTUAL
:
7507 n
= snprintf(name
, len
, "p%u", attrs
->phys
.port_number
);
7509 n
= snprintf(name
, len
, "p%us%u",
7510 attrs
->phys
.port_number
,
7511 attrs
->phys
.split_subport_number
);
7513 case DEVLINK_PORT_FLAVOUR_CPU
:
7514 case DEVLINK_PORT_FLAVOUR_DSA
:
7515 /* As CPU and DSA ports do not have a netdevice associated
7516 * case should not ever happen.
7520 case DEVLINK_PORT_FLAVOUR_PCI_PF
:
7521 n
= snprintf(name
, len
, "pf%u", attrs
->pci_pf
.pf
);
7523 case DEVLINK_PORT_FLAVOUR_PCI_VF
:
7524 n
= snprintf(name
, len
, "pf%uvf%u",
7525 attrs
->pci_vf
.pf
, attrs
->pci_vf
.vf
);
7535 int devlink_sb_register(struct devlink
*devlink
, unsigned int sb_index
,
7536 u32 size
, u16 ingress_pools_count
,
7537 u16 egress_pools_count
, u16 ingress_tc_count
,
7538 u16 egress_tc_count
)
7540 struct devlink_sb
*devlink_sb
;
7543 mutex_lock(&devlink
->lock
);
7544 if (devlink_sb_index_exists(devlink
, sb_index
)) {
7549 devlink_sb
= kzalloc(sizeof(*devlink_sb
), GFP_KERNEL
);
7554 devlink_sb
->index
= sb_index
;
7555 devlink_sb
->size
= size
;
7556 devlink_sb
->ingress_pools_count
= ingress_pools_count
;
7557 devlink_sb
->egress_pools_count
= egress_pools_count
;
7558 devlink_sb
->ingress_tc_count
= ingress_tc_count
;
7559 devlink_sb
->egress_tc_count
= egress_tc_count
;
7560 list_add_tail(&devlink_sb
->list
, &devlink
->sb_list
);
7562 mutex_unlock(&devlink
->lock
);
7565 EXPORT_SYMBOL_GPL(devlink_sb_register
);
7567 void devlink_sb_unregister(struct devlink
*devlink
, unsigned int sb_index
)
7569 struct devlink_sb
*devlink_sb
;
7571 mutex_lock(&devlink
->lock
);
7572 devlink_sb
= devlink_sb_get_by_index(devlink
, sb_index
);
7573 WARN_ON(!devlink_sb
);
7574 list_del(&devlink_sb
->list
);
7575 mutex_unlock(&devlink
->lock
);
7578 EXPORT_SYMBOL_GPL(devlink_sb_unregister
);
7581 * devlink_dpipe_headers_register - register dpipe headers
7584 * @dpipe_headers: dpipe header array
7586 * Register the headers supported by hardware.
7588 int devlink_dpipe_headers_register(struct devlink
*devlink
,
7589 struct devlink_dpipe_headers
*dpipe_headers
)
7591 mutex_lock(&devlink
->lock
);
7592 devlink
->dpipe_headers
= dpipe_headers
;
7593 mutex_unlock(&devlink
->lock
);
7596 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register
);
7599 * devlink_dpipe_headers_unregister - unregister dpipe headers
7603 * Unregister the headers supported by hardware.
7605 void devlink_dpipe_headers_unregister(struct devlink
*devlink
)
7607 mutex_lock(&devlink
->lock
);
7608 devlink
->dpipe_headers
= NULL
;
7609 mutex_unlock(&devlink
->lock
);
7611 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister
);
7614 * devlink_dpipe_table_counter_enabled - check if counter allocation
7617 * @table_name: tables name
7619 * Used by driver to check if counter allocation is required.
7620 * After counter allocation is turned on the table entries
7621 * are updated to include counter statistics.
7623 * After that point on the driver must respect the counter
7624 * state so that each entry added to the table is added
7627 bool devlink_dpipe_table_counter_enabled(struct devlink
*devlink
,
7628 const char *table_name
)
7630 struct devlink_dpipe_table
*table
;
7634 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
7635 table_name
, devlink
);
7638 enabled
= table
->counters_enabled
;
7642 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled
);
7645 * devlink_dpipe_table_register - register dpipe table
7648 * @table_name: table name
7649 * @table_ops: table ops
7651 * @counter_control_extern: external control for counters
7653 int devlink_dpipe_table_register(struct devlink
*devlink
,
7654 const char *table_name
,
7655 struct devlink_dpipe_table_ops
*table_ops
,
7656 void *priv
, bool counter_control_extern
)
7658 struct devlink_dpipe_table
*table
;
7661 if (WARN_ON(!table_ops
->size_get
))
7664 mutex_lock(&devlink
->lock
);
7666 if (devlink_dpipe_table_find(&devlink
->dpipe_table_list
, table_name
,
7672 table
= kzalloc(sizeof(*table
), GFP_KERNEL
);
7678 table
->name
= table_name
;
7679 table
->table_ops
= table_ops
;
7681 table
->counter_control_extern
= counter_control_extern
;
7683 list_add_tail_rcu(&table
->list
, &devlink
->dpipe_table_list
);
7685 mutex_unlock(&devlink
->lock
);
7688 EXPORT_SYMBOL_GPL(devlink_dpipe_table_register
);
7691 * devlink_dpipe_table_unregister - unregister dpipe table
7694 * @table_name: table name
7696 void devlink_dpipe_table_unregister(struct devlink
*devlink
,
7697 const char *table_name
)
7699 struct devlink_dpipe_table
*table
;
7701 mutex_lock(&devlink
->lock
);
7702 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
7703 table_name
, devlink
);
7706 list_del_rcu(&table
->list
);
7707 mutex_unlock(&devlink
->lock
);
7708 kfree_rcu(table
, rcu
);
7711 mutex_unlock(&devlink
->lock
);
7713 EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister
);
7716 * devlink_resource_register - devlink resource register
7719 * @resource_name: resource's name
7720 * @resource_size: resource's size
7721 * @resource_id: resource's id
7722 * @parent_resource_id: resource's parent id
7723 * @size_params: size parameters
7725 int devlink_resource_register(struct devlink
*devlink
,
7726 const char *resource_name
,
7729 u64 parent_resource_id
,
7730 const struct devlink_resource_size_params
*size_params
)
7732 struct devlink_resource
*resource
;
7733 struct list_head
*resource_list
;
7737 top_hierarchy
= parent_resource_id
== DEVLINK_RESOURCE_ID_PARENT_TOP
;
7739 mutex_lock(&devlink
->lock
);
7740 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
7746 resource
= kzalloc(sizeof(*resource
), GFP_KERNEL
);
7752 if (top_hierarchy
) {
7753 resource_list
= &devlink
->resource_list
;
7755 struct devlink_resource
*parent_resource
;
7757 parent_resource
= devlink_resource_find(devlink
, NULL
,
7758 parent_resource_id
);
7759 if (parent_resource
) {
7760 resource_list
= &parent_resource
->resource_list
;
7761 resource
->parent
= parent_resource
;
7769 resource
->name
= resource_name
;
7770 resource
->size
= resource_size
;
7771 resource
->size_new
= resource_size
;
7772 resource
->id
= resource_id
;
7773 resource
->size_valid
= true;
7774 memcpy(&resource
->size_params
, size_params
,
7775 sizeof(resource
->size_params
));
7776 INIT_LIST_HEAD(&resource
->resource_list
);
7777 list_add_tail(&resource
->list
, resource_list
);
7779 mutex_unlock(&devlink
->lock
);
7782 EXPORT_SYMBOL_GPL(devlink_resource_register
);
7785 * devlink_resources_unregister - free all resources
7788 * @resource: resource
7790 void devlink_resources_unregister(struct devlink
*devlink
,
7791 struct devlink_resource
*resource
)
7793 struct devlink_resource
*tmp
, *child_resource
;
7794 struct list_head
*resource_list
;
7797 resource_list
= &resource
->resource_list
;
7799 resource_list
= &devlink
->resource_list
;
7802 mutex_lock(&devlink
->lock
);
7804 list_for_each_entry_safe(child_resource
, tmp
, resource_list
, list
) {
7805 devlink_resources_unregister(devlink
, child_resource
);
7806 list_del(&child_resource
->list
);
7807 kfree(child_resource
);
7811 mutex_unlock(&devlink
->lock
);
7813 EXPORT_SYMBOL_GPL(devlink_resources_unregister
);
7816 * devlink_resource_size_get - get and update size
7819 * @resource_id: the requested resource id
7820 * @p_resource_size: ptr to update
7822 int devlink_resource_size_get(struct devlink
*devlink
,
7824 u64
*p_resource_size
)
7826 struct devlink_resource
*resource
;
7829 mutex_lock(&devlink
->lock
);
7830 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
7835 *p_resource_size
= resource
->size_new
;
7836 resource
->size
= resource
->size_new
;
7838 mutex_unlock(&devlink
->lock
);
7841 EXPORT_SYMBOL_GPL(devlink_resource_size_get
);
7844 * devlink_dpipe_table_resource_set - set the resource id
7847 * @table_name: table name
7848 * @resource_id: resource id
7849 * @resource_units: number of resource's units consumed per table's entry
7851 int devlink_dpipe_table_resource_set(struct devlink
*devlink
,
7852 const char *table_name
, u64 resource_id
,
7855 struct devlink_dpipe_table
*table
;
7858 mutex_lock(&devlink
->lock
);
7859 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
7860 table_name
, devlink
);
7865 table
->resource_id
= resource_id
;
7866 table
->resource_units
= resource_units
;
7867 table
->resource_valid
= true;
7869 mutex_unlock(&devlink
->lock
);
7872 EXPORT_SYMBOL_GPL(devlink_dpipe_table_resource_set
);
7875 * devlink_resource_occ_get_register - register occupancy getter
7878 * @resource_id: resource id
7879 * @occ_get: occupancy getter callback
7880 * @occ_get_priv: occupancy getter callback priv
7882 void devlink_resource_occ_get_register(struct devlink
*devlink
,
7884 devlink_resource_occ_get_t
*occ_get
,
7887 struct devlink_resource
*resource
;
7889 mutex_lock(&devlink
->lock
);
7890 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
7891 if (WARN_ON(!resource
))
7893 WARN_ON(resource
->occ_get
);
7895 resource
->occ_get
= occ_get
;
7896 resource
->occ_get_priv
= occ_get_priv
;
7898 mutex_unlock(&devlink
->lock
);
7900 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register
);
7903 * devlink_resource_occ_get_unregister - unregister occupancy getter
7906 * @resource_id: resource id
7908 void devlink_resource_occ_get_unregister(struct devlink
*devlink
,
7911 struct devlink_resource
*resource
;
7913 mutex_lock(&devlink
->lock
);
7914 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
7915 if (WARN_ON(!resource
))
7917 WARN_ON(!resource
->occ_get
);
7919 resource
->occ_get
= NULL
;
7920 resource
->occ_get_priv
= NULL
;
7922 mutex_unlock(&devlink
->lock
);
7924 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister
);
7926 static int devlink_param_verify(const struct devlink_param
*param
)
7928 if (!param
|| !param
->name
|| !param
->supported_cmodes
)
7931 return devlink_param_generic_verify(param
);
7933 return devlink_param_driver_verify(param
);
7936 static int __devlink_params_register(struct devlink
*devlink
,
7937 unsigned int port_index
,
7938 struct list_head
*param_list
,
7939 const struct devlink_param
*params
,
7940 size_t params_count
,
7941 enum devlink_command reg_cmd
,
7942 enum devlink_command unreg_cmd
)
7944 const struct devlink_param
*param
= params
;
7948 mutex_lock(&devlink
->lock
);
7949 for (i
= 0; i
< params_count
; i
++, param
++) {
7950 err
= devlink_param_verify(param
);
7954 err
= devlink_param_register_one(devlink
, port_index
,
7955 param_list
, param
, reg_cmd
);
7960 mutex_unlock(&devlink
->lock
);
7966 for (param
--; i
> 0; i
--, param
--)
7967 devlink_param_unregister_one(devlink
, port_index
, param_list
,
7970 mutex_unlock(&devlink
->lock
);
7974 static void __devlink_params_unregister(struct devlink
*devlink
,
7975 unsigned int port_index
,
7976 struct list_head
*param_list
,
7977 const struct devlink_param
*params
,
7978 size_t params_count
,
7979 enum devlink_command cmd
)
7981 const struct devlink_param
*param
= params
;
7984 mutex_lock(&devlink
->lock
);
7985 for (i
= 0; i
< params_count
; i
++, param
++)
7986 devlink_param_unregister_one(devlink
, 0, param_list
, param
,
7988 mutex_unlock(&devlink
->lock
);
7992 * devlink_params_register - register configuration parameters
7995 * @params: configuration parameters array
7996 * @params_count: number of parameters provided
7998 * Register the configuration parameters supported by the driver.
8000 int devlink_params_register(struct devlink
*devlink
,
8001 const struct devlink_param
*params
,
8002 size_t params_count
)
8004 return __devlink_params_register(devlink
, 0, &devlink
->param_list
,
8005 params
, params_count
,
8006 DEVLINK_CMD_PARAM_NEW
,
8007 DEVLINK_CMD_PARAM_DEL
);
8009 EXPORT_SYMBOL_GPL(devlink_params_register
);
8012 * devlink_params_unregister - unregister configuration parameters
8014 * @params: configuration parameters to unregister
8015 * @params_count: number of parameters provided
8017 void devlink_params_unregister(struct devlink
*devlink
,
8018 const struct devlink_param
*params
,
8019 size_t params_count
)
8021 return __devlink_params_unregister(devlink
, 0, &devlink
->param_list
,
8022 params
, params_count
,
8023 DEVLINK_CMD_PARAM_DEL
);
8025 EXPORT_SYMBOL_GPL(devlink_params_unregister
);
8028 * devlink_params_publish - publish configuration parameters
8032 * Publish previously registered configuration parameters.
8034 void devlink_params_publish(struct devlink
*devlink
)
8036 struct devlink_param_item
*param_item
;
8038 list_for_each_entry(param_item
, &devlink
->param_list
, list
) {
8039 if (param_item
->published
)
8041 param_item
->published
= true;
8042 devlink_param_notify(devlink
, 0, param_item
,
8043 DEVLINK_CMD_PARAM_NEW
);
8046 EXPORT_SYMBOL_GPL(devlink_params_publish
);
8049 * devlink_params_unpublish - unpublish configuration parameters
8053 * Unpublish previously registered configuration parameters.
8055 void devlink_params_unpublish(struct devlink
*devlink
)
8057 struct devlink_param_item
*param_item
;
8059 list_for_each_entry(param_item
, &devlink
->param_list
, list
) {
8060 if (!param_item
->published
)
8062 param_item
->published
= false;
8063 devlink_param_notify(devlink
, 0, param_item
,
8064 DEVLINK_CMD_PARAM_DEL
);
8067 EXPORT_SYMBOL_GPL(devlink_params_unpublish
);
8070 * devlink_port_params_register - register port configuration parameters
8072 * @devlink_port: devlink port
8073 * @params: configuration parameters array
8074 * @params_count: number of parameters provided
8076 * Register the configuration parameters supported by the port.
8078 int devlink_port_params_register(struct devlink_port
*devlink_port
,
8079 const struct devlink_param
*params
,
8080 size_t params_count
)
8082 return __devlink_params_register(devlink_port
->devlink
,
8083 devlink_port
->index
,
8084 &devlink_port
->param_list
, params
,
8086 DEVLINK_CMD_PORT_PARAM_NEW
,
8087 DEVLINK_CMD_PORT_PARAM_DEL
);
8089 EXPORT_SYMBOL_GPL(devlink_port_params_register
);
8092 * devlink_port_params_unregister - unregister port configuration
8095 * @devlink_port: devlink port
8096 * @params: configuration parameters array
8097 * @params_count: number of parameters provided
8099 void devlink_port_params_unregister(struct devlink_port
*devlink_port
,
8100 const struct devlink_param
*params
,
8101 size_t params_count
)
8103 return __devlink_params_unregister(devlink_port
->devlink
,
8104 devlink_port
->index
,
8105 &devlink_port
->param_list
,
8106 params
, params_count
,
8107 DEVLINK_CMD_PORT_PARAM_DEL
);
8109 EXPORT_SYMBOL_GPL(devlink_port_params_unregister
);
8112 __devlink_param_driverinit_value_get(struct list_head
*param_list
, u32 param_id
,
8113 union devlink_param_value
*init_val
)
8115 struct devlink_param_item
*param_item
;
8117 param_item
= devlink_param_find_by_id(param_list
, param_id
);
8121 if (!param_item
->driverinit_value_valid
||
8122 !devlink_param_cmode_is_supported(param_item
->param
,
8123 DEVLINK_PARAM_CMODE_DRIVERINIT
))
8126 if (param_item
->param
->type
== DEVLINK_PARAM_TYPE_STRING
)
8127 strcpy(init_val
->vstr
, param_item
->driverinit_value
.vstr
);
8129 *init_val
= param_item
->driverinit_value
;
8135 __devlink_param_driverinit_value_set(struct devlink
*devlink
,
8136 unsigned int port_index
,
8137 struct list_head
*param_list
, u32 param_id
,
8138 union devlink_param_value init_val
,
8139 enum devlink_command cmd
)
8141 struct devlink_param_item
*param_item
;
8143 param_item
= devlink_param_find_by_id(param_list
, param_id
);
8147 if (!devlink_param_cmode_is_supported(param_item
->param
,
8148 DEVLINK_PARAM_CMODE_DRIVERINIT
))
8151 if (param_item
->param
->type
== DEVLINK_PARAM_TYPE_STRING
)
8152 strcpy(param_item
->driverinit_value
.vstr
, init_val
.vstr
);
8154 param_item
->driverinit_value
= init_val
;
8155 param_item
->driverinit_value_valid
= true;
8157 devlink_param_notify(devlink
, port_index
, param_item
, cmd
);
8162 * devlink_param_driverinit_value_get - get configuration parameter
8163 * value for driver initializing
8166 * @param_id: parameter ID
8167 * @init_val: value of parameter in driverinit configuration mode
8169 * This function should be used by the driver to get driverinit
8170 * configuration for initialization after reload command.
8172 int devlink_param_driverinit_value_get(struct devlink
*devlink
, u32 param_id
,
8173 union devlink_param_value
*init_val
)
8175 if (!devlink_reload_supported(devlink
))
8178 return __devlink_param_driverinit_value_get(&devlink
->param_list
,
8179 param_id
, init_val
);
8181 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_get
);
8184 * devlink_param_driverinit_value_set - set value of configuration
8185 * parameter for driverinit
8186 * configuration mode
8189 * @param_id: parameter ID
8190 * @init_val: value of parameter to set for driverinit configuration mode
8192 * This function should be used by the driver to set driverinit
8193 * configuration mode default value.
8195 int devlink_param_driverinit_value_set(struct devlink
*devlink
, u32 param_id
,
8196 union devlink_param_value init_val
)
8198 return __devlink_param_driverinit_value_set(devlink
, 0,
8199 &devlink
->param_list
,
8201 DEVLINK_CMD_PARAM_NEW
);
8203 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set
);
8206 * devlink_port_param_driverinit_value_get - get configuration parameter
8207 * value for driver initializing
8209 * @devlink_port: devlink_port
8210 * @param_id: parameter ID
8211 * @init_val: value of parameter in driverinit configuration mode
8213 * This function should be used by the driver to get driverinit
8214 * configuration for initialization after reload command.
8216 int devlink_port_param_driverinit_value_get(struct devlink_port
*devlink_port
,
8218 union devlink_param_value
*init_val
)
8220 struct devlink
*devlink
= devlink_port
->devlink
;
8222 if (!devlink_reload_supported(devlink
))
8225 return __devlink_param_driverinit_value_get(&devlink_port
->param_list
,
8226 param_id
, init_val
);
8228 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_get
);
8231 * devlink_port_param_driverinit_value_set - set value of configuration
8232 * parameter for driverinit
8233 * configuration mode
8235 * @devlink_port: devlink_port
8236 * @param_id: parameter ID
8237 * @init_val: value of parameter to set for driverinit configuration mode
8239 * This function should be used by the driver to set driverinit
8240 * configuration mode default value.
8242 int devlink_port_param_driverinit_value_set(struct devlink_port
*devlink_port
,
8244 union devlink_param_value init_val
)
8246 return __devlink_param_driverinit_value_set(devlink_port
->devlink
,
8247 devlink_port
->index
,
8248 &devlink_port
->param_list
,
8250 DEVLINK_CMD_PORT_PARAM_NEW
);
8252 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_set
);
8255 * devlink_param_value_changed - notify devlink on a parameter's value
8256 * change. Should be called by the driver
8257 * right after the change.
8260 * @param_id: parameter ID
8262 * This function should be used by the driver to notify devlink on value
8263 * change, excluding driverinit configuration mode.
8264 * For driverinit configuration mode driver should use the function
8266 void devlink_param_value_changed(struct devlink
*devlink
, u32 param_id
)
8268 struct devlink_param_item
*param_item
;
8270 param_item
= devlink_param_find_by_id(&devlink
->param_list
, param_id
);
8271 WARN_ON(!param_item
);
8273 devlink_param_notify(devlink
, 0, param_item
, DEVLINK_CMD_PARAM_NEW
);
8275 EXPORT_SYMBOL_GPL(devlink_param_value_changed
);
8278 * devlink_port_param_value_changed - notify devlink on a parameter's value
8279 * change. Should be called by the driver
8280 * right after the change.
8282 * @devlink_port: devlink_port
8283 * @param_id: parameter ID
8285 * This function should be used by the driver to notify devlink on value
8286 * change, excluding driverinit configuration mode.
8287 * For driverinit configuration mode driver should use the function
8288 * devlink_port_param_driverinit_value_set() instead.
8290 void devlink_port_param_value_changed(struct devlink_port
*devlink_port
,
8293 struct devlink_param_item
*param_item
;
8295 param_item
= devlink_param_find_by_id(&devlink_port
->param_list
,
8297 WARN_ON(!param_item
);
8299 devlink_param_notify(devlink_port
->devlink
, devlink_port
->index
,
8300 param_item
, DEVLINK_CMD_PORT_PARAM_NEW
);
8302 EXPORT_SYMBOL_GPL(devlink_port_param_value_changed
);
8305 * devlink_param_value_str_fill - Safely fill-up the string preventing
8306 * from overflow of the preallocated buffer
8308 * @dst_val: destination devlink_param_value
8309 * @src: source buffer
8311 void devlink_param_value_str_fill(union devlink_param_value
*dst_val
,
8316 len
= strlcpy(dst_val
->vstr
, src
, __DEVLINK_PARAM_MAX_STRING_VALUE
);
8317 WARN_ON(len
>= __DEVLINK_PARAM_MAX_STRING_VALUE
);
8319 EXPORT_SYMBOL_GPL(devlink_param_value_str_fill
);
8322 * devlink_region_create - create a new address region
8325 * @ops: region operations and name
8326 * @region_max_snapshots: Maximum supported number of snapshots for region
8327 * @region_size: size of region
8329 struct devlink_region
*
8330 devlink_region_create(struct devlink
*devlink
,
8331 const struct devlink_region_ops
*ops
,
8332 u32 region_max_snapshots
, u64 region_size
)
8334 struct devlink_region
*region
;
8337 if (WARN_ON(!ops
) || WARN_ON(!ops
->destructor
))
8338 return ERR_PTR(-EINVAL
);
8340 mutex_lock(&devlink
->lock
);
8342 if (devlink_region_get_by_name(devlink
, ops
->name
)) {
8347 region
= kzalloc(sizeof(*region
), GFP_KERNEL
);
8353 region
->devlink
= devlink
;
8354 region
->max_snapshots
= region_max_snapshots
;
8356 region
->size
= region_size
;
8357 INIT_LIST_HEAD(®ion
->snapshot_list
);
8358 list_add_tail(®ion
->list
, &devlink
->region_list
);
8359 devlink_nl_region_notify(region
, NULL
, DEVLINK_CMD_REGION_NEW
);
8361 mutex_unlock(&devlink
->lock
);
8365 mutex_unlock(&devlink
->lock
);
8366 return ERR_PTR(err
);
8368 EXPORT_SYMBOL_GPL(devlink_region_create
);
8371 * devlink_region_destroy - destroy address region
8373 * @region: devlink region to destroy
8375 void devlink_region_destroy(struct devlink_region
*region
)
8377 struct devlink
*devlink
= region
->devlink
;
8378 struct devlink_snapshot
*snapshot
, *ts
;
8380 mutex_lock(&devlink
->lock
);
8382 /* Free all snapshots of region */
8383 list_for_each_entry_safe(snapshot
, ts
, ®ion
->snapshot_list
, list
)
8384 devlink_region_snapshot_del(region
, snapshot
);
8386 list_del(®ion
->list
);
8388 devlink_nl_region_notify(region
, NULL
, DEVLINK_CMD_REGION_DEL
);
8389 mutex_unlock(&devlink
->lock
);
8392 EXPORT_SYMBOL_GPL(devlink_region_destroy
);
8395 * devlink_region_snapshot_id_get - get snapshot ID
8397 * This callback should be called when adding a new snapshot,
8398 * Driver should use the same id for multiple snapshots taken
8399 * on multiple regions at the same time/by the same trigger.
8401 * The caller of this function must use devlink_region_snapshot_id_put
8402 * when finished creating regions using this id.
8404 * Returns zero on success, or a negative error code on failure.
8407 * @id: storage to return id
8409 int devlink_region_snapshot_id_get(struct devlink
*devlink
, u32
*id
)
8413 mutex_lock(&devlink
->lock
);
8414 err
= __devlink_region_snapshot_id_get(devlink
, id
);
8415 mutex_unlock(&devlink
->lock
);
8419 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get
);
8422 * devlink_region_snapshot_id_put - put snapshot ID reference
8424 * This should be called by a driver after finishing creating snapshots
8425 * with an id. Doing so ensures that the ID can later be released in the
8426 * event that all snapshots using it have been destroyed.
8429 * @id: id to release reference on
8431 void devlink_region_snapshot_id_put(struct devlink
*devlink
, u32 id
)
8433 mutex_lock(&devlink
->lock
);
8434 __devlink_snapshot_id_decrement(devlink
, id
);
8435 mutex_unlock(&devlink
->lock
);
8437 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put
);
8440 * devlink_region_snapshot_create - create a new snapshot
8441 * This will add a new snapshot of a region. The snapshot
8442 * will be stored on the region struct and can be accessed
8443 * from devlink. This is useful for future analyses of snapshots.
8444 * Multiple snapshots can be created on a region.
8445 * The @snapshot_id should be obtained using the getter function.
8447 * @region: devlink region of the snapshot
8448 * @data: snapshot data
8449 * @snapshot_id: snapshot id to be created
8451 int devlink_region_snapshot_create(struct devlink_region
*region
,
8452 u8
*data
, u32 snapshot_id
)
8454 struct devlink
*devlink
= region
->devlink
;
8457 mutex_lock(&devlink
->lock
);
8458 err
= __devlink_region_snapshot_create(region
, data
, snapshot_id
);
8459 mutex_unlock(&devlink
->lock
);
8463 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create
);
8465 #define DEVLINK_TRAP(_id, _type) \
8467 .type = DEVLINK_TRAP_TYPE_##_type, \
8468 .id = DEVLINK_TRAP_GENERIC_ID_##_id, \
8469 .name = DEVLINK_TRAP_GENERIC_NAME_##_id, \
8472 static const struct devlink_trap devlink_trap_generic
[] = {
8473 DEVLINK_TRAP(SMAC_MC
, DROP
),
8474 DEVLINK_TRAP(VLAN_TAG_MISMATCH
, DROP
),
8475 DEVLINK_TRAP(INGRESS_VLAN_FILTER
, DROP
),
8476 DEVLINK_TRAP(INGRESS_STP_FILTER
, DROP
),
8477 DEVLINK_TRAP(EMPTY_TX_LIST
, DROP
),
8478 DEVLINK_TRAP(PORT_LOOPBACK_FILTER
, DROP
),
8479 DEVLINK_TRAP(BLACKHOLE_ROUTE
, DROP
),
8480 DEVLINK_TRAP(TTL_ERROR
, EXCEPTION
),
8481 DEVLINK_TRAP(TAIL_DROP
, DROP
),
8482 DEVLINK_TRAP(NON_IP_PACKET
, DROP
),
8483 DEVLINK_TRAP(UC_DIP_MC_DMAC
, DROP
),
8484 DEVLINK_TRAP(DIP_LB
, DROP
),
8485 DEVLINK_TRAP(SIP_MC
, DROP
),
8486 DEVLINK_TRAP(SIP_LB
, DROP
),
8487 DEVLINK_TRAP(CORRUPTED_IP_HDR
, DROP
),
8488 DEVLINK_TRAP(IPV4_SIP_BC
, DROP
),
8489 DEVLINK_TRAP(IPV6_MC_DIP_RESERVED_SCOPE
, DROP
),
8490 DEVLINK_TRAP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE
, DROP
),
8491 DEVLINK_TRAP(MTU_ERROR
, EXCEPTION
),
8492 DEVLINK_TRAP(UNRESOLVED_NEIGH
, EXCEPTION
),
8493 DEVLINK_TRAP(RPF
, EXCEPTION
),
8494 DEVLINK_TRAP(REJECT_ROUTE
, EXCEPTION
),
8495 DEVLINK_TRAP(IPV4_LPM_UNICAST_MISS
, EXCEPTION
),
8496 DEVLINK_TRAP(IPV6_LPM_UNICAST_MISS
, EXCEPTION
),
8497 DEVLINK_TRAP(NON_ROUTABLE
, DROP
),
8498 DEVLINK_TRAP(DECAP_ERROR
, EXCEPTION
),
8499 DEVLINK_TRAP(OVERLAY_SMAC_MC
, DROP
),
8500 DEVLINK_TRAP(INGRESS_FLOW_ACTION_DROP
, DROP
),
8501 DEVLINK_TRAP(EGRESS_FLOW_ACTION_DROP
, DROP
),
8502 DEVLINK_TRAP(STP
, CONTROL
),
8503 DEVLINK_TRAP(LACP
, CONTROL
),
8504 DEVLINK_TRAP(LLDP
, CONTROL
),
8505 DEVLINK_TRAP(IGMP_QUERY
, CONTROL
),
8506 DEVLINK_TRAP(IGMP_V1_REPORT
, CONTROL
),
8507 DEVLINK_TRAP(IGMP_V2_REPORT
, CONTROL
),
8508 DEVLINK_TRAP(IGMP_V3_REPORT
, CONTROL
),
8509 DEVLINK_TRAP(IGMP_V2_LEAVE
, CONTROL
),
8510 DEVLINK_TRAP(MLD_QUERY
, CONTROL
),
8511 DEVLINK_TRAP(MLD_V1_REPORT
, CONTROL
),
8512 DEVLINK_TRAP(MLD_V2_REPORT
, CONTROL
),
8513 DEVLINK_TRAP(MLD_V1_DONE
, CONTROL
),
8514 DEVLINK_TRAP(IPV4_DHCP
, CONTROL
),
8515 DEVLINK_TRAP(IPV6_DHCP
, CONTROL
),
8516 DEVLINK_TRAP(ARP_REQUEST
, CONTROL
),
8517 DEVLINK_TRAP(ARP_RESPONSE
, CONTROL
),
8518 DEVLINK_TRAP(ARP_OVERLAY
, CONTROL
),
8519 DEVLINK_TRAP(IPV6_NEIGH_SOLICIT
, CONTROL
),
8520 DEVLINK_TRAP(IPV6_NEIGH_ADVERT
, CONTROL
),
8521 DEVLINK_TRAP(IPV4_BFD
, CONTROL
),
8522 DEVLINK_TRAP(IPV6_BFD
, CONTROL
),
8523 DEVLINK_TRAP(IPV4_OSPF
, CONTROL
),
8524 DEVLINK_TRAP(IPV6_OSPF
, CONTROL
),
8525 DEVLINK_TRAP(IPV4_BGP
, CONTROL
),
8526 DEVLINK_TRAP(IPV6_BGP
, CONTROL
),
8527 DEVLINK_TRAP(IPV4_VRRP
, CONTROL
),
8528 DEVLINK_TRAP(IPV6_VRRP
, CONTROL
),
8529 DEVLINK_TRAP(IPV4_PIM
, CONTROL
),
8530 DEVLINK_TRAP(IPV6_PIM
, CONTROL
),
8531 DEVLINK_TRAP(UC_LB
, CONTROL
),
8532 DEVLINK_TRAP(LOCAL_ROUTE
, CONTROL
),
8533 DEVLINK_TRAP(EXTERNAL_ROUTE
, CONTROL
),
8534 DEVLINK_TRAP(IPV6_UC_DIP_LINK_LOCAL_SCOPE
, CONTROL
),
8535 DEVLINK_TRAP(IPV6_DIP_ALL_NODES
, CONTROL
),
8536 DEVLINK_TRAP(IPV6_DIP_ALL_ROUTERS
, CONTROL
),
8537 DEVLINK_TRAP(IPV6_ROUTER_SOLICIT
, CONTROL
),
8538 DEVLINK_TRAP(IPV6_ROUTER_ADVERT
, CONTROL
),
8539 DEVLINK_TRAP(IPV6_REDIRECT
, CONTROL
),
8540 DEVLINK_TRAP(IPV4_ROUTER_ALERT
, CONTROL
),
8541 DEVLINK_TRAP(IPV6_ROUTER_ALERT
, CONTROL
),
8542 DEVLINK_TRAP(PTP_EVENT
, CONTROL
),
8543 DEVLINK_TRAP(PTP_GENERAL
, CONTROL
),
8544 DEVLINK_TRAP(FLOW_ACTION_SAMPLE
, CONTROL
),
8545 DEVLINK_TRAP(FLOW_ACTION_TRAP
, CONTROL
),
8548 #define DEVLINK_TRAP_GROUP(_id) \
8550 .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \
8551 .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \
8554 static const struct devlink_trap_group devlink_trap_group_generic
[] = {
8555 DEVLINK_TRAP_GROUP(L2_DROPS
),
8556 DEVLINK_TRAP_GROUP(L3_DROPS
),
8557 DEVLINK_TRAP_GROUP(L3_EXCEPTIONS
),
8558 DEVLINK_TRAP_GROUP(BUFFER_DROPS
),
8559 DEVLINK_TRAP_GROUP(TUNNEL_DROPS
),
8560 DEVLINK_TRAP_GROUP(ACL_DROPS
),
8561 DEVLINK_TRAP_GROUP(STP
),
8562 DEVLINK_TRAP_GROUP(LACP
),
8563 DEVLINK_TRAP_GROUP(LLDP
),
8564 DEVLINK_TRAP_GROUP(MC_SNOOPING
),
8565 DEVLINK_TRAP_GROUP(DHCP
),
8566 DEVLINK_TRAP_GROUP(NEIGH_DISCOVERY
),
8567 DEVLINK_TRAP_GROUP(BFD
),
8568 DEVLINK_TRAP_GROUP(OSPF
),
8569 DEVLINK_TRAP_GROUP(BGP
),
8570 DEVLINK_TRAP_GROUP(VRRP
),
8571 DEVLINK_TRAP_GROUP(PIM
),
8572 DEVLINK_TRAP_GROUP(UC_LB
),
8573 DEVLINK_TRAP_GROUP(LOCAL_DELIVERY
),
8574 DEVLINK_TRAP_GROUP(IPV6
),
8575 DEVLINK_TRAP_GROUP(PTP_EVENT
),
8576 DEVLINK_TRAP_GROUP(PTP_GENERAL
),
8577 DEVLINK_TRAP_GROUP(ACL_SAMPLE
),
8578 DEVLINK_TRAP_GROUP(ACL_TRAP
),
8581 static int devlink_trap_generic_verify(const struct devlink_trap
*trap
)
8583 if (trap
->id
> DEVLINK_TRAP_GENERIC_ID_MAX
)
8586 if (strcmp(trap
->name
, devlink_trap_generic
[trap
->id
].name
))
8589 if (trap
->type
!= devlink_trap_generic
[trap
->id
].type
)
8595 static int devlink_trap_driver_verify(const struct devlink_trap
*trap
)
8599 if (trap
->id
<= DEVLINK_TRAP_GENERIC_ID_MAX
)
8602 for (i
= 0; i
< ARRAY_SIZE(devlink_trap_generic
); i
++) {
8603 if (!strcmp(trap
->name
, devlink_trap_generic
[i
].name
))
8610 static int devlink_trap_verify(const struct devlink_trap
*trap
)
8612 if (!trap
|| !trap
->name
)
8616 return devlink_trap_generic_verify(trap
);
8618 return devlink_trap_driver_verify(trap
);
8622 devlink_trap_group_generic_verify(const struct devlink_trap_group
*group
)
8624 if (group
->id
> DEVLINK_TRAP_GROUP_GENERIC_ID_MAX
)
8627 if (strcmp(group
->name
, devlink_trap_group_generic
[group
->id
].name
))
8634 devlink_trap_group_driver_verify(const struct devlink_trap_group
*group
)
8638 if (group
->id
<= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX
)
8641 for (i
= 0; i
< ARRAY_SIZE(devlink_trap_group_generic
); i
++) {
8642 if (!strcmp(group
->name
, devlink_trap_group_generic
[i
].name
))
8649 static int devlink_trap_group_verify(const struct devlink_trap_group
*group
)
8652 return devlink_trap_group_generic_verify(group
);
8654 return devlink_trap_group_driver_verify(group
);
8658 devlink_trap_group_notify(struct devlink
*devlink
,
8659 const struct devlink_trap_group_item
*group_item
,
8660 enum devlink_command cmd
)
8662 struct sk_buff
*msg
;
8665 WARN_ON_ONCE(cmd
!= DEVLINK_CMD_TRAP_GROUP_NEW
&&
8666 cmd
!= DEVLINK_CMD_TRAP_GROUP_DEL
);
8668 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
8672 err
= devlink_nl_trap_group_fill(msg
, devlink
, group_item
, cmd
, 0, 0,
8679 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
8680 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
8684 devlink_trap_item_group_link(struct devlink
*devlink
,
8685 struct devlink_trap_item
*trap_item
)
8687 u16 group_id
= trap_item
->trap
->init_group_id
;
8688 struct devlink_trap_group_item
*group_item
;
8690 group_item
= devlink_trap_group_item_lookup_by_id(devlink
, group_id
);
8691 if (WARN_ON_ONCE(!group_item
))
8694 trap_item
->group_item
= group_item
;
8699 static void devlink_trap_notify(struct devlink
*devlink
,
8700 const struct devlink_trap_item
*trap_item
,
8701 enum devlink_command cmd
)
8703 struct sk_buff
*msg
;
8706 WARN_ON_ONCE(cmd
!= DEVLINK_CMD_TRAP_NEW
&&
8707 cmd
!= DEVLINK_CMD_TRAP_DEL
);
8709 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
8713 err
= devlink_nl_trap_fill(msg
, devlink
, trap_item
, cmd
, 0, 0, 0);
8719 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
8720 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
8724 devlink_trap_register(struct devlink
*devlink
,
8725 const struct devlink_trap
*trap
, void *priv
)
8727 struct devlink_trap_item
*trap_item
;
8730 if (devlink_trap_item_lookup(devlink
, trap
->name
))
8733 trap_item
= kzalloc(sizeof(*trap_item
), GFP_KERNEL
);
8737 trap_item
->stats
= netdev_alloc_pcpu_stats(struct devlink_stats
);
8738 if (!trap_item
->stats
) {
8740 goto err_stats_alloc
;
8743 trap_item
->trap
= trap
;
8744 trap_item
->action
= trap
->init_action
;
8745 trap_item
->priv
= priv
;
8747 err
= devlink_trap_item_group_link(devlink
, trap_item
);
8749 goto err_group_link
;
8751 err
= devlink
->ops
->trap_init(devlink
, trap
, trap_item
);
8755 list_add_tail(&trap_item
->list
, &devlink
->trap_list
);
8756 devlink_trap_notify(devlink
, trap_item
, DEVLINK_CMD_TRAP_NEW
);
8762 free_percpu(trap_item
->stats
);
8768 static void devlink_trap_unregister(struct devlink
*devlink
,
8769 const struct devlink_trap
*trap
)
8771 struct devlink_trap_item
*trap_item
;
8773 trap_item
= devlink_trap_item_lookup(devlink
, trap
->name
);
8774 if (WARN_ON_ONCE(!trap_item
))
8777 devlink_trap_notify(devlink
, trap_item
, DEVLINK_CMD_TRAP_DEL
);
8778 list_del(&trap_item
->list
);
8779 if (devlink
->ops
->trap_fini
)
8780 devlink
->ops
->trap_fini(devlink
, trap
, trap_item
);
8781 free_percpu(trap_item
->stats
);
8785 static void devlink_trap_disable(struct devlink
*devlink
,
8786 const struct devlink_trap
*trap
)
8788 struct devlink_trap_item
*trap_item
;
8790 trap_item
= devlink_trap_item_lookup(devlink
, trap
->name
);
8791 if (WARN_ON_ONCE(!trap_item
))
8794 devlink
->ops
->trap_action_set(devlink
, trap
, DEVLINK_TRAP_ACTION_DROP
);
8795 trap_item
->action
= DEVLINK_TRAP_ACTION_DROP
;
8799 * devlink_traps_register - Register packet traps with devlink.
8800 * @devlink: devlink.
8801 * @traps: Packet traps.
8802 * @traps_count: Count of provided packet traps.
8803 * @priv: Driver private information.
8805 * Return: Non-zero value on failure.
8807 int devlink_traps_register(struct devlink
*devlink
,
8808 const struct devlink_trap
*traps
,
8809 size_t traps_count
, void *priv
)
8813 if (!devlink
->ops
->trap_init
|| !devlink
->ops
->trap_action_set
)
8816 mutex_lock(&devlink
->lock
);
8817 for (i
= 0; i
< traps_count
; i
++) {
8818 const struct devlink_trap
*trap
= &traps
[i
];
8820 err
= devlink_trap_verify(trap
);
8822 goto err_trap_verify
;
8824 err
= devlink_trap_register(devlink
, trap
, priv
);
8826 goto err_trap_register
;
8828 mutex_unlock(&devlink
->lock
);
8834 for (i
--; i
>= 0; i
--)
8835 devlink_trap_unregister(devlink
, &traps
[i
]);
8836 mutex_unlock(&devlink
->lock
);
8839 EXPORT_SYMBOL_GPL(devlink_traps_register
);
8842 * devlink_traps_unregister - Unregister packet traps from devlink.
8843 * @devlink: devlink.
8844 * @traps: Packet traps.
8845 * @traps_count: Count of provided packet traps.
8847 void devlink_traps_unregister(struct devlink
*devlink
,
8848 const struct devlink_trap
*traps
,
8853 mutex_lock(&devlink
->lock
);
8854 /* Make sure we do not have any packets in-flight while unregistering
8855 * traps by disabling all of them and waiting for a grace period.
8857 for (i
= traps_count
- 1; i
>= 0; i
--)
8858 devlink_trap_disable(devlink
, &traps
[i
]);
8860 for (i
= traps_count
- 1; i
>= 0; i
--)
8861 devlink_trap_unregister(devlink
, &traps
[i
]);
8862 mutex_unlock(&devlink
->lock
);
8864 EXPORT_SYMBOL_GPL(devlink_traps_unregister
);
8867 devlink_trap_stats_update(struct devlink_stats __percpu
*trap_stats
,
8870 struct devlink_stats
*stats
;
8872 stats
= this_cpu_ptr(trap_stats
);
8873 u64_stats_update_begin(&stats
->syncp
);
8874 stats
->rx_bytes
+= skb_len
;
8875 stats
->rx_packets
++;
8876 u64_stats_update_end(&stats
->syncp
);
8880 devlink_trap_report_metadata_fill(struct net_dm_hw_metadata
*hw_metadata
,
8881 const struct devlink_trap_item
*trap_item
,
8882 struct devlink_port
*in_devlink_port
,
8883 const struct flow_action_cookie
*fa_cookie
)
8885 struct devlink_trap_group_item
*group_item
= trap_item
->group_item
;
8887 hw_metadata
->trap_group_name
= group_item
->group
->name
;
8888 hw_metadata
->trap_name
= trap_item
->trap
->name
;
8889 hw_metadata
->fa_cookie
= fa_cookie
;
8891 spin_lock(&in_devlink_port
->type_lock
);
8892 if (in_devlink_port
->type
== DEVLINK_PORT_TYPE_ETH
)
8893 hw_metadata
->input_dev
= in_devlink_port
->type_dev
;
8894 spin_unlock(&in_devlink_port
->type_lock
);
8898 * devlink_trap_report - Report trapped packet to drop monitor.
8899 * @devlink: devlink.
8900 * @skb: Trapped packet.
8901 * @trap_ctx: Trap context.
8902 * @in_devlink_port: Input devlink port.
8903 * @fa_cookie: Flow action cookie. Could be NULL.
8905 void devlink_trap_report(struct devlink
*devlink
, struct sk_buff
*skb
,
8906 void *trap_ctx
, struct devlink_port
*in_devlink_port
,
8907 const struct flow_action_cookie
*fa_cookie
)
8910 struct devlink_trap_item
*trap_item
= trap_ctx
;
8911 struct net_dm_hw_metadata hw_metadata
= {};
8913 devlink_trap_stats_update(trap_item
->stats
, skb
->len
);
8914 devlink_trap_stats_update(trap_item
->group_item
->stats
, skb
->len
);
8916 /* Control packets were not dropped by the device or encountered an
8917 * exception during forwarding and therefore should not be reported to
8918 * the kernel's drop monitor.
8920 if (trap_item
->trap
->type
== DEVLINK_TRAP_TYPE_CONTROL
)
8923 devlink_trap_report_metadata_fill(&hw_metadata
, trap_item
,
8924 in_devlink_port
, fa_cookie
);
8925 net_dm_hw_report(skb
, &hw_metadata
);
8927 EXPORT_SYMBOL_GPL(devlink_trap_report
);
8930 * devlink_trap_ctx_priv - Trap context to driver private information.
8931 * @trap_ctx: Trap context.
8933 * Return: Driver private information passed during registration.
8935 void *devlink_trap_ctx_priv(void *trap_ctx
)
8937 struct devlink_trap_item
*trap_item
= trap_ctx
;
8939 return trap_item
->priv
;
8941 EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv
);
8944 devlink_trap_group_item_policer_link(struct devlink
*devlink
,
8945 struct devlink_trap_group_item
*group_item
)
8947 u32 policer_id
= group_item
->group
->init_policer_id
;
8948 struct devlink_trap_policer_item
*policer_item
;
8950 if (policer_id
== 0)
8953 policer_item
= devlink_trap_policer_item_lookup(devlink
, policer_id
);
8954 if (WARN_ON_ONCE(!policer_item
))
8957 group_item
->policer_item
= policer_item
;
8963 devlink_trap_group_register(struct devlink
*devlink
,
8964 const struct devlink_trap_group
*group
)
8966 struct devlink_trap_group_item
*group_item
;
8969 if (devlink_trap_group_item_lookup(devlink
, group
->name
))
8972 group_item
= kzalloc(sizeof(*group_item
), GFP_KERNEL
);
8976 group_item
->stats
= netdev_alloc_pcpu_stats(struct devlink_stats
);
8977 if (!group_item
->stats
) {
8979 goto err_stats_alloc
;
8982 group_item
->group
= group
;
8984 err
= devlink_trap_group_item_policer_link(devlink
, group_item
);
8986 goto err_policer_link
;
8988 if (devlink
->ops
->trap_group_init
) {
8989 err
= devlink
->ops
->trap_group_init(devlink
, group
);
8991 goto err_group_init
;
8994 list_add_tail(&group_item
->list
, &devlink
->trap_group_list
);
8995 devlink_trap_group_notify(devlink
, group_item
,
8996 DEVLINK_CMD_TRAP_GROUP_NEW
);
9002 free_percpu(group_item
->stats
);
9009 devlink_trap_group_unregister(struct devlink
*devlink
,
9010 const struct devlink_trap_group
*group
)
9012 struct devlink_trap_group_item
*group_item
;
9014 group_item
= devlink_trap_group_item_lookup(devlink
, group
->name
);
9015 if (WARN_ON_ONCE(!group_item
))
9018 devlink_trap_group_notify(devlink
, group_item
,
9019 DEVLINK_CMD_TRAP_GROUP_DEL
);
9020 list_del(&group_item
->list
);
9021 free_percpu(group_item
->stats
);
9026 * devlink_trap_groups_register - Register packet trap groups with devlink.
9027 * @devlink: devlink.
9028 * @groups: Packet trap groups.
9029 * @groups_count: Count of provided packet trap groups.
9031 * Return: Non-zero value on failure.
9033 int devlink_trap_groups_register(struct devlink
*devlink
,
9034 const struct devlink_trap_group
*groups
,
9035 size_t groups_count
)
9039 mutex_lock(&devlink
->lock
);
9040 for (i
= 0; i
< groups_count
; i
++) {
9041 const struct devlink_trap_group
*group
= &groups
[i
];
9043 err
= devlink_trap_group_verify(group
);
9045 goto err_trap_group_verify
;
9047 err
= devlink_trap_group_register(devlink
, group
);
9049 goto err_trap_group_register
;
9051 mutex_unlock(&devlink
->lock
);
9055 err_trap_group_register
:
9056 err_trap_group_verify
:
9057 for (i
--; i
>= 0; i
--)
9058 devlink_trap_group_unregister(devlink
, &groups
[i
]);
9059 mutex_unlock(&devlink
->lock
);
9062 EXPORT_SYMBOL_GPL(devlink_trap_groups_register
);
9065 * devlink_trap_groups_unregister - Unregister packet trap groups from devlink.
9066 * @devlink: devlink.
9067 * @groups: Packet trap groups.
9068 * @groups_count: Count of provided packet trap groups.
9070 void devlink_trap_groups_unregister(struct devlink
*devlink
,
9071 const struct devlink_trap_group
*groups
,
9072 size_t groups_count
)
9076 mutex_lock(&devlink
->lock
);
9077 for (i
= groups_count
- 1; i
>= 0; i
--)
9078 devlink_trap_group_unregister(devlink
, &groups
[i
]);
9079 mutex_unlock(&devlink
->lock
);
9081 EXPORT_SYMBOL_GPL(devlink_trap_groups_unregister
);
9084 devlink_trap_policer_notify(struct devlink
*devlink
,
9085 const struct devlink_trap_policer_item
*policer_item
,
9086 enum devlink_command cmd
)
9088 struct sk_buff
*msg
;
9091 WARN_ON_ONCE(cmd
!= DEVLINK_CMD_TRAP_POLICER_NEW
&&
9092 cmd
!= DEVLINK_CMD_TRAP_POLICER_DEL
);
9094 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
9098 err
= devlink_nl_trap_policer_fill(msg
, devlink
, policer_item
, cmd
, 0,
9105 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
9106 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
9110 devlink_trap_policer_register(struct devlink
*devlink
,
9111 const struct devlink_trap_policer
*policer
)
9113 struct devlink_trap_policer_item
*policer_item
;
9116 if (devlink_trap_policer_item_lookup(devlink
, policer
->id
))
9119 policer_item
= kzalloc(sizeof(*policer_item
), GFP_KERNEL
);
9123 policer_item
->policer
= policer
;
9124 policer_item
->rate
= policer
->init_rate
;
9125 policer_item
->burst
= policer
->init_burst
;
9127 if (devlink
->ops
->trap_policer_init
) {
9128 err
= devlink
->ops
->trap_policer_init(devlink
, policer
);
9130 goto err_policer_init
;
9133 list_add_tail(&policer_item
->list
, &devlink
->trap_policer_list
);
9134 devlink_trap_policer_notify(devlink
, policer_item
,
9135 DEVLINK_CMD_TRAP_POLICER_NEW
);
9140 kfree(policer_item
);
9145 devlink_trap_policer_unregister(struct devlink
*devlink
,
9146 const struct devlink_trap_policer
*policer
)
9148 struct devlink_trap_policer_item
*policer_item
;
9150 policer_item
= devlink_trap_policer_item_lookup(devlink
, policer
->id
);
9151 if (WARN_ON_ONCE(!policer_item
))
9154 devlink_trap_policer_notify(devlink
, policer_item
,
9155 DEVLINK_CMD_TRAP_POLICER_DEL
);
9156 list_del(&policer_item
->list
);
9157 if (devlink
->ops
->trap_policer_fini
)
9158 devlink
->ops
->trap_policer_fini(devlink
, policer
);
9159 kfree(policer_item
);
9163 * devlink_trap_policers_register - Register packet trap policers with devlink.
9164 * @devlink: devlink.
9165 * @policers: Packet trap policers.
9166 * @policers_count: Count of provided packet trap policers.
9168 * Return: Non-zero value on failure.
9171 devlink_trap_policers_register(struct devlink
*devlink
,
9172 const struct devlink_trap_policer
*policers
,
9173 size_t policers_count
)
9177 mutex_lock(&devlink
->lock
);
9178 for (i
= 0; i
< policers_count
; i
++) {
9179 const struct devlink_trap_policer
*policer
= &policers
[i
];
9181 if (WARN_ON(policer
->id
== 0 ||
9182 policer
->max_rate
< policer
->min_rate
||
9183 policer
->max_burst
< policer
->min_burst
)) {
9185 goto err_trap_policer_verify
;
9188 err
= devlink_trap_policer_register(devlink
, policer
);
9190 goto err_trap_policer_register
;
9192 mutex_unlock(&devlink
->lock
);
9196 err_trap_policer_register
:
9197 err_trap_policer_verify
:
9198 for (i
--; i
>= 0; i
--)
9199 devlink_trap_policer_unregister(devlink
, &policers
[i
]);
9200 mutex_unlock(&devlink
->lock
);
9203 EXPORT_SYMBOL_GPL(devlink_trap_policers_register
);
9206 * devlink_trap_policers_unregister - Unregister packet trap policers from devlink.
9207 * @devlink: devlink.
9208 * @policers: Packet trap policers.
9209 * @policers_count: Count of provided packet trap policers.
9212 devlink_trap_policers_unregister(struct devlink
*devlink
,
9213 const struct devlink_trap_policer
*policers
,
9214 size_t policers_count
)
9218 mutex_lock(&devlink
->lock
);
9219 for (i
= policers_count
- 1; i
>= 0; i
--)
9220 devlink_trap_policer_unregister(devlink
, &policers
[i
]);
9221 mutex_unlock(&devlink
->lock
);
9223 EXPORT_SYMBOL_GPL(devlink_trap_policers_unregister
);
9225 static void __devlink_compat_running_version(struct devlink
*devlink
,
9226 char *buf
, size_t len
)
9228 const struct nlattr
*nlattr
;
9229 struct devlink_info_req req
;
9230 struct sk_buff
*msg
;
9233 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
9238 err
= devlink
->ops
->info_get(devlink
, &req
, NULL
);
9242 nla_for_each_attr(nlattr
, (void *)msg
->data
, msg
->len
, rem
) {
9243 const struct nlattr
*kv
;
9246 if (nla_type(nlattr
) != DEVLINK_ATTR_INFO_VERSION_RUNNING
)
9249 nla_for_each_nested(kv
, nlattr
, rem_kv
) {
9250 if (nla_type(kv
) != DEVLINK_ATTR_INFO_VERSION_VALUE
)
9253 strlcat(buf
, nla_data(kv
), len
);
9254 strlcat(buf
, " ", len
);
9261 void devlink_compat_running_version(struct net_device
*dev
,
9262 char *buf
, size_t len
)
9264 struct devlink
*devlink
;
9269 devlink
= netdev_to_devlink(dev
);
9270 if (!devlink
|| !devlink
->ops
->info_get
)
9273 mutex_lock(&devlink
->lock
);
9274 __devlink_compat_running_version(devlink
, buf
, len
);
9275 mutex_unlock(&devlink
->lock
);
9282 int devlink_compat_flash_update(struct net_device
*dev
, const char *file_name
)
9284 struct devlink
*devlink
;
9290 devlink
= netdev_to_devlink(dev
);
9291 if (!devlink
|| !devlink
->ops
->flash_update
) {
9296 mutex_lock(&devlink
->lock
);
9297 ret
= devlink
->ops
->flash_update(devlink
, file_name
, NULL
, NULL
);
9298 mutex_unlock(&devlink
->lock
);
9307 int devlink_compat_phys_port_name_get(struct net_device
*dev
,
9308 char *name
, size_t len
)
9310 struct devlink_port
*devlink_port
;
9312 /* RTNL mutex is held here which ensures that devlink_port
9313 * instance cannot disappear in the middle. No need to take
9314 * any devlink lock as only permanent values are accessed.
9318 devlink_port
= netdev_to_devlink_port(dev
);
9322 return __devlink_port_phys_port_name_get(devlink_port
, name
, len
);
9325 int devlink_compat_switch_id_get(struct net_device
*dev
,
9326 struct netdev_phys_item_id
*ppid
)
9328 struct devlink_port
*devlink_port
;
9330 /* Caller must hold RTNL mutex or reference to dev, which ensures that
9331 * devlink_port instance cannot disappear in the middle. No need to take
9332 * any devlink lock as only permanent values are accessed.
9334 devlink_port
= netdev_to_devlink_port(dev
);
9335 if (!devlink_port
|| !devlink_port
->attrs
.switch_port
)
9338 memcpy(ppid
, &devlink_port
->attrs
.switch_id
, sizeof(*ppid
));
9343 static void __net_exit
devlink_pernet_pre_exit(struct net
*net
)
9345 struct devlink
*devlink
;
9348 /* In case network namespace is getting destroyed, reload
9349 * all devlink instances from this namespace into init_net.
9351 mutex_lock(&devlink_mutex
);
9352 list_for_each_entry(devlink
, &devlink_list
, list
) {
9353 if (net_eq(devlink_net(devlink
), net
)) {
9354 if (WARN_ON(!devlink_reload_supported(devlink
)))
9356 err
= devlink_reload(devlink
, &init_net
, NULL
);
9357 if (err
&& err
!= -EOPNOTSUPP
)
9358 pr_warn("Failed to reload devlink instance into init_net\n");
9361 mutex_unlock(&devlink_mutex
);
9364 static struct pernet_operations devlink_pernet_ops __net_initdata
= {
9365 .pre_exit
= devlink_pernet_pre_exit
,
9368 static int __init
devlink_init(void)
9372 err
= genl_register_family(&devlink_nl_family
);
9375 err
= register_pernet_subsys(&devlink_pernet_ops
);
9382 subsys_initcall(devlink_init
);