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
;
348 struct list_head snapshot_list
;
354 struct devlink_snapshot
{
355 struct list_head list
;
356 struct devlink_region
*region
;
357 devlink_snapshot_data_dest_t
*data_destructor
;
362 static struct devlink_region
*
363 devlink_region_get_by_name(struct devlink
*devlink
, const char *region_name
)
365 struct devlink_region
*region
;
367 list_for_each_entry(region
, &devlink
->region_list
, list
)
368 if (!strcmp(region
->name
, region_name
))
374 static struct devlink_snapshot
*
375 devlink_region_snapshot_get_by_id(struct devlink_region
*region
, u32 id
)
377 struct devlink_snapshot
*snapshot
;
379 list_for_each_entry(snapshot
, ®ion
->snapshot_list
, list
)
380 if (snapshot
->id
== id
)
386 #define DEVLINK_NL_FLAG_NEED_DEVLINK BIT(0)
387 #define DEVLINK_NL_FLAG_NEED_PORT BIT(1)
388 #define DEVLINK_NL_FLAG_NEED_SB BIT(2)
390 /* The per devlink instance lock is taken by default in the pre-doit
391 * operation, yet several commands do not require this. The global
392 * devlink lock is taken and protects from disruption by user-calls.
394 #define DEVLINK_NL_FLAG_NO_LOCK BIT(3)
396 static int devlink_nl_pre_doit(const struct genl_ops
*ops
,
397 struct sk_buff
*skb
, struct genl_info
*info
)
399 struct devlink
*devlink
;
402 mutex_lock(&devlink_mutex
);
403 devlink
= devlink_get_from_info(info
);
404 if (IS_ERR(devlink
)) {
405 mutex_unlock(&devlink_mutex
);
406 return PTR_ERR(devlink
);
408 if (~ops
->internal_flags
& DEVLINK_NL_FLAG_NO_LOCK
)
409 mutex_lock(&devlink
->lock
);
410 if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_DEVLINK
) {
411 info
->user_ptr
[0] = devlink
;
412 } else if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_PORT
) {
413 struct devlink_port
*devlink_port
;
415 devlink_port
= devlink_port_get_from_info(devlink
, info
);
416 if (IS_ERR(devlink_port
)) {
417 err
= PTR_ERR(devlink_port
);
420 info
->user_ptr
[0] = devlink_port
;
422 if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_SB
) {
423 struct devlink_sb
*devlink_sb
;
425 devlink_sb
= devlink_sb_get_from_info(devlink
, info
);
426 if (IS_ERR(devlink_sb
)) {
427 err
= PTR_ERR(devlink_sb
);
430 info
->user_ptr
[1] = devlink_sb
;
435 if (~ops
->internal_flags
& DEVLINK_NL_FLAG_NO_LOCK
)
436 mutex_unlock(&devlink
->lock
);
437 mutex_unlock(&devlink_mutex
);
441 static void devlink_nl_post_doit(const struct genl_ops
*ops
,
442 struct sk_buff
*skb
, struct genl_info
*info
)
444 struct devlink
*devlink
;
446 /* When devlink changes netns, it would not be found
447 * by devlink_get_from_info(). So try if it is stored first.
449 if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_DEVLINK
) {
450 devlink
= info
->user_ptr
[0];
452 devlink
= devlink_get_from_info(info
);
453 WARN_ON(IS_ERR(devlink
));
455 if (!IS_ERR(devlink
) && ~ops
->internal_flags
& DEVLINK_NL_FLAG_NO_LOCK
)
456 mutex_unlock(&devlink
->lock
);
457 mutex_unlock(&devlink_mutex
);
460 static struct genl_family devlink_nl_family
;
462 enum devlink_multicast_groups
{
463 DEVLINK_MCGRP_CONFIG
,
466 static const struct genl_multicast_group devlink_nl_mcgrps
[] = {
467 [DEVLINK_MCGRP_CONFIG
] = { .name
= DEVLINK_GENL_MCGRP_CONFIG_NAME
},
470 static int devlink_nl_put_handle(struct sk_buff
*msg
, struct devlink
*devlink
)
472 if (nla_put_string(msg
, DEVLINK_ATTR_BUS_NAME
, devlink
->dev
->bus
->name
))
474 if (nla_put_string(msg
, DEVLINK_ATTR_DEV_NAME
, dev_name(devlink
->dev
)))
479 static int devlink_nl_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
480 enum devlink_command cmd
, u32 portid
,
485 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
489 if (devlink_nl_put_handle(msg
, devlink
))
490 goto nla_put_failure
;
491 if (nla_put_u8(msg
, DEVLINK_ATTR_RELOAD_FAILED
, devlink
->reload_failed
))
492 goto nla_put_failure
;
494 genlmsg_end(msg
, hdr
);
498 genlmsg_cancel(msg
, hdr
);
502 static void devlink_notify(struct devlink
*devlink
, enum devlink_command cmd
)
507 WARN_ON(cmd
!= DEVLINK_CMD_NEW
&& cmd
!= DEVLINK_CMD_DEL
);
509 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
513 err
= devlink_nl_fill(msg
, devlink
, cmd
, 0, 0, 0);
519 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
520 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
523 static int devlink_nl_port_attrs_put(struct sk_buff
*msg
,
524 struct devlink_port
*devlink_port
)
526 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
530 if (nla_put_u16(msg
, DEVLINK_ATTR_PORT_FLAVOUR
, attrs
->flavour
))
532 switch (devlink_port
->attrs
.flavour
) {
533 case DEVLINK_PORT_FLAVOUR_PCI_PF
:
534 if (nla_put_u16(msg
, DEVLINK_ATTR_PORT_PCI_PF_NUMBER
,
538 case DEVLINK_PORT_FLAVOUR_PCI_VF
:
539 if (nla_put_u16(msg
, DEVLINK_ATTR_PORT_PCI_PF_NUMBER
,
541 nla_put_u16(msg
, DEVLINK_ATTR_PORT_PCI_VF_NUMBER
,
545 case DEVLINK_PORT_FLAVOUR_PHYSICAL
:
546 case DEVLINK_PORT_FLAVOUR_CPU
:
547 case DEVLINK_PORT_FLAVOUR_DSA
:
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
,
573 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
577 if (devlink_nl_put_handle(msg
, devlink
))
578 goto nla_put_failure
;
579 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, devlink_port
->index
))
580 goto nla_put_failure
;
582 spin_lock_bh(&devlink_port
->type_lock
);
583 if (nla_put_u16(msg
, DEVLINK_ATTR_PORT_TYPE
, devlink_port
->type
))
584 goto nla_put_failure_type_locked
;
585 if (devlink_port
->desired_type
!= DEVLINK_PORT_TYPE_NOTSET
&&
586 nla_put_u16(msg
, DEVLINK_ATTR_PORT_DESIRED_TYPE
,
587 devlink_port
->desired_type
))
588 goto nla_put_failure_type_locked
;
589 if (devlink_port
->type
== DEVLINK_PORT_TYPE_ETH
) {
590 struct net_device
*netdev
= devlink_port
->type_dev
;
593 (nla_put_u32(msg
, DEVLINK_ATTR_PORT_NETDEV_IFINDEX
,
595 nla_put_string(msg
, DEVLINK_ATTR_PORT_NETDEV_NAME
,
597 goto nla_put_failure_type_locked
;
599 if (devlink_port
->type
== DEVLINK_PORT_TYPE_IB
) {
600 struct ib_device
*ibdev
= devlink_port
->type_dev
;
603 nla_put_string(msg
, DEVLINK_ATTR_PORT_IBDEV_NAME
,
605 goto nla_put_failure_type_locked
;
607 spin_unlock_bh(&devlink_port
->type_lock
);
608 if (devlink_nl_port_attrs_put(msg
, devlink_port
))
609 goto nla_put_failure
;
611 genlmsg_end(msg
, hdr
);
614 nla_put_failure_type_locked
:
615 spin_unlock_bh(&devlink_port
->type_lock
);
617 genlmsg_cancel(msg
, hdr
);
621 static void devlink_port_notify(struct devlink_port
*devlink_port
,
622 enum devlink_command cmd
)
624 struct devlink
*devlink
= devlink_port
->devlink
;
628 if (!devlink_port
->registered
)
631 WARN_ON(cmd
!= DEVLINK_CMD_PORT_NEW
&& cmd
!= DEVLINK_CMD_PORT_DEL
);
633 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
637 err
= devlink_nl_port_fill(msg
, devlink
, devlink_port
, cmd
, 0, 0, 0);
643 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
644 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
647 static int devlink_nl_cmd_get_doit(struct sk_buff
*skb
, struct genl_info
*info
)
649 struct devlink
*devlink
= info
->user_ptr
[0];
653 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
657 err
= devlink_nl_fill(msg
, devlink
, DEVLINK_CMD_NEW
,
658 info
->snd_portid
, info
->snd_seq
, 0);
664 return genlmsg_reply(msg
, info
);
667 static int devlink_nl_cmd_get_dumpit(struct sk_buff
*msg
,
668 struct netlink_callback
*cb
)
670 struct devlink
*devlink
;
671 int start
= cb
->args
[0];
675 mutex_lock(&devlink_mutex
);
676 list_for_each_entry(devlink
, &devlink_list
, list
) {
677 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
683 err
= devlink_nl_fill(msg
, devlink
, DEVLINK_CMD_NEW
,
684 NETLINK_CB(cb
->skb
).portid
,
685 cb
->nlh
->nlmsg_seq
, NLM_F_MULTI
);
691 mutex_unlock(&devlink_mutex
);
697 static int devlink_nl_cmd_port_get_doit(struct sk_buff
*skb
,
698 struct genl_info
*info
)
700 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
701 struct devlink
*devlink
= devlink_port
->devlink
;
705 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
709 err
= devlink_nl_port_fill(msg
, devlink
, devlink_port
,
710 DEVLINK_CMD_PORT_NEW
,
711 info
->snd_portid
, info
->snd_seq
, 0);
717 return genlmsg_reply(msg
, info
);
720 static int devlink_nl_cmd_port_get_dumpit(struct sk_buff
*msg
,
721 struct netlink_callback
*cb
)
723 struct devlink
*devlink
;
724 struct devlink_port
*devlink_port
;
725 int start
= cb
->args
[0];
729 mutex_lock(&devlink_mutex
);
730 list_for_each_entry(devlink
, &devlink_list
, list
) {
731 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
733 mutex_lock(&devlink
->lock
);
734 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
739 err
= devlink_nl_port_fill(msg
, devlink
, devlink_port
,
741 NETLINK_CB(cb
->skb
).portid
,
745 mutex_unlock(&devlink
->lock
);
750 mutex_unlock(&devlink
->lock
);
753 mutex_unlock(&devlink_mutex
);
759 static int devlink_port_type_set(struct devlink
*devlink
,
760 struct devlink_port
*devlink_port
,
761 enum devlink_port_type port_type
)
766 if (devlink
->ops
->port_type_set
) {
767 if (port_type
== DEVLINK_PORT_TYPE_NOTSET
)
769 if (port_type
== devlink_port
->type
)
771 err
= devlink
->ops
->port_type_set(devlink_port
, port_type
);
774 devlink_port
->desired_type
= port_type
;
775 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
781 static int devlink_nl_cmd_port_set_doit(struct sk_buff
*skb
,
782 struct genl_info
*info
)
784 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
785 struct devlink
*devlink
= devlink_port
->devlink
;
788 if (info
->attrs
[DEVLINK_ATTR_PORT_TYPE
]) {
789 enum devlink_port_type port_type
;
791 port_type
= nla_get_u16(info
->attrs
[DEVLINK_ATTR_PORT_TYPE
]);
792 err
= devlink_port_type_set(devlink
, devlink_port
, port_type
);
799 static int devlink_port_split(struct devlink
*devlink
, u32 port_index
,
800 u32 count
, struct netlink_ext_ack
*extack
)
803 if (devlink
->ops
->port_split
)
804 return devlink
->ops
->port_split(devlink
, port_index
, count
,
809 static int devlink_nl_cmd_port_split_doit(struct sk_buff
*skb
,
810 struct genl_info
*info
)
812 struct devlink
*devlink
= info
->user_ptr
[0];
816 if (!info
->attrs
[DEVLINK_ATTR_PORT_INDEX
] ||
817 !info
->attrs
[DEVLINK_ATTR_PORT_SPLIT_COUNT
])
820 port_index
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_PORT_INDEX
]);
821 count
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_PORT_SPLIT_COUNT
]);
822 return devlink_port_split(devlink
, port_index
, count
, info
->extack
);
825 static int devlink_port_unsplit(struct devlink
*devlink
, u32 port_index
,
826 struct netlink_ext_ack
*extack
)
829 if (devlink
->ops
->port_unsplit
)
830 return devlink
->ops
->port_unsplit(devlink
, port_index
, extack
);
834 static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff
*skb
,
835 struct genl_info
*info
)
837 struct devlink
*devlink
= info
->user_ptr
[0];
840 if (!info
->attrs
[DEVLINK_ATTR_PORT_INDEX
])
843 port_index
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_PORT_INDEX
]);
844 return devlink_port_unsplit(devlink
, port_index
, info
->extack
);
847 static int devlink_nl_sb_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
848 struct devlink_sb
*devlink_sb
,
849 enum devlink_command cmd
, u32 portid
,
854 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
858 if (devlink_nl_put_handle(msg
, devlink
))
859 goto nla_put_failure
;
860 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
861 goto nla_put_failure
;
862 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_SIZE
, devlink_sb
->size
))
863 goto nla_put_failure
;
864 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT
,
865 devlink_sb
->ingress_pools_count
))
866 goto nla_put_failure
;
867 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT
,
868 devlink_sb
->egress_pools_count
))
869 goto nla_put_failure
;
870 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_INGRESS_TC_COUNT
,
871 devlink_sb
->ingress_tc_count
))
872 goto nla_put_failure
;
873 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_EGRESS_TC_COUNT
,
874 devlink_sb
->egress_tc_count
))
875 goto nla_put_failure
;
877 genlmsg_end(msg
, hdr
);
881 genlmsg_cancel(msg
, hdr
);
885 static int devlink_nl_cmd_sb_get_doit(struct sk_buff
*skb
,
886 struct genl_info
*info
)
888 struct devlink
*devlink
= info
->user_ptr
[0];
889 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
893 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
897 err
= devlink_nl_sb_fill(msg
, devlink
, devlink_sb
,
899 info
->snd_portid
, info
->snd_seq
, 0);
905 return genlmsg_reply(msg
, info
);
908 static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff
*msg
,
909 struct netlink_callback
*cb
)
911 struct devlink
*devlink
;
912 struct devlink_sb
*devlink_sb
;
913 int start
= cb
->args
[0];
917 mutex_lock(&devlink_mutex
);
918 list_for_each_entry(devlink
, &devlink_list
, list
) {
919 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
921 mutex_lock(&devlink
->lock
);
922 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
927 err
= devlink_nl_sb_fill(msg
, devlink
, devlink_sb
,
929 NETLINK_CB(cb
->skb
).portid
,
933 mutex_unlock(&devlink
->lock
);
938 mutex_unlock(&devlink
->lock
);
941 mutex_unlock(&devlink_mutex
);
947 static int devlink_nl_sb_pool_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
948 struct devlink_sb
*devlink_sb
,
949 u16 pool_index
, enum devlink_command cmd
,
950 u32 portid
, u32 seq
, int flags
)
952 struct devlink_sb_pool_info pool_info
;
956 err
= devlink
->ops
->sb_pool_get(devlink
, devlink_sb
->index
,
957 pool_index
, &pool_info
);
961 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
965 if (devlink_nl_put_handle(msg
, devlink
))
966 goto nla_put_failure
;
967 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
968 goto nla_put_failure
;
969 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_POOL_INDEX
, pool_index
))
970 goto nla_put_failure
;
971 if (nla_put_u8(msg
, DEVLINK_ATTR_SB_POOL_TYPE
, pool_info
.pool_type
))
972 goto nla_put_failure
;
973 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_POOL_SIZE
, pool_info
.size
))
974 goto nla_put_failure
;
975 if (nla_put_u8(msg
, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
,
976 pool_info
.threshold_type
))
977 goto nla_put_failure
;
978 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_POOL_CELL_SIZE
,
979 pool_info
.cell_size
))
980 goto nla_put_failure
;
982 genlmsg_end(msg
, hdr
);
986 genlmsg_cancel(msg
, hdr
);
990 static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff
*skb
,
991 struct genl_info
*info
)
993 struct devlink
*devlink
= info
->user_ptr
[0];
994 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
999 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1004 if (!devlink
->ops
->sb_pool_get
)
1007 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1011 err
= devlink_nl_sb_pool_fill(msg
, devlink
, devlink_sb
, pool_index
,
1012 DEVLINK_CMD_SB_POOL_NEW
,
1013 info
->snd_portid
, info
->snd_seq
, 0);
1019 return genlmsg_reply(msg
, info
);
1022 static int __sb_pool_get_dumpit(struct sk_buff
*msg
, int start
, int *p_idx
,
1023 struct devlink
*devlink
,
1024 struct devlink_sb
*devlink_sb
,
1025 u32 portid
, u32 seq
)
1027 u16 pool_count
= devlink_sb_pool_count(devlink_sb
);
1031 for (pool_index
= 0; pool_index
< pool_count
; pool_index
++) {
1032 if (*p_idx
< start
) {
1036 err
= devlink_nl_sb_pool_fill(msg
, devlink
,
1039 DEVLINK_CMD_SB_POOL_NEW
,
1040 portid
, seq
, NLM_F_MULTI
);
1048 static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff
*msg
,
1049 struct netlink_callback
*cb
)
1051 struct devlink
*devlink
;
1052 struct devlink_sb
*devlink_sb
;
1053 int start
= cb
->args
[0];
1057 mutex_lock(&devlink_mutex
);
1058 list_for_each_entry(devlink
, &devlink_list
, list
) {
1059 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)) ||
1060 !devlink
->ops
->sb_pool_get
)
1062 mutex_lock(&devlink
->lock
);
1063 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
1064 err
= __sb_pool_get_dumpit(msg
, start
, &idx
, devlink
,
1066 NETLINK_CB(cb
->skb
).portid
,
1067 cb
->nlh
->nlmsg_seq
);
1068 if (err
&& err
!= -EOPNOTSUPP
) {
1069 mutex_unlock(&devlink
->lock
);
1073 mutex_unlock(&devlink
->lock
);
1076 mutex_unlock(&devlink_mutex
);
1078 if (err
!= -EMSGSIZE
)
1085 static int devlink_sb_pool_set(struct devlink
*devlink
, unsigned int sb_index
,
1086 u16 pool_index
, u32 size
,
1087 enum devlink_sb_threshold_type threshold_type
,
1088 struct netlink_ext_ack
*extack
)
1091 const struct devlink_ops
*ops
= devlink
->ops
;
1093 if (ops
->sb_pool_set
)
1094 return ops
->sb_pool_set(devlink
, sb_index
, pool_index
,
1095 size
, threshold_type
, extack
);
1099 static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff
*skb
,
1100 struct genl_info
*info
)
1102 struct devlink
*devlink
= info
->user_ptr
[0];
1103 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1104 enum devlink_sb_threshold_type threshold_type
;
1109 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1114 err
= devlink_sb_th_type_get_from_info(info
, &threshold_type
);
1118 if (!info
->attrs
[DEVLINK_ATTR_SB_POOL_SIZE
])
1121 size
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_SB_POOL_SIZE
]);
1122 return devlink_sb_pool_set(devlink
, devlink_sb
->index
,
1123 pool_index
, size
, threshold_type
,
1127 static int devlink_nl_sb_port_pool_fill(struct sk_buff
*msg
,
1128 struct devlink
*devlink
,
1129 struct devlink_port
*devlink_port
,
1130 struct devlink_sb
*devlink_sb
,
1132 enum devlink_command cmd
,
1133 u32 portid
, u32 seq
, int flags
)
1135 const struct devlink_ops
*ops
= devlink
->ops
;
1140 err
= ops
->sb_port_pool_get(devlink_port
, devlink_sb
->index
,
1141 pool_index
, &threshold
);
1145 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
1149 if (devlink_nl_put_handle(msg
, devlink
))
1150 goto nla_put_failure
;
1151 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, devlink_port
->index
))
1152 goto nla_put_failure
;
1153 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
1154 goto nla_put_failure
;
1155 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_POOL_INDEX
, pool_index
))
1156 goto nla_put_failure
;
1157 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_THRESHOLD
, threshold
))
1158 goto nla_put_failure
;
1160 if (ops
->sb_occ_port_pool_get
) {
1164 err
= ops
->sb_occ_port_pool_get(devlink_port
, devlink_sb
->index
,
1165 pool_index
, &cur
, &max
);
1166 if (err
&& err
!= -EOPNOTSUPP
)
1169 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_CUR
, cur
))
1170 goto nla_put_failure
;
1171 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_MAX
, max
))
1172 goto nla_put_failure
;
1176 genlmsg_end(msg
, hdr
);
1180 genlmsg_cancel(msg
, hdr
);
1184 static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff
*skb
,
1185 struct genl_info
*info
)
1187 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1188 struct devlink
*devlink
= devlink_port
->devlink
;
1189 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1190 struct sk_buff
*msg
;
1194 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1199 if (!devlink
->ops
->sb_port_pool_get
)
1202 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1206 err
= devlink_nl_sb_port_pool_fill(msg
, devlink
, devlink_port
,
1207 devlink_sb
, pool_index
,
1208 DEVLINK_CMD_SB_PORT_POOL_NEW
,
1209 info
->snd_portid
, info
->snd_seq
, 0);
1215 return genlmsg_reply(msg
, info
);
1218 static int __sb_port_pool_get_dumpit(struct sk_buff
*msg
, int start
, int *p_idx
,
1219 struct devlink
*devlink
,
1220 struct devlink_sb
*devlink_sb
,
1221 u32 portid
, u32 seq
)
1223 struct devlink_port
*devlink_port
;
1224 u16 pool_count
= devlink_sb_pool_count(devlink_sb
);
1228 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
1229 for (pool_index
= 0; pool_index
< pool_count
; pool_index
++) {
1230 if (*p_idx
< start
) {
1234 err
= devlink_nl_sb_port_pool_fill(msg
, devlink
,
1238 DEVLINK_CMD_SB_PORT_POOL_NEW
,
1249 static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff
*msg
,
1250 struct netlink_callback
*cb
)
1252 struct devlink
*devlink
;
1253 struct devlink_sb
*devlink_sb
;
1254 int start
= cb
->args
[0];
1258 mutex_lock(&devlink_mutex
);
1259 list_for_each_entry(devlink
, &devlink_list
, list
) {
1260 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)) ||
1261 !devlink
->ops
->sb_port_pool_get
)
1263 mutex_lock(&devlink
->lock
);
1264 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
1265 err
= __sb_port_pool_get_dumpit(msg
, start
, &idx
,
1266 devlink
, devlink_sb
,
1267 NETLINK_CB(cb
->skb
).portid
,
1268 cb
->nlh
->nlmsg_seq
);
1269 if (err
&& err
!= -EOPNOTSUPP
) {
1270 mutex_unlock(&devlink
->lock
);
1274 mutex_unlock(&devlink
->lock
);
1277 mutex_unlock(&devlink_mutex
);
1279 if (err
!= -EMSGSIZE
)
1286 static int devlink_sb_port_pool_set(struct devlink_port
*devlink_port
,
1287 unsigned int sb_index
, u16 pool_index
,
1289 struct netlink_ext_ack
*extack
)
1292 const struct devlink_ops
*ops
= devlink_port
->devlink
->ops
;
1294 if (ops
->sb_port_pool_set
)
1295 return ops
->sb_port_pool_set(devlink_port
, sb_index
,
1296 pool_index
, threshold
, extack
);
1300 static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff
*skb
,
1301 struct genl_info
*info
)
1303 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1304 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1309 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1314 if (!info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
])
1317 threshold
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
]);
1318 return devlink_sb_port_pool_set(devlink_port
, devlink_sb
->index
,
1319 pool_index
, threshold
, info
->extack
);
1323 devlink_nl_sb_tc_pool_bind_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
1324 struct devlink_port
*devlink_port
,
1325 struct devlink_sb
*devlink_sb
, u16 tc_index
,
1326 enum devlink_sb_pool_type pool_type
,
1327 enum devlink_command cmd
,
1328 u32 portid
, u32 seq
, int flags
)
1330 const struct devlink_ops
*ops
= devlink
->ops
;
1336 err
= ops
->sb_tc_pool_bind_get(devlink_port
, devlink_sb
->index
,
1337 tc_index
, pool_type
,
1338 &pool_index
, &threshold
);
1342 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
1346 if (devlink_nl_put_handle(msg
, devlink
))
1347 goto nla_put_failure
;
1348 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, devlink_port
->index
))
1349 goto nla_put_failure
;
1350 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
1351 goto nla_put_failure
;
1352 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_TC_INDEX
, tc_index
))
1353 goto nla_put_failure
;
1354 if (nla_put_u8(msg
, DEVLINK_ATTR_SB_POOL_TYPE
, pool_type
))
1355 goto nla_put_failure
;
1356 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_POOL_INDEX
, pool_index
))
1357 goto nla_put_failure
;
1358 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_THRESHOLD
, threshold
))
1359 goto nla_put_failure
;
1361 if (ops
->sb_occ_tc_port_bind_get
) {
1365 err
= ops
->sb_occ_tc_port_bind_get(devlink_port
,
1367 tc_index
, pool_type
,
1369 if (err
&& err
!= -EOPNOTSUPP
)
1372 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_CUR
, cur
))
1373 goto nla_put_failure
;
1374 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_MAX
, max
))
1375 goto nla_put_failure
;
1379 genlmsg_end(msg
, hdr
);
1383 genlmsg_cancel(msg
, hdr
);
1387 static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff
*skb
,
1388 struct genl_info
*info
)
1390 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1391 struct devlink
*devlink
= devlink_port
->devlink
;
1392 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1393 struct sk_buff
*msg
;
1394 enum devlink_sb_pool_type pool_type
;
1398 err
= devlink_sb_pool_type_get_from_info(info
, &pool_type
);
1402 err
= devlink_sb_tc_index_get_from_info(devlink_sb
, info
,
1403 pool_type
, &tc_index
);
1407 if (!devlink
->ops
->sb_tc_pool_bind_get
)
1410 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1414 err
= devlink_nl_sb_tc_pool_bind_fill(msg
, devlink
, devlink_port
,
1415 devlink_sb
, tc_index
, pool_type
,
1416 DEVLINK_CMD_SB_TC_POOL_BIND_NEW
,
1424 return genlmsg_reply(msg
, info
);
1427 static int __sb_tc_pool_bind_get_dumpit(struct sk_buff
*msg
,
1428 int start
, int *p_idx
,
1429 struct devlink
*devlink
,
1430 struct devlink_sb
*devlink_sb
,
1431 u32 portid
, u32 seq
)
1433 struct devlink_port
*devlink_port
;
1437 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
1439 tc_index
< devlink_sb
->ingress_tc_count
; tc_index
++) {
1440 if (*p_idx
< start
) {
1444 err
= devlink_nl_sb_tc_pool_bind_fill(msg
, devlink
,
1448 DEVLINK_SB_POOL_TYPE_INGRESS
,
1449 DEVLINK_CMD_SB_TC_POOL_BIND_NEW
,
1457 tc_index
< devlink_sb
->egress_tc_count
; tc_index
++) {
1458 if (*p_idx
< start
) {
1462 err
= devlink_nl_sb_tc_pool_bind_fill(msg
, devlink
,
1466 DEVLINK_SB_POOL_TYPE_EGRESS
,
1467 DEVLINK_CMD_SB_TC_POOL_BIND_NEW
,
1479 devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff
*msg
,
1480 struct netlink_callback
*cb
)
1482 struct devlink
*devlink
;
1483 struct devlink_sb
*devlink_sb
;
1484 int start
= cb
->args
[0];
1488 mutex_lock(&devlink_mutex
);
1489 list_for_each_entry(devlink
, &devlink_list
, list
) {
1490 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)) ||
1491 !devlink
->ops
->sb_tc_pool_bind_get
)
1494 mutex_lock(&devlink
->lock
);
1495 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
1496 err
= __sb_tc_pool_bind_get_dumpit(msg
, start
, &idx
,
1499 NETLINK_CB(cb
->skb
).portid
,
1500 cb
->nlh
->nlmsg_seq
);
1501 if (err
&& err
!= -EOPNOTSUPP
) {
1502 mutex_unlock(&devlink
->lock
);
1506 mutex_unlock(&devlink
->lock
);
1509 mutex_unlock(&devlink_mutex
);
1511 if (err
!= -EMSGSIZE
)
1518 static int devlink_sb_tc_pool_bind_set(struct devlink_port
*devlink_port
,
1519 unsigned int sb_index
, u16 tc_index
,
1520 enum devlink_sb_pool_type pool_type
,
1521 u16 pool_index
, u32 threshold
,
1522 struct netlink_ext_ack
*extack
)
1525 const struct devlink_ops
*ops
= devlink_port
->devlink
->ops
;
1527 if (ops
->sb_tc_pool_bind_set
)
1528 return ops
->sb_tc_pool_bind_set(devlink_port
, sb_index
,
1529 tc_index
, pool_type
,
1530 pool_index
, threshold
, extack
);
1534 static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff
*skb
,
1535 struct genl_info
*info
)
1537 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1538 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1539 enum devlink_sb_pool_type pool_type
;
1545 err
= devlink_sb_pool_type_get_from_info(info
, &pool_type
);
1549 err
= devlink_sb_tc_index_get_from_info(devlink_sb
, info
,
1550 pool_type
, &tc_index
);
1554 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1559 if (!info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
])
1562 threshold
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
]);
1563 return devlink_sb_tc_pool_bind_set(devlink_port
, devlink_sb
->index
,
1564 tc_index
, pool_type
,
1565 pool_index
, threshold
, info
->extack
);
1568 static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff
*skb
,
1569 struct genl_info
*info
)
1571 struct devlink
*devlink
= info
->user_ptr
[0];
1572 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1573 const struct devlink_ops
*ops
= devlink
->ops
;
1575 if (ops
->sb_occ_snapshot
)
1576 return ops
->sb_occ_snapshot(devlink
, devlink_sb
->index
);
1580 static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff
*skb
,
1581 struct genl_info
*info
)
1583 struct devlink
*devlink
= info
->user_ptr
[0];
1584 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1585 const struct devlink_ops
*ops
= devlink
->ops
;
1587 if (ops
->sb_occ_max_clear
)
1588 return ops
->sb_occ_max_clear(devlink
, devlink_sb
->index
);
1592 static int devlink_nl_eswitch_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
1593 enum devlink_command cmd
, u32 portid
,
1596 const struct devlink_ops
*ops
= devlink
->ops
;
1597 enum devlink_eswitch_encap_mode encap_mode
;
1603 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
1607 err
= devlink_nl_put_handle(msg
, devlink
);
1609 goto nla_put_failure
;
1611 if (ops
->eswitch_mode_get
) {
1612 err
= ops
->eswitch_mode_get(devlink
, &mode
);
1614 goto nla_put_failure
;
1615 err
= nla_put_u16(msg
, DEVLINK_ATTR_ESWITCH_MODE
, mode
);
1617 goto nla_put_failure
;
1620 if (ops
->eswitch_inline_mode_get
) {
1621 err
= ops
->eswitch_inline_mode_get(devlink
, &inline_mode
);
1623 goto nla_put_failure
;
1624 err
= nla_put_u8(msg
, DEVLINK_ATTR_ESWITCH_INLINE_MODE
,
1627 goto nla_put_failure
;
1630 if (ops
->eswitch_encap_mode_get
) {
1631 err
= ops
->eswitch_encap_mode_get(devlink
, &encap_mode
);
1633 goto nla_put_failure
;
1634 err
= nla_put_u8(msg
, DEVLINK_ATTR_ESWITCH_ENCAP_MODE
, encap_mode
);
1636 goto nla_put_failure
;
1639 genlmsg_end(msg
, hdr
);
1643 genlmsg_cancel(msg
, hdr
);
1647 static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff
*skb
,
1648 struct genl_info
*info
)
1650 struct devlink
*devlink
= info
->user_ptr
[0];
1651 struct sk_buff
*msg
;
1654 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1658 err
= devlink_nl_eswitch_fill(msg
, devlink
, DEVLINK_CMD_ESWITCH_GET
,
1659 info
->snd_portid
, info
->snd_seq
, 0);
1666 return genlmsg_reply(msg
, info
);
1669 static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff
*skb
,
1670 struct genl_info
*info
)
1672 struct devlink
*devlink
= info
->user_ptr
[0];
1673 const struct devlink_ops
*ops
= devlink
->ops
;
1674 enum devlink_eswitch_encap_mode encap_mode
;
1679 if (info
->attrs
[DEVLINK_ATTR_ESWITCH_MODE
]) {
1680 if (!ops
->eswitch_mode_set
)
1682 mode
= nla_get_u16(info
->attrs
[DEVLINK_ATTR_ESWITCH_MODE
]);
1683 err
= ops
->eswitch_mode_set(devlink
, mode
, info
->extack
);
1688 if (info
->attrs
[DEVLINK_ATTR_ESWITCH_INLINE_MODE
]) {
1689 if (!ops
->eswitch_inline_mode_set
)
1691 inline_mode
= nla_get_u8(
1692 info
->attrs
[DEVLINK_ATTR_ESWITCH_INLINE_MODE
]);
1693 err
= ops
->eswitch_inline_mode_set(devlink
, inline_mode
,
1699 if (info
->attrs
[DEVLINK_ATTR_ESWITCH_ENCAP_MODE
]) {
1700 if (!ops
->eswitch_encap_mode_set
)
1702 encap_mode
= nla_get_u8(info
->attrs
[DEVLINK_ATTR_ESWITCH_ENCAP_MODE
]);
1703 err
= ops
->eswitch_encap_mode_set(devlink
, encap_mode
,
1712 int devlink_dpipe_match_put(struct sk_buff
*skb
,
1713 struct devlink_dpipe_match
*match
)
1715 struct devlink_dpipe_header
*header
= match
->header
;
1716 struct devlink_dpipe_field
*field
= &header
->fields
[match
->field_id
];
1717 struct nlattr
*match_attr
;
1719 match_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_MATCH
);
1723 if (nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_MATCH_TYPE
, match
->type
) ||
1724 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_INDEX
, match
->header_index
) ||
1725 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_ID
, header
->id
) ||
1726 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_ID
, field
->id
) ||
1727 nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL
, header
->global
))
1728 goto nla_put_failure
;
1730 nla_nest_end(skb
, match_attr
);
1734 nla_nest_cancel(skb
, match_attr
);
1737 EXPORT_SYMBOL_GPL(devlink_dpipe_match_put
);
1739 static int devlink_dpipe_matches_put(struct devlink_dpipe_table
*table
,
1740 struct sk_buff
*skb
)
1742 struct nlattr
*matches_attr
;
1744 matches_attr
= nla_nest_start_noflag(skb
,
1745 DEVLINK_ATTR_DPIPE_TABLE_MATCHES
);
1749 if (table
->table_ops
->matches_dump(table
->priv
, skb
))
1750 goto nla_put_failure
;
1752 nla_nest_end(skb
, matches_attr
);
1756 nla_nest_cancel(skb
, matches_attr
);
1760 int devlink_dpipe_action_put(struct sk_buff
*skb
,
1761 struct devlink_dpipe_action
*action
)
1763 struct devlink_dpipe_header
*header
= action
->header
;
1764 struct devlink_dpipe_field
*field
= &header
->fields
[action
->field_id
];
1765 struct nlattr
*action_attr
;
1767 action_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_ACTION
);
1771 if (nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_ACTION_TYPE
, action
->type
) ||
1772 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_INDEX
, action
->header_index
) ||
1773 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_ID
, header
->id
) ||
1774 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_ID
, field
->id
) ||
1775 nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL
, header
->global
))
1776 goto nla_put_failure
;
1778 nla_nest_end(skb
, action_attr
);
1782 nla_nest_cancel(skb
, action_attr
);
1785 EXPORT_SYMBOL_GPL(devlink_dpipe_action_put
);
1787 static int devlink_dpipe_actions_put(struct devlink_dpipe_table
*table
,
1788 struct sk_buff
*skb
)
1790 struct nlattr
*actions_attr
;
1792 actions_attr
= nla_nest_start_noflag(skb
,
1793 DEVLINK_ATTR_DPIPE_TABLE_ACTIONS
);
1797 if (table
->table_ops
->actions_dump(table
->priv
, skb
))
1798 goto nla_put_failure
;
1800 nla_nest_end(skb
, actions_attr
);
1804 nla_nest_cancel(skb
, actions_attr
);
1808 static int devlink_dpipe_table_put(struct sk_buff
*skb
,
1809 struct devlink_dpipe_table
*table
)
1811 struct nlattr
*table_attr
;
1814 table_size
= table
->table_ops
->size_get(table
->priv
);
1815 table_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_TABLE
);
1819 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_TABLE_NAME
, table
->name
) ||
1820 nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_TABLE_SIZE
, table_size
,
1822 goto nla_put_failure
;
1823 if (nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
,
1824 table
->counters_enabled
))
1825 goto nla_put_failure
;
1827 if (table
->resource_valid
) {
1828 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID
,
1829 table
->resource_id
, DEVLINK_ATTR_PAD
) ||
1830 nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS
,
1831 table
->resource_units
, DEVLINK_ATTR_PAD
))
1832 goto nla_put_failure
;
1834 if (devlink_dpipe_matches_put(table
, skb
))
1835 goto nla_put_failure
;
1837 if (devlink_dpipe_actions_put(table
, skb
))
1838 goto nla_put_failure
;
1840 nla_nest_end(skb
, table_attr
);
1844 nla_nest_cancel(skb
, table_attr
);
1848 static int devlink_dpipe_send_and_alloc_skb(struct sk_buff
**pskb
,
1849 struct genl_info
*info
)
1854 err
= genlmsg_reply(*pskb
, info
);
1858 *pskb
= genlmsg_new(GENLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1864 static int devlink_dpipe_tables_fill(struct genl_info
*info
,
1865 enum devlink_command cmd
, int flags
,
1866 struct list_head
*dpipe_tables
,
1867 const char *table_name
)
1869 struct devlink
*devlink
= info
->user_ptr
[0];
1870 struct devlink_dpipe_table
*table
;
1871 struct nlattr
*tables_attr
;
1872 struct sk_buff
*skb
= NULL
;
1873 struct nlmsghdr
*nlh
;
1879 table
= list_first_entry(dpipe_tables
,
1880 struct devlink_dpipe_table
, list
);
1882 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
1886 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
1887 &devlink_nl_family
, NLM_F_MULTI
, cmd
);
1893 if (devlink_nl_put_handle(skb
, devlink
))
1894 goto nla_put_failure
;
1895 tables_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_TABLES
);
1897 goto nla_put_failure
;
1901 list_for_each_entry_from(table
, dpipe_tables
, list
) {
1903 err
= devlink_dpipe_table_put(skb
, table
);
1911 if (!strcmp(table
->name
, table_name
)) {
1912 err
= devlink_dpipe_table_put(skb
, table
);
1920 nla_nest_end(skb
, tables_attr
);
1921 genlmsg_end(skb
, hdr
);
1926 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
1927 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
1929 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
1935 return genlmsg_reply(skb
, info
);
1944 static int devlink_nl_cmd_dpipe_table_get(struct sk_buff
*skb
,
1945 struct genl_info
*info
)
1947 struct devlink
*devlink
= info
->user_ptr
[0];
1948 const char *table_name
= NULL
;
1950 if (info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
])
1951 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
1953 return devlink_dpipe_tables_fill(info
, DEVLINK_CMD_DPIPE_TABLE_GET
, 0,
1954 &devlink
->dpipe_table_list
,
1958 static int devlink_dpipe_value_put(struct sk_buff
*skb
,
1959 struct devlink_dpipe_value
*value
)
1961 if (nla_put(skb
, DEVLINK_ATTR_DPIPE_VALUE
,
1962 value
->value_size
, value
->value
))
1965 if (nla_put(skb
, DEVLINK_ATTR_DPIPE_VALUE_MASK
,
1966 value
->value_size
, value
->mask
))
1968 if (value
->mapping_valid
)
1969 if (nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_VALUE_MAPPING
,
1970 value
->mapping_value
))
1975 static int devlink_dpipe_action_value_put(struct sk_buff
*skb
,
1976 struct devlink_dpipe_value
*value
)
1980 if (devlink_dpipe_action_put(skb
, value
->action
))
1982 if (devlink_dpipe_value_put(skb
, value
))
1987 static int devlink_dpipe_action_values_put(struct sk_buff
*skb
,
1988 struct devlink_dpipe_value
*values
,
1989 unsigned int values_count
)
1991 struct nlattr
*action_attr
;
1995 for (i
= 0; i
< values_count
; i
++) {
1996 action_attr
= nla_nest_start_noflag(skb
,
1997 DEVLINK_ATTR_DPIPE_ACTION_VALUE
);
2000 err
= devlink_dpipe_action_value_put(skb
, &values
[i
]);
2002 goto err_action_value_put
;
2003 nla_nest_end(skb
, action_attr
);
2007 err_action_value_put
:
2008 nla_nest_cancel(skb
, action_attr
);
2012 static int devlink_dpipe_match_value_put(struct sk_buff
*skb
,
2013 struct devlink_dpipe_value
*value
)
2017 if (devlink_dpipe_match_put(skb
, value
->match
))
2019 if (devlink_dpipe_value_put(skb
, value
))
2024 static int devlink_dpipe_match_values_put(struct sk_buff
*skb
,
2025 struct devlink_dpipe_value
*values
,
2026 unsigned int values_count
)
2028 struct nlattr
*match_attr
;
2032 for (i
= 0; i
< values_count
; i
++) {
2033 match_attr
= nla_nest_start_noflag(skb
,
2034 DEVLINK_ATTR_DPIPE_MATCH_VALUE
);
2037 err
= devlink_dpipe_match_value_put(skb
, &values
[i
]);
2039 goto err_match_value_put
;
2040 nla_nest_end(skb
, match_attr
);
2044 err_match_value_put
:
2045 nla_nest_cancel(skb
, match_attr
);
2049 static int devlink_dpipe_entry_put(struct sk_buff
*skb
,
2050 struct devlink_dpipe_entry
*entry
)
2052 struct nlattr
*entry_attr
, *matches_attr
, *actions_attr
;
2055 entry_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_ENTRY
);
2059 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_ENTRY_INDEX
, entry
->index
,
2061 goto nla_put_failure
;
2062 if (entry
->counter_valid
)
2063 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER
,
2064 entry
->counter
, DEVLINK_ATTR_PAD
))
2065 goto nla_put_failure
;
2067 matches_attr
= nla_nest_start_noflag(skb
,
2068 DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES
);
2070 goto nla_put_failure
;
2072 err
= devlink_dpipe_match_values_put(skb
, entry
->match_values
,
2073 entry
->match_values_count
);
2075 nla_nest_cancel(skb
, matches_attr
);
2076 goto err_match_values_put
;
2078 nla_nest_end(skb
, matches_attr
);
2080 actions_attr
= nla_nest_start_noflag(skb
,
2081 DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES
);
2083 goto nla_put_failure
;
2085 err
= devlink_dpipe_action_values_put(skb
, entry
->action_values
,
2086 entry
->action_values_count
);
2088 nla_nest_cancel(skb
, actions_attr
);
2089 goto err_action_values_put
;
2091 nla_nest_end(skb
, actions_attr
);
2093 nla_nest_end(skb
, entry_attr
);
2098 err_match_values_put
:
2099 err_action_values_put
:
2100 nla_nest_cancel(skb
, entry_attr
);
2104 static struct devlink_dpipe_table
*
2105 devlink_dpipe_table_find(struct list_head
*dpipe_tables
,
2106 const char *table_name
)
2108 struct devlink_dpipe_table
*table
;
2110 list_for_each_entry_rcu(table
, dpipe_tables
, list
) {
2111 if (!strcmp(table
->name
, table_name
))
2117 int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx
*dump_ctx
)
2119 struct devlink
*devlink
;
2122 err
= devlink_dpipe_send_and_alloc_skb(&dump_ctx
->skb
,
2127 dump_ctx
->hdr
= genlmsg_put(dump_ctx
->skb
,
2128 dump_ctx
->info
->snd_portid
,
2129 dump_ctx
->info
->snd_seq
,
2130 &devlink_nl_family
, NLM_F_MULTI
,
2133 goto nla_put_failure
;
2135 devlink
= dump_ctx
->info
->user_ptr
[0];
2136 if (devlink_nl_put_handle(dump_ctx
->skb
, devlink
))
2137 goto nla_put_failure
;
2138 dump_ctx
->nest
= nla_nest_start_noflag(dump_ctx
->skb
,
2139 DEVLINK_ATTR_DPIPE_ENTRIES
);
2140 if (!dump_ctx
->nest
)
2141 goto nla_put_failure
;
2145 nlmsg_free(dump_ctx
->skb
);
2148 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare
);
2150 int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx
*dump_ctx
,
2151 struct devlink_dpipe_entry
*entry
)
2153 return devlink_dpipe_entry_put(dump_ctx
->skb
, entry
);
2155 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append
);
2157 int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx
*dump_ctx
)
2159 nla_nest_end(dump_ctx
->skb
, dump_ctx
->nest
);
2160 genlmsg_end(dump_ctx
->skb
, dump_ctx
->hdr
);
2163 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close
);
2165 void devlink_dpipe_entry_clear(struct devlink_dpipe_entry
*entry
)
2168 unsigned int value_count
, value_index
;
2169 struct devlink_dpipe_value
*value
;
2171 value
= entry
->action_values
;
2172 value_count
= entry
->action_values_count
;
2173 for (value_index
= 0; value_index
< value_count
; value_index
++) {
2174 kfree(value
[value_index
].value
);
2175 kfree(value
[value_index
].mask
);
2178 value
= entry
->match_values
;
2179 value_count
= entry
->match_values_count
;
2180 for (value_index
= 0; value_index
< value_count
; value_index
++) {
2181 kfree(value
[value_index
].value
);
2182 kfree(value
[value_index
].mask
);
2185 EXPORT_SYMBOL(devlink_dpipe_entry_clear
);
2187 static int devlink_dpipe_entries_fill(struct genl_info
*info
,
2188 enum devlink_command cmd
, int flags
,
2189 struct devlink_dpipe_table
*table
)
2191 struct devlink_dpipe_dump_ctx dump_ctx
;
2192 struct nlmsghdr
*nlh
;
2195 dump_ctx
.skb
= NULL
;
2197 dump_ctx
.info
= info
;
2199 err
= table
->table_ops
->entries_dump(table
->priv
,
2200 table
->counters_enabled
,
2206 nlh
= nlmsg_put(dump_ctx
.skb
, info
->snd_portid
, info
->snd_seq
,
2207 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
2209 err
= devlink_dpipe_send_and_alloc_skb(&dump_ctx
.skb
, info
);
2214 return genlmsg_reply(dump_ctx
.skb
, info
);
2217 static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff
*skb
,
2218 struct genl_info
*info
)
2220 struct devlink
*devlink
= info
->user_ptr
[0];
2221 struct devlink_dpipe_table
*table
;
2222 const char *table_name
;
2224 if (!info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
])
2227 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
2228 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
2233 if (!table
->table_ops
->entries_dump
)
2236 return devlink_dpipe_entries_fill(info
, DEVLINK_CMD_DPIPE_ENTRIES_GET
,
2240 static int devlink_dpipe_fields_put(struct sk_buff
*skb
,
2241 const struct devlink_dpipe_header
*header
)
2243 struct devlink_dpipe_field
*field
;
2244 struct nlattr
*field_attr
;
2247 for (i
= 0; i
< header
->fields_count
; i
++) {
2248 field
= &header
->fields
[i
];
2249 field_attr
= nla_nest_start_noflag(skb
,
2250 DEVLINK_ATTR_DPIPE_FIELD
);
2253 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_FIELD_NAME
, field
->name
) ||
2254 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_ID
, field
->id
) ||
2255 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH
, field
->bitwidth
) ||
2256 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE
, field
->mapping_type
))
2257 goto nla_put_failure
;
2258 nla_nest_end(skb
, field_attr
);
2263 nla_nest_cancel(skb
, field_attr
);
2267 static int devlink_dpipe_header_put(struct sk_buff
*skb
,
2268 struct devlink_dpipe_header
*header
)
2270 struct nlattr
*fields_attr
, *header_attr
;
2273 header_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_HEADER
);
2277 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_HEADER_NAME
, header
->name
) ||
2278 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_ID
, header
->id
) ||
2279 nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL
, header
->global
))
2280 goto nla_put_failure
;
2282 fields_attr
= nla_nest_start_noflag(skb
,
2283 DEVLINK_ATTR_DPIPE_HEADER_FIELDS
);
2285 goto nla_put_failure
;
2287 err
= devlink_dpipe_fields_put(skb
, header
);
2289 nla_nest_cancel(skb
, fields_attr
);
2290 goto nla_put_failure
;
2292 nla_nest_end(skb
, fields_attr
);
2293 nla_nest_end(skb
, header_attr
);
2298 nla_nest_cancel(skb
, header_attr
);
2302 static int devlink_dpipe_headers_fill(struct genl_info
*info
,
2303 enum devlink_command cmd
, int flags
,
2304 struct devlink_dpipe_headers
*
2307 struct devlink
*devlink
= info
->user_ptr
[0];
2308 struct nlattr
*headers_attr
;
2309 struct sk_buff
*skb
= NULL
;
2310 struct nlmsghdr
*nlh
;
2317 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2321 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2322 &devlink_nl_family
, NLM_F_MULTI
, cmd
);
2328 if (devlink_nl_put_handle(skb
, devlink
))
2329 goto nla_put_failure
;
2330 headers_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_HEADERS
);
2332 goto nla_put_failure
;
2335 for (; i
< dpipe_headers
->headers_count
; i
++) {
2336 err
= devlink_dpipe_header_put(skb
, dpipe_headers
->headers
[i
]);
2344 nla_nest_end(skb
, headers_attr
);
2345 genlmsg_end(skb
, hdr
);
2346 if (i
!= dpipe_headers
->headers_count
)
2350 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2351 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
2353 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2358 return genlmsg_reply(skb
, info
);
2367 static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff
*skb
,
2368 struct genl_info
*info
)
2370 struct devlink
*devlink
= info
->user_ptr
[0];
2372 if (!devlink
->dpipe_headers
)
2374 return devlink_dpipe_headers_fill(info
, DEVLINK_CMD_DPIPE_HEADERS_GET
,
2375 0, devlink
->dpipe_headers
);
2378 static int devlink_dpipe_table_counters_set(struct devlink
*devlink
,
2379 const char *table_name
,
2382 struct devlink_dpipe_table
*table
;
2384 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
2389 if (table
->counter_control_extern
)
2392 if (!(table
->counters_enabled
^ enable
))
2395 table
->counters_enabled
= enable
;
2396 if (table
->table_ops
->counters_set_update
)
2397 table
->table_ops
->counters_set_update(table
->priv
, enable
);
2401 static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff
*skb
,
2402 struct genl_info
*info
)
2404 struct devlink
*devlink
= info
->user_ptr
[0];
2405 const char *table_name
;
2406 bool counters_enable
;
2408 if (!info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
] ||
2409 !info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
])
2412 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
2413 counters_enable
= !!nla_get_u8(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
]);
2415 return devlink_dpipe_table_counters_set(devlink
, table_name
,
2419 static struct devlink_resource
*
2420 devlink_resource_find(struct devlink
*devlink
,
2421 struct devlink_resource
*resource
, u64 resource_id
)
2423 struct list_head
*resource_list
;
2426 resource_list
= &resource
->resource_list
;
2428 resource_list
= &devlink
->resource_list
;
2430 list_for_each_entry(resource
, resource_list
, list
) {
2431 struct devlink_resource
*child_resource
;
2433 if (resource
->id
== resource_id
)
2436 child_resource
= devlink_resource_find(devlink
, resource
,
2439 return child_resource
;
2445 devlink_resource_validate_children(struct devlink_resource
*resource
)
2447 struct devlink_resource
*child_resource
;
2448 bool size_valid
= true;
2451 if (list_empty(&resource
->resource_list
))
2454 list_for_each_entry(child_resource
, &resource
->resource_list
, list
)
2455 parts_size
+= child_resource
->size_new
;
2457 if (parts_size
> resource
->size_new
)
2460 resource
->size_valid
= size_valid
;
2464 devlink_resource_validate_size(struct devlink_resource
*resource
, u64 size
,
2465 struct netlink_ext_ack
*extack
)
2470 if (size
> resource
->size_params
.size_max
) {
2471 NL_SET_ERR_MSG_MOD(extack
, "Size larger than maximum");
2475 if (size
< resource
->size_params
.size_min
) {
2476 NL_SET_ERR_MSG_MOD(extack
, "Size smaller than minimum");
2480 div64_u64_rem(size
, resource
->size_params
.size_granularity
, &reminder
);
2482 NL_SET_ERR_MSG_MOD(extack
, "Wrong granularity");
2489 static int devlink_nl_cmd_resource_set(struct sk_buff
*skb
,
2490 struct genl_info
*info
)
2492 struct devlink
*devlink
= info
->user_ptr
[0];
2493 struct devlink_resource
*resource
;
2498 if (!info
->attrs
[DEVLINK_ATTR_RESOURCE_ID
] ||
2499 !info
->attrs
[DEVLINK_ATTR_RESOURCE_SIZE
])
2501 resource_id
= nla_get_u64(info
->attrs
[DEVLINK_ATTR_RESOURCE_ID
]);
2503 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
2507 size
= nla_get_u64(info
->attrs
[DEVLINK_ATTR_RESOURCE_SIZE
]);
2508 err
= devlink_resource_validate_size(resource
, size
, info
->extack
);
2512 resource
->size_new
= size
;
2513 devlink_resource_validate_children(resource
);
2514 if (resource
->parent
)
2515 devlink_resource_validate_children(resource
->parent
);
2520 devlink_resource_size_params_put(struct devlink_resource
*resource
,
2521 struct sk_buff
*skb
)
2523 struct devlink_resource_size_params
*size_params
;
2525 size_params
= &resource
->size_params
;
2526 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_GRAN
,
2527 size_params
->size_granularity
, DEVLINK_ATTR_PAD
) ||
2528 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_MAX
,
2529 size_params
->size_max
, DEVLINK_ATTR_PAD
) ||
2530 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_MIN
,
2531 size_params
->size_min
, DEVLINK_ATTR_PAD
) ||
2532 nla_put_u8(skb
, DEVLINK_ATTR_RESOURCE_UNIT
, size_params
->unit
))
2537 static int devlink_resource_occ_put(struct devlink_resource
*resource
,
2538 struct sk_buff
*skb
)
2540 if (!resource
->occ_get
)
2542 return nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_OCC
,
2543 resource
->occ_get(resource
->occ_get_priv
),
2547 static int devlink_resource_put(struct devlink
*devlink
, struct sk_buff
*skb
,
2548 struct devlink_resource
*resource
)
2550 struct devlink_resource
*child_resource
;
2551 struct nlattr
*child_resource_attr
;
2552 struct nlattr
*resource_attr
;
2554 resource_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_RESOURCE
);
2558 if (nla_put_string(skb
, DEVLINK_ATTR_RESOURCE_NAME
, resource
->name
) ||
2559 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE
, resource
->size
,
2560 DEVLINK_ATTR_PAD
) ||
2561 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_ID
, resource
->id
,
2563 goto nla_put_failure
;
2564 if (resource
->size
!= resource
->size_new
)
2565 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_NEW
,
2566 resource
->size_new
, DEVLINK_ATTR_PAD
);
2567 if (devlink_resource_occ_put(resource
, skb
))
2568 goto nla_put_failure
;
2569 if (devlink_resource_size_params_put(resource
, skb
))
2570 goto nla_put_failure
;
2571 if (list_empty(&resource
->resource_list
))
2574 if (nla_put_u8(skb
, DEVLINK_ATTR_RESOURCE_SIZE_VALID
,
2575 resource
->size_valid
))
2576 goto nla_put_failure
;
2578 child_resource_attr
= nla_nest_start_noflag(skb
,
2579 DEVLINK_ATTR_RESOURCE_LIST
);
2580 if (!child_resource_attr
)
2581 goto nla_put_failure
;
2583 list_for_each_entry(child_resource
, &resource
->resource_list
, list
) {
2584 if (devlink_resource_put(devlink
, skb
, child_resource
))
2585 goto resource_put_failure
;
2588 nla_nest_end(skb
, child_resource_attr
);
2590 nla_nest_end(skb
, resource_attr
);
2593 resource_put_failure
:
2594 nla_nest_cancel(skb
, child_resource_attr
);
2596 nla_nest_cancel(skb
, resource_attr
);
2600 static int devlink_resource_fill(struct genl_info
*info
,
2601 enum devlink_command cmd
, int flags
)
2603 struct devlink
*devlink
= info
->user_ptr
[0];
2604 struct devlink_resource
*resource
;
2605 struct nlattr
*resources_attr
;
2606 struct sk_buff
*skb
= NULL
;
2607 struct nlmsghdr
*nlh
;
2613 resource
= list_first_entry(&devlink
->resource_list
,
2614 struct devlink_resource
, list
);
2616 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2620 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2621 &devlink_nl_family
, NLM_F_MULTI
, cmd
);
2627 if (devlink_nl_put_handle(skb
, devlink
))
2628 goto nla_put_failure
;
2630 resources_attr
= nla_nest_start_noflag(skb
,
2631 DEVLINK_ATTR_RESOURCE_LIST
);
2632 if (!resources_attr
)
2633 goto nla_put_failure
;
2637 list_for_each_entry_from(resource
, &devlink
->resource_list
, list
) {
2638 err
= devlink_resource_put(devlink
, skb
, resource
);
2641 goto err_resource_put
;
2647 nla_nest_end(skb
, resources_attr
);
2648 genlmsg_end(skb
, hdr
);
2652 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2653 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
2655 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2660 return genlmsg_reply(skb
, info
);
2669 static int devlink_nl_cmd_resource_dump(struct sk_buff
*skb
,
2670 struct genl_info
*info
)
2672 struct devlink
*devlink
= info
->user_ptr
[0];
2674 if (list_empty(&devlink
->resource_list
))
2677 return devlink_resource_fill(info
, DEVLINK_CMD_RESOURCE_DUMP
, 0);
2681 devlink_resources_validate(struct devlink
*devlink
,
2682 struct devlink_resource
*resource
,
2683 struct genl_info
*info
)
2685 struct list_head
*resource_list
;
2689 resource_list
= &resource
->resource_list
;
2691 resource_list
= &devlink
->resource_list
;
2693 list_for_each_entry(resource
, resource_list
, list
) {
2694 if (!resource
->size_valid
)
2696 err
= devlink_resources_validate(devlink
, resource
, info
);
2703 static struct net
*devlink_netns_get(struct sk_buff
*skb
,
2704 struct genl_info
*info
)
2706 struct nlattr
*netns_pid_attr
= info
->attrs
[DEVLINK_ATTR_NETNS_PID
];
2707 struct nlattr
*netns_fd_attr
= info
->attrs
[DEVLINK_ATTR_NETNS_FD
];
2708 struct nlattr
*netns_id_attr
= info
->attrs
[DEVLINK_ATTR_NETNS_ID
];
2711 if (!!netns_pid_attr
+ !!netns_fd_attr
+ !!netns_id_attr
> 1) {
2712 NL_SET_ERR_MSG(info
->extack
, "multiple netns identifying attributes specified");
2713 return ERR_PTR(-EINVAL
);
2716 if (netns_pid_attr
) {
2717 net
= get_net_ns_by_pid(nla_get_u32(netns_pid_attr
));
2718 } else if (netns_fd_attr
) {
2719 net
= get_net_ns_by_fd(nla_get_u32(netns_fd_attr
));
2720 } else if (netns_id_attr
) {
2721 net
= get_net_ns_by_id(sock_net(skb
->sk
),
2722 nla_get_u32(netns_id_attr
));
2724 net
= ERR_PTR(-EINVAL
);
2727 net
= ERR_PTR(-EINVAL
);
2730 NL_SET_ERR_MSG(info
->extack
, "Unknown network namespace");
2731 return ERR_PTR(-EINVAL
);
2733 if (!netlink_ns_capable(skb
, net
->user_ns
, CAP_NET_ADMIN
)) {
2735 return ERR_PTR(-EPERM
);
2740 static void devlink_param_notify(struct devlink
*devlink
,
2741 unsigned int port_index
,
2742 struct devlink_param_item
*param_item
,
2743 enum devlink_command cmd
);
2745 static void devlink_reload_netns_change(struct devlink
*devlink
,
2746 struct net
*dest_net
)
2748 struct devlink_param_item
*param_item
;
2750 /* Userspace needs to be notified about devlink objects
2751 * removed from original and entering new network namespace.
2752 * The rest of the devlink objects are re-created during
2753 * reload process so the notifications are generated separatelly.
2756 list_for_each_entry(param_item
, &devlink
->param_list
, list
)
2757 devlink_param_notify(devlink
, 0, param_item
,
2758 DEVLINK_CMD_PARAM_DEL
);
2759 devlink_notify(devlink
, DEVLINK_CMD_DEL
);
2761 __devlink_net_set(devlink
, dest_net
);
2763 devlink_notify(devlink
, DEVLINK_CMD_NEW
);
2764 list_for_each_entry(param_item
, &devlink
->param_list
, list
)
2765 devlink_param_notify(devlink
, 0, param_item
,
2766 DEVLINK_CMD_PARAM_NEW
);
2769 static bool devlink_reload_supported(struct devlink
*devlink
)
2771 return devlink
->ops
->reload_down
&& devlink
->ops
->reload_up
;
2774 static void devlink_reload_failed_set(struct devlink
*devlink
,
2777 if (devlink
->reload_failed
== reload_failed
)
2779 devlink
->reload_failed
= reload_failed
;
2780 devlink_notify(devlink
, DEVLINK_CMD_NEW
);
2783 bool devlink_is_reload_failed(const struct devlink
*devlink
)
2785 return devlink
->reload_failed
;
2787 EXPORT_SYMBOL_GPL(devlink_is_reload_failed
);
2789 static int devlink_reload(struct devlink
*devlink
, struct net
*dest_net
,
2790 struct netlink_ext_ack
*extack
)
2794 if (!devlink
->reload_enabled
)
2797 err
= devlink
->ops
->reload_down(devlink
, !!dest_net
, extack
);
2801 if (dest_net
&& !net_eq(dest_net
, devlink_net(devlink
)))
2802 devlink_reload_netns_change(devlink
, dest_net
);
2804 err
= devlink
->ops
->reload_up(devlink
, extack
);
2805 devlink_reload_failed_set(devlink
, !!err
);
2809 static int devlink_nl_cmd_reload(struct sk_buff
*skb
, struct genl_info
*info
)
2811 struct devlink
*devlink
= info
->user_ptr
[0];
2812 struct net
*dest_net
= NULL
;
2815 if (!devlink_reload_supported(devlink
) || !devlink
->reload_enabled
)
2818 err
= devlink_resources_validate(devlink
, NULL
, info
);
2820 NL_SET_ERR_MSG_MOD(info
->extack
, "resources size validation failed");
2824 if (info
->attrs
[DEVLINK_ATTR_NETNS_PID
] ||
2825 info
->attrs
[DEVLINK_ATTR_NETNS_FD
] ||
2826 info
->attrs
[DEVLINK_ATTR_NETNS_ID
]) {
2827 dest_net
= devlink_netns_get(skb
, info
);
2828 if (IS_ERR(dest_net
))
2829 return PTR_ERR(dest_net
);
2832 err
= devlink_reload(devlink
, dest_net
, info
->extack
);
2840 static int devlink_nl_flash_update_fill(struct sk_buff
*msg
,
2841 struct devlink
*devlink
,
2842 enum devlink_command cmd
,
2843 const char *status_msg
,
2844 const char *component
,
2845 unsigned long done
, unsigned long total
)
2849 hdr
= genlmsg_put(msg
, 0, 0, &devlink_nl_family
, 0, cmd
);
2853 if (devlink_nl_put_handle(msg
, devlink
))
2854 goto nla_put_failure
;
2856 if (cmd
!= DEVLINK_CMD_FLASH_UPDATE_STATUS
)
2860 nla_put_string(msg
, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG
,
2862 goto nla_put_failure
;
2864 nla_put_string(msg
, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT
,
2866 goto nla_put_failure
;
2867 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE
,
2868 done
, DEVLINK_ATTR_PAD
))
2869 goto nla_put_failure
;
2870 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL
,
2871 total
, DEVLINK_ATTR_PAD
))
2872 goto nla_put_failure
;
2875 genlmsg_end(msg
, hdr
);
2879 genlmsg_cancel(msg
, hdr
);
2883 static void __devlink_flash_update_notify(struct devlink
*devlink
,
2884 enum devlink_command cmd
,
2885 const char *status_msg
,
2886 const char *component
,
2888 unsigned long total
)
2890 struct sk_buff
*msg
;
2893 WARN_ON(cmd
!= DEVLINK_CMD_FLASH_UPDATE
&&
2894 cmd
!= DEVLINK_CMD_FLASH_UPDATE_END
&&
2895 cmd
!= DEVLINK_CMD_FLASH_UPDATE_STATUS
);
2897 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
2901 err
= devlink_nl_flash_update_fill(msg
, devlink
, cmd
, status_msg
,
2902 component
, done
, total
);
2906 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
2907 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
2914 void devlink_flash_update_begin_notify(struct devlink
*devlink
)
2916 __devlink_flash_update_notify(devlink
,
2917 DEVLINK_CMD_FLASH_UPDATE
,
2920 EXPORT_SYMBOL_GPL(devlink_flash_update_begin_notify
);
2922 void devlink_flash_update_end_notify(struct devlink
*devlink
)
2924 __devlink_flash_update_notify(devlink
,
2925 DEVLINK_CMD_FLASH_UPDATE_END
,
2928 EXPORT_SYMBOL_GPL(devlink_flash_update_end_notify
);
2930 void devlink_flash_update_status_notify(struct devlink
*devlink
,
2931 const char *status_msg
,
2932 const char *component
,
2934 unsigned long total
)
2936 __devlink_flash_update_notify(devlink
,
2937 DEVLINK_CMD_FLASH_UPDATE_STATUS
,
2938 status_msg
, component
, done
, total
);
2940 EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify
);
2942 static int devlink_nl_cmd_flash_update(struct sk_buff
*skb
,
2943 struct genl_info
*info
)
2945 struct devlink
*devlink
= info
->user_ptr
[0];
2946 const char *file_name
, *component
;
2947 struct nlattr
*nla_component
;
2949 if (!devlink
->ops
->flash_update
)
2952 if (!info
->attrs
[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME
])
2954 file_name
= nla_data(info
->attrs
[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME
]);
2956 nla_component
= info
->attrs
[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT
];
2957 component
= nla_component
? nla_data(nla_component
) : NULL
;
2959 return devlink
->ops
->flash_update(devlink
, file_name
, component
,
2963 static const struct devlink_param devlink_param_generic
[] = {
2965 .id
= DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET
,
2966 .name
= DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME
,
2967 .type
= DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE
,
2970 .id
= DEVLINK_PARAM_GENERIC_ID_MAX_MACS
,
2971 .name
= DEVLINK_PARAM_GENERIC_MAX_MACS_NAME
,
2972 .type
= DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE
,
2975 .id
= DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV
,
2976 .name
= DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME
,
2977 .type
= DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE
,
2980 .id
= DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT
,
2981 .name
= DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME
,
2982 .type
= DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE
,
2985 .id
= DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI
,
2986 .name
= DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME
,
2987 .type
= DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE
,
2990 .id
= DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX
,
2991 .name
= DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME
,
2992 .type
= DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE
,
2995 .id
= DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN
,
2996 .name
= DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME
,
2997 .type
= DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE
,
3000 .id
= DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY
,
3001 .name
= DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME
,
3002 .type
= DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE
,
3005 .id
= DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE
,
3006 .name
= DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME
,
3007 .type
= DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE
,
3010 .id
= DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE
,
3011 .name
= DEVLINK_PARAM_GENERIC_ENABLE_ROCE_NAME
,
3012 .type
= DEVLINK_PARAM_GENERIC_ENABLE_ROCE_TYPE
,
3016 static int devlink_param_generic_verify(const struct devlink_param
*param
)
3018 /* verify it match generic parameter by id and name */
3019 if (param
->id
> DEVLINK_PARAM_GENERIC_ID_MAX
)
3021 if (strcmp(param
->name
, devlink_param_generic
[param
->id
].name
))
3024 WARN_ON(param
->type
!= devlink_param_generic
[param
->id
].type
);
3029 static int devlink_param_driver_verify(const struct devlink_param
*param
)
3033 if (param
->id
<= DEVLINK_PARAM_GENERIC_ID_MAX
)
3035 /* verify no such name in generic params */
3036 for (i
= 0; i
<= DEVLINK_PARAM_GENERIC_ID_MAX
; i
++)
3037 if (!strcmp(param
->name
, devlink_param_generic
[i
].name
))
3043 static struct devlink_param_item
*
3044 devlink_param_find_by_name(struct list_head
*param_list
,
3045 const char *param_name
)
3047 struct devlink_param_item
*param_item
;
3049 list_for_each_entry(param_item
, param_list
, list
)
3050 if (!strcmp(param_item
->param
->name
, param_name
))
3055 static struct devlink_param_item
*
3056 devlink_param_find_by_id(struct list_head
*param_list
, u32 param_id
)
3058 struct devlink_param_item
*param_item
;
3060 list_for_each_entry(param_item
, param_list
, list
)
3061 if (param_item
->param
->id
== param_id
)
3067 devlink_param_cmode_is_supported(const struct devlink_param
*param
,
3068 enum devlink_param_cmode cmode
)
3070 return test_bit(cmode
, ¶m
->supported_cmodes
);
3073 static int devlink_param_get(struct devlink
*devlink
,
3074 const struct devlink_param
*param
,
3075 struct devlink_param_gset_ctx
*ctx
)
3079 return param
->get(devlink
, param
->id
, ctx
);
3082 static int devlink_param_set(struct devlink
*devlink
,
3083 const struct devlink_param
*param
,
3084 struct devlink_param_gset_ctx
*ctx
)
3088 return param
->set(devlink
, param
->id
, ctx
);
3092 devlink_param_type_to_nla_type(enum devlink_param_type param_type
)
3094 switch (param_type
) {
3095 case DEVLINK_PARAM_TYPE_U8
:
3097 case DEVLINK_PARAM_TYPE_U16
:
3099 case DEVLINK_PARAM_TYPE_U32
:
3101 case DEVLINK_PARAM_TYPE_STRING
:
3103 case DEVLINK_PARAM_TYPE_BOOL
:
3111 devlink_nl_param_value_fill_one(struct sk_buff
*msg
,
3112 enum devlink_param_type type
,
3113 enum devlink_param_cmode cmode
,
3114 union devlink_param_value val
)
3116 struct nlattr
*param_value_attr
;
3118 param_value_attr
= nla_nest_start_noflag(msg
,
3119 DEVLINK_ATTR_PARAM_VALUE
);
3120 if (!param_value_attr
)
3121 goto nla_put_failure
;
3123 if (nla_put_u8(msg
, DEVLINK_ATTR_PARAM_VALUE_CMODE
, cmode
))
3124 goto value_nest_cancel
;
3127 case DEVLINK_PARAM_TYPE_U8
:
3128 if (nla_put_u8(msg
, DEVLINK_ATTR_PARAM_VALUE_DATA
, val
.vu8
))
3129 goto value_nest_cancel
;
3131 case DEVLINK_PARAM_TYPE_U16
:
3132 if (nla_put_u16(msg
, DEVLINK_ATTR_PARAM_VALUE_DATA
, val
.vu16
))
3133 goto value_nest_cancel
;
3135 case DEVLINK_PARAM_TYPE_U32
:
3136 if (nla_put_u32(msg
, DEVLINK_ATTR_PARAM_VALUE_DATA
, val
.vu32
))
3137 goto value_nest_cancel
;
3139 case DEVLINK_PARAM_TYPE_STRING
:
3140 if (nla_put_string(msg
, DEVLINK_ATTR_PARAM_VALUE_DATA
,
3142 goto value_nest_cancel
;
3144 case DEVLINK_PARAM_TYPE_BOOL
:
3146 nla_put_flag(msg
, DEVLINK_ATTR_PARAM_VALUE_DATA
))
3147 goto value_nest_cancel
;
3151 nla_nest_end(msg
, param_value_attr
);
3155 nla_nest_cancel(msg
, param_value_attr
);
3160 static int devlink_nl_param_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
3161 unsigned int port_index
,
3162 struct devlink_param_item
*param_item
,
3163 enum devlink_command cmd
,
3164 u32 portid
, u32 seq
, int flags
)
3166 union devlink_param_value param_value
[DEVLINK_PARAM_CMODE_MAX
+ 1];
3167 bool param_value_set
[DEVLINK_PARAM_CMODE_MAX
+ 1] = {};
3168 const struct devlink_param
*param
= param_item
->param
;
3169 struct devlink_param_gset_ctx ctx
;
3170 struct nlattr
*param_values_list
;
3171 struct nlattr
*param_attr
;
3177 /* Get value from driver part to driverinit configuration mode */
3178 for (i
= 0; i
<= DEVLINK_PARAM_CMODE_MAX
; i
++) {
3179 if (!devlink_param_cmode_is_supported(param
, i
))
3181 if (i
== DEVLINK_PARAM_CMODE_DRIVERINIT
) {
3182 if (!param_item
->driverinit_value_valid
)
3184 param_value
[i
] = param_item
->driverinit_value
;
3186 if (!param_item
->published
)
3189 err
= devlink_param_get(devlink
, param
, &ctx
);
3192 param_value
[i
] = ctx
.val
;
3194 param_value_set
[i
] = true;
3197 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
3201 if (devlink_nl_put_handle(msg
, devlink
))
3202 goto genlmsg_cancel
;
3204 if (cmd
== DEVLINK_CMD_PORT_PARAM_GET
||
3205 cmd
== DEVLINK_CMD_PORT_PARAM_NEW
||
3206 cmd
== DEVLINK_CMD_PORT_PARAM_DEL
)
3207 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, port_index
))
3208 goto genlmsg_cancel
;
3210 param_attr
= nla_nest_start_noflag(msg
, DEVLINK_ATTR_PARAM
);
3212 goto genlmsg_cancel
;
3213 if (nla_put_string(msg
, DEVLINK_ATTR_PARAM_NAME
, param
->name
))
3214 goto param_nest_cancel
;
3215 if (param
->generic
&& nla_put_flag(msg
, DEVLINK_ATTR_PARAM_GENERIC
))
3216 goto param_nest_cancel
;
3218 nla_type
= devlink_param_type_to_nla_type(param
->type
);
3220 goto param_nest_cancel
;
3221 if (nla_put_u8(msg
, DEVLINK_ATTR_PARAM_TYPE
, nla_type
))
3222 goto param_nest_cancel
;
3224 param_values_list
= nla_nest_start_noflag(msg
,
3225 DEVLINK_ATTR_PARAM_VALUES_LIST
);
3226 if (!param_values_list
)
3227 goto param_nest_cancel
;
3229 for (i
= 0; i
<= DEVLINK_PARAM_CMODE_MAX
; i
++) {
3230 if (!param_value_set
[i
])
3232 err
= devlink_nl_param_value_fill_one(msg
, param
->type
,
3235 goto values_list_nest_cancel
;
3238 nla_nest_end(msg
, param_values_list
);
3239 nla_nest_end(msg
, param_attr
);
3240 genlmsg_end(msg
, hdr
);
3243 values_list_nest_cancel
:
3244 nla_nest_end(msg
, param_values_list
);
3246 nla_nest_cancel(msg
, param_attr
);
3248 genlmsg_cancel(msg
, hdr
);
3252 static void devlink_param_notify(struct devlink
*devlink
,
3253 unsigned int port_index
,
3254 struct devlink_param_item
*param_item
,
3255 enum devlink_command cmd
)
3257 struct sk_buff
*msg
;
3260 WARN_ON(cmd
!= DEVLINK_CMD_PARAM_NEW
&& cmd
!= DEVLINK_CMD_PARAM_DEL
&&
3261 cmd
!= DEVLINK_CMD_PORT_PARAM_NEW
&&
3262 cmd
!= DEVLINK_CMD_PORT_PARAM_DEL
);
3264 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
3267 err
= devlink_nl_param_fill(msg
, devlink
, port_index
, param_item
, cmd
,
3274 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
3275 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
3278 static int devlink_nl_cmd_param_get_dumpit(struct sk_buff
*msg
,
3279 struct netlink_callback
*cb
)
3281 struct devlink_param_item
*param_item
;
3282 struct devlink
*devlink
;
3283 int start
= cb
->args
[0];
3287 mutex_lock(&devlink_mutex
);
3288 list_for_each_entry(devlink
, &devlink_list
, list
) {
3289 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
3291 mutex_lock(&devlink
->lock
);
3292 list_for_each_entry(param_item
, &devlink
->param_list
, list
) {
3297 err
= devlink_nl_param_fill(msg
, devlink
, 0, param_item
,
3298 DEVLINK_CMD_PARAM_GET
,
3299 NETLINK_CB(cb
->skb
).portid
,
3302 if (err
&& err
!= -EOPNOTSUPP
) {
3303 mutex_unlock(&devlink
->lock
);
3308 mutex_unlock(&devlink
->lock
);
3311 mutex_unlock(&devlink_mutex
);
3313 if (err
!= -EMSGSIZE
)
3321 devlink_param_type_get_from_info(struct genl_info
*info
,
3322 enum devlink_param_type
*param_type
)
3324 if (!info
->attrs
[DEVLINK_ATTR_PARAM_TYPE
])
3327 switch (nla_get_u8(info
->attrs
[DEVLINK_ATTR_PARAM_TYPE
])) {
3329 *param_type
= DEVLINK_PARAM_TYPE_U8
;
3332 *param_type
= DEVLINK_PARAM_TYPE_U16
;
3335 *param_type
= DEVLINK_PARAM_TYPE_U32
;
3338 *param_type
= DEVLINK_PARAM_TYPE_STRING
;
3341 *param_type
= DEVLINK_PARAM_TYPE_BOOL
;
3351 devlink_param_value_get_from_info(const struct devlink_param
*param
,
3352 struct genl_info
*info
,
3353 union devlink_param_value
*value
)
3357 if (param
->type
!= DEVLINK_PARAM_TYPE_BOOL
&&
3358 !info
->attrs
[DEVLINK_ATTR_PARAM_VALUE_DATA
])
3361 switch (param
->type
) {
3362 case DEVLINK_PARAM_TYPE_U8
:
3363 value
->vu8
= nla_get_u8(info
->attrs
[DEVLINK_ATTR_PARAM_VALUE_DATA
]);
3365 case DEVLINK_PARAM_TYPE_U16
:
3366 value
->vu16
= nla_get_u16(info
->attrs
[DEVLINK_ATTR_PARAM_VALUE_DATA
]);
3368 case DEVLINK_PARAM_TYPE_U32
:
3369 value
->vu32
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_PARAM_VALUE_DATA
]);
3371 case DEVLINK_PARAM_TYPE_STRING
:
3372 len
= strnlen(nla_data(info
->attrs
[DEVLINK_ATTR_PARAM_VALUE_DATA
]),
3373 nla_len(info
->attrs
[DEVLINK_ATTR_PARAM_VALUE_DATA
]));
3374 if (len
== nla_len(info
->attrs
[DEVLINK_ATTR_PARAM_VALUE_DATA
]) ||
3375 len
>= __DEVLINK_PARAM_MAX_STRING_VALUE
)
3378 nla_data(info
->attrs
[DEVLINK_ATTR_PARAM_VALUE_DATA
]));
3380 case DEVLINK_PARAM_TYPE_BOOL
:
3381 value
->vbool
= info
->attrs
[DEVLINK_ATTR_PARAM_VALUE_DATA
] ?
3388 static struct devlink_param_item
*
3389 devlink_param_get_from_info(struct list_head
*param_list
,
3390 struct genl_info
*info
)
3394 if (!info
->attrs
[DEVLINK_ATTR_PARAM_NAME
])
3397 param_name
= nla_data(info
->attrs
[DEVLINK_ATTR_PARAM_NAME
]);
3398 return devlink_param_find_by_name(param_list
, param_name
);
3401 static int devlink_nl_cmd_param_get_doit(struct sk_buff
*skb
,
3402 struct genl_info
*info
)
3404 struct devlink
*devlink
= info
->user_ptr
[0];
3405 struct devlink_param_item
*param_item
;
3406 struct sk_buff
*msg
;
3409 param_item
= devlink_param_get_from_info(&devlink
->param_list
, info
);
3413 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
3417 err
= devlink_nl_param_fill(msg
, devlink
, 0, param_item
,
3418 DEVLINK_CMD_PARAM_GET
,
3419 info
->snd_portid
, info
->snd_seq
, 0);
3425 return genlmsg_reply(msg
, info
);
3428 static int __devlink_nl_cmd_param_set_doit(struct devlink
*devlink
,
3429 unsigned int port_index
,
3430 struct list_head
*param_list
,
3431 struct genl_info
*info
,
3432 enum devlink_command cmd
)
3434 enum devlink_param_type param_type
;
3435 struct devlink_param_gset_ctx ctx
;
3436 enum devlink_param_cmode cmode
;
3437 struct devlink_param_item
*param_item
;
3438 const struct devlink_param
*param
;
3439 union devlink_param_value value
;
3442 param_item
= devlink_param_get_from_info(param_list
, info
);
3445 param
= param_item
->param
;
3446 err
= devlink_param_type_get_from_info(info
, ¶m_type
);
3449 if (param_type
!= param
->type
)
3451 err
= devlink_param_value_get_from_info(param
, info
, &value
);
3454 if (param
->validate
) {
3455 err
= param
->validate(devlink
, param
->id
, value
, info
->extack
);
3460 if (!info
->attrs
[DEVLINK_ATTR_PARAM_VALUE_CMODE
])
3462 cmode
= nla_get_u8(info
->attrs
[DEVLINK_ATTR_PARAM_VALUE_CMODE
]);
3463 if (!devlink_param_cmode_is_supported(param
, cmode
))
3466 if (cmode
== DEVLINK_PARAM_CMODE_DRIVERINIT
) {
3467 if (param
->type
== DEVLINK_PARAM_TYPE_STRING
)
3468 strcpy(param_item
->driverinit_value
.vstr
, value
.vstr
);
3470 param_item
->driverinit_value
= value
;
3471 param_item
->driverinit_value_valid
= true;
3477 err
= devlink_param_set(devlink
, param
, &ctx
);
3482 devlink_param_notify(devlink
, port_index
, param_item
, cmd
);
3486 static int devlink_nl_cmd_param_set_doit(struct sk_buff
*skb
,
3487 struct genl_info
*info
)
3489 struct devlink
*devlink
= info
->user_ptr
[0];
3491 return __devlink_nl_cmd_param_set_doit(devlink
, 0, &devlink
->param_list
,
3492 info
, DEVLINK_CMD_PARAM_NEW
);
3495 static int devlink_param_register_one(struct devlink
*devlink
,
3496 unsigned int port_index
,
3497 struct list_head
*param_list
,
3498 const struct devlink_param
*param
,
3499 enum devlink_command cmd
)
3501 struct devlink_param_item
*param_item
;
3503 if (devlink_param_find_by_name(param_list
, param
->name
))
3506 if (param
->supported_cmodes
== BIT(DEVLINK_PARAM_CMODE_DRIVERINIT
))
3507 WARN_ON(param
->get
|| param
->set
);
3509 WARN_ON(!param
->get
|| !param
->set
);
3511 param_item
= kzalloc(sizeof(*param_item
), GFP_KERNEL
);
3514 param_item
->param
= param
;
3516 list_add_tail(¶m_item
->list
, param_list
);
3517 devlink_param_notify(devlink
, port_index
, param_item
, cmd
);
3521 static void devlink_param_unregister_one(struct devlink
*devlink
,
3522 unsigned int port_index
,
3523 struct list_head
*param_list
,
3524 const struct devlink_param
*param
,
3525 enum devlink_command cmd
)
3527 struct devlink_param_item
*param_item
;
3529 param_item
= devlink_param_find_by_name(param_list
, param
->name
);
3530 WARN_ON(!param_item
);
3531 devlink_param_notify(devlink
, port_index
, param_item
, cmd
);
3532 list_del(¶m_item
->list
);
3536 static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff
*msg
,
3537 struct netlink_callback
*cb
)
3539 struct devlink_param_item
*param_item
;
3540 struct devlink_port
*devlink_port
;
3541 struct devlink
*devlink
;
3542 int start
= cb
->args
[0];
3546 mutex_lock(&devlink_mutex
);
3547 list_for_each_entry(devlink
, &devlink_list
, list
) {
3548 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
3550 mutex_lock(&devlink
->lock
);
3551 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
3552 list_for_each_entry(param_item
,
3553 &devlink_port
->param_list
, list
) {
3558 err
= devlink_nl_param_fill(msg
,
3559 devlink_port
->devlink
,
3560 devlink_port
->index
, param_item
,
3561 DEVLINK_CMD_PORT_PARAM_GET
,
3562 NETLINK_CB(cb
->skb
).portid
,
3565 if (err
&& err
!= -EOPNOTSUPP
) {
3566 mutex_unlock(&devlink
->lock
);
3572 mutex_unlock(&devlink
->lock
);
3575 mutex_unlock(&devlink_mutex
);
3577 if (err
!= -EMSGSIZE
)
3584 static int devlink_nl_cmd_port_param_get_doit(struct sk_buff
*skb
,
3585 struct genl_info
*info
)
3587 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
3588 struct devlink_param_item
*param_item
;
3589 struct sk_buff
*msg
;
3592 param_item
= devlink_param_get_from_info(&devlink_port
->param_list
,
3597 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
3601 err
= devlink_nl_param_fill(msg
, devlink_port
->devlink
,
3602 devlink_port
->index
, param_item
,
3603 DEVLINK_CMD_PORT_PARAM_GET
,
3604 info
->snd_portid
, info
->snd_seq
, 0);
3610 return genlmsg_reply(msg
, info
);
3613 static int devlink_nl_cmd_port_param_set_doit(struct sk_buff
*skb
,
3614 struct genl_info
*info
)
3616 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
3618 return __devlink_nl_cmd_param_set_doit(devlink_port
->devlink
,
3619 devlink_port
->index
,
3620 &devlink_port
->param_list
, info
,
3621 DEVLINK_CMD_PORT_PARAM_NEW
);
3624 static int devlink_nl_region_snapshot_id_put(struct sk_buff
*msg
,
3625 struct devlink
*devlink
,
3626 struct devlink_snapshot
*snapshot
)
3628 struct nlattr
*snap_attr
;
3631 snap_attr
= nla_nest_start_noflag(msg
, DEVLINK_ATTR_REGION_SNAPSHOT
);
3635 err
= nla_put_u32(msg
, DEVLINK_ATTR_REGION_SNAPSHOT_ID
, snapshot
->id
);
3637 goto nla_put_failure
;
3639 nla_nest_end(msg
, snap_attr
);
3643 nla_nest_cancel(msg
, snap_attr
);
3647 static int devlink_nl_region_snapshots_id_put(struct sk_buff
*msg
,
3648 struct devlink
*devlink
,
3649 struct devlink_region
*region
)
3651 struct devlink_snapshot
*snapshot
;
3652 struct nlattr
*snapshots_attr
;
3655 snapshots_attr
= nla_nest_start_noflag(msg
,
3656 DEVLINK_ATTR_REGION_SNAPSHOTS
);
3657 if (!snapshots_attr
)
3660 list_for_each_entry(snapshot
, ®ion
->snapshot_list
, list
) {
3661 err
= devlink_nl_region_snapshot_id_put(msg
, devlink
, snapshot
);
3663 goto nla_put_failure
;
3666 nla_nest_end(msg
, snapshots_attr
);
3670 nla_nest_cancel(msg
, snapshots_attr
);
3674 static int devlink_nl_region_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
3675 enum devlink_command cmd
, u32 portid
,
3677 struct devlink_region
*region
)
3682 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
3686 err
= devlink_nl_put_handle(msg
, devlink
);
3688 goto nla_put_failure
;
3690 err
= nla_put_string(msg
, DEVLINK_ATTR_REGION_NAME
, region
->name
);
3692 goto nla_put_failure
;
3694 err
= nla_put_u64_64bit(msg
, DEVLINK_ATTR_REGION_SIZE
,
3698 goto nla_put_failure
;
3700 err
= devlink_nl_region_snapshots_id_put(msg
, devlink
, region
);
3702 goto nla_put_failure
;
3704 genlmsg_end(msg
, hdr
);
3708 genlmsg_cancel(msg
, hdr
);
3712 static void devlink_nl_region_notify(struct devlink_region
*region
,
3713 struct devlink_snapshot
*snapshot
,
3714 enum devlink_command cmd
)
3716 struct devlink
*devlink
= region
->devlink
;
3717 struct sk_buff
*msg
;
3721 WARN_ON(cmd
!= DEVLINK_CMD_REGION_NEW
&& cmd
!= DEVLINK_CMD_REGION_DEL
);
3723 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
3727 hdr
= genlmsg_put(msg
, 0, 0, &devlink_nl_family
, 0, cmd
);
3731 err
= devlink_nl_put_handle(msg
, devlink
);
3733 goto out_cancel_msg
;
3735 err
= nla_put_string(msg
, DEVLINK_ATTR_REGION_NAME
,
3738 goto out_cancel_msg
;
3741 err
= nla_put_u32(msg
, DEVLINK_ATTR_REGION_SNAPSHOT_ID
,
3744 goto out_cancel_msg
;
3746 err
= nla_put_u64_64bit(msg
, DEVLINK_ATTR_REGION_SIZE
,
3747 region
->size
, DEVLINK_ATTR_PAD
);
3749 goto out_cancel_msg
;
3751 genlmsg_end(msg
, hdr
);
3753 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
3754 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
3759 genlmsg_cancel(msg
, hdr
);
3764 static void devlink_region_snapshot_del(struct devlink_region
*region
,
3765 struct devlink_snapshot
*snapshot
)
3767 devlink_nl_region_notify(region
, snapshot
, DEVLINK_CMD_REGION_DEL
);
3768 region
->cur_snapshots
--;
3769 list_del(&snapshot
->list
);
3770 (*snapshot
->data_destructor
)(snapshot
->data
);
3774 static int devlink_nl_cmd_region_get_doit(struct sk_buff
*skb
,
3775 struct genl_info
*info
)
3777 struct devlink
*devlink
= info
->user_ptr
[0];
3778 struct devlink_region
*region
;
3779 const char *region_name
;
3780 struct sk_buff
*msg
;
3783 if (!info
->attrs
[DEVLINK_ATTR_REGION_NAME
])
3786 region_name
= nla_data(info
->attrs
[DEVLINK_ATTR_REGION_NAME
]);
3787 region
= devlink_region_get_by_name(devlink
, region_name
);
3791 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
3795 err
= devlink_nl_region_fill(msg
, devlink
, DEVLINK_CMD_REGION_GET
,
3796 info
->snd_portid
, info
->snd_seq
, 0,
3803 return genlmsg_reply(msg
, info
);
3806 static int devlink_nl_cmd_region_get_dumpit(struct sk_buff
*msg
,
3807 struct netlink_callback
*cb
)
3809 struct devlink_region
*region
;
3810 struct devlink
*devlink
;
3811 int start
= cb
->args
[0];
3815 mutex_lock(&devlink_mutex
);
3816 list_for_each_entry(devlink
, &devlink_list
, list
) {
3817 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
3820 mutex_lock(&devlink
->lock
);
3821 list_for_each_entry(region
, &devlink
->region_list
, list
) {
3826 err
= devlink_nl_region_fill(msg
, devlink
,
3827 DEVLINK_CMD_REGION_GET
,
3828 NETLINK_CB(cb
->skb
).portid
,
3830 NLM_F_MULTI
, region
);
3832 mutex_unlock(&devlink
->lock
);
3837 mutex_unlock(&devlink
->lock
);
3840 mutex_unlock(&devlink_mutex
);
3845 static int devlink_nl_cmd_region_del(struct sk_buff
*skb
,
3846 struct genl_info
*info
)
3848 struct devlink
*devlink
= info
->user_ptr
[0];
3849 struct devlink_snapshot
*snapshot
;
3850 struct devlink_region
*region
;
3851 const char *region_name
;
3854 if (!info
->attrs
[DEVLINK_ATTR_REGION_NAME
] ||
3855 !info
->attrs
[DEVLINK_ATTR_REGION_SNAPSHOT_ID
])
3858 region_name
= nla_data(info
->attrs
[DEVLINK_ATTR_REGION_NAME
]);
3859 snapshot_id
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_REGION_SNAPSHOT_ID
]);
3861 region
= devlink_region_get_by_name(devlink
, region_name
);
3865 snapshot
= devlink_region_snapshot_get_by_id(region
, snapshot_id
);
3869 devlink_region_snapshot_del(region
, snapshot
);
3873 static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff
*msg
,
3874 struct devlink
*devlink
,
3875 u8
*chunk
, u32 chunk_size
,
3878 struct nlattr
*chunk_attr
;
3881 chunk_attr
= nla_nest_start_noflag(msg
, DEVLINK_ATTR_REGION_CHUNK
);
3885 err
= nla_put(msg
, DEVLINK_ATTR_REGION_CHUNK_DATA
, chunk_size
, chunk
);
3887 goto nla_put_failure
;
3889 err
= nla_put_u64_64bit(msg
, DEVLINK_ATTR_REGION_CHUNK_ADDR
, addr
,
3892 goto nla_put_failure
;
3894 nla_nest_end(msg
, chunk_attr
);
3898 nla_nest_cancel(msg
, chunk_attr
);
3902 #define DEVLINK_REGION_READ_CHUNK_SIZE 256
3904 static int devlink_nl_region_read_snapshot_fill(struct sk_buff
*skb
,
3905 struct devlink
*devlink
,
3906 struct devlink_region
*region
,
3907 struct nlattr
**attrs
,
3913 struct devlink_snapshot
*snapshot
;
3914 u64 curr_offset
= start_offset
;
3918 *new_offset
= start_offset
;
3920 snapshot_id
= nla_get_u32(attrs
[DEVLINK_ATTR_REGION_SNAPSHOT_ID
]);
3921 snapshot
= devlink_region_snapshot_get_by_id(region
, snapshot_id
);
3925 if (end_offset
> region
->size
|| dump
)
3926 end_offset
= region
->size
;
3928 while (curr_offset
< end_offset
) {
3932 if (end_offset
- curr_offset
< DEVLINK_REGION_READ_CHUNK_SIZE
)
3933 data_size
= end_offset
- curr_offset
;
3935 data_size
= DEVLINK_REGION_READ_CHUNK_SIZE
;
3937 data
= &snapshot
->data
[curr_offset
];
3938 err
= devlink_nl_cmd_region_read_chunk_fill(skb
, devlink
,
3944 curr_offset
+= data_size
;
3946 *new_offset
= curr_offset
;
3951 static int devlink_nl_cmd_region_read_dumpit(struct sk_buff
*skb
,
3952 struct netlink_callback
*cb
)
3954 const struct genl_dumpit_info
*info
= genl_dumpit_info(cb
);
3955 u64 ret_offset
, start_offset
, end_offset
= 0;
3956 struct nlattr
**attrs
= info
->attrs
;
3957 struct devlink_region
*region
;
3958 struct nlattr
*chunks_attr
;
3959 const char *region_name
;
3960 struct devlink
*devlink
;
3965 start_offset
= *((u64
*)&cb
->args
[0]);
3967 mutex_lock(&devlink_mutex
);
3968 devlink
= devlink_get_from_attrs(sock_net(cb
->skb
->sk
), attrs
);
3969 if (IS_ERR(devlink
)) {
3970 err
= PTR_ERR(devlink
);
3974 mutex_lock(&devlink
->lock
);
3976 if (!attrs
[DEVLINK_ATTR_REGION_NAME
] ||
3977 !attrs
[DEVLINK_ATTR_REGION_SNAPSHOT_ID
]) {
3982 region_name
= nla_data(attrs
[DEVLINK_ATTR_REGION_NAME
]);
3983 region
= devlink_region_get_by_name(devlink
, region_name
);
3989 hdr
= genlmsg_put(skb
, NETLINK_CB(cb
->skb
).portid
, cb
->nlh
->nlmsg_seq
,
3990 &devlink_nl_family
, NLM_F_ACK
| NLM_F_MULTI
,
3991 DEVLINK_CMD_REGION_READ
);
3997 err
= devlink_nl_put_handle(skb
, devlink
);
3999 goto nla_put_failure
;
4001 err
= nla_put_string(skb
, DEVLINK_ATTR_REGION_NAME
, region_name
);
4003 goto nla_put_failure
;
4005 chunks_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_REGION_CHUNKS
);
4008 goto nla_put_failure
;
4011 if (attrs
[DEVLINK_ATTR_REGION_CHUNK_ADDR
] &&
4012 attrs
[DEVLINK_ATTR_REGION_CHUNK_LEN
]) {
4015 nla_get_u64(attrs
[DEVLINK_ATTR_REGION_CHUNK_ADDR
]);
4017 end_offset
= nla_get_u64(attrs
[DEVLINK_ATTR_REGION_CHUNK_ADDR
]);
4018 end_offset
+= nla_get_u64(attrs
[DEVLINK_ATTR_REGION_CHUNK_LEN
]);
4022 err
= devlink_nl_region_read_snapshot_fill(skb
, devlink
,
4028 if (err
&& err
!= -EMSGSIZE
)
4029 goto nla_put_failure
;
4031 /* Check if there was any progress done to prevent infinite loop */
4032 if (ret_offset
== start_offset
) {
4034 goto nla_put_failure
;
4037 *((u64
*)&cb
->args
[0]) = ret_offset
;
4039 nla_nest_end(skb
, chunks_attr
);
4040 genlmsg_end(skb
, hdr
);
4041 mutex_unlock(&devlink
->lock
);
4042 mutex_unlock(&devlink_mutex
);
4047 genlmsg_cancel(skb
, hdr
);
4049 mutex_unlock(&devlink
->lock
);
4051 mutex_unlock(&devlink_mutex
);
4055 struct devlink_info_req
{
4056 struct sk_buff
*msg
;
4059 int devlink_info_driver_name_put(struct devlink_info_req
*req
, const char *name
)
4061 return nla_put_string(req
->msg
, DEVLINK_ATTR_INFO_DRIVER_NAME
, name
);
4063 EXPORT_SYMBOL_GPL(devlink_info_driver_name_put
);
4065 int devlink_info_serial_number_put(struct devlink_info_req
*req
, const char *sn
)
4067 return nla_put_string(req
->msg
, DEVLINK_ATTR_INFO_SERIAL_NUMBER
, sn
);
4069 EXPORT_SYMBOL_GPL(devlink_info_serial_number_put
);
4071 static int devlink_info_version_put(struct devlink_info_req
*req
, int attr
,
4072 const char *version_name
,
4073 const char *version_value
)
4075 struct nlattr
*nest
;
4078 nest
= nla_nest_start_noflag(req
->msg
, attr
);
4082 err
= nla_put_string(req
->msg
, DEVLINK_ATTR_INFO_VERSION_NAME
,
4085 goto nla_put_failure
;
4087 err
= nla_put_string(req
->msg
, DEVLINK_ATTR_INFO_VERSION_VALUE
,
4090 goto nla_put_failure
;
4092 nla_nest_end(req
->msg
, nest
);
4097 nla_nest_cancel(req
->msg
, nest
);
4101 int devlink_info_version_fixed_put(struct devlink_info_req
*req
,
4102 const char *version_name
,
4103 const char *version_value
)
4105 return devlink_info_version_put(req
, DEVLINK_ATTR_INFO_VERSION_FIXED
,
4106 version_name
, version_value
);
4108 EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put
);
4110 int devlink_info_version_stored_put(struct devlink_info_req
*req
,
4111 const char *version_name
,
4112 const char *version_value
)
4114 return devlink_info_version_put(req
, DEVLINK_ATTR_INFO_VERSION_STORED
,
4115 version_name
, version_value
);
4117 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put
);
4119 int devlink_info_version_running_put(struct devlink_info_req
*req
,
4120 const char *version_name
,
4121 const char *version_value
)
4123 return devlink_info_version_put(req
, DEVLINK_ATTR_INFO_VERSION_RUNNING
,
4124 version_name
, version_value
);
4126 EXPORT_SYMBOL_GPL(devlink_info_version_running_put
);
4129 devlink_nl_info_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
4130 enum devlink_command cmd
, u32 portid
,
4131 u32 seq
, int flags
, struct netlink_ext_ack
*extack
)
4133 struct devlink_info_req req
;
4137 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
4142 if (devlink_nl_put_handle(msg
, devlink
))
4143 goto err_cancel_msg
;
4146 err
= devlink
->ops
->info_get(devlink
, &req
, extack
);
4148 goto err_cancel_msg
;
4150 genlmsg_end(msg
, hdr
);
4154 genlmsg_cancel(msg
, hdr
);
4158 static int devlink_nl_cmd_info_get_doit(struct sk_buff
*skb
,
4159 struct genl_info
*info
)
4161 struct devlink
*devlink
= info
->user_ptr
[0];
4162 struct sk_buff
*msg
;
4165 if (!devlink
->ops
->info_get
)
4168 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
4172 err
= devlink_nl_info_fill(msg
, devlink
, DEVLINK_CMD_INFO_GET
,
4173 info
->snd_portid
, info
->snd_seq
, 0,
4180 return genlmsg_reply(msg
, info
);
4183 static int devlink_nl_cmd_info_get_dumpit(struct sk_buff
*msg
,
4184 struct netlink_callback
*cb
)
4186 struct devlink
*devlink
;
4187 int start
= cb
->args
[0];
4191 mutex_lock(&devlink_mutex
);
4192 list_for_each_entry(devlink
, &devlink_list
, list
) {
4193 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
4200 if (!devlink
->ops
->info_get
) {
4205 mutex_lock(&devlink
->lock
);
4206 err
= devlink_nl_info_fill(msg
, devlink
, DEVLINK_CMD_INFO_GET
,
4207 NETLINK_CB(cb
->skb
).portid
,
4208 cb
->nlh
->nlmsg_seq
, NLM_F_MULTI
,
4210 mutex_unlock(&devlink
->lock
);
4211 if (err
&& err
!= -EOPNOTSUPP
)
4215 mutex_unlock(&devlink_mutex
);
4217 if (err
!= -EMSGSIZE
)
4224 struct devlink_fmsg_item
{
4225 struct list_head list
;
4232 struct devlink_fmsg
{
4233 struct list_head item_list
;
4236 static struct devlink_fmsg
*devlink_fmsg_alloc(void)
4238 struct devlink_fmsg
*fmsg
;
4240 fmsg
= kzalloc(sizeof(*fmsg
), GFP_KERNEL
);
4244 INIT_LIST_HEAD(&fmsg
->item_list
);
4249 static void devlink_fmsg_free(struct devlink_fmsg
*fmsg
)
4251 struct devlink_fmsg_item
*item
, *tmp
;
4253 list_for_each_entry_safe(item
, tmp
, &fmsg
->item_list
, list
) {
4254 list_del(&item
->list
);
4260 static int devlink_fmsg_nest_common(struct devlink_fmsg
*fmsg
,
4263 struct devlink_fmsg_item
*item
;
4265 item
= kzalloc(sizeof(*item
), GFP_KERNEL
);
4269 item
->attrtype
= attrtype
;
4270 list_add_tail(&item
->list
, &fmsg
->item_list
);
4275 int devlink_fmsg_obj_nest_start(struct devlink_fmsg
*fmsg
)
4277 return devlink_fmsg_nest_common(fmsg
, DEVLINK_ATTR_FMSG_OBJ_NEST_START
);
4279 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start
);
4281 static int devlink_fmsg_nest_end(struct devlink_fmsg
*fmsg
)
4283 return devlink_fmsg_nest_common(fmsg
, DEVLINK_ATTR_FMSG_NEST_END
);
4286 int devlink_fmsg_obj_nest_end(struct devlink_fmsg
*fmsg
)
4288 return devlink_fmsg_nest_end(fmsg
);
4290 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end
);
4292 #define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN)
4294 static int devlink_fmsg_put_name(struct devlink_fmsg
*fmsg
, const char *name
)
4296 struct devlink_fmsg_item
*item
;
4298 if (strlen(name
) + 1 > DEVLINK_FMSG_MAX_SIZE
)
4301 item
= kzalloc(sizeof(*item
) + strlen(name
) + 1, GFP_KERNEL
);
4305 item
->nla_type
= NLA_NUL_STRING
;
4306 item
->len
= strlen(name
) + 1;
4307 item
->attrtype
= DEVLINK_ATTR_FMSG_OBJ_NAME
;
4308 memcpy(&item
->value
, name
, item
->len
);
4309 list_add_tail(&item
->list
, &fmsg
->item_list
);
4314 int devlink_fmsg_pair_nest_start(struct devlink_fmsg
*fmsg
, const char *name
)
4318 err
= devlink_fmsg_nest_common(fmsg
, DEVLINK_ATTR_FMSG_PAIR_NEST_START
);
4322 err
= devlink_fmsg_put_name(fmsg
, name
);
4328 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start
);
4330 int devlink_fmsg_pair_nest_end(struct devlink_fmsg
*fmsg
)
4332 return devlink_fmsg_nest_end(fmsg
);
4334 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end
);
4336 int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg
*fmsg
,
4341 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
4345 err
= devlink_fmsg_nest_common(fmsg
, DEVLINK_ATTR_FMSG_ARR_NEST_START
);
4351 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start
);
4353 int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg
*fmsg
)
4357 err
= devlink_fmsg_nest_end(fmsg
);
4361 err
= devlink_fmsg_nest_end(fmsg
);
4367 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end
);
4369 static int devlink_fmsg_put_value(struct devlink_fmsg
*fmsg
,
4370 const void *value
, u16 value_len
,
4373 struct devlink_fmsg_item
*item
;
4375 if (value_len
> DEVLINK_FMSG_MAX_SIZE
)
4378 item
= kzalloc(sizeof(*item
) + value_len
, GFP_KERNEL
);
4382 item
->nla_type
= value_nla_type
;
4383 item
->len
= value_len
;
4384 item
->attrtype
= DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA
;
4385 memcpy(&item
->value
, value
, item
->len
);
4386 list_add_tail(&item
->list
, &fmsg
->item_list
);
4391 int devlink_fmsg_bool_put(struct devlink_fmsg
*fmsg
, bool value
)
4393 return devlink_fmsg_put_value(fmsg
, &value
, sizeof(value
), NLA_FLAG
);
4395 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_put
);
4397 int devlink_fmsg_u8_put(struct devlink_fmsg
*fmsg
, u8 value
)
4399 return devlink_fmsg_put_value(fmsg
, &value
, sizeof(value
), NLA_U8
);
4401 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_put
);
4403 int devlink_fmsg_u32_put(struct devlink_fmsg
*fmsg
, u32 value
)
4405 return devlink_fmsg_put_value(fmsg
, &value
, sizeof(value
), NLA_U32
);
4407 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put
);
4409 int devlink_fmsg_u64_put(struct devlink_fmsg
*fmsg
, u64 value
)
4411 return devlink_fmsg_put_value(fmsg
, &value
, sizeof(value
), NLA_U64
);
4413 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_put
);
4415 int devlink_fmsg_string_put(struct devlink_fmsg
*fmsg
, const char *value
)
4417 return devlink_fmsg_put_value(fmsg
, value
, strlen(value
) + 1,
4420 EXPORT_SYMBOL_GPL(devlink_fmsg_string_put
);
4422 static int devlink_fmsg_binary_put(struct devlink_fmsg
*fmsg
, const void *value
,
4425 return devlink_fmsg_put_value(fmsg
, value
, value_len
, NLA_BINARY
);
4428 int devlink_fmsg_bool_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
4433 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
4437 err
= devlink_fmsg_bool_put(fmsg
, value
);
4441 err
= devlink_fmsg_pair_nest_end(fmsg
);
4447 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put
);
4449 int devlink_fmsg_u8_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
4454 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
4458 err
= devlink_fmsg_u8_put(fmsg
, value
);
4462 err
= devlink_fmsg_pair_nest_end(fmsg
);
4468 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put
);
4470 int devlink_fmsg_u32_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
4475 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
4479 err
= devlink_fmsg_u32_put(fmsg
, value
);
4483 err
= devlink_fmsg_pair_nest_end(fmsg
);
4489 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put
);
4491 int devlink_fmsg_u64_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
4496 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
4500 err
= devlink_fmsg_u64_put(fmsg
, value
);
4504 err
= devlink_fmsg_pair_nest_end(fmsg
);
4510 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put
);
4512 int devlink_fmsg_string_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
4517 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
4521 err
= devlink_fmsg_string_put(fmsg
, value
);
4525 err
= devlink_fmsg_pair_nest_end(fmsg
);
4531 EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put
);
4533 int devlink_fmsg_binary_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
4534 const void *value
, u32 value_len
)
4540 err
= devlink_fmsg_arr_pair_nest_start(fmsg
, name
);
4544 for (offset
= 0; offset
< value_len
; offset
+= data_size
) {
4545 data_size
= value_len
- offset
;
4546 if (data_size
> DEVLINK_FMSG_MAX_SIZE
)
4547 data_size
= DEVLINK_FMSG_MAX_SIZE
;
4548 err
= devlink_fmsg_binary_put(fmsg
, value
+ offset
, data_size
);
4553 err
= devlink_fmsg_arr_pair_nest_end(fmsg
);
4559 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put
);
4562 devlink_fmsg_item_fill_type(struct devlink_fmsg_item
*msg
, struct sk_buff
*skb
)
4564 switch (msg
->nla_type
) {
4569 case NLA_NUL_STRING
:
4571 return nla_put_u8(skb
, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE
,
4579 devlink_fmsg_item_fill_data(struct devlink_fmsg_item
*msg
, struct sk_buff
*skb
)
4581 int attrtype
= DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA
;
4584 switch (msg
->nla_type
) {
4586 /* Always provide flag data, regardless of its value */
4587 tmp
= *(bool *) msg
->value
;
4589 return nla_put_u8(skb
, attrtype
, tmp
);
4591 return nla_put_u8(skb
, attrtype
, *(u8
*) msg
->value
);
4593 return nla_put_u32(skb
, attrtype
, *(u32
*) msg
->value
);
4595 return nla_put_u64_64bit(skb
, attrtype
, *(u64
*) msg
->value
,
4597 case NLA_NUL_STRING
:
4598 return nla_put_string(skb
, attrtype
, (char *) &msg
->value
);
4600 return nla_put(skb
, attrtype
, msg
->len
, (void *) &msg
->value
);
4607 devlink_fmsg_prepare_skb(struct devlink_fmsg
*fmsg
, struct sk_buff
*skb
,
4610 struct devlink_fmsg_item
*item
;
4611 struct nlattr
*fmsg_nlattr
;
4615 fmsg_nlattr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_FMSG
);
4619 list_for_each_entry(item
, &fmsg
->item_list
, list
) {
4625 switch (item
->attrtype
) {
4626 case DEVLINK_ATTR_FMSG_OBJ_NEST_START
:
4627 case DEVLINK_ATTR_FMSG_PAIR_NEST_START
:
4628 case DEVLINK_ATTR_FMSG_ARR_NEST_START
:
4629 case DEVLINK_ATTR_FMSG_NEST_END
:
4630 err
= nla_put_flag(skb
, item
->attrtype
);
4632 case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA
:
4633 err
= devlink_fmsg_item_fill_type(item
, skb
);
4636 err
= devlink_fmsg_item_fill_data(item
, skb
);
4638 case DEVLINK_ATTR_FMSG_OBJ_NAME
:
4639 err
= nla_put_string(skb
, item
->attrtype
,
4640 (char *) &item
->value
);
4652 nla_nest_end(skb
, fmsg_nlattr
);
4656 static int devlink_fmsg_snd(struct devlink_fmsg
*fmsg
,
4657 struct genl_info
*info
,
4658 enum devlink_command cmd
, int flags
)
4660 struct nlmsghdr
*nlh
;
4661 struct sk_buff
*skb
;
4668 int tmp_index
= index
;
4670 skb
= genlmsg_new(GENLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
4674 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
4675 &devlink_nl_family
, flags
| NLM_F_MULTI
, cmd
);
4678 goto nla_put_failure
;
4681 err
= devlink_fmsg_prepare_skb(fmsg
, skb
, &index
);
4684 else if (err
!= -EMSGSIZE
|| tmp_index
== index
)
4685 goto nla_put_failure
;
4687 genlmsg_end(skb
, hdr
);
4688 err
= genlmsg_reply(skb
, info
);
4693 skb
= genlmsg_new(GENLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
4696 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
4697 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
4700 goto nla_put_failure
;
4703 return genlmsg_reply(skb
, info
);
4710 static int devlink_fmsg_dumpit(struct devlink_fmsg
*fmsg
, struct sk_buff
*skb
,
4711 struct netlink_callback
*cb
,
4712 enum devlink_command cmd
)
4714 int index
= cb
->args
[0];
4715 int tmp_index
= index
;
4719 hdr
= genlmsg_put(skb
, NETLINK_CB(cb
->skb
).portid
, cb
->nlh
->nlmsg_seq
,
4720 &devlink_nl_family
, NLM_F_ACK
| NLM_F_MULTI
, cmd
);
4723 goto nla_put_failure
;
4726 err
= devlink_fmsg_prepare_skb(fmsg
, skb
, &index
);
4727 if ((err
&& err
!= -EMSGSIZE
) || tmp_index
== index
)
4728 goto nla_put_failure
;
4730 cb
->args
[0] = index
;
4731 genlmsg_end(skb
, hdr
);
4735 genlmsg_cancel(skb
, hdr
);
4739 struct devlink_health_reporter
{
4740 struct list_head list
;
4742 const struct devlink_health_reporter_ops
*ops
;
4743 struct devlink
*devlink
;
4744 struct devlink_fmsg
*dump_fmsg
;
4745 struct mutex dump_lock
; /* lock parallel read/write from dump buffers */
4746 u64 graceful_period
;
4753 u64 last_recovery_ts
;
4754 refcount_t refcount
;
4758 devlink_health_reporter_priv(struct devlink_health_reporter
*reporter
)
4760 return reporter
->priv
;
4762 EXPORT_SYMBOL_GPL(devlink_health_reporter_priv
);
4764 static struct devlink_health_reporter
*
4765 devlink_health_reporter_find_by_name(struct devlink
*devlink
,
4766 const char *reporter_name
)
4768 struct devlink_health_reporter
*reporter
;
4770 lockdep_assert_held(&devlink
->reporters_lock
);
4771 list_for_each_entry(reporter
, &devlink
->reporter_list
, list
)
4772 if (!strcmp(reporter
->ops
->name
, reporter_name
))
4778 * devlink_health_reporter_create - create devlink health reporter
4782 * @graceful_period: to avoid recovery loops, in msecs
4783 * @auto_recover: auto recover when error occurs
4786 struct devlink_health_reporter
*
4787 devlink_health_reporter_create(struct devlink
*devlink
,
4788 const struct devlink_health_reporter_ops
*ops
,
4789 u64 graceful_period
, bool auto_recover
,
4792 struct devlink_health_reporter
*reporter
;
4794 mutex_lock(&devlink
->reporters_lock
);
4795 if (devlink_health_reporter_find_by_name(devlink
, ops
->name
)) {
4796 reporter
= ERR_PTR(-EEXIST
);
4800 if (WARN_ON(auto_recover
&& !ops
->recover
) ||
4801 WARN_ON(graceful_period
&& !ops
->recover
)) {
4802 reporter
= ERR_PTR(-EINVAL
);
4806 reporter
= kzalloc(sizeof(*reporter
), GFP_KERNEL
);
4808 reporter
= ERR_PTR(-ENOMEM
);
4812 reporter
->priv
= priv
;
4813 reporter
->ops
= ops
;
4814 reporter
->devlink
= devlink
;
4815 reporter
->graceful_period
= graceful_period
;
4816 reporter
->auto_recover
= auto_recover
;
4817 mutex_init(&reporter
->dump_lock
);
4818 refcount_set(&reporter
->refcount
, 1);
4819 list_add_tail(&reporter
->list
, &devlink
->reporter_list
);
4821 mutex_unlock(&devlink
->reporters_lock
);
4824 EXPORT_SYMBOL_GPL(devlink_health_reporter_create
);
4827 * devlink_health_reporter_destroy - destroy devlink health reporter
4829 * @reporter: devlink health reporter to destroy
4832 devlink_health_reporter_destroy(struct devlink_health_reporter
*reporter
)
4834 mutex_lock(&reporter
->devlink
->reporters_lock
);
4835 list_del(&reporter
->list
);
4836 mutex_unlock(&reporter
->devlink
->reporters_lock
);
4837 while (refcount_read(&reporter
->refcount
) > 1)
4839 mutex_destroy(&reporter
->dump_lock
);
4840 if (reporter
->dump_fmsg
)
4841 devlink_fmsg_free(reporter
->dump_fmsg
);
4844 EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy
);
4847 devlink_health_reporter_state_update(struct devlink_health_reporter
*reporter
,
4848 enum devlink_health_reporter_state state
)
4850 if (WARN_ON(state
!= DEVLINK_HEALTH_REPORTER_STATE_HEALTHY
&&
4851 state
!= DEVLINK_HEALTH_REPORTER_STATE_ERROR
))
4854 if (reporter
->health_state
== state
)
4857 reporter
->health_state
= state
;
4858 trace_devlink_health_reporter_state_update(reporter
->devlink
,
4859 reporter
->ops
->name
, state
);
4861 EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update
);
4864 devlink_health_reporter_recover(struct devlink_health_reporter
*reporter
,
4865 void *priv_ctx
, struct netlink_ext_ack
*extack
)
4869 if (reporter
->health_state
== DEVLINK_HEALTH_REPORTER_STATE_HEALTHY
)
4872 if (!reporter
->ops
->recover
)
4875 err
= reporter
->ops
->recover(reporter
, priv_ctx
, extack
);
4879 reporter
->recovery_count
++;
4880 reporter
->health_state
= DEVLINK_HEALTH_REPORTER_STATE_HEALTHY
;
4881 reporter
->last_recovery_ts
= jiffies
;
4887 devlink_health_dump_clear(struct devlink_health_reporter
*reporter
)
4889 if (!reporter
->dump_fmsg
)
4891 devlink_fmsg_free(reporter
->dump_fmsg
);
4892 reporter
->dump_fmsg
= NULL
;
4895 static int devlink_health_do_dump(struct devlink_health_reporter
*reporter
,
4897 struct netlink_ext_ack
*extack
)
4901 if (!reporter
->ops
->dump
)
4904 if (reporter
->dump_fmsg
)
4907 reporter
->dump_fmsg
= devlink_fmsg_alloc();
4908 if (!reporter
->dump_fmsg
) {
4913 err
= devlink_fmsg_obj_nest_start(reporter
->dump_fmsg
);
4917 err
= reporter
->ops
->dump(reporter
, reporter
->dump_fmsg
,
4922 err
= devlink_fmsg_obj_nest_end(reporter
->dump_fmsg
);
4926 reporter
->dump_ts
= jiffies
;
4927 reporter
->dump_real_ts
= ktime_get_real_ns();
4932 devlink_health_dump_clear(reporter
);
4936 int devlink_health_report(struct devlink_health_reporter
*reporter
,
4937 const char *msg
, void *priv_ctx
)
4939 enum devlink_health_reporter_state prev_health_state
;
4940 struct devlink
*devlink
= reporter
->devlink
;
4942 /* write a log message of the current error */
4944 trace_devlink_health_report(devlink
, reporter
->ops
->name
, msg
);
4945 reporter
->error_count
++;
4946 prev_health_state
= reporter
->health_state
;
4947 reporter
->health_state
= DEVLINK_HEALTH_REPORTER_STATE_ERROR
;
4949 /* abort if the previous error wasn't recovered */
4950 if (reporter
->auto_recover
&&
4951 (prev_health_state
!= DEVLINK_HEALTH_REPORTER_STATE_HEALTHY
||
4952 jiffies
- reporter
->last_recovery_ts
<
4953 msecs_to_jiffies(reporter
->graceful_period
))) {
4954 trace_devlink_health_recover_aborted(devlink
,
4955 reporter
->ops
->name
,
4956 reporter
->health_state
,
4958 reporter
->last_recovery_ts
);
4962 reporter
->health_state
= DEVLINK_HEALTH_REPORTER_STATE_ERROR
;
4964 mutex_lock(&reporter
->dump_lock
);
4965 /* store current dump of current error, for later analysis */
4966 devlink_health_do_dump(reporter
, priv_ctx
, NULL
);
4967 mutex_unlock(&reporter
->dump_lock
);
4969 if (reporter
->auto_recover
)
4970 return devlink_health_reporter_recover(reporter
,
4975 EXPORT_SYMBOL_GPL(devlink_health_report
);
4977 static struct devlink_health_reporter
*
4978 devlink_health_reporter_get_from_attrs(struct devlink
*devlink
,
4979 struct nlattr
**attrs
)
4981 struct devlink_health_reporter
*reporter
;
4982 char *reporter_name
;
4984 if (!attrs
[DEVLINK_ATTR_HEALTH_REPORTER_NAME
])
4987 reporter_name
= nla_data(attrs
[DEVLINK_ATTR_HEALTH_REPORTER_NAME
]);
4988 mutex_lock(&devlink
->reporters_lock
);
4989 reporter
= devlink_health_reporter_find_by_name(devlink
, reporter_name
);
4991 refcount_inc(&reporter
->refcount
);
4992 mutex_unlock(&devlink
->reporters_lock
);
4996 static struct devlink_health_reporter
*
4997 devlink_health_reporter_get_from_info(struct devlink
*devlink
,
4998 struct genl_info
*info
)
5000 return devlink_health_reporter_get_from_attrs(devlink
, info
->attrs
);
5003 static struct devlink_health_reporter
*
5004 devlink_health_reporter_get_from_cb(struct netlink_callback
*cb
)
5006 const struct genl_dumpit_info
*info
= genl_dumpit_info(cb
);
5007 struct devlink_health_reporter
*reporter
;
5008 struct nlattr
**attrs
= info
->attrs
;
5009 struct devlink
*devlink
;
5011 mutex_lock(&devlink_mutex
);
5012 devlink
= devlink_get_from_attrs(sock_net(cb
->skb
->sk
), attrs
);
5013 if (IS_ERR(devlink
))
5016 reporter
= devlink_health_reporter_get_from_attrs(devlink
, attrs
);
5017 mutex_unlock(&devlink_mutex
);
5020 mutex_unlock(&devlink_mutex
);
5025 devlink_health_reporter_put(struct devlink_health_reporter
*reporter
)
5027 refcount_dec(&reporter
->refcount
);
5031 devlink_nl_health_reporter_fill(struct sk_buff
*msg
,
5032 struct devlink
*devlink
,
5033 struct devlink_health_reporter
*reporter
,
5034 enum devlink_command cmd
, u32 portid
,
5037 struct nlattr
*reporter_attr
;
5040 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
5044 if (devlink_nl_put_handle(msg
, devlink
))
5045 goto genlmsg_cancel
;
5047 reporter_attr
= nla_nest_start_noflag(msg
,
5048 DEVLINK_ATTR_HEALTH_REPORTER
);
5050 goto genlmsg_cancel
;
5051 if (nla_put_string(msg
, DEVLINK_ATTR_HEALTH_REPORTER_NAME
,
5052 reporter
->ops
->name
))
5053 goto reporter_nest_cancel
;
5054 if (nla_put_u8(msg
, DEVLINK_ATTR_HEALTH_REPORTER_STATE
,
5055 reporter
->health_state
))
5056 goto reporter_nest_cancel
;
5057 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT
,
5058 reporter
->error_count
, DEVLINK_ATTR_PAD
))
5059 goto reporter_nest_cancel
;
5060 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT
,
5061 reporter
->recovery_count
, DEVLINK_ATTR_PAD
))
5062 goto reporter_nest_cancel
;
5063 if (reporter
->ops
->recover
&&
5064 nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
,
5065 reporter
->graceful_period
,
5067 goto reporter_nest_cancel
;
5068 if (reporter
->ops
->recover
&&
5069 nla_put_u8(msg
, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
,
5070 reporter
->auto_recover
))
5071 goto reporter_nest_cancel
;
5072 if (reporter
->dump_fmsg
&&
5073 nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS
,
5074 jiffies_to_msecs(reporter
->dump_ts
),
5076 goto reporter_nest_cancel
;
5077 if (reporter
->dump_fmsg
&&
5078 nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS
,
5079 reporter
->dump_real_ts
, DEVLINK_ATTR_PAD
))
5080 goto reporter_nest_cancel
;
5082 nla_nest_end(msg
, reporter_attr
);
5083 genlmsg_end(msg
, hdr
);
5086 reporter_nest_cancel
:
5087 nla_nest_end(msg
, reporter_attr
);
5089 genlmsg_cancel(msg
, hdr
);
5093 static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff
*skb
,
5094 struct genl_info
*info
)
5096 struct devlink
*devlink
= info
->user_ptr
[0];
5097 struct devlink_health_reporter
*reporter
;
5098 struct sk_buff
*msg
;
5101 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5105 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
5111 err
= devlink_nl_health_reporter_fill(msg
, devlink
, reporter
,
5112 DEVLINK_CMD_HEALTH_REPORTER_GET
,
5113 info
->snd_portid
, info
->snd_seq
,
5120 err
= genlmsg_reply(msg
, info
);
5122 devlink_health_reporter_put(reporter
);
5127 devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff
*msg
,
5128 struct netlink_callback
*cb
)
5130 struct devlink_health_reporter
*reporter
;
5131 struct devlink
*devlink
;
5132 int start
= cb
->args
[0];
5136 mutex_lock(&devlink_mutex
);
5137 list_for_each_entry(devlink
, &devlink_list
, list
) {
5138 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
5140 mutex_lock(&devlink
->reporters_lock
);
5141 list_for_each_entry(reporter
, &devlink
->reporter_list
,
5147 err
= devlink_nl_health_reporter_fill(msg
, devlink
,
5149 DEVLINK_CMD_HEALTH_REPORTER_GET
,
5150 NETLINK_CB(cb
->skb
).portid
,
5154 mutex_unlock(&devlink
->reporters_lock
);
5159 mutex_unlock(&devlink
->reporters_lock
);
5162 mutex_unlock(&devlink_mutex
);
5169 devlink_nl_cmd_health_reporter_set_doit(struct sk_buff
*skb
,
5170 struct genl_info
*info
)
5172 struct devlink
*devlink
= info
->user_ptr
[0];
5173 struct devlink_health_reporter
*reporter
;
5176 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5180 if (!reporter
->ops
->recover
&&
5181 (info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
] ||
5182 info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
])) {
5187 if (info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
])
5188 reporter
->graceful_period
=
5189 nla_get_u64(info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
]);
5191 if (info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
])
5192 reporter
->auto_recover
=
5193 nla_get_u8(info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
]);
5195 devlink_health_reporter_put(reporter
);
5198 devlink_health_reporter_put(reporter
);
5202 static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff
*skb
,
5203 struct genl_info
*info
)
5205 struct devlink
*devlink
= info
->user_ptr
[0];
5206 struct devlink_health_reporter
*reporter
;
5209 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5213 err
= devlink_health_reporter_recover(reporter
, NULL
, info
->extack
);
5215 devlink_health_reporter_put(reporter
);
5219 static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff
*skb
,
5220 struct genl_info
*info
)
5222 struct devlink
*devlink
= info
->user_ptr
[0];
5223 struct devlink_health_reporter
*reporter
;
5224 struct devlink_fmsg
*fmsg
;
5227 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5231 if (!reporter
->ops
->diagnose
) {
5232 devlink_health_reporter_put(reporter
);
5236 fmsg
= devlink_fmsg_alloc();
5238 devlink_health_reporter_put(reporter
);
5242 err
= devlink_fmsg_obj_nest_start(fmsg
);
5246 err
= reporter
->ops
->diagnose(reporter
, fmsg
, info
->extack
);
5250 err
= devlink_fmsg_obj_nest_end(fmsg
);
5254 err
= devlink_fmsg_snd(fmsg
, info
,
5255 DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE
, 0);
5258 devlink_fmsg_free(fmsg
);
5259 devlink_health_reporter_put(reporter
);
5264 devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff
*skb
,
5265 struct netlink_callback
*cb
)
5267 struct devlink_health_reporter
*reporter
;
5268 u64 start
= cb
->args
[0];
5271 reporter
= devlink_health_reporter_get_from_cb(cb
);
5275 if (!reporter
->ops
->dump
) {
5279 mutex_lock(&reporter
->dump_lock
);
5281 err
= devlink_health_do_dump(reporter
, NULL
, cb
->extack
);
5284 cb
->args
[1] = reporter
->dump_ts
;
5286 if (!reporter
->dump_fmsg
|| cb
->args
[1] != reporter
->dump_ts
) {
5287 NL_SET_ERR_MSG_MOD(cb
->extack
, "Dump trampled, please retry");
5292 err
= devlink_fmsg_dumpit(reporter
->dump_fmsg
, skb
, cb
,
5293 DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET
);
5295 mutex_unlock(&reporter
->dump_lock
);
5297 devlink_health_reporter_put(reporter
);
5302 devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff
*skb
,
5303 struct genl_info
*info
)
5305 struct devlink
*devlink
= info
->user_ptr
[0];
5306 struct devlink_health_reporter
*reporter
;
5308 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5312 if (!reporter
->ops
->dump
) {
5313 devlink_health_reporter_put(reporter
);
5317 mutex_lock(&reporter
->dump_lock
);
5318 devlink_health_dump_clear(reporter
);
5319 mutex_unlock(&reporter
->dump_lock
);
5320 devlink_health_reporter_put(reporter
);
5324 struct devlink_stats
{
5327 struct u64_stats_sync syncp
;
5331 * struct devlink_trap_group_item - Packet trap group attributes.
5332 * @group: Immutable packet trap group attributes.
5333 * @refcount: Number of trap items using the group.
5334 * @list: trap_group_list member.
5335 * @stats: Trap group statistics.
5337 * Describes packet trap group attributes. Created by devlink during trap
5340 struct devlink_trap_group_item
{
5341 const struct devlink_trap_group
*group
;
5342 refcount_t refcount
;
5343 struct list_head list
;
5344 struct devlink_stats __percpu
*stats
;
5348 * struct devlink_trap_item - Packet trap attributes.
5349 * @trap: Immutable packet trap attributes.
5350 * @group_item: Associated group item.
5351 * @list: trap_list member.
5352 * @action: Trap action.
5353 * @stats: Trap statistics.
5354 * @priv: Driver private information.
5356 * Describes both mutable and immutable packet trap attributes. Created by
5357 * devlink during trap registration and used for all trap related operations.
5359 struct devlink_trap_item
{
5360 const struct devlink_trap
*trap
;
5361 struct devlink_trap_group_item
*group_item
;
5362 struct list_head list
;
5363 enum devlink_trap_action action
;
5364 struct devlink_stats __percpu
*stats
;
5368 static struct devlink_trap_item
*
5369 devlink_trap_item_lookup(struct devlink
*devlink
, const char *name
)
5371 struct devlink_trap_item
*trap_item
;
5373 list_for_each_entry(trap_item
, &devlink
->trap_list
, list
) {
5374 if (!strcmp(trap_item
->trap
->name
, name
))
5381 static struct devlink_trap_item
*
5382 devlink_trap_item_get_from_info(struct devlink
*devlink
,
5383 struct genl_info
*info
)
5385 struct nlattr
*attr
;
5387 if (!info
->attrs
[DEVLINK_ATTR_TRAP_NAME
])
5389 attr
= info
->attrs
[DEVLINK_ATTR_TRAP_NAME
];
5391 return devlink_trap_item_lookup(devlink
, nla_data(attr
));
5395 devlink_trap_action_get_from_info(struct genl_info
*info
,
5396 enum devlink_trap_action
*p_trap_action
)
5400 val
= nla_get_u8(info
->attrs
[DEVLINK_ATTR_TRAP_ACTION
]);
5402 case DEVLINK_TRAP_ACTION_DROP
: /* fall-through */
5403 case DEVLINK_TRAP_ACTION_TRAP
:
5404 *p_trap_action
= val
;
5413 static int devlink_trap_metadata_put(struct sk_buff
*msg
,
5414 const struct devlink_trap
*trap
)
5416 struct nlattr
*attr
;
5418 attr
= nla_nest_start(msg
, DEVLINK_ATTR_TRAP_METADATA
);
5422 if ((trap
->metadata_cap
& DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT
) &&
5423 nla_put_flag(msg
, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT
))
5424 goto nla_put_failure
;
5426 nla_nest_end(msg
, attr
);
5431 nla_nest_cancel(msg
, attr
);
5435 static void devlink_trap_stats_read(struct devlink_stats __percpu
*trap_stats
,
5436 struct devlink_stats
*stats
)
5440 memset(stats
, 0, sizeof(*stats
));
5441 for_each_possible_cpu(i
) {
5442 struct devlink_stats
*cpu_stats
;
5443 u64 rx_packets
, rx_bytes
;
5446 cpu_stats
= per_cpu_ptr(trap_stats
, i
);
5448 start
= u64_stats_fetch_begin_irq(&cpu_stats
->syncp
);
5449 rx_packets
= cpu_stats
->rx_packets
;
5450 rx_bytes
= cpu_stats
->rx_bytes
;
5451 } while (u64_stats_fetch_retry_irq(&cpu_stats
->syncp
, start
));
5453 stats
->rx_packets
+= rx_packets
;
5454 stats
->rx_bytes
+= rx_bytes
;
5458 static int devlink_trap_stats_put(struct sk_buff
*msg
,
5459 struct devlink_stats __percpu
*trap_stats
)
5461 struct devlink_stats stats
;
5462 struct nlattr
*attr
;
5464 devlink_trap_stats_read(trap_stats
, &stats
);
5466 attr
= nla_nest_start(msg
, DEVLINK_ATTR_STATS
);
5470 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_STATS_RX_PACKETS
,
5471 stats
.rx_packets
, DEVLINK_ATTR_PAD
))
5472 goto nla_put_failure
;
5474 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_STATS_RX_BYTES
,
5475 stats
.rx_bytes
, DEVLINK_ATTR_PAD
))
5476 goto nla_put_failure
;
5478 nla_nest_end(msg
, attr
);
5483 nla_nest_cancel(msg
, attr
);
5487 static int devlink_nl_trap_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
5488 const struct devlink_trap_item
*trap_item
,
5489 enum devlink_command cmd
, u32 portid
, u32 seq
,
5492 struct devlink_trap_group_item
*group_item
= trap_item
->group_item
;
5496 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
5500 if (devlink_nl_put_handle(msg
, devlink
))
5501 goto nla_put_failure
;
5503 if (nla_put_string(msg
, DEVLINK_ATTR_TRAP_GROUP_NAME
,
5504 group_item
->group
->name
))
5505 goto nla_put_failure
;
5507 if (nla_put_string(msg
, DEVLINK_ATTR_TRAP_NAME
, trap_item
->trap
->name
))
5508 goto nla_put_failure
;
5510 if (nla_put_u8(msg
, DEVLINK_ATTR_TRAP_TYPE
, trap_item
->trap
->type
))
5511 goto nla_put_failure
;
5513 if (trap_item
->trap
->generic
&&
5514 nla_put_flag(msg
, DEVLINK_ATTR_TRAP_GENERIC
))
5515 goto nla_put_failure
;
5517 if (nla_put_u8(msg
, DEVLINK_ATTR_TRAP_ACTION
, trap_item
->action
))
5518 goto nla_put_failure
;
5520 err
= devlink_trap_metadata_put(msg
, trap_item
->trap
);
5522 goto nla_put_failure
;
5524 err
= devlink_trap_stats_put(msg
, trap_item
->stats
);
5526 goto nla_put_failure
;
5528 genlmsg_end(msg
, hdr
);
5533 genlmsg_cancel(msg
, hdr
);
5537 static int devlink_nl_cmd_trap_get_doit(struct sk_buff
*skb
,
5538 struct genl_info
*info
)
5540 struct netlink_ext_ack
*extack
= info
->extack
;
5541 struct devlink
*devlink
= info
->user_ptr
[0];
5542 struct devlink_trap_item
*trap_item
;
5543 struct sk_buff
*msg
;
5546 if (list_empty(&devlink
->trap_list
))
5549 trap_item
= devlink_trap_item_get_from_info(devlink
, info
);
5551 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap");
5555 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
5559 err
= devlink_nl_trap_fill(msg
, devlink
, trap_item
,
5560 DEVLINK_CMD_TRAP_NEW
, info
->snd_portid
,
5565 return genlmsg_reply(msg
, info
);
5572 static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff
*msg
,
5573 struct netlink_callback
*cb
)
5575 struct devlink_trap_item
*trap_item
;
5576 struct devlink
*devlink
;
5577 int start
= cb
->args
[0];
5581 mutex_lock(&devlink_mutex
);
5582 list_for_each_entry(devlink
, &devlink_list
, list
) {
5583 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
5585 mutex_lock(&devlink
->lock
);
5586 list_for_each_entry(trap_item
, &devlink
->trap_list
, list
) {
5591 err
= devlink_nl_trap_fill(msg
, devlink
, trap_item
,
5592 DEVLINK_CMD_TRAP_NEW
,
5593 NETLINK_CB(cb
->skb
).portid
,
5597 mutex_unlock(&devlink
->lock
);
5602 mutex_unlock(&devlink
->lock
);
5605 mutex_unlock(&devlink_mutex
);
5611 static int __devlink_trap_action_set(struct devlink
*devlink
,
5612 struct devlink_trap_item
*trap_item
,
5613 enum devlink_trap_action trap_action
,
5614 struct netlink_ext_ack
*extack
)
5618 if (trap_item
->action
!= trap_action
&&
5619 trap_item
->trap
->type
!= DEVLINK_TRAP_TYPE_DROP
) {
5620 NL_SET_ERR_MSG_MOD(extack
, "Cannot change action of non-drop traps. Skipping");
5624 err
= devlink
->ops
->trap_action_set(devlink
, trap_item
->trap
,
5629 trap_item
->action
= trap_action
;
5634 static int devlink_trap_action_set(struct devlink
*devlink
,
5635 struct devlink_trap_item
*trap_item
,
5636 struct genl_info
*info
)
5638 enum devlink_trap_action trap_action
;
5641 if (!info
->attrs
[DEVLINK_ATTR_TRAP_ACTION
])
5644 err
= devlink_trap_action_get_from_info(info
, &trap_action
);
5646 NL_SET_ERR_MSG_MOD(info
->extack
, "Invalid trap action");
5650 return __devlink_trap_action_set(devlink
, trap_item
, trap_action
,
5654 static int devlink_nl_cmd_trap_set_doit(struct sk_buff
*skb
,
5655 struct genl_info
*info
)
5657 struct netlink_ext_ack
*extack
= info
->extack
;
5658 struct devlink
*devlink
= info
->user_ptr
[0];
5659 struct devlink_trap_item
*trap_item
;
5662 if (list_empty(&devlink
->trap_list
))
5665 trap_item
= devlink_trap_item_get_from_info(devlink
, info
);
5667 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap");
5671 err
= devlink_trap_action_set(devlink
, trap_item
, info
);
5678 static struct devlink_trap_group_item
*
5679 devlink_trap_group_item_lookup(struct devlink
*devlink
, const char *name
)
5681 struct devlink_trap_group_item
*group_item
;
5683 list_for_each_entry(group_item
, &devlink
->trap_group_list
, list
) {
5684 if (!strcmp(group_item
->group
->name
, name
))
5691 static struct devlink_trap_group_item
*
5692 devlink_trap_group_item_get_from_info(struct devlink
*devlink
,
5693 struct genl_info
*info
)
5697 if (!info
->attrs
[DEVLINK_ATTR_TRAP_GROUP_NAME
])
5699 name
= nla_data(info
->attrs
[DEVLINK_ATTR_TRAP_GROUP_NAME
]);
5701 return devlink_trap_group_item_lookup(devlink
, name
);
5705 devlink_nl_trap_group_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
5706 const struct devlink_trap_group_item
*group_item
,
5707 enum devlink_command cmd
, u32 portid
, u32 seq
,
5713 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
5717 if (devlink_nl_put_handle(msg
, devlink
))
5718 goto nla_put_failure
;
5720 if (nla_put_string(msg
, DEVLINK_ATTR_TRAP_GROUP_NAME
,
5721 group_item
->group
->name
))
5722 goto nla_put_failure
;
5724 if (group_item
->group
->generic
&&
5725 nla_put_flag(msg
, DEVLINK_ATTR_TRAP_GENERIC
))
5726 goto nla_put_failure
;
5728 err
= devlink_trap_stats_put(msg
, group_item
->stats
);
5730 goto nla_put_failure
;
5732 genlmsg_end(msg
, hdr
);
5737 genlmsg_cancel(msg
, hdr
);
5741 static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff
*skb
,
5742 struct genl_info
*info
)
5744 struct netlink_ext_ack
*extack
= info
->extack
;
5745 struct devlink
*devlink
= info
->user_ptr
[0];
5746 struct devlink_trap_group_item
*group_item
;
5747 struct sk_buff
*msg
;
5750 if (list_empty(&devlink
->trap_group_list
))
5753 group_item
= devlink_trap_group_item_get_from_info(devlink
, info
);
5755 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap group");
5759 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
5763 err
= devlink_nl_trap_group_fill(msg
, devlink
, group_item
,
5764 DEVLINK_CMD_TRAP_GROUP_NEW
,
5765 info
->snd_portid
, info
->snd_seq
, 0);
5767 goto err_trap_group_fill
;
5769 return genlmsg_reply(msg
, info
);
5771 err_trap_group_fill
:
5776 static int devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff
*msg
,
5777 struct netlink_callback
*cb
)
5779 enum devlink_command cmd
= DEVLINK_CMD_TRAP_GROUP_NEW
;
5780 struct devlink_trap_group_item
*group_item
;
5781 u32 portid
= NETLINK_CB(cb
->skb
).portid
;
5782 struct devlink
*devlink
;
5783 int start
= cb
->args
[0];
5787 mutex_lock(&devlink_mutex
);
5788 list_for_each_entry(devlink
, &devlink_list
, list
) {
5789 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
5791 mutex_lock(&devlink
->lock
);
5792 list_for_each_entry(group_item
, &devlink
->trap_group_list
,
5798 err
= devlink_nl_trap_group_fill(msg
, devlink
,
5804 mutex_unlock(&devlink
->lock
);
5809 mutex_unlock(&devlink
->lock
);
5812 mutex_unlock(&devlink_mutex
);
5819 __devlink_trap_group_action_set(struct devlink
*devlink
,
5820 struct devlink_trap_group_item
*group_item
,
5821 enum devlink_trap_action trap_action
,
5822 struct netlink_ext_ack
*extack
)
5824 const char *group_name
= group_item
->group
->name
;
5825 struct devlink_trap_item
*trap_item
;
5828 list_for_each_entry(trap_item
, &devlink
->trap_list
, list
) {
5829 if (strcmp(trap_item
->trap
->group
.name
, group_name
))
5831 err
= __devlink_trap_action_set(devlink
, trap_item
,
5832 trap_action
, extack
);
5841 devlink_trap_group_action_set(struct devlink
*devlink
,
5842 struct devlink_trap_group_item
*group_item
,
5843 struct genl_info
*info
)
5845 enum devlink_trap_action trap_action
;
5848 if (!info
->attrs
[DEVLINK_ATTR_TRAP_ACTION
])
5851 err
= devlink_trap_action_get_from_info(info
, &trap_action
);
5853 NL_SET_ERR_MSG_MOD(info
->extack
, "Invalid trap action");
5857 err
= __devlink_trap_group_action_set(devlink
, group_item
, trap_action
,
5865 static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff
*skb
,
5866 struct genl_info
*info
)
5868 struct netlink_ext_ack
*extack
= info
->extack
;
5869 struct devlink
*devlink
= info
->user_ptr
[0];
5870 struct devlink_trap_group_item
*group_item
;
5873 if (list_empty(&devlink
->trap_group_list
))
5876 group_item
= devlink_trap_group_item_get_from_info(devlink
, info
);
5878 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap group");
5882 err
= devlink_trap_group_action_set(devlink
, group_item
, info
);
5889 static const struct nla_policy devlink_nl_policy
[DEVLINK_ATTR_MAX
+ 1] = {
5890 [DEVLINK_ATTR_BUS_NAME
] = { .type
= NLA_NUL_STRING
},
5891 [DEVLINK_ATTR_DEV_NAME
] = { .type
= NLA_NUL_STRING
},
5892 [DEVLINK_ATTR_PORT_INDEX
] = { .type
= NLA_U32
},
5893 [DEVLINK_ATTR_PORT_TYPE
] = { .type
= NLA_U16
},
5894 [DEVLINK_ATTR_PORT_SPLIT_COUNT
] = { .type
= NLA_U32
},
5895 [DEVLINK_ATTR_SB_INDEX
] = { .type
= NLA_U32
},
5896 [DEVLINK_ATTR_SB_POOL_INDEX
] = { .type
= NLA_U16
},
5897 [DEVLINK_ATTR_SB_POOL_TYPE
] = { .type
= NLA_U8
},
5898 [DEVLINK_ATTR_SB_POOL_SIZE
] = { .type
= NLA_U32
},
5899 [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
] = { .type
= NLA_U8
},
5900 [DEVLINK_ATTR_SB_THRESHOLD
] = { .type
= NLA_U32
},
5901 [DEVLINK_ATTR_SB_TC_INDEX
] = { .type
= NLA_U16
},
5902 [DEVLINK_ATTR_ESWITCH_MODE
] = { .type
= NLA_U16
},
5903 [DEVLINK_ATTR_ESWITCH_INLINE_MODE
] = { .type
= NLA_U8
},
5904 [DEVLINK_ATTR_ESWITCH_ENCAP_MODE
] = { .type
= NLA_U8
},
5905 [DEVLINK_ATTR_DPIPE_TABLE_NAME
] = { .type
= NLA_NUL_STRING
},
5906 [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
] = { .type
= NLA_U8
},
5907 [DEVLINK_ATTR_RESOURCE_ID
] = { .type
= NLA_U64
},
5908 [DEVLINK_ATTR_RESOURCE_SIZE
] = { .type
= NLA_U64
},
5909 [DEVLINK_ATTR_PARAM_NAME
] = { .type
= NLA_NUL_STRING
},
5910 [DEVLINK_ATTR_PARAM_TYPE
] = { .type
= NLA_U8
},
5911 [DEVLINK_ATTR_PARAM_VALUE_CMODE
] = { .type
= NLA_U8
},
5912 [DEVLINK_ATTR_REGION_NAME
] = { .type
= NLA_NUL_STRING
},
5913 [DEVLINK_ATTR_REGION_SNAPSHOT_ID
] = { .type
= NLA_U32
},
5914 [DEVLINK_ATTR_HEALTH_REPORTER_NAME
] = { .type
= NLA_NUL_STRING
},
5915 [DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
] = { .type
= NLA_U64
},
5916 [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
] = { .type
= NLA_U8
},
5917 [DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME
] = { .type
= NLA_NUL_STRING
},
5918 [DEVLINK_ATTR_FLASH_UPDATE_COMPONENT
] = { .type
= NLA_NUL_STRING
},
5919 [DEVLINK_ATTR_TRAP_NAME
] = { .type
= NLA_NUL_STRING
},
5920 [DEVLINK_ATTR_TRAP_ACTION
] = { .type
= NLA_U8
},
5921 [DEVLINK_ATTR_TRAP_GROUP_NAME
] = { .type
= NLA_NUL_STRING
},
5922 [DEVLINK_ATTR_NETNS_PID
] = { .type
= NLA_U32
},
5923 [DEVLINK_ATTR_NETNS_FD
] = { .type
= NLA_U32
},
5924 [DEVLINK_ATTR_NETNS_ID
] = { .type
= NLA_U32
},
5927 static const struct genl_ops devlink_nl_ops
[] = {
5929 .cmd
= DEVLINK_CMD_GET
,
5930 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5931 .doit
= devlink_nl_cmd_get_doit
,
5932 .dumpit
= devlink_nl_cmd_get_dumpit
,
5933 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
5934 /* can be retrieved by unprivileged users */
5937 .cmd
= DEVLINK_CMD_PORT_GET
,
5938 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5939 .doit
= devlink_nl_cmd_port_get_doit
,
5940 .dumpit
= devlink_nl_cmd_port_get_dumpit
,
5941 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
5942 /* can be retrieved by unprivileged users */
5945 .cmd
= DEVLINK_CMD_PORT_SET
,
5946 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5947 .doit
= devlink_nl_cmd_port_set_doit
,
5948 .flags
= GENL_ADMIN_PERM
,
5949 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
5952 .cmd
= DEVLINK_CMD_PORT_SPLIT
,
5953 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5954 .doit
= devlink_nl_cmd_port_split_doit
,
5955 .flags
= GENL_ADMIN_PERM
,
5956 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
5957 DEVLINK_NL_FLAG_NO_LOCK
,
5960 .cmd
= DEVLINK_CMD_PORT_UNSPLIT
,
5961 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5962 .doit
= devlink_nl_cmd_port_unsplit_doit
,
5963 .flags
= GENL_ADMIN_PERM
,
5964 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
5965 DEVLINK_NL_FLAG_NO_LOCK
,
5968 .cmd
= DEVLINK_CMD_SB_GET
,
5969 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5970 .doit
= devlink_nl_cmd_sb_get_doit
,
5971 .dumpit
= devlink_nl_cmd_sb_get_dumpit
,
5972 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
5973 DEVLINK_NL_FLAG_NEED_SB
,
5974 /* can be retrieved by unprivileged users */
5977 .cmd
= DEVLINK_CMD_SB_POOL_GET
,
5978 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5979 .doit
= devlink_nl_cmd_sb_pool_get_doit
,
5980 .dumpit
= devlink_nl_cmd_sb_pool_get_dumpit
,
5981 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
5982 DEVLINK_NL_FLAG_NEED_SB
,
5983 /* can be retrieved by unprivileged users */
5986 .cmd
= DEVLINK_CMD_SB_POOL_SET
,
5987 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5988 .doit
= devlink_nl_cmd_sb_pool_set_doit
,
5989 .flags
= GENL_ADMIN_PERM
,
5990 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
5991 DEVLINK_NL_FLAG_NEED_SB
,
5994 .cmd
= DEVLINK_CMD_SB_PORT_POOL_GET
,
5995 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5996 .doit
= devlink_nl_cmd_sb_port_pool_get_doit
,
5997 .dumpit
= devlink_nl_cmd_sb_port_pool_get_dumpit
,
5998 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
5999 DEVLINK_NL_FLAG_NEED_SB
,
6000 /* can be retrieved by unprivileged users */
6003 .cmd
= DEVLINK_CMD_SB_PORT_POOL_SET
,
6004 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6005 .doit
= devlink_nl_cmd_sb_port_pool_set_doit
,
6006 .flags
= GENL_ADMIN_PERM
,
6007 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
6008 DEVLINK_NL_FLAG_NEED_SB
,
6011 .cmd
= DEVLINK_CMD_SB_TC_POOL_BIND_GET
,
6012 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6013 .doit
= devlink_nl_cmd_sb_tc_pool_bind_get_doit
,
6014 .dumpit
= devlink_nl_cmd_sb_tc_pool_bind_get_dumpit
,
6015 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
6016 DEVLINK_NL_FLAG_NEED_SB
,
6017 /* can be retrieved by unprivileged users */
6020 .cmd
= DEVLINK_CMD_SB_TC_POOL_BIND_SET
,
6021 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6022 .doit
= devlink_nl_cmd_sb_tc_pool_bind_set_doit
,
6023 .flags
= GENL_ADMIN_PERM
,
6024 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
6025 DEVLINK_NL_FLAG_NEED_SB
,
6028 .cmd
= DEVLINK_CMD_SB_OCC_SNAPSHOT
,
6029 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6030 .doit
= devlink_nl_cmd_sb_occ_snapshot_doit
,
6031 .flags
= GENL_ADMIN_PERM
,
6032 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6033 DEVLINK_NL_FLAG_NEED_SB
,
6036 .cmd
= DEVLINK_CMD_SB_OCC_MAX_CLEAR
,
6037 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6038 .doit
= devlink_nl_cmd_sb_occ_max_clear_doit
,
6039 .flags
= GENL_ADMIN_PERM
,
6040 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6041 DEVLINK_NL_FLAG_NEED_SB
,
6044 .cmd
= DEVLINK_CMD_ESWITCH_GET
,
6045 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6046 .doit
= devlink_nl_cmd_eswitch_get_doit
,
6047 .flags
= GENL_ADMIN_PERM
,
6048 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6051 .cmd
= DEVLINK_CMD_ESWITCH_SET
,
6052 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6053 .doit
= devlink_nl_cmd_eswitch_set_doit
,
6054 .flags
= GENL_ADMIN_PERM
,
6055 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6056 DEVLINK_NL_FLAG_NO_LOCK
,
6059 .cmd
= DEVLINK_CMD_DPIPE_TABLE_GET
,
6060 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6061 .doit
= devlink_nl_cmd_dpipe_table_get
,
6062 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6063 /* can be retrieved by unprivileged users */
6066 .cmd
= DEVLINK_CMD_DPIPE_ENTRIES_GET
,
6067 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6068 .doit
= devlink_nl_cmd_dpipe_entries_get
,
6069 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6070 /* can be retrieved by unprivileged users */
6073 .cmd
= DEVLINK_CMD_DPIPE_HEADERS_GET
,
6074 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6075 .doit
= devlink_nl_cmd_dpipe_headers_get
,
6076 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6077 /* can be retrieved by unprivileged users */
6080 .cmd
= DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET
,
6081 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6082 .doit
= devlink_nl_cmd_dpipe_table_counters_set
,
6083 .flags
= GENL_ADMIN_PERM
,
6084 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6087 .cmd
= DEVLINK_CMD_RESOURCE_SET
,
6088 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6089 .doit
= devlink_nl_cmd_resource_set
,
6090 .flags
= GENL_ADMIN_PERM
,
6091 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6094 .cmd
= DEVLINK_CMD_RESOURCE_DUMP
,
6095 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6096 .doit
= devlink_nl_cmd_resource_dump
,
6097 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6098 /* can be retrieved by unprivileged users */
6101 .cmd
= DEVLINK_CMD_RELOAD
,
6102 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6103 .doit
= devlink_nl_cmd_reload
,
6104 .flags
= GENL_ADMIN_PERM
,
6105 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6106 DEVLINK_NL_FLAG_NO_LOCK
,
6109 .cmd
= DEVLINK_CMD_PARAM_GET
,
6110 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6111 .doit
= devlink_nl_cmd_param_get_doit
,
6112 .dumpit
= devlink_nl_cmd_param_get_dumpit
,
6113 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6114 /* can be retrieved by unprivileged users */
6117 .cmd
= DEVLINK_CMD_PARAM_SET
,
6118 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6119 .doit
= devlink_nl_cmd_param_set_doit
,
6120 .flags
= GENL_ADMIN_PERM
,
6121 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6124 .cmd
= DEVLINK_CMD_PORT_PARAM_GET
,
6125 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6126 .doit
= devlink_nl_cmd_port_param_get_doit
,
6127 .dumpit
= devlink_nl_cmd_port_param_get_dumpit
,
6128 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
6129 /* can be retrieved by unprivileged users */
6132 .cmd
= DEVLINK_CMD_PORT_PARAM_SET
,
6133 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6134 .doit
= devlink_nl_cmd_port_param_set_doit
,
6135 .flags
= GENL_ADMIN_PERM
,
6136 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
6139 .cmd
= DEVLINK_CMD_REGION_GET
,
6140 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6141 .doit
= devlink_nl_cmd_region_get_doit
,
6142 .dumpit
= devlink_nl_cmd_region_get_dumpit
,
6143 .flags
= GENL_ADMIN_PERM
,
6144 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6147 .cmd
= DEVLINK_CMD_REGION_DEL
,
6148 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6149 .doit
= devlink_nl_cmd_region_del
,
6150 .flags
= GENL_ADMIN_PERM
,
6151 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6154 .cmd
= DEVLINK_CMD_REGION_READ
,
6155 .validate
= GENL_DONT_VALIDATE_STRICT
|
6156 GENL_DONT_VALIDATE_DUMP_STRICT
,
6157 .dumpit
= devlink_nl_cmd_region_read_dumpit
,
6158 .flags
= GENL_ADMIN_PERM
,
6159 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6162 .cmd
= DEVLINK_CMD_INFO_GET
,
6163 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6164 .doit
= devlink_nl_cmd_info_get_doit
,
6165 .dumpit
= devlink_nl_cmd_info_get_dumpit
,
6166 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6167 /* can be retrieved by unprivileged users */
6170 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_GET
,
6171 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6172 .doit
= devlink_nl_cmd_health_reporter_get_doit
,
6173 .dumpit
= devlink_nl_cmd_health_reporter_get_dumpit
,
6174 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6175 DEVLINK_NL_FLAG_NO_LOCK
,
6176 /* can be retrieved by unprivileged users */
6179 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_SET
,
6180 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6181 .doit
= devlink_nl_cmd_health_reporter_set_doit
,
6182 .flags
= GENL_ADMIN_PERM
,
6183 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6184 DEVLINK_NL_FLAG_NO_LOCK
,
6187 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_RECOVER
,
6188 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6189 .doit
= devlink_nl_cmd_health_reporter_recover_doit
,
6190 .flags
= GENL_ADMIN_PERM
,
6191 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6192 DEVLINK_NL_FLAG_NO_LOCK
,
6195 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE
,
6196 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6197 .doit
= devlink_nl_cmd_health_reporter_diagnose_doit
,
6198 .flags
= GENL_ADMIN_PERM
,
6199 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6200 DEVLINK_NL_FLAG_NO_LOCK
,
6203 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET
,
6204 .validate
= GENL_DONT_VALIDATE_STRICT
|
6205 GENL_DONT_VALIDATE_DUMP_STRICT
,
6206 .dumpit
= devlink_nl_cmd_health_reporter_dump_get_dumpit
,
6207 .flags
= GENL_ADMIN_PERM
,
6208 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6209 DEVLINK_NL_FLAG_NO_LOCK
,
6212 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR
,
6213 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6214 .doit
= devlink_nl_cmd_health_reporter_dump_clear_doit
,
6215 .flags
= GENL_ADMIN_PERM
,
6216 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6217 DEVLINK_NL_FLAG_NO_LOCK
,
6220 .cmd
= DEVLINK_CMD_FLASH_UPDATE
,
6221 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6222 .doit
= devlink_nl_cmd_flash_update
,
6223 .flags
= GENL_ADMIN_PERM
,
6224 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6227 .cmd
= DEVLINK_CMD_TRAP_GET
,
6228 .doit
= devlink_nl_cmd_trap_get_doit
,
6229 .dumpit
= devlink_nl_cmd_trap_get_dumpit
,
6230 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6231 /* can be retrieved by unprivileged users */
6234 .cmd
= DEVLINK_CMD_TRAP_SET
,
6235 .doit
= devlink_nl_cmd_trap_set_doit
,
6236 .flags
= GENL_ADMIN_PERM
,
6237 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6240 .cmd
= DEVLINK_CMD_TRAP_GROUP_GET
,
6241 .doit
= devlink_nl_cmd_trap_group_get_doit
,
6242 .dumpit
= devlink_nl_cmd_trap_group_get_dumpit
,
6243 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6244 /* can be retrieved by unprivileged users */
6247 .cmd
= DEVLINK_CMD_TRAP_GROUP_SET
,
6248 .doit
= devlink_nl_cmd_trap_group_set_doit
,
6249 .flags
= GENL_ADMIN_PERM
,
6250 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6254 static struct genl_family devlink_nl_family __ro_after_init
= {
6255 .name
= DEVLINK_GENL_NAME
,
6256 .version
= DEVLINK_GENL_VERSION
,
6257 .maxattr
= DEVLINK_ATTR_MAX
,
6258 .policy
= devlink_nl_policy
,
6260 .pre_doit
= devlink_nl_pre_doit
,
6261 .post_doit
= devlink_nl_post_doit
,
6262 .module
= THIS_MODULE
,
6263 .ops
= devlink_nl_ops
,
6264 .n_ops
= ARRAY_SIZE(devlink_nl_ops
),
6265 .mcgrps
= devlink_nl_mcgrps
,
6266 .n_mcgrps
= ARRAY_SIZE(devlink_nl_mcgrps
),
6270 * devlink_alloc - Allocate new devlink instance resources
6273 * @priv_size: size of user private data
6275 * Allocate new devlink instance resources, including devlink index
6278 struct devlink
*devlink_alloc(const struct devlink_ops
*ops
, size_t priv_size
)
6280 struct devlink
*devlink
;
6285 devlink
= kzalloc(sizeof(*devlink
) + priv_size
, GFP_KERNEL
);
6289 __devlink_net_set(devlink
, &init_net
);
6290 INIT_LIST_HEAD(&devlink
->port_list
);
6291 INIT_LIST_HEAD(&devlink
->sb_list
);
6292 INIT_LIST_HEAD_RCU(&devlink
->dpipe_table_list
);
6293 INIT_LIST_HEAD(&devlink
->resource_list
);
6294 INIT_LIST_HEAD(&devlink
->param_list
);
6295 INIT_LIST_HEAD(&devlink
->region_list
);
6296 INIT_LIST_HEAD(&devlink
->reporter_list
);
6297 INIT_LIST_HEAD(&devlink
->trap_list
);
6298 INIT_LIST_HEAD(&devlink
->trap_group_list
);
6299 mutex_init(&devlink
->lock
);
6300 mutex_init(&devlink
->reporters_lock
);
6303 EXPORT_SYMBOL_GPL(devlink_alloc
);
6306 * devlink_register - Register devlink instance
6309 * @dev: parent device
6311 int devlink_register(struct devlink
*devlink
, struct device
*dev
)
6313 mutex_lock(&devlink_mutex
);
6315 devlink
->registered
= true;
6316 list_add_tail(&devlink
->list
, &devlink_list
);
6317 devlink_notify(devlink
, DEVLINK_CMD_NEW
);
6318 mutex_unlock(&devlink_mutex
);
6321 EXPORT_SYMBOL_GPL(devlink_register
);
6324 * devlink_unregister - Unregister devlink instance
6328 void devlink_unregister(struct devlink
*devlink
)
6330 mutex_lock(&devlink_mutex
);
6331 WARN_ON(devlink_reload_supported(devlink
) &&
6332 devlink
->reload_enabled
);
6333 devlink_notify(devlink
, DEVLINK_CMD_DEL
);
6334 list_del(&devlink
->list
);
6335 mutex_unlock(&devlink_mutex
);
6337 EXPORT_SYMBOL_GPL(devlink_unregister
);
6340 * devlink_reload_enable - Enable reload of devlink instance
6344 * Should be called at end of device initialization
6345 * process when reload operation is supported.
6347 void devlink_reload_enable(struct devlink
*devlink
)
6349 mutex_lock(&devlink_mutex
);
6350 devlink
->reload_enabled
= true;
6351 mutex_unlock(&devlink_mutex
);
6353 EXPORT_SYMBOL_GPL(devlink_reload_enable
);
6356 * devlink_reload_disable - Disable reload of devlink instance
6360 * Should be called at the beginning of device cleanup
6361 * process when reload operation is supported.
6363 void devlink_reload_disable(struct devlink
*devlink
)
6365 mutex_lock(&devlink_mutex
);
6366 /* Mutex is taken which ensures that no reload operation is in
6367 * progress while setting up forbidded flag.
6369 devlink
->reload_enabled
= false;
6370 mutex_unlock(&devlink_mutex
);
6372 EXPORT_SYMBOL_GPL(devlink_reload_disable
);
6375 * devlink_free - Free devlink instance resources
6379 void devlink_free(struct devlink
*devlink
)
6381 mutex_destroy(&devlink
->reporters_lock
);
6382 mutex_destroy(&devlink
->lock
);
6383 WARN_ON(!list_empty(&devlink
->trap_group_list
));
6384 WARN_ON(!list_empty(&devlink
->trap_list
));
6385 WARN_ON(!list_empty(&devlink
->reporter_list
));
6386 WARN_ON(!list_empty(&devlink
->region_list
));
6387 WARN_ON(!list_empty(&devlink
->param_list
));
6388 WARN_ON(!list_empty(&devlink
->resource_list
));
6389 WARN_ON(!list_empty(&devlink
->dpipe_table_list
));
6390 WARN_ON(!list_empty(&devlink
->sb_list
));
6391 WARN_ON(!list_empty(&devlink
->port_list
));
6395 EXPORT_SYMBOL_GPL(devlink_free
);
6397 static void devlink_port_type_warn(struct work_struct
*work
)
6399 WARN(true, "Type was not set for devlink port.");
6402 static bool devlink_port_type_should_warn(struct devlink_port
*devlink_port
)
6404 /* Ignore CPU and DSA flavours. */
6405 return devlink_port
->attrs
.flavour
!= DEVLINK_PORT_FLAVOUR_CPU
&&
6406 devlink_port
->attrs
.flavour
!= DEVLINK_PORT_FLAVOUR_DSA
;
6409 #define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 30)
6411 static void devlink_port_type_warn_schedule(struct devlink_port
*devlink_port
)
6413 if (!devlink_port_type_should_warn(devlink_port
))
6415 /* Schedule a work to WARN in case driver does not set port
6416 * type within timeout.
6418 schedule_delayed_work(&devlink_port
->type_warn_dw
,
6419 DEVLINK_PORT_TYPE_WARN_TIMEOUT
);
6422 static void devlink_port_type_warn_cancel(struct devlink_port
*devlink_port
)
6424 if (!devlink_port_type_should_warn(devlink_port
))
6426 cancel_delayed_work_sync(&devlink_port
->type_warn_dw
);
6430 * devlink_port_register - Register devlink port
6433 * @devlink_port: devlink port
6434 * @port_index: driver-specific numerical identifier of the port
6436 * Register devlink port with provided port index. User can use
6437 * any indexing, even hw-related one. devlink_port structure
6438 * is convenient to be embedded inside user driver private structure.
6439 * Note that the caller should take care of zeroing the devlink_port
6442 int devlink_port_register(struct devlink
*devlink
,
6443 struct devlink_port
*devlink_port
,
6444 unsigned int port_index
)
6446 mutex_lock(&devlink
->lock
);
6447 if (devlink_port_index_exists(devlink
, port_index
)) {
6448 mutex_unlock(&devlink
->lock
);
6451 devlink_port
->devlink
= devlink
;
6452 devlink_port
->index
= port_index
;
6453 devlink_port
->registered
= true;
6454 spin_lock_init(&devlink_port
->type_lock
);
6455 list_add_tail(&devlink_port
->list
, &devlink
->port_list
);
6456 INIT_LIST_HEAD(&devlink_port
->param_list
);
6457 mutex_unlock(&devlink
->lock
);
6458 INIT_DELAYED_WORK(&devlink_port
->type_warn_dw
, &devlink_port_type_warn
);
6459 devlink_port_type_warn_schedule(devlink_port
);
6460 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
6463 EXPORT_SYMBOL_GPL(devlink_port_register
);
6466 * devlink_port_unregister - Unregister devlink port
6468 * @devlink_port: devlink port
6470 void devlink_port_unregister(struct devlink_port
*devlink_port
)
6472 struct devlink
*devlink
= devlink_port
->devlink
;
6474 devlink_port_type_warn_cancel(devlink_port
);
6475 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_DEL
);
6476 mutex_lock(&devlink
->lock
);
6477 list_del(&devlink_port
->list
);
6478 mutex_unlock(&devlink
->lock
);
6480 EXPORT_SYMBOL_GPL(devlink_port_unregister
);
6482 static void __devlink_port_type_set(struct devlink_port
*devlink_port
,
6483 enum devlink_port_type type
,
6486 if (WARN_ON(!devlink_port
->registered
))
6488 devlink_port_type_warn_cancel(devlink_port
);
6489 spin_lock_bh(&devlink_port
->type_lock
);
6490 devlink_port
->type
= type
;
6491 devlink_port
->type_dev
= type_dev
;
6492 spin_unlock_bh(&devlink_port
->type_lock
);
6493 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
6497 * devlink_port_type_eth_set - Set port type to Ethernet
6499 * @devlink_port: devlink port
6500 * @netdev: related netdevice
6502 void devlink_port_type_eth_set(struct devlink_port
*devlink_port
,
6503 struct net_device
*netdev
)
6505 const struct net_device_ops
*ops
= netdev
->netdev_ops
;
6507 /* If driver registers devlink port, it should set devlink port
6508 * attributes accordingly so the compat functions are called
6509 * and the original ops are not used.
6511 if (ops
->ndo_get_phys_port_name
) {
6512 /* Some drivers use the same set of ndos for netdevs
6513 * that have devlink_port registered and also for
6514 * those who don't. Make sure that ndo_get_phys_port_name
6515 * returns -EOPNOTSUPP here in case it is defined.
6518 char name
[IFNAMSIZ
];
6521 err
= ops
->ndo_get_phys_port_name(netdev
, name
, sizeof(name
));
6522 WARN_ON(err
!= -EOPNOTSUPP
);
6524 if (ops
->ndo_get_port_parent_id
) {
6525 /* Some drivers use the same set of ndos for netdevs
6526 * that have devlink_port registered and also for
6527 * those who don't. Make sure that ndo_get_port_parent_id
6528 * returns -EOPNOTSUPP here in case it is defined.
6531 struct netdev_phys_item_id ppid
;
6534 err
= ops
->ndo_get_port_parent_id(netdev
, &ppid
);
6535 WARN_ON(err
!= -EOPNOTSUPP
);
6537 __devlink_port_type_set(devlink_port
, DEVLINK_PORT_TYPE_ETH
, netdev
);
6539 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set
);
6542 * devlink_port_type_ib_set - Set port type to InfiniBand
6544 * @devlink_port: devlink port
6545 * @ibdev: related IB device
6547 void devlink_port_type_ib_set(struct devlink_port
*devlink_port
,
6548 struct ib_device
*ibdev
)
6550 __devlink_port_type_set(devlink_port
, DEVLINK_PORT_TYPE_IB
, ibdev
);
6552 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set
);
6555 * devlink_port_type_clear - Clear port type
6557 * @devlink_port: devlink port
6559 void devlink_port_type_clear(struct devlink_port
*devlink_port
)
6561 __devlink_port_type_set(devlink_port
, DEVLINK_PORT_TYPE_NOTSET
, NULL
);
6562 devlink_port_type_warn_schedule(devlink_port
);
6564 EXPORT_SYMBOL_GPL(devlink_port_type_clear
);
6566 static int __devlink_port_attrs_set(struct devlink_port
*devlink_port
,
6567 enum devlink_port_flavour flavour
,
6568 const unsigned char *switch_id
,
6569 unsigned char switch_id_len
)
6571 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
6573 if (WARN_ON(devlink_port
->registered
))
6576 attrs
->flavour
= flavour
;
6578 attrs
->switch_port
= true;
6579 if (WARN_ON(switch_id_len
> MAX_PHYS_ITEM_ID_LEN
))
6580 switch_id_len
= MAX_PHYS_ITEM_ID_LEN
;
6581 memcpy(attrs
->switch_id
.id
, switch_id
, switch_id_len
);
6582 attrs
->switch_id
.id_len
= switch_id_len
;
6584 attrs
->switch_port
= false;
6590 * devlink_port_attrs_set - Set port attributes
6592 * @devlink_port: devlink port
6593 * @flavour: flavour of the port
6594 * @port_number: number of the port that is facing user, for example
6595 * the front panel port number
6596 * @split: indicates if this is split port
6597 * @split_subport_number: if the port is split, this is the number
6599 * @switch_id: if the port is part of switch, this is buffer with ID,
6600 * otwerwise this is NULL
6601 * @switch_id_len: length of the switch_id buffer
6603 void devlink_port_attrs_set(struct devlink_port
*devlink_port
,
6604 enum devlink_port_flavour flavour
,
6605 u32 port_number
, bool split
,
6606 u32 split_subport_number
,
6607 const unsigned char *switch_id
,
6608 unsigned char switch_id_len
)
6610 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
6613 ret
= __devlink_port_attrs_set(devlink_port
, flavour
,
6614 switch_id
, switch_id_len
);
6617 attrs
->split
= split
;
6618 attrs
->phys
.port_number
= port_number
;
6619 attrs
->phys
.split_subport_number
= split_subport_number
;
6621 EXPORT_SYMBOL_GPL(devlink_port_attrs_set
);
6624 * devlink_port_attrs_pci_pf_set - Set PCI PF port attributes
6626 * @devlink_port: devlink port
6627 * @pf: associated PF for the devlink port instance
6628 * @switch_id: if the port is part of switch, this is buffer with ID,
6629 * otherwise this is NULL
6630 * @switch_id_len: length of the switch_id buffer
6632 void devlink_port_attrs_pci_pf_set(struct devlink_port
*devlink_port
,
6633 const unsigned char *switch_id
,
6634 unsigned char switch_id_len
, u16 pf
)
6636 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
6639 ret
= __devlink_port_attrs_set(devlink_port
,
6640 DEVLINK_PORT_FLAVOUR_PCI_PF
,
6641 switch_id
, switch_id_len
);
6645 attrs
->pci_pf
.pf
= pf
;
6647 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set
);
6650 * devlink_port_attrs_pci_vf_set - Set PCI VF port attributes
6652 * @devlink_port: devlink port
6653 * @pf: associated PF for the devlink port instance
6654 * @vf: associated VF of a PF for the devlink port instance
6655 * @switch_id: if the port is part of switch, this is buffer with ID,
6656 * otherwise this is NULL
6657 * @switch_id_len: length of the switch_id buffer
6659 void devlink_port_attrs_pci_vf_set(struct devlink_port
*devlink_port
,
6660 const unsigned char *switch_id
,
6661 unsigned char switch_id_len
,
6664 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
6667 ret
= __devlink_port_attrs_set(devlink_port
,
6668 DEVLINK_PORT_FLAVOUR_PCI_VF
,
6669 switch_id
, switch_id_len
);
6672 attrs
->pci_vf
.pf
= pf
;
6673 attrs
->pci_vf
.vf
= vf
;
6675 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set
);
6677 static int __devlink_port_phys_port_name_get(struct devlink_port
*devlink_port
,
6678 char *name
, size_t len
)
6680 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
6686 switch (attrs
->flavour
) {
6687 case DEVLINK_PORT_FLAVOUR_PHYSICAL
:
6689 n
= snprintf(name
, len
, "p%u", attrs
->phys
.port_number
);
6691 n
= snprintf(name
, len
, "p%us%u",
6692 attrs
->phys
.port_number
,
6693 attrs
->phys
.split_subport_number
);
6695 case DEVLINK_PORT_FLAVOUR_CPU
:
6696 case DEVLINK_PORT_FLAVOUR_DSA
:
6697 /* As CPU and DSA ports do not have a netdevice associated
6698 * case should not ever happen.
6702 case DEVLINK_PORT_FLAVOUR_PCI_PF
:
6703 n
= snprintf(name
, len
, "pf%u", attrs
->pci_pf
.pf
);
6705 case DEVLINK_PORT_FLAVOUR_PCI_VF
:
6706 n
= snprintf(name
, len
, "pf%uvf%u",
6707 attrs
->pci_vf
.pf
, attrs
->pci_vf
.vf
);
6717 int devlink_sb_register(struct devlink
*devlink
, unsigned int sb_index
,
6718 u32 size
, u16 ingress_pools_count
,
6719 u16 egress_pools_count
, u16 ingress_tc_count
,
6720 u16 egress_tc_count
)
6722 struct devlink_sb
*devlink_sb
;
6725 mutex_lock(&devlink
->lock
);
6726 if (devlink_sb_index_exists(devlink
, sb_index
)) {
6731 devlink_sb
= kzalloc(sizeof(*devlink_sb
), GFP_KERNEL
);
6736 devlink_sb
->index
= sb_index
;
6737 devlink_sb
->size
= size
;
6738 devlink_sb
->ingress_pools_count
= ingress_pools_count
;
6739 devlink_sb
->egress_pools_count
= egress_pools_count
;
6740 devlink_sb
->ingress_tc_count
= ingress_tc_count
;
6741 devlink_sb
->egress_tc_count
= egress_tc_count
;
6742 list_add_tail(&devlink_sb
->list
, &devlink
->sb_list
);
6744 mutex_unlock(&devlink
->lock
);
6747 EXPORT_SYMBOL_GPL(devlink_sb_register
);
6749 void devlink_sb_unregister(struct devlink
*devlink
, unsigned int sb_index
)
6751 struct devlink_sb
*devlink_sb
;
6753 mutex_lock(&devlink
->lock
);
6754 devlink_sb
= devlink_sb_get_by_index(devlink
, sb_index
);
6755 WARN_ON(!devlink_sb
);
6756 list_del(&devlink_sb
->list
);
6757 mutex_unlock(&devlink
->lock
);
6760 EXPORT_SYMBOL_GPL(devlink_sb_unregister
);
6763 * devlink_dpipe_headers_register - register dpipe headers
6766 * @dpipe_headers: dpipe header array
6768 * Register the headers supported by hardware.
6770 int devlink_dpipe_headers_register(struct devlink
*devlink
,
6771 struct devlink_dpipe_headers
*dpipe_headers
)
6773 mutex_lock(&devlink
->lock
);
6774 devlink
->dpipe_headers
= dpipe_headers
;
6775 mutex_unlock(&devlink
->lock
);
6778 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register
);
6781 * devlink_dpipe_headers_unregister - unregister dpipe headers
6785 * Unregister the headers supported by hardware.
6787 void devlink_dpipe_headers_unregister(struct devlink
*devlink
)
6789 mutex_lock(&devlink
->lock
);
6790 devlink
->dpipe_headers
= NULL
;
6791 mutex_unlock(&devlink
->lock
);
6793 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister
);
6796 * devlink_dpipe_table_counter_enabled - check if counter allocation
6799 * @table_name: tables name
6801 * Used by driver to check if counter allocation is required.
6802 * After counter allocation is turned on the table entries
6803 * are updated to include counter statistics.
6805 * After that point on the driver must respect the counter
6806 * state so that each entry added to the table is added
6809 bool devlink_dpipe_table_counter_enabled(struct devlink
*devlink
,
6810 const char *table_name
)
6812 struct devlink_dpipe_table
*table
;
6816 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
6820 enabled
= table
->counters_enabled
;
6824 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled
);
6827 * devlink_dpipe_table_register - register dpipe table
6830 * @table_name: table name
6831 * @table_ops: table ops
6833 * @counter_control_extern: external control for counters
6835 int devlink_dpipe_table_register(struct devlink
*devlink
,
6836 const char *table_name
,
6837 struct devlink_dpipe_table_ops
*table_ops
,
6838 void *priv
, bool counter_control_extern
)
6840 struct devlink_dpipe_table
*table
;
6842 if (devlink_dpipe_table_find(&devlink
->dpipe_table_list
, table_name
))
6845 if (WARN_ON(!table_ops
->size_get
))
6848 table
= kzalloc(sizeof(*table
), GFP_KERNEL
);
6852 table
->name
= table_name
;
6853 table
->table_ops
= table_ops
;
6855 table
->counter_control_extern
= counter_control_extern
;
6857 mutex_lock(&devlink
->lock
);
6858 list_add_tail_rcu(&table
->list
, &devlink
->dpipe_table_list
);
6859 mutex_unlock(&devlink
->lock
);
6862 EXPORT_SYMBOL_GPL(devlink_dpipe_table_register
);
6865 * devlink_dpipe_table_unregister - unregister dpipe table
6868 * @table_name: table name
6870 void devlink_dpipe_table_unregister(struct devlink
*devlink
,
6871 const char *table_name
)
6873 struct devlink_dpipe_table
*table
;
6875 mutex_lock(&devlink
->lock
);
6876 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
6880 list_del_rcu(&table
->list
);
6881 mutex_unlock(&devlink
->lock
);
6882 kfree_rcu(table
, rcu
);
6885 mutex_unlock(&devlink
->lock
);
6887 EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister
);
6890 * devlink_resource_register - devlink resource register
6893 * @resource_name: resource's name
6894 * @resource_size: resource's size
6895 * @resource_id: resource's id
6896 * @parent_resource_id: resource's parent id
6897 * @size_params: size parameters
6899 int devlink_resource_register(struct devlink
*devlink
,
6900 const char *resource_name
,
6903 u64 parent_resource_id
,
6904 const struct devlink_resource_size_params
*size_params
)
6906 struct devlink_resource
*resource
;
6907 struct list_head
*resource_list
;
6911 top_hierarchy
= parent_resource_id
== DEVLINK_RESOURCE_ID_PARENT_TOP
;
6913 mutex_lock(&devlink
->lock
);
6914 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
6920 resource
= kzalloc(sizeof(*resource
), GFP_KERNEL
);
6926 if (top_hierarchy
) {
6927 resource_list
= &devlink
->resource_list
;
6929 struct devlink_resource
*parent_resource
;
6931 parent_resource
= devlink_resource_find(devlink
, NULL
,
6932 parent_resource_id
);
6933 if (parent_resource
) {
6934 resource_list
= &parent_resource
->resource_list
;
6935 resource
->parent
= parent_resource
;
6943 resource
->name
= resource_name
;
6944 resource
->size
= resource_size
;
6945 resource
->size_new
= resource_size
;
6946 resource
->id
= resource_id
;
6947 resource
->size_valid
= true;
6948 memcpy(&resource
->size_params
, size_params
,
6949 sizeof(resource
->size_params
));
6950 INIT_LIST_HEAD(&resource
->resource_list
);
6951 list_add_tail(&resource
->list
, resource_list
);
6953 mutex_unlock(&devlink
->lock
);
6956 EXPORT_SYMBOL_GPL(devlink_resource_register
);
6959 * devlink_resources_unregister - free all resources
6962 * @resource: resource
6964 void devlink_resources_unregister(struct devlink
*devlink
,
6965 struct devlink_resource
*resource
)
6967 struct devlink_resource
*tmp
, *child_resource
;
6968 struct list_head
*resource_list
;
6971 resource_list
= &resource
->resource_list
;
6973 resource_list
= &devlink
->resource_list
;
6976 mutex_lock(&devlink
->lock
);
6978 list_for_each_entry_safe(child_resource
, tmp
, resource_list
, list
) {
6979 devlink_resources_unregister(devlink
, child_resource
);
6980 list_del(&child_resource
->list
);
6981 kfree(child_resource
);
6985 mutex_unlock(&devlink
->lock
);
6987 EXPORT_SYMBOL_GPL(devlink_resources_unregister
);
6990 * devlink_resource_size_get - get and update size
6993 * @resource_id: the requested resource id
6994 * @p_resource_size: ptr to update
6996 int devlink_resource_size_get(struct devlink
*devlink
,
6998 u64
*p_resource_size
)
7000 struct devlink_resource
*resource
;
7003 mutex_lock(&devlink
->lock
);
7004 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
7009 *p_resource_size
= resource
->size_new
;
7010 resource
->size
= resource
->size_new
;
7012 mutex_unlock(&devlink
->lock
);
7015 EXPORT_SYMBOL_GPL(devlink_resource_size_get
);
7018 * devlink_dpipe_table_resource_set - set the resource id
7021 * @table_name: table name
7022 * @resource_id: resource id
7023 * @resource_units: number of resource's units consumed per table's entry
7025 int devlink_dpipe_table_resource_set(struct devlink
*devlink
,
7026 const char *table_name
, u64 resource_id
,
7029 struct devlink_dpipe_table
*table
;
7032 mutex_lock(&devlink
->lock
);
7033 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
7039 table
->resource_id
= resource_id
;
7040 table
->resource_units
= resource_units
;
7041 table
->resource_valid
= true;
7043 mutex_unlock(&devlink
->lock
);
7046 EXPORT_SYMBOL_GPL(devlink_dpipe_table_resource_set
);
7049 * devlink_resource_occ_get_register - register occupancy getter
7052 * @resource_id: resource id
7053 * @occ_get: occupancy getter callback
7054 * @occ_get_priv: occupancy getter callback priv
7056 void devlink_resource_occ_get_register(struct devlink
*devlink
,
7058 devlink_resource_occ_get_t
*occ_get
,
7061 struct devlink_resource
*resource
;
7063 mutex_lock(&devlink
->lock
);
7064 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
7065 if (WARN_ON(!resource
))
7067 WARN_ON(resource
->occ_get
);
7069 resource
->occ_get
= occ_get
;
7070 resource
->occ_get_priv
= occ_get_priv
;
7072 mutex_unlock(&devlink
->lock
);
7074 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register
);
7077 * devlink_resource_occ_get_unregister - unregister occupancy getter
7080 * @resource_id: resource id
7082 void devlink_resource_occ_get_unregister(struct devlink
*devlink
,
7085 struct devlink_resource
*resource
;
7087 mutex_lock(&devlink
->lock
);
7088 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
7089 if (WARN_ON(!resource
))
7091 WARN_ON(!resource
->occ_get
);
7093 resource
->occ_get
= NULL
;
7094 resource
->occ_get_priv
= NULL
;
7096 mutex_unlock(&devlink
->lock
);
7098 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister
);
7100 static int devlink_param_verify(const struct devlink_param
*param
)
7102 if (!param
|| !param
->name
|| !param
->supported_cmodes
)
7105 return devlink_param_generic_verify(param
);
7107 return devlink_param_driver_verify(param
);
7110 static int __devlink_params_register(struct devlink
*devlink
,
7111 unsigned int port_index
,
7112 struct list_head
*param_list
,
7113 const struct devlink_param
*params
,
7114 size_t params_count
,
7115 enum devlink_command reg_cmd
,
7116 enum devlink_command unreg_cmd
)
7118 const struct devlink_param
*param
= params
;
7122 mutex_lock(&devlink
->lock
);
7123 for (i
= 0; i
< params_count
; i
++, param
++) {
7124 err
= devlink_param_verify(param
);
7128 err
= devlink_param_register_one(devlink
, port_index
,
7129 param_list
, param
, reg_cmd
);
7134 mutex_unlock(&devlink
->lock
);
7140 for (param
--; i
> 0; i
--, param
--)
7141 devlink_param_unregister_one(devlink
, port_index
, param_list
,
7144 mutex_unlock(&devlink
->lock
);
7148 static void __devlink_params_unregister(struct devlink
*devlink
,
7149 unsigned int port_index
,
7150 struct list_head
*param_list
,
7151 const struct devlink_param
*params
,
7152 size_t params_count
,
7153 enum devlink_command cmd
)
7155 const struct devlink_param
*param
= params
;
7158 mutex_lock(&devlink
->lock
);
7159 for (i
= 0; i
< params_count
; i
++, param
++)
7160 devlink_param_unregister_one(devlink
, 0, param_list
, param
,
7162 mutex_unlock(&devlink
->lock
);
7166 * devlink_params_register - register configuration parameters
7169 * @params: configuration parameters array
7170 * @params_count: number of parameters provided
7172 * Register the configuration parameters supported by the driver.
7174 int devlink_params_register(struct devlink
*devlink
,
7175 const struct devlink_param
*params
,
7176 size_t params_count
)
7178 return __devlink_params_register(devlink
, 0, &devlink
->param_list
,
7179 params
, params_count
,
7180 DEVLINK_CMD_PARAM_NEW
,
7181 DEVLINK_CMD_PARAM_DEL
);
7183 EXPORT_SYMBOL_GPL(devlink_params_register
);
7186 * devlink_params_unregister - unregister configuration parameters
7188 * @params: configuration parameters to unregister
7189 * @params_count: number of parameters provided
7191 void devlink_params_unregister(struct devlink
*devlink
,
7192 const struct devlink_param
*params
,
7193 size_t params_count
)
7195 return __devlink_params_unregister(devlink
, 0, &devlink
->param_list
,
7196 params
, params_count
,
7197 DEVLINK_CMD_PARAM_DEL
);
7199 EXPORT_SYMBOL_GPL(devlink_params_unregister
);
7202 * devlink_params_publish - publish configuration parameters
7206 * Publish previously registered configuration parameters.
7208 void devlink_params_publish(struct devlink
*devlink
)
7210 struct devlink_param_item
*param_item
;
7212 list_for_each_entry(param_item
, &devlink
->param_list
, list
) {
7213 if (param_item
->published
)
7215 param_item
->published
= true;
7216 devlink_param_notify(devlink
, 0, param_item
,
7217 DEVLINK_CMD_PARAM_NEW
);
7220 EXPORT_SYMBOL_GPL(devlink_params_publish
);
7223 * devlink_params_unpublish - unpublish configuration parameters
7227 * Unpublish previously registered configuration parameters.
7229 void devlink_params_unpublish(struct devlink
*devlink
)
7231 struct devlink_param_item
*param_item
;
7233 list_for_each_entry(param_item
, &devlink
->param_list
, list
) {
7234 if (!param_item
->published
)
7236 param_item
->published
= false;
7237 devlink_param_notify(devlink
, 0, param_item
,
7238 DEVLINK_CMD_PARAM_DEL
);
7241 EXPORT_SYMBOL_GPL(devlink_params_unpublish
);
7244 * devlink_port_params_register - register port configuration parameters
7246 * @devlink_port: devlink port
7247 * @params: configuration parameters array
7248 * @params_count: number of parameters provided
7250 * Register the configuration parameters supported by the port.
7252 int devlink_port_params_register(struct devlink_port
*devlink_port
,
7253 const struct devlink_param
*params
,
7254 size_t params_count
)
7256 return __devlink_params_register(devlink_port
->devlink
,
7257 devlink_port
->index
,
7258 &devlink_port
->param_list
, params
,
7260 DEVLINK_CMD_PORT_PARAM_NEW
,
7261 DEVLINK_CMD_PORT_PARAM_DEL
);
7263 EXPORT_SYMBOL_GPL(devlink_port_params_register
);
7266 * devlink_port_params_unregister - unregister port configuration
7269 * @devlink_port: devlink port
7270 * @params: configuration parameters array
7271 * @params_count: number of parameters provided
7273 void devlink_port_params_unregister(struct devlink_port
*devlink_port
,
7274 const struct devlink_param
*params
,
7275 size_t params_count
)
7277 return __devlink_params_unregister(devlink_port
->devlink
,
7278 devlink_port
->index
,
7279 &devlink_port
->param_list
,
7280 params
, params_count
,
7281 DEVLINK_CMD_PORT_PARAM_DEL
);
7283 EXPORT_SYMBOL_GPL(devlink_port_params_unregister
);
7286 __devlink_param_driverinit_value_get(struct list_head
*param_list
, u32 param_id
,
7287 union devlink_param_value
*init_val
)
7289 struct devlink_param_item
*param_item
;
7291 param_item
= devlink_param_find_by_id(param_list
, param_id
);
7295 if (!param_item
->driverinit_value_valid
||
7296 !devlink_param_cmode_is_supported(param_item
->param
,
7297 DEVLINK_PARAM_CMODE_DRIVERINIT
))
7300 if (param_item
->param
->type
== DEVLINK_PARAM_TYPE_STRING
)
7301 strcpy(init_val
->vstr
, param_item
->driverinit_value
.vstr
);
7303 *init_val
= param_item
->driverinit_value
;
7309 __devlink_param_driverinit_value_set(struct devlink
*devlink
,
7310 unsigned int port_index
,
7311 struct list_head
*param_list
, u32 param_id
,
7312 union devlink_param_value init_val
,
7313 enum devlink_command cmd
)
7315 struct devlink_param_item
*param_item
;
7317 param_item
= devlink_param_find_by_id(param_list
, param_id
);
7321 if (!devlink_param_cmode_is_supported(param_item
->param
,
7322 DEVLINK_PARAM_CMODE_DRIVERINIT
))
7325 if (param_item
->param
->type
== DEVLINK_PARAM_TYPE_STRING
)
7326 strcpy(param_item
->driverinit_value
.vstr
, init_val
.vstr
);
7328 param_item
->driverinit_value
= init_val
;
7329 param_item
->driverinit_value_valid
= true;
7331 devlink_param_notify(devlink
, port_index
, param_item
, cmd
);
7336 * devlink_param_driverinit_value_get - get configuration parameter
7337 * value for driver initializing
7340 * @param_id: parameter ID
7341 * @init_val: value of parameter in driverinit configuration mode
7343 * This function should be used by the driver to get driverinit
7344 * configuration for initialization after reload command.
7346 int devlink_param_driverinit_value_get(struct devlink
*devlink
, u32 param_id
,
7347 union devlink_param_value
*init_val
)
7349 if (!devlink_reload_supported(devlink
))
7352 return __devlink_param_driverinit_value_get(&devlink
->param_list
,
7353 param_id
, init_val
);
7355 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_get
);
7358 * devlink_param_driverinit_value_set - set value of configuration
7359 * parameter for driverinit
7360 * configuration mode
7363 * @param_id: parameter ID
7364 * @init_val: value of parameter to set for driverinit configuration mode
7366 * This function should be used by the driver to set driverinit
7367 * configuration mode default value.
7369 int devlink_param_driverinit_value_set(struct devlink
*devlink
, u32 param_id
,
7370 union devlink_param_value init_val
)
7372 return __devlink_param_driverinit_value_set(devlink
, 0,
7373 &devlink
->param_list
,
7375 DEVLINK_CMD_PARAM_NEW
);
7377 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set
);
7380 * devlink_port_param_driverinit_value_get - get configuration parameter
7381 * value for driver initializing
7383 * @devlink_port: devlink_port
7384 * @param_id: parameter ID
7385 * @init_val: value of parameter in driverinit configuration mode
7387 * This function should be used by the driver to get driverinit
7388 * configuration for initialization after reload command.
7390 int devlink_port_param_driverinit_value_get(struct devlink_port
*devlink_port
,
7392 union devlink_param_value
*init_val
)
7394 struct devlink
*devlink
= devlink_port
->devlink
;
7396 if (!devlink_reload_supported(devlink
))
7399 return __devlink_param_driverinit_value_get(&devlink_port
->param_list
,
7400 param_id
, init_val
);
7402 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_get
);
7405 * devlink_port_param_driverinit_value_set - set value of configuration
7406 * parameter for driverinit
7407 * configuration mode
7409 * @devlink_port: devlink_port
7410 * @param_id: parameter ID
7411 * @init_val: value of parameter to set for driverinit configuration mode
7413 * This function should be used by the driver to set driverinit
7414 * configuration mode default value.
7416 int devlink_port_param_driverinit_value_set(struct devlink_port
*devlink_port
,
7418 union devlink_param_value init_val
)
7420 return __devlink_param_driverinit_value_set(devlink_port
->devlink
,
7421 devlink_port
->index
,
7422 &devlink_port
->param_list
,
7424 DEVLINK_CMD_PORT_PARAM_NEW
);
7426 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_set
);
7429 * devlink_param_value_changed - notify devlink on a parameter's value
7430 * change. Should be called by the driver
7431 * right after the change.
7434 * @param_id: parameter ID
7436 * This function should be used by the driver to notify devlink on value
7437 * change, excluding driverinit configuration mode.
7438 * For driverinit configuration mode driver should use the function
7440 void devlink_param_value_changed(struct devlink
*devlink
, u32 param_id
)
7442 struct devlink_param_item
*param_item
;
7444 param_item
= devlink_param_find_by_id(&devlink
->param_list
, param_id
);
7445 WARN_ON(!param_item
);
7447 devlink_param_notify(devlink
, 0, param_item
, DEVLINK_CMD_PARAM_NEW
);
7449 EXPORT_SYMBOL_GPL(devlink_param_value_changed
);
7452 * devlink_port_param_value_changed - notify devlink on a parameter's value
7453 * change. Should be called by the driver
7454 * right after the change.
7456 * @devlink_port: devlink_port
7457 * @param_id: parameter ID
7459 * This function should be used by the driver to notify devlink on value
7460 * change, excluding driverinit configuration mode.
7461 * For driverinit configuration mode driver should use the function
7462 * devlink_port_param_driverinit_value_set() instead.
7464 void devlink_port_param_value_changed(struct devlink_port
*devlink_port
,
7467 struct devlink_param_item
*param_item
;
7469 param_item
= devlink_param_find_by_id(&devlink_port
->param_list
,
7471 WARN_ON(!param_item
);
7473 devlink_param_notify(devlink_port
->devlink
, devlink_port
->index
,
7474 param_item
, DEVLINK_CMD_PORT_PARAM_NEW
);
7476 EXPORT_SYMBOL_GPL(devlink_port_param_value_changed
);
7479 * devlink_param_value_str_fill - Safely fill-up the string preventing
7480 * from overflow of the preallocated buffer
7482 * @dst_val: destination devlink_param_value
7483 * @src: source buffer
7485 void devlink_param_value_str_fill(union devlink_param_value
*dst_val
,
7490 len
= strlcpy(dst_val
->vstr
, src
, __DEVLINK_PARAM_MAX_STRING_VALUE
);
7491 WARN_ON(len
>= __DEVLINK_PARAM_MAX_STRING_VALUE
);
7493 EXPORT_SYMBOL_GPL(devlink_param_value_str_fill
);
7496 * devlink_region_create - create a new address region
7499 * @region_name: region name
7500 * @region_max_snapshots: Maximum supported number of snapshots for region
7501 * @region_size: size of region
7503 struct devlink_region
*devlink_region_create(struct devlink
*devlink
,
7504 const char *region_name
,
7505 u32 region_max_snapshots
,
7508 struct devlink_region
*region
;
7511 mutex_lock(&devlink
->lock
);
7513 if (devlink_region_get_by_name(devlink
, region_name
)) {
7518 region
= kzalloc(sizeof(*region
), GFP_KERNEL
);
7524 region
->devlink
= devlink
;
7525 region
->max_snapshots
= region_max_snapshots
;
7526 region
->name
= region_name
;
7527 region
->size
= region_size
;
7528 INIT_LIST_HEAD(®ion
->snapshot_list
);
7529 list_add_tail(®ion
->list
, &devlink
->region_list
);
7530 devlink_nl_region_notify(region
, NULL
, DEVLINK_CMD_REGION_NEW
);
7532 mutex_unlock(&devlink
->lock
);
7536 mutex_unlock(&devlink
->lock
);
7537 return ERR_PTR(err
);
7539 EXPORT_SYMBOL_GPL(devlink_region_create
);
7542 * devlink_region_destroy - destroy address region
7544 * @region: devlink region to destroy
7546 void devlink_region_destroy(struct devlink_region
*region
)
7548 struct devlink
*devlink
= region
->devlink
;
7549 struct devlink_snapshot
*snapshot
, *ts
;
7551 mutex_lock(&devlink
->lock
);
7553 /* Free all snapshots of region */
7554 list_for_each_entry_safe(snapshot
, ts
, ®ion
->snapshot_list
, list
)
7555 devlink_region_snapshot_del(region
, snapshot
);
7557 list_del(®ion
->list
);
7559 devlink_nl_region_notify(region
, NULL
, DEVLINK_CMD_REGION_DEL
);
7560 mutex_unlock(&devlink
->lock
);
7563 EXPORT_SYMBOL_GPL(devlink_region_destroy
);
7566 * devlink_region_shapshot_id_get - get snapshot ID
7568 * This callback should be called when adding a new snapshot,
7569 * Driver should use the same id for multiple snapshots taken
7570 * on multiple regions at the same time/by the same trigger.
7574 u32
devlink_region_shapshot_id_get(struct devlink
*devlink
)
7578 mutex_lock(&devlink
->lock
);
7579 id
= ++devlink
->snapshot_id
;
7580 mutex_unlock(&devlink
->lock
);
7584 EXPORT_SYMBOL_GPL(devlink_region_shapshot_id_get
);
7587 * devlink_region_snapshot_create - create a new snapshot
7588 * This will add a new snapshot of a region. The snapshot
7589 * will be stored on the region struct and can be accessed
7590 * from devlink. This is useful for future analyses of snapshots.
7591 * Multiple snapshots can be created on a region.
7592 * The @snapshot_id should be obtained using the getter function.
7594 * @region: devlink region of the snapshot
7595 * @data: snapshot data
7596 * @snapshot_id: snapshot id to be created
7597 * @data_destructor: pointer to destructor function to free data
7599 int devlink_region_snapshot_create(struct devlink_region
*region
,
7600 u8
*data
, u32 snapshot_id
,
7601 devlink_snapshot_data_dest_t
*data_destructor
)
7603 struct devlink
*devlink
= region
->devlink
;
7604 struct devlink_snapshot
*snapshot
;
7607 mutex_lock(&devlink
->lock
);
7609 /* check if region can hold one more snapshot */
7610 if (region
->cur_snapshots
== region
->max_snapshots
) {
7615 if (devlink_region_snapshot_get_by_id(region
, snapshot_id
)) {
7620 snapshot
= kzalloc(sizeof(*snapshot
), GFP_KERNEL
);
7626 snapshot
->id
= snapshot_id
;
7627 snapshot
->region
= region
;
7628 snapshot
->data
= data
;
7629 snapshot
->data_destructor
= data_destructor
;
7631 list_add_tail(&snapshot
->list
, ®ion
->snapshot_list
);
7633 region
->cur_snapshots
++;
7635 devlink_nl_region_notify(region
, snapshot
, DEVLINK_CMD_REGION_NEW
);
7636 mutex_unlock(&devlink
->lock
);
7640 mutex_unlock(&devlink
->lock
);
7643 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create
);
7645 #define DEVLINK_TRAP(_id, _type) \
7647 .type = DEVLINK_TRAP_TYPE_##_type, \
7648 .id = DEVLINK_TRAP_GENERIC_ID_##_id, \
7649 .name = DEVLINK_TRAP_GENERIC_NAME_##_id, \
7652 static const struct devlink_trap devlink_trap_generic
[] = {
7653 DEVLINK_TRAP(SMAC_MC
, DROP
),
7654 DEVLINK_TRAP(VLAN_TAG_MISMATCH
, DROP
),
7655 DEVLINK_TRAP(INGRESS_VLAN_FILTER
, DROP
),
7656 DEVLINK_TRAP(INGRESS_STP_FILTER
, DROP
),
7657 DEVLINK_TRAP(EMPTY_TX_LIST
, DROP
),
7658 DEVLINK_TRAP(PORT_LOOPBACK_FILTER
, DROP
),
7659 DEVLINK_TRAP(BLACKHOLE_ROUTE
, DROP
),
7660 DEVLINK_TRAP(TTL_ERROR
, EXCEPTION
),
7661 DEVLINK_TRAP(TAIL_DROP
, DROP
),
7662 DEVLINK_TRAP(NON_IP_PACKET
, DROP
),
7663 DEVLINK_TRAP(UC_DIP_MC_DMAC
, DROP
),
7664 DEVLINK_TRAP(DIP_LB
, DROP
),
7665 DEVLINK_TRAP(SIP_MC
, DROP
),
7666 DEVLINK_TRAP(SIP_LB
, DROP
),
7667 DEVLINK_TRAP(CORRUPTED_IP_HDR
, DROP
),
7668 DEVLINK_TRAP(IPV4_SIP_BC
, DROP
),
7669 DEVLINK_TRAP(IPV6_MC_DIP_RESERVED_SCOPE
, DROP
),
7670 DEVLINK_TRAP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE
, DROP
),
7671 DEVLINK_TRAP(MTU_ERROR
, EXCEPTION
),
7672 DEVLINK_TRAP(UNRESOLVED_NEIGH
, EXCEPTION
),
7673 DEVLINK_TRAP(RPF
, EXCEPTION
),
7674 DEVLINK_TRAP(REJECT_ROUTE
, EXCEPTION
),
7675 DEVLINK_TRAP(IPV4_LPM_UNICAST_MISS
, EXCEPTION
),
7676 DEVLINK_TRAP(IPV6_LPM_UNICAST_MISS
, EXCEPTION
),
7679 #define DEVLINK_TRAP_GROUP(_id) \
7681 .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \
7682 .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \
7685 static const struct devlink_trap_group devlink_trap_group_generic
[] = {
7686 DEVLINK_TRAP_GROUP(L2_DROPS
),
7687 DEVLINK_TRAP_GROUP(L3_DROPS
),
7688 DEVLINK_TRAP_GROUP(BUFFER_DROPS
),
7691 static int devlink_trap_generic_verify(const struct devlink_trap
*trap
)
7693 if (trap
->id
> DEVLINK_TRAP_GENERIC_ID_MAX
)
7696 if (strcmp(trap
->name
, devlink_trap_generic
[trap
->id
].name
))
7699 if (trap
->type
!= devlink_trap_generic
[trap
->id
].type
)
7705 static int devlink_trap_driver_verify(const struct devlink_trap
*trap
)
7709 if (trap
->id
<= DEVLINK_TRAP_GENERIC_ID_MAX
)
7712 for (i
= 0; i
< ARRAY_SIZE(devlink_trap_generic
); i
++) {
7713 if (!strcmp(trap
->name
, devlink_trap_generic
[i
].name
))
7720 static int devlink_trap_verify(const struct devlink_trap
*trap
)
7722 if (!trap
|| !trap
->name
|| !trap
->group
.name
)
7726 return devlink_trap_generic_verify(trap
);
7728 return devlink_trap_driver_verify(trap
);
7732 devlink_trap_group_generic_verify(const struct devlink_trap_group
*group
)
7734 if (group
->id
> DEVLINK_TRAP_GROUP_GENERIC_ID_MAX
)
7737 if (strcmp(group
->name
, devlink_trap_group_generic
[group
->id
].name
))
7744 devlink_trap_group_driver_verify(const struct devlink_trap_group
*group
)
7748 if (group
->id
<= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX
)
7751 for (i
= 0; i
< ARRAY_SIZE(devlink_trap_group_generic
); i
++) {
7752 if (!strcmp(group
->name
, devlink_trap_group_generic
[i
].name
))
7759 static int devlink_trap_group_verify(const struct devlink_trap_group
*group
)
7762 return devlink_trap_group_generic_verify(group
);
7764 return devlink_trap_group_driver_verify(group
);
7768 devlink_trap_group_notify(struct devlink
*devlink
,
7769 const struct devlink_trap_group_item
*group_item
,
7770 enum devlink_command cmd
)
7772 struct sk_buff
*msg
;
7775 WARN_ON_ONCE(cmd
!= DEVLINK_CMD_TRAP_GROUP_NEW
&&
7776 cmd
!= DEVLINK_CMD_TRAP_GROUP_DEL
);
7778 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
7782 err
= devlink_nl_trap_group_fill(msg
, devlink
, group_item
, cmd
, 0, 0,
7789 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
7790 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
7793 static struct devlink_trap_group_item
*
7794 devlink_trap_group_item_create(struct devlink
*devlink
,
7795 const struct devlink_trap_group
*group
)
7797 struct devlink_trap_group_item
*group_item
;
7800 err
= devlink_trap_group_verify(group
);
7802 return ERR_PTR(err
);
7804 group_item
= kzalloc(sizeof(*group_item
), GFP_KERNEL
);
7806 return ERR_PTR(-ENOMEM
);
7808 group_item
->stats
= netdev_alloc_pcpu_stats(struct devlink_stats
);
7809 if (!group_item
->stats
) {
7811 goto err_stats_alloc
;
7814 group_item
->group
= group
;
7815 refcount_set(&group_item
->refcount
, 1);
7817 if (devlink
->ops
->trap_group_init
) {
7818 err
= devlink
->ops
->trap_group_init(devlink
, group
);
7820 goto err_group_init
;
7823 list_add_tail(&group_item
->list
, &devlink
->trap_group_list
);
7824 devlink_trap_group_notify(devlink
, group_item
,
7825 DEVLINK_CMD_TRAP_GROUP_NEW
);
7830 free_percpu(group_item
->stats
);
7833 return ERR_PTR(err
);
7837 devlink_trap_group_item_destroy(struct devlink
*devlink
,
7838 struct devlink_trap_group_item
*group_item
)
7840 devlink_trap_group_notify(devlink
, group_item
,
7841 DEVLINK_CMD_TRAP_GROUP_DEL
);
7842 list_del(&group_item
->list
);
7843 free_percpu(group_item
->stats
);
7847 static struct devlink_trap_group_item
*
7848 devlink_trap_group_item_get(struct devlink
*devlink
,
7849 const struct devlink_trap_group
*group
)
7851 struct devlink_trap_group_item
*group_item
;
7853 group_item
= devlink_trap_group_item_lookup(devlink
, group
->name
);
7855 refcount_inc(&group_item
->refcount
);
7859 return devlink_trap_group_item_create(devlink
, group
);
7863 devlink_trap_group_item_put(struct devlink
*devlink
,
7864 struct devlink_trap_group_item
*group_item
)
7866 if (!refcount_dec_and_test(&group_item
->refcount
))
7869 devlink_trap_group_item_destroy(devlink
, group_item
);
7873 devlink_trap_item_group_link(struct devlink
*devlink
,
7874 struct devlink_trap_item
*trap_item
)
7876 struct devlink_trap_group_item
*group_item
;
7878 group_item
= devlink_trap_group_item_get(devlink
,
7879 &trap_item
->trap
->group
);
7880 if (IS_ERR(group_item
))
7881 return PTR_ERR(group_item
);
7883 trap_item
->group_item
= group_item
;
7889 devlink_trap_item_group_unlink(struct devlink
*devlink
,
7890 struct devlink_trap_item
*trap_item
)
7892 devlink_trap_group_item_put(devlink
, trap_item
->group_item
);
7895 static void devlink_trap_notify(struct devlink
*devlink
,
7896 const struct devlink_trap_item
*trap_item
,
7897 enum devlink_command cmd
)
7899 struct sk_buff
*msg
;
7902 WARN_ON_ONCE(cmd
!= DEVLINK_CMD_TRAP_NEW
&&
7903 cmd
!= DEVLINK_CMD_TRAP_DEL
);
7905 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
7909 err
= devlink_nl_trap_fill(msg
, devlink
, trap_item
, cmd
, 0, 0, 0);
7915 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
7916 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
7920 devlink_trap_register(struct devlink
*devlink
,
7921 const struct devlink_trap
*trap
, void *priv
)
7923 struct devlink_trap_item
*trap_item
;
7926 if (devlink_trap_item_lookup(devlink
, trap
->name
))
7929 trap_item
= kzalloc(sizeof(*trap_item
), GFP_KERNEL
);
7933 trap_item
->stats
= netdev_alloc_pcpu_stats(struct devlink_stats
);
7934 if (!trap_item
->stats
) {
7936 goto err_stats_alloc
;
7939 trap_item
->trap
= trap
;
7940 trap_item
->action
= trap
->init_action
;
7941 trap_item
->priv
= priv
;
7943 err
= devlink_trap_item_group_link(devlink
, trap_item
);
7945 goto err_group_link
;
7947 err
= devlink
->ops
->trap_init(devlink
, trap
, trap_item
);
7951 list_add_tail(&trap_item
->list
, &devlink
->trap_list
);
7952 devlink_trap_notify(devlink
, trap_item
, DEVLINK_CMD_TRAP_NEW
);
7957 devlink_trap_item_group_unlink(devlink
, trap_item
);
7959 free_percpu(trap_item
->stats
);
7965 static void devlink_trap_unregister(struct devlink
*devlink
,
7966 const struct devlink_trap
*trap
)
7968 struct devlink_trap_item
*trap_item
;
7970 trap_item
= devlink_trap_item_lookup(devlink
, trap
->name
);
7971 if (WARN_ON_ONCE(!trap_item
))
7974 devlink_trap_notify(devlink
, trap_item
, DEVLINK_CMD_TRAP_DEL
);
7975 list_del(&trap_item
->list
);
7976 if (devlink
->ops
->trap_fini
)
7977 devlink
->ops
->trap_fini(devlink
, trap
, trap_item
);
7978 devlink_trap_item_group_unlink(devlink
, trap_item
);
7979 free_percpu(trap_item
->stats
);
7983 static void devlink_trap_disable(struct devlink
*devlink
,
7984 const struct devlink_trap
*trap
)
7986 struct devlink_trap_item
*trap_item
;
7988 trap_item
= devlink_trap_item_lookup(devlink
, trap
->name
);
7989 if (WARN_ON_ONCE(!trap_item
))
7992 devlink
->ops
->trap_action_set(devlink
, trap
, DEVLINK_TRAP_ACTION_DROP
);
7993 trap_item
->action
= DEVLINK_TRAP_ACTION_DROP
;
7997 * devlink_traps_register - Register packet traps with devlink.
7998 * @devlink: devlink.
7999 * @traps: Packet traps.
8000 * @traps_count: Count of provided packet traps.
8001 * @priv: Driver private information.
8003 * Return: Non-zero value on failure.
8005 int devlink_traps_register(struct devlink
*devlink
,
8006 const struct devlink_trap
*traps
,
8007 size_t traps_count
, void *priv
)
8011 if (!devlink
->ops
->trap_init
|| !devlink
->ops
->trap_action_set
)
8014 mutex_lock(&devlink
->lock
);
8015 for (i
= 0; i
< traps_count
; i
++) {
8016 const struct devlink_trap
*trap
= &traps
[i
];
8018 err
= devlink_trap_verify(trap
);
8020 goto err_trap_verify
;
8022 err
= devlink_trap_register(devlink
, trap
, priv
);
8024 goto err_trap_register
;
8026 mutex_unlock(&devlink
->lock
);
8032 for (i
--; i
>= 0; i
--)
8033 devlink_trap_unregister(devlink
, &traps
[i
]);
8034 mutex_unlock(&devlink
->lock
);
8037 EXPORT_SYMBOL_GPL(devlink_traps_register
);
8040 * devlink_traps_unregister - Unregister packet traps from devlink.
8041 * @devlink: devlink.
8042 * @traps: Packet traps.
8043 * @traps_count: Count of provided packet traps.
8045 void devlink_traps_unregister(struct devlink
*devlink
,
8046 const struct devlink_trap
*traps
,
8051 mutex_lock(&devlink
->lock
);
8052 /* Make sure we do not have any packets in-flight while unregistering
8053 * traps by disabling all of them and waiting for a grace period.
8055 for (i
= traps_count
- 1; i
>= 0; i
--)
8056 devlink_trap_disable(devlink
, &traps
[i
]);
8058 for (i
= traps_count
- 1; i
>= 0; i
--)
8059 devlink_trap_unregister(devlink
, &traps
[i
]);
8060 mutex_unlock(&devlink
->lock
);
8062 EXPORT_SYMBOL_GPL(devlink_traps_unregister
);
8065 devlink_trap_stats_update(struct devlink_stats __percpu
*trap_stats
,
8068 struct devlink_stats
*stats
;
8070 stats
= this_cpu_ptr(trap_stats
);
8071 u64_stats_update_begin(&stats
->syncp
);
8072 stats
->rx_bytes
+= skb_len
;
8073 stats
->rx_packets
++;
8074 u64_stats_update_end(&stats
->syncp
);
8078 devlink_trap_report_metadata_fill(struct net_dm_hw_metadata
*hw_metadata
,
8079 const struct devlink_trap_item
*trap_item
,
8080 struct devlink_port
*in_devlink_port
)
8082 struct devlink_trap_group_item
*group_item
= trap_item
->group_item
;
8084 hw_metadata
->trap_group_name
= group_item
->group
->name
;
8085 hw_metadata
->trap_name
= trap_item
->trap
->name
;
8087 spin_lock(&in_devlink_port
->type_lock
);
8088 if (in_devlink_port
->type
== DEVLINK_PORT_TYPE_ETH
)
8089 hw_metadata
->input_dev
= in_devlink_port
->type_dev
;
8090 spin_unlock(&in_devlink_port
->type_lock
);
8094 * devlink_trap_report - Report trapped packet to drop monitor.
8095 * @devlink: devlink.
8096 * @skb: Trapped packet.
8097 * @trap_ctx: Trap context.
8098 * @in_devlink_port: Input devlink port.
8100 void devlink_trap_report(struct devlink
*devlink
, struct sk_buff
*skb
,
8101 void *trap_ctx
, struct devlink_port
*in_devlink_port
)
8103 struct devlink_trap_item
*trap_item
= trap_ctx
;
8104 struct net_dm_hw_metadata hw_metadata
= {};
8106 devlink_trap_stats_update(trap_item
->stats
, skb
->len
);
8107 devlink_trap_stats_update(trap_item
->group_item
->stats
, skb
->len
);
8109 devlink_trap_report_metadata_fill(&hw_metadata
, trap_item
,
8111 net_dm_hw_report(skb
, &hw_metadata
);
8113 EXPORT_SYMBOL_GPL(devlink_trap_report
);
8116 * devlink_trap_ctx_priv - Trap context to driver private information.
8117 * @trap_ctx: Trap context.
8119 * Return: Driver private information passed during registration.
8121 void *devlink_trap_ctx_priv(void *trap_ctx
)
8123 struct devlink_trap_item
*trap_item
= trap_ctx
;
8125 return trap_item
->priv
;
8127 EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv
);
8129 static void __devlink_compat_running_version(struct devlink
*devlink
,
8130 char *buf
, size_t len
)
8132 const struct nlattr
*nlattr
;
8133 struct devlink_info_req req
;
8134 struct sk_buff
*msg
;
8137 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
8142 err
= devlink
->ops
->info_get(devlink
, &req
, NULL
);
8146 nla_for_each_attr(nlattr
, (void *)msg
->data
, msg
->len
, rem
) {
8147 const struct nlattr
*kv
;
8150 if (nla_type(nlattr
) != DEVLINK_ATTR_INFO_VERSION_RUNNING
)
8153 nla_for_each_nested(kv
, nlattr
, rem_kv
) {
8154 if (nla_type(kv
) != DEVLINK_ATTR_INFO_VERSION_VALUE
)
8157 strlcat(buf
, nla_data(kv
), len
);
8158 strlcat(buf
, " ", len
);
8165 void devlink_compat_running_version(struct net_device
*dev
,
8166 char *buf
, size_t len
)
8168 struct devlink
*devlink
;
8173 devlink
= netdev_to_devlink(dev
);
8174 if (!devlink
|| !devlink
->ops
->info_get
)
8177 mutex_lock(&devlink
->lock
);
8178 __devlink_compat_running_version(devlink
, buf
, len
);
8179 mutex_unlock(&devlink
->lock
);
8186 int devlink_compat_flash_update(struct net_device
*dev
, const char *file_name
)
8188 struct devlink
*devlink
;
8194 devlink
= netdev_to_devlink(dev
);
8195 if (!devlink
|| !devlink
->ops
->flash_update
) {
8200 mutex_lock(&devlink
->lock
);
8201 ret
= devlink
->ops
->flash_update(devlink
, file_name
, NULL
, NULL
);
8202 mutex_unlock(&devlink
->lock
);
8211 int devlink_compat_phys_port_name_get(struct net_device
*dev
,
8212 char *name
, size_t len
)
8214 struct devlink_port
*devlink_port
;
8216 /* RTNL mutex is held here which ensures that devlink_port
8217 * instance cannot disappear in the middle. No need to take
8218 * any devlink lock as only permanent values are accessed.
8222 devlink_port
= netdev_to_devlink_port(dev
);
8226 return __devlink_port_phys_port_name_get(devlink_port
, name
, len
);
8229 int devlink_compat_switch_id_get(struct net_device
*dev
,
8230 struct netdev_phys_item_id
*ppid
)
8232 struct devlink_port
*devlink_port
;
8234 /* Caller must hold RTNL mutex or reference to dev, which ensures that
8235 * devlink_port instance cannot disappear in the middle. No need to take
8236 * any devlink lock as only permanent values are accessed.
8238 devlink_port
= netdev_to_devlink_port(dev
);
8239 if (!devlink_port
|| !devlink_port
->attrs
.switch_port
)
8242 memcpy(ppid
, &devlink_port
->attrs
.switch_id
, sizeof(*ppid
));
8247 static void __net_exit
devlink_pernet_pre_exit(struct net
*net
)
8249 struct devlink
*devlink
;
8252 /* In case network namespace is getting destroyed, reload
8253 * all devlink instances from this namespace into init_net.
8255 mutex_lock(&devlink_mutex
);
8256 list_for_each_entry(devlink
, &devlink_list
, list
) {
8257 if (net_eq(devlink_net(devlink
), net
)) {
8258 if (WARN_ON(!devlink_reload_supported(devlink
)))
8260 err
= devlink_reload(devlink
, &init_net
, NULL
);
8261 if (err
&& err
!= -EOPNOTSUPP
)
8262 pr_warn("Failed to reload devlink instance into init_net\n");
8265 mutex_unlock(&devlink_mutex
);
8268 static struct pernet_operations devlink_pernet_ops __net_initdata
= {
8269 .pre_exit
= devlink_pernet_pre_exit
,
8272 static int __init
devlink_init(void)
8276 err
= genl_register_family(&devlink_nl_family
);
8279 err
= register_pernet_subsys(&devlink_pernet_ops
);
8286 subsys_initcall(devlink_init
);