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_nl_health_reporter_fill(struct sk_buff
*msg
,
4848 struct devlink
*devlink
,
4849 struct devlink_health_reporter
*reporter
,
4850 enum devlink_command cmd
, u32 portid
,
4853 struct nlattr
*reporter_attr
;
4856 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
4860 if (devlink_nl_put_handle(msg
, devlink
))
4861 goto genlmsg_cancel
;
4863 reporter_attr
= nla_nest_start_noflag(msg
,
4864 DEVLINK_ATTR_HEALTH_REPORTER
);
4866 goto genlmsg_cancel
;
4867 if (nla_put_string(msg
, DEVLINK_ATTR_HEALTH_REPORTER_NAME
,
4868 reporter
->ops
->name
))
4869 goto reporter_nest_cancel
;
4870 if (nla_put_u8(msg
, DEVLINK_ATTR_HEALTH_REPORTER_STATE
,
4871 reporter
->health_state
))
4872 goto reporter_nest_cancel
;
4873 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT
,
4874 reporter
->error_count
, DEVLINK_ATTR_PAD
))
4875 goto reporter_nest_cancel
;
4876 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT
,
4877 reporter
->recovery_count
, DEVLINK_ATTR_PAD
))
4878 goto reporter_nest_cancel
;
4879 if (reporter
->ops
->recover
&&
4880 nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
,
4881 reporter
->graceful_period
,
4883 goto reporter_nest_cancel
;
4884 if (reporter
->ops
->recover
&&
4885 nla_put_u8(msg
, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
,
4886 reporter
->auto_recover
))
4887 goto reporter_nest_cancel
;
4888 if (reporter
->dump_fmsg
&&
4889 nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS
,
4890 jiffies_to_msecs(reporter
->dump_ts
),
4892 goto reporter_nest_cancel
;
4893 if (reporter
->dump_fmsg
&&
4894 nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS
,
4895 reporter
->dump_real_ts
, DEVLINK_ATTR_PAD
))
4896 goto reporter_nest_cancel
;
4898 nla_nest_end(msg
, reporter_attr
);
4899 genlmsg_end(msg
, hdr
);
4902 reporter_nest_cancel
:
4903 nla_nest_end(msg
, reporter_attr
);
4905 genlmsg_cancel(msg
, hdr
);
4909 static void devlink_recover_notify(struct devlink_health_reporter
*reporter
,
4910 enum devlink_command cmd
)
4912 struct sk_buff
*msg
;
4915 WARN_ON(cmd
!= DEVLINK_CMD_HEALTH_REPORTER_RECOVER
);
4917 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
4921 err
= devlink_nl_health_reporter_fill(msg
, reporter
->devlink
,
4922 reporter
, cmd
, 0, 0, 0);
4928 genlmsg_multicast_netns(&devlink_nl_family
,
4929 devlink_net(reporter
->devlink
),
4930 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
4934 devlink_health_reporter_recovery_done(struct devlink_health_reporter
*reporter
)
4936 reporter
->recovery_count
++;
4937 reporter
->last_recovery_ts
= jiffies
;
4939 EXPORT_SYMBOL_GPL(devlink_health_reporter_recovery_done
);
4942 devlink_health_reporter_recover(struct devlink_health_reporter
*reporter
,
4943 void *priv_ctx
, struct netlink_ext_ack
*extack
)
4947 if (reporter
->health_state
== DEVLINK_HEALTH_REPORTER_STATE_HEALTHY
)
4950 if (!reporter
->ops
->recover
)
4953 err
= reporter
->ops
->recover(reporter
, priv_ctx
, extack
);
4957 devlink_health_reporter_recovery_done(reporter
);
4958 reporter
->health_state
= DEVLINK_HEALTH_REPORTER_STATE_HEALTHY
;
4959 devlink_recover_notify(reporter
, DEVLINK_CMD_HEALTH_REPORTER_RECOVER
);
4965 devlink_health_dump_clear(struct devlink_health_reporter
*reporter
)
4967 if (!reporter
->dump_fmsg
)
4969 devlink_fmsg_free(reporter
->dump_fmsg
);
4970 reporter
->dump_fmsg
= NULL
;
4973 static int devlink_health_do_dump(struct devlink_health_reporter
*reporter
,
4975 struct netlink_ext_ack
*extack
)
4979 if (!reporter
->ops
->dump
)
4982 if (reporter
->dump_fmsg
)
4985 reporter
->dump_fmsg
= devlink_fmsg_alloc();
4986 if (!reporter
->dump_fmsg
) {
4991 err
= devlink_fmsg_obj_nest_start(reporter
->dump_fmsg
);
4995 err
= reporter
->ops
->dump(reporter
, reporter
->dump_fmsg
,
5000 err
= devlink_fmsg_obj_nest_end(reporter
->dump_fmsg
);
5004 reporter
->dump_ts
= jiffies
;
5005 reporter
->dump_real_ts
= ktime_get_real_ns();
5010 devlink_health_dump_clear(reporter
);
5014 int devlink_health_report(struct devlink_health_reporter
*reporter
,
5015 const char *msg
, void *priv_ctx
)
5017 enum devlink_health_reporter_state prev_health_state
;
5018 struct devlink
*devlink
= reporter
->devlink
;
5020 /* write a log message of the current error */
5022 trace_devlink_health_report(devlink
, reporter
->ops
->name
, msg
);
5023 reporter
->error_count
++;
5024 prev_health_state
= reporter
->health_state
;
5025 reporter
->health_state
= DEVLINK_HEALTH_REPORTER_STATE_ERROR
;
5026 devlink_recover_notify(reporter
, DEVLINK_CMD_HEALTH_REPORTER_RECOVER
);
5028 /* abort if the previous error wasn't recovered */
5029 if (reporter
->auto_recover
&&
5030 (prev_health_state
!= DEVLINK_HEALTH_REPORTER_STATE_HEALTHY
||
5031 jiffies
- reporter
->last_recovery_ts
<
5032 msecs_to_jiffies(reporter
->graceful_period
))) {
5033 trace_devlink_health_recover_aborted(devlink
,
5034 reporter
->ops
->name
,
5035 reporter
->health_state
,
5037 reporter
->last_recovery_ts
);
5041 reporter
->health_state
= DEVLINK_HEALTH_REPORTER_STATE_ERROR
;
5043 mutex_lock(&reporter
->dump_lock
);
5044 /* store current dump of current error, for later analysis */
5045 devlink_health_do_dump(reporter
, priv_ctx
, NULL
);
5046 mutex_unlock(&reporter
->dump_lock
);
5048 if (reporter
->auto_recover
)
5049 return devlink_health_reporter_recover(reporter
,
5054 EXPORT_SYMBOL_GPL(devlink_health_report
);
5056 static struct devlink_health_reporter
*
5057 devlink_health_reporter_get_from_attrs(struct devlink
*devlink
,
5058 struct nlattr
**attrs
)
5060 struct devlink_health_reporter
*reporter
;
5061 char *reporter_name
;
5063 if (!attrs
[DEVLINK_ATTR_HEALTH_REPORTER_NAME
])
5066 reporter_name
= nla_data(attrs
[DEVLINK_ATTR_HEALTH_REPORTER_NAME
]);
5067 mutex_lock(&devlink
->reporters_lock
);
5068 reporter
= devlink_health_reporter_find_by_name(devlink
, reporter_name
);
5070 refcount_inc(&reporter
->refcount
);
5071 mutex_unlock(&devlink
->reporters_lock
);
5075 static struct devlink_health_reporter
*
5076 devlink_health_reporter_get_from_info(struct devlink
*devlink
,
5077 struct genl_info
*info
)
5079 return devlink_health_reporter_get_from_attrs(devlink
, info
->attrs
);
5082 static struct devlink_health_reporter
*
5083 devlink_health_reporter_get_from_cb(struct netlink_callback
*cb
)
5085 const struct genl_dumpit_info
*info
= genl_dumpit_info(cb
);
5086 struct devlink_health_reporter
*reporter
;
5087 struct nlattr
**attrs
= info
->attrs
;
5088 struct devlink
*devlink
;
5090 mutex_lock(&devlink_mutex
);
5091 devlink
= devlink_get_from_attrs(sock_net(cb
->skb
->sk
), attrs
);
5092 if (IS_ERR(devlink
))
5095 reporter
= devlink_health_reporter_get_from_attrs(devlink
, attrs
);
5096 mutex_unlock(&devlink_mutex
);
5099 mutex_unlock(&devlink_mutex
);
5104 devlink_health_reporter_put(struct devlink_health_reporter
*reporter
)
5106 refcount_dec(&reporter
->refcount
);
5110 devlink_health_reporter_state_update(struct devlink_health_reporter
*reporter
,
5111 enum devlink_health_reporter_state state
)
5113 if (WARN_ON(state
!= DEVLINK_HEALTH_REPORTER_STATE_HEALTHY
&&
5114 state
!= DEVLINK_HEALTH_REPORTER_STATE_ERROR
))
5117 if (reporter
->health_state
== state
)
5120 reporter
->health_state
= state
;
5121 trace_devlink_health_reporter_state_update(reporter
->devlink
,
5122 reporter
->ops
->name
, state
);
5123 devlink_recover_notify(reporter
, DEVLINK_CMD_HEALTH_REPORTER_RECOVER
);
5125 EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update
);
5127 static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff
*skb
,
5128 struct genl_info
*info
)
5130 struct devlink
*devlink
= info
->user_ptr
[0];
5131 struct devlink_health_reporter
*reporter
;
5132 struct sk_buff
*msg
;
5135 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5139 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
5145 err
= devlink_nl_health_reporter_fill(msg
, devlink
, reporter
,
5146 DEVLINK_CMD_HEALTH_REPORTER_GET
,
5147 info
->snd_portid
, info
->snd_seq
,
5154 err
= genlmsg_reply(msg
, info
);
5156 devlink_health_reporter_put(reporter
);
5161 devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff
*msg
,
5162 struct netlink_callback
*cb
)
5164 struct devlink_health_reporter
*reporter
;
5165 struct devlink
*devlink
;
5166 int start
= cb
->args
[0];
5170 mutex_lock(&devlink_mutex
);
5171 list_for_each_entry(devlink
, &devlink_list
, list
) {
5172 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
5174 mutex_lock(&devlink
->reporters_lock
);
5175 list_for_each_entry(reporter
, &devlink
->reporter_list
,
5181 err
= devlink_nl_health_reporter_fill(msg
, devlink
,
5183 DEVLINK_CMD_HEALTH_REPORTER_GET
,
5184 NETLINK_CB(cb
->skb
).portid
,
5188 mutex_unlock(&devlink
->reporters_lock
);
5193 mutex_unlock(&devlink
->reporters_lock
);
5196 mutex_unlock(&devlink_mutex
);
5203 devlink_nl_cmd_health_reporter_set_doit(struct sk_buff
*skb
,
5204 struct genl_info
*info
)
5206 struct devlink
*devlink
= info
->user_ptr
[0];
5207 struct devlink_health_reporter
*reporter
;
5210 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5214 if (!reporter
->ops
->recover
&&
5215 (info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
] ||
5216 info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
])) {
5221 if (info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
])
5222 reporter
->graceful_period
=
5223 nla_get_u64(info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
]);
5225 if (info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
])
5226 reporter
->auto_recover
=
5227 nla_get_u8(info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
]);
5229 devlink_health_reporter_put(reporter
);
5232 devlink_health_reporter_put(reporter
);
5236 static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff
*skb
,
5237 struct genl_info
*info
)
5239 struct devlink
*devlink
= info
->user_ptr
[0];
5240 struct devlink_health_reporter
*reporter
;
5243 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5247 err
= devlink_health_reporter_recover(reporter
, NULL
, info
->extack
);
5249 devlink_health_reporter_put(reporter
);
5253 static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff
*skb
,
5254 struct genl_info
*info
)
5256 struct devlink
*devlink
= info
->user_ptr
[0];
5257 struct devlink_health_reporter
*reporter
;
5258 struct devlink_fmsg
*fmsg
;
5261 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5265 if (!reporter
->ops
->diagnose
) {
5266 devlink_health_reporter_put(reporter
);
5270 fmsg
= devlink_fmsg_alloc();
5272 devlink_health_reporter_put(reporter
);
5276 err
= devlink_fmsg_obj_nest_start(fmsg
);
5280 err
= reporter
->ops
->diagnose(reporter
, fmsg
, info
->extack
);
5284 err
= devlink_fmsg_obj_nest_end(fmsg
);
5288 err
= devlink_fmsg_snd(fmsg
, info
,
5289 DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE
, 0);
5292 devlink_fmsg_free(fmsg
);
5293 devlink_health_reporter_put(reporter
);
5298 devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff
*skb
,
5299 struct netlink_callback
*cb
)
5301 struct devlink_health_reporter
*reporter
;
5302 u64 start
= cb
->args
[0];
5305 reporter
= devlink_health_reporter_get_from_cb(cb
);
5309 if (!reporter
->ops
->dump
) {
5313 mutex_lock(&reporter
->dump_lock
);
5315 err
= devlink_health_do_dump(reporter
, NULL
, cb
->extack
);
5318 cb
->args
[1] = reporter
->dump_ts
;
5320 if (!reporter
->dump_fmsg
|| cb
->args
[1] != reporter
->dump_ts
) {
5321 NL_SET_ERR_MSG_MOD(cb
->extack
, "Dump trampled, please retry");
5326 err
= devlink_fmsg_dumpit(reporter
->dump_fmsg
, skb
, cb
,
5327 DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET
);
5329 mutex_unlock(&reporter
->dump_lock
);
5331 devlink_health_reporter_put(reporter
);
5336 devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff
*skb
,
5337 struct genl_info
*info
)
5339 struct devlink
*devlink
= info
->user_ptr
[0];
5340 struct devlink_health_reporter
*reporter
;
5342 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5346 if (!reporter
->ops
->dump
) {
5347 devlink_health_reporter_put(reporter
);
5351 mutex_lock(&reporter
->dump_lock
);
5352 devlink_health_dump_clear(reporter
);
5353 mutex_unlock(&reporter
->dump_lock
);
5354 devlink_health_reporter_put(reporter
);
5358 struct devlink_stats
{
5361 struct u64_stats_sync syncp
;
5365 * struct devlink_trap_group_item - Packet trap group attributes.
5366 * @group: Immutable packet trap group attributes.
5367 * @refcount: Number of trap items using the group.
5368 * @list: trap_group_list member.
5369 * @stats: Trap group statistics.
5371 * Describes packet trap group attributes. Created by devlink during trap
5374 struct devlink_trap_group_item
{
5375 const struct devlink_trap_group
*group
;
5376 refcount_t refcount
;
5377 struct list_head list
;
5378 struct devlink_stats __percpu
*stats
;
5382 * struct devlink_trap_item - Packet trap attributes.
5383 * @trap: Immutable packet trap attributes.
5384 * @group_item: Associated group item.
5385 * @list: trap_list member.
5386 * @action: Trap action.
5387 * @stats: Trap statistics.
5388 * @priv: Driver private information.
5390 * Describes both mutable and immutable packet trap attributes. Created by
5391 * devlink during trap registration and used for all trap related operations.
5393 struct devlink_trap_item
{
5394 const struct devlink_trap
*trap
;
5395 struct devlink_trap_group_item
*group_item
;
5396 struct list_head list
;
5397 enum devlink_trap_action action
;
5398 struct devlink_stats __percpu
*stats
;
5402 static struct devlink_trap_item
*
5403 devlink_trap_item_lookup(struct devlink
*devlink
, const char *name
)
5405 struct devlink_trap_item
*trap_item
;
5407 list_for_each_entry(trap_item
, &devlink
->trap_list
, list
) {
5408 if (!strcmp(trap_item
->trap
->name
, name
))
5415 static struct devlink_trap_item
*
5416 devlink_trap_item_get_from_info(struct devlink
*devlink
,
5417 struct genl_info
*info
)
5419 struct nlattr
*attr
;
5421 if (!info
->attrs
[DEVLINK_ATTR_TRAP_NAME
])
5423 attr
= info
->attrs
[DEVLINK_ATTR_TRAP_NAME
];
5425 return devlink_trap_item_lookup(devlink
, nla_data(attr
));
5429 devlink_trap_action_get_from_info(struct genl_info
*info
,
5430 enum devlink_trap_action
*p_trap_action
)
5434 val
= nla_get_u8(info
->attrs
[DEVLINK_ATTR_TRAP_ACTION
]);
5436 case DEVLINK_TRAP_ACTION_DROP
: /* fall-through */
5437 case DEVLINK_TRAP_ACTION_TRAP
:
5438 *p_trap_action
= val
;
5447 static int devlink_trap_metadata_put(struct sk_buff
*msg
,
5448 const struct devlink_trap
*trap
)
5450 struct nlattr
*attr
;
5452 attr
= nla_nest_start(msg
, DEVLINK_ATTR_TRAP_METADATA
);
5456 if ((trap
->metadata_cap
& DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT
) &&
5457 nla_put_flag(msg
, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT
))
5458 goto nla_put_failure
;
5460 nla_nest_end(msg
, attr
);
5465 nla_nest_cancel(msg
, attr
);
5469 static void devlink_trap_stats_read(struct devlink_stats __percpu
*trap_stats
,
5470 struct devlink_stats
*stats
)
5474 memset(stats
, 0, sizeof(*stats
));
5475 for_each_possible_cpu(i
) {
5476 struct devlink_stats
*cpu_stats
;
5477 u64 rx_packets
, rx_bytes
;
5480 cpu_stats
= per_cpu_ptr(trap_stats
, i
);
5482 start
= u64_stats_fetch_begin_irq(&cpu_stats
->syncp
);
5483 rx_packets
= cpu_stats
->rx_packets
;
5484 rx_bytes
= cpu_stats
->rx_bytes
;
5485 } while (u64_stats_fetch_retry_irq(&cpu_stats
->syncp
, start
));
5487 stats
->rx_packets
+= rx_packets
;
5488 stats
->rx_bytes
+= rx_bytes
;
5492 static int devlink_trap_stats_put(struct sk_buff
*msg
,
5493 struct devlink_stats __percpu
*trap_stats
)
5495 struct devlink_stats stats
;
5496 struct nlattr
*attr
;
5498 devlink_trap_stats_read(trap_stats
, &stats
);
5500 attr
= nla_nest_start(msg
, DEVLINK_ATTR_STATS
);
5504 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_STATS_RX_PACKETS
,
5505 stats
.rx_packets
, DEVLINK_ATTR_PAD
))
5506 goto nla_put_failure
;
5508 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_STATS_RX_BYTES
,
5509 stats
.rx_bytes
, DEVLINK_ATTR_PAD
))
5510 goto nla_put_failure
;
5512 nla_nest_end(msg
, attr
);
5517 nla_nest_cancel(msg
, attr
);
5521 static int devlink_nl_trap_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
5522 const struct devlink_trap_item
*trap_item
,
5523 enum devlink_command cmd
, u32 portid
, u32 seq
,
5526 struct devlink_trap_group_item
*group_item
= trap_item
->group_item
;
5530 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
5534 if (devlink_nl_put_handle(msg
, devlink
))
5535 goto nla_put_failure
;
5537 if (nla_put_string(msg
, DEVLINK_ATTR_TRAP_GROUP_NAME
,
5538 group_item
->group
->name
))
5539 goto nla_put_failure
;
5541 if (nla_put_string(msg
, DEVLINK_ATTR_TRAP_NAME
, trap_item
->trap
->name
))
5542 goto nla_put_failure
;
5544 if (nla_put_u8(msg
, DEVLINK_ATTR_TRAP_TYPE
, trap_item
->trap
->type
))
5545 goto nla_put_failure
;
5547 if (trap_item
->trap
->generic
&&
5548 nla_put_flag(msg
, DEVLINK_ATTR_TRAP_GENERIC
))
5549 goto nla_put_failure
;
5551 if (nla_put_u8(msg
, DEVLINK_ATTR_TRAP_ACTION
, trap_item
->action
))
5552 goto nla_put_failure
;
5554 err
= devlink_trap_metadata_put(msg
, trap_item
->trap
);
5556 goto nla_put_failure
;
5558 err
= devlink_trap_stats_put(msg
, trap_item
->stats
);
5560 goto nla_put_failure
;
5562 genlmsg_end(msg
, hdr
);
5567 genlmsg_cancel(msg
, hdr
);
5571 static int devlink_nl_cmd_trap_get_doit(struct sk_buff
*skb
,
5572 struct genl_info
*info
)
5574 struct netlink_ext_ack
*extack
= info
->extack
;
5575 struct devlink
*devlink
= info
->user_ptr
[0];
5576 struct devlink_trap_item
*trap_item
;
5577 struct sk_buff
*msg
;
5580 if (list_empty(&devlink
->trap_list
))
5583 trap_item
= devlink_trap_item_get_from_info(devlink
, info
);
5585 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap");
5589 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
5593 err
= devlink_nl_trap_fill(msg
, devlink
, trap_item
,
5594 DEVLINK_CMD_TRAP_NEW
, info
->snd_portid
,
5599 return genlmsg_reply(msg
, info
);
5606 static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff
*msg
,
5607 struct netlink_callback
*cb
)
5609 struct devlink_trap_item
*trap_item
;
5610 struct devlink
*devlink
;
5611 int start
= cb
->args
[0];
5615 mutex_lock(&devlink_mutex
);
5616 list_for_each_entry(devlink
, &devlink_list
, list
) {
5617 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
5619 mutex_lock(&devlink
->lock
);
5620 list_for_each_entry(trap_item
, &devlink
->trap_list
, list
) {
5625 err
= devlink_nl_trap_fill(msg
, devlink
, trap_item
,
5626 DEVLINK_CMD_TRAP_NEW
,
5627 NETLINK_CB(cb
->skb
).portid
,
5631 mutex_unlock(&devlink
->lock
);
5636 mutex_unlock(&devlink
->lock
);
5639 mutex_unlock(&devlink_mutex
);
5645 static int __devlink_trap_action_set(struct devlink
*devlink
,
5646 struct devlink_trap_item
*trap_item
,
5647 enum devlink_trap_action trap_action
,
5648 struct netlink_ext_ack
*extack
)
5652 if (trap_item
->action
!= trap_action
&&
5653 trap_item
->trap
->type
!= DEVLINK_TRAP_TYPE_DROP
) {
5654 NL_SET_ERR_MSG_MOD(extack
, "Cannot change action of non-drop traps. Skipping");
5658 err
= devlink
->ops
->trap_action_set(devlink
, trap_item
->trap
,
5663 trap_item
->action
= trap_action
;
5668 static int devlink_trap_action_set(struct devlink
*devlink
,
5669 struct devlink_trap_item
*trap_item
,
5670 struct genl_info
*info
)
5672 enum devlink_trap_action trap_action
;
5675 if (!info
->attrs
[DEVLINK_ATTR_TRAP_ACTION
])
5678 err
= devlink_trap_action_get_from_info(info
, &trap_action
);
5680 NL_SET_ERR_MSG_MOD(info
->extack
, "Invalid trap action");
5684 return __devlink_trap_action_set(devlink
, trap_item
, trap_action
,
5688 static int devlink_nl_cmd_trap_set_doit(struct sk_buff
*skb
,
5689 struct genl_info
*info
)
5691 struct netlink_ext_ack
*extack
= info
->extack
;
5692 struct devlink
*devlink
= info
->user_ptr
[0];
5693 struct devlink_trap_item
*trap_item
;
5696 if (list_empty(&devlink
->trap_list
))
5699 trap_item
= devlink_trap_item_get_from_info(devlink
, info
);
5701 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap");
5705 err
= devlink_trap_action_set(devlink
, trap_item
, info
);
5712 static struct devlink_trap_group_item
*
5713 devlink_trap_group_item_lookup(struct devlink
*devlink
, const char *name
)
5715 struct devlink_trap_group_item
*group_item
;
5717 list_for_each_entry(group_item
, &devlink
->trap_group_list
, list
) {
5718 if (!strcmp(group_item
->group
->name
, name
))
5725 static struct devlink_trap_group_item
*
5726 devlink_trap_group_item_get_from_info(struct devlink
*devlink
,
5727 struct genl_info
*info
)
5731 if (!info
->attrs
[DEVLINK_ATTR_TRAP_GROUP_NAME
])
5733 name
= nla_data(info
->attrs
[DEVLINK_ATTR_TRAP_GROUP_NAME
]);
5735 return devlink_trap_group_item_lookup(devlink
, name
);
5739 devlink_nl_trap_group_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
5740 const struct devlink_trap_group_item
*group_item
,
5741 enum devlink_command cmd
, u32 portid
, u32 seq
,
5747 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
5751 if (devlink_nl_put_handle(msg
, devlink
))
5752 goto nla_put_failure
;
5754 if (nla_put_string(msg
, DEVLINK_ATTR_TRAP_GROUP_NAME
,
5755 group_item
->group
->name
))
5756 goto nla_put_failure
;
5758 if (group_item
->group
->generic
&&
5759 nla_put_flag(msg
, DEVLINK_ATTR_TRAP_GENERIC
))
5760 goto nla_put_failure
;
5762 err
= devlink_trap_stats_put(msg
, group_item
->stats
);
5764 goto nla_put_failure
;
5766 genlmsg_end(msg
, hdr
);
5771 genlmsg_cancel(msg
, hdr
);
5775 static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff
*skb
,
5776 struct genl_info
*info
)
5778 struct netlink_ext_ack
*extack
= info
->extack
;
5779 struct devlink
*devlink
= info
->user_ptr
[0];
5780 struct devlink_trap_group_item
*group_item
;
5781 struct sk_buff
*msg
;
5784 if (list_empty(&devlink
->trap_group_list
))
5787 group_item
= devlink_trap_group_item_get_from_info(devlink
, info
);
5789 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap group");
5793 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
5797 err
= devlink_nl_trap_group_fill(msg
, devlink
, group_item
,
5798 DEVLINK_CMD_TRAP_GROUP_NEW
,
5799 info
->snd_portid
, info
->snd_seq
, 0);
5801 goto err_trap_group_fill
;
5803 return genlmsg_reply(msg
, info
);
5805 err_trap_group_fill
:
5810 static int devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff
*msg
,
5811 struct netlink_callback
*cb
)
5813 enum devlink_command cmd
= DEVLINK_CMD_TRAP_GROUP_NEW
;
5814 struct devlink_trap_group_item
*group_item
;
5815 u32 portid
= NETLINK_CB(cb
->skb
).portid
;
5816 struct devlink
*devlink
;
5817 int start
= cb
->args
[0];
5821 mutex_lock(&devlink_mutex
);
5822 list_for_each_entry(devlink
, &devlink_list
, list
) {
5823 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
5825 mutex_lock(&devlink
->lock
);
5826 list_for_each_entry(group_item
, &devlink
->trap_group_list
,
5832 err
= devlink_nl_trap_group_fill(msg
, devlink
,
5838 mutex_unlock(&devlink
->lock
);
5843 mutex_unlock(&devlink
->lock
);
5846 mutex_unlock(&devlink_mutex
);
5853 __devlink_trap_group_action_set(struct devlink
*devlink
,
5854 struct devlink_trap_group_item
*group_item
,
5855 enum devlink_trap_action trap_action
,
5856 struct netlink_ext_ack
*extack
)
5858 const char *group_name
= group_item
->group
->name
;
5859 struct devlink_trap_item
*trap_item
;
5862 list_for_each_entry(trap_item
, &devlink
->trap_list
, list
) {
5863 if (strcmp(trap_item
->trap
->group
.name
, group_name
))
5865 err
= __devlink_trap_action_set(devlink
, trap_item
,
5866 trap_action
, extack
);
5875 devlink_trap_group_action_set(struct devlink
*devlink
,
5876 struct devlink_trap_group_item
*group_item
,
5877 struct genl_info
*info
)
5879 enum devlink_trap_action trap_action
;
5882 if (!info
->attrs
[DEVLINK_ATTR_TRAP_ACTION
])
5885 err
= devlink_trap_action_get_from_info(info
, &trap_action
);
5887 NL_SET_ERR_MSG_MOD(info
->extack
, "Invalid trap action");
5891 err
= __devlink_trap_group_action_set(devlink
, group_item
, trap_action
,
5899 static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff
*skb
,
5900 struct genl_info
*info
)
5902 struct netlink_ext_ack
*extack
= info
->extack
;
5903 struct devlink
*devlink
= info
->user_ptr
[0];
5904 struct devlink_trap_group_item
*group_item
;
5907 if (list_empty(&devlink
->trap_group_list
))
5910 group_item
= devlink_trap_group_item_get_from_info(devlink
, info
);
5912 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap group");
5916 err
= devlink_trap_group_action_set(devlink
, group_item
, info
);
5923 static const struct nla_policy devlink_nl_policy
[DEVLINK_ATTR_MAX
+ 1] = {
5924 [DEVLINK_ATTR_BUS_NAME
] = { .type
= NLA_NUL_STRING
},
5925 [DEVLINK_ATTR_DEV_NAME
] = { .type
= NLA_NUL_STRING
},
5926 [DEVLINK_ATTR_PORT_INDEX
] = { .type
= NLA_U32
},
5927 [DEVLINK_ATTR_PORT_TYPE
] = { .type
= NLA_U16
},
5928 [DEVLINK_ATTR_PORT_SPLIT_COUNT
] = { .type
= NLA_U32
},
5929 [DEVLINK_ATTR_SB_INDEX
] = { .type
= NLA_U32
},
5930 [DEVLINK_ATTR_SB_POOL_INDEX
] = { .type
= NLA_U16
},
5931 [DEVLINK_ATTR_SB_POOL_TYPE
] = { .type
= NLA_U8
},
5932 [DEVLINK_ATTR_SB_POOL_SIZE
] = { .type
= NLA_U32
},
5933 [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
] = { .type
= NLA_U8
},
5934 [DEVLINK_ATTR_SB_THRESHOLD
] = { .type
= NLA_U32
},
5935 [DEVLINK_ATTR_SB_TC_INDEX
] = { .type
= NLA_U16
},
5936 [DEVLINK_ATTR_ESWITCH_MODE
] = { .type
= NLA_U16
},
5937 [DEVLINK_ATTR_ESWITCH_INLINE_MODE
] = { .type
= NLA_U8
},
5938 [DEVLINK_ATTR_ESWITCH_ENCAP_MODE
] = { .type
= NLA_U8
},
5939 [DEVLINK_ATTR_DPIPE_TABLE_NAME
] = { .type
= NLA_NUL_STRING
},
5940 [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
] = { .type
= NLA_U8
},
5941 [DEVLINK_ATTR_RESOURCE_ID
] = { .type
= NLA_U64
},
5942 [DEVLINK_ATTR_RESOURCE_SIZE
] = { .type
= NLA_U64
},
5943 [DEVLINK_ATTR_PARAM_NAME
] = { .type
= NLA_NUL_STRING
},
5944 [DEVLINK_ATTR_PARAM_TYPE
] = { .type
= NLA_U8
},
5945 [DEVLINK_ATTR_PARAM_VALUE_CMODE
] = { .type
= NLA_U8
},
5946 [DEVLINK_ATTR_REGION_NAME
] = { .type
= NLA_NUL_STRING
},
5947 [DEVLINK_ATTR_REGION_SNAPSHOT_ID
] = { .type
= NLA_U32
},
5948 [DEVLINK_ATTR_HEALTH_REPORTER_NAME
] = { .type
= NLA_NUL_STRING
},
5949 [DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
] = { .type
= NLA_U64
},
5950 [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
] = { .type
= NLA_U8
},
5951 [DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME
] = { .type
= NLA_NUL_STRING
},
5952 [DEVLINK_ATTR_FLASH_UPDATE_COMPONENT
] = { .type
= NLA_NUL_STRING
},
5953 [DEVLINK_ATTR_TRAP_NAME
] = { .type
= NLA_NUL_STRING
},
5954 [DEVLINK_ATTR_TRAP_ACTION
] = { .type
= NLA_U8
},
5955 [DEVLINK_ATTR_TRAP_GROUP_NAME
] = { .type
= NLA_NUL_STRING
},
5956 [DEVLINK_ATTR_NETNS_PID
] = { .type
= NLA_U32
},
5957 [DEVLINK_ATTR_NETNS_FD
] = { .type
= NLA_U32
},
5958 [DEVLINK_ATTR_NETNS_ID
] = { .type
= NLA_U32
},
5961 static const struct genl_ops devlink_nl_ops
[] = {
5963 .cmd
= DEVLINK_CMD_GET
,
5964 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5965 .doit
= devlink_nl_cmd_get_doit
,
5966 .dumpit
= devlink_nl_cmd_get_dumpit
,
5967 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
5968 /* can be retrieved by unprivileged users */
5971 .cmd
= DEVLINK_CMD_PORT_GET
,
5972 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5973 .doit
= devlink_nl_cmd_port_get_doit
,
5974 .dumpit
= devlink_nl_cmd_port_get_dumpit
,
5975 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
5976 /* can be retrieved by unprivileged users */
5979 .cmd
= DEVLINK_CMD_PORT_SET
,
5980 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5981 .doit
= devlink_nl_cmd_port_set_doit
,
5982 .flags
= GENL_ADMIN_PERM
,
5983 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
5986 .cmd
= DEVLINK_CMD_PORT_SPLIT
,
5987 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5988 .doit
= devlink_nl_cmd_port_split_doit
,
5989 .flags
= GENL_ADMIN_PERM
,
5990 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
5991 DEVLINK_NL_FLAG_NO_LOCK
,
5994 .cmd
= DEVLINK_CMD_PORT_UNSPLIT
,
5995 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
5996 .doit
= devlink_nl_cmd_port_unsplit_doit
,
5997 .flags
= GENL_ADMIN_PERM
,
5998 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
5999 DEVLINK_NL_FLAG_NO_LOCK
,
6002 .cmd
= DEVLINK_CMD_SB_GET
,
6003 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6004 .doit
= devlink_nl_cmd_sb_get_doit
,
6005 .dumpit
= devlink_nl_cmd_sb_get_dumpit
,
6006 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6007 DEVLINK_NL_FLAG_NEED_SB
,
6008 /* can be retrieved by unprivileged users */
6011 .cmd
= DEVLINK_CMD_SB_POOL_GET
,
6012 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6013 .doit
= devlink_nl_cmd_sb_pool_get_doit
,
6014 .dumpit
= devlink_nl_cmd_sb_pool_get_dumpit
,
6015 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6016 DEVLINK_NL_FLAG_NEED_SB
,
6017 /* can be retrieved by unprivileged users */
6020 .cmd
= DEVLINK_CMD_SB_POOL_SET
,
6021 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6022 .doit
= devlink_nl_cmd_sb_pool_set_doit
,
6023 .flags
= GENL_ADMIN_PERM
,
6024 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6025 DEVLINK_NL_FLAG_NEED_SB
,
6028 .cmd
= DEVLINK_CMD_SB_PORT_POOL_GET
,
6029 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6030 .doit
= devlink_nl_cmd_sb_port_pool_get_doit
,
6031 .dumpit
= devlink_nl_cmd_sb_port_pool_get_dumpit
,
6032 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
6033 DEVLINK_NL_FLAG_NEED_SB
,
6034 /* can be retrieved by unprivileged users */
6037 .cmd
= DEVLINK_CMD_SB_PORT_POOL_SET
,
6038 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6039 .doit
= devlink_nl_cmd_sb_port_pool_set_doit
,
6040 .flags
= GENL_ADMIN_PERM
,
6041 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
6042 DEVLINK_NL_FLAG_NEED_SB
,
6045 .cmd
= DEVLINK_CMD_SB_TC_POOL_BIND_GET
,
6046 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6047 .doit
= devlink_nl_cmd_sb_tc_pool_bind_get_doit
,
6048 .dumpit
= devlink_nl_cmd_sb_tc_pool_bind_get_dumpit
,
6049 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
6050 DEVLINK_NL_FLAG_NEED_SB
,
6051 /* can be retrieved by unprivileged users */
6054 .cmd
= DEVLINK_CMD_SB_TC_POOL_BIND_SET
,
6055 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6056 .doit
= devlink_nl_cmd_sb_tc_pool_bind_set_doit
,
6057 .flags
= GENL_ADMIN_PERM
,
6058 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
6059 DEVLINK_NL_FLAG_NEED_SB
,
6062 .cmd
= DEVLINK_CMD_SB_OCC_SNAPSHOT
,
6063 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6064 .doit
= devlink_nl_cmd_sb_occ_snapshot_doit
,
6065 .flags
= GENL_ADMIN_PERM
,
6066 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6067 DEVLINK_NL_FLAG_NEED_SB
,
6070 .cmd
= DEVLINK_CMD_SB_OCC_MAX_CLEAR
,
6071 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6072 .doit
= devlink_nl_cmd_sb_occ_max_clear_doit
,
6073 .flags
= GENL_ADMIN_PERM
,
6074 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6075 DEVLINK_NL_FLAG_NEED_SB
,
6078 .cmd
= DEVLINK_CMD_ESWITCH_GET
,
6079 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6080 .doit
= devlink_nl_cmd_eswitch_get_doit
,
6081 .flags
= GENL_ADMIN_PERM
,
6082 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6085 .cmd
= DEVLINK_CMD_ESWITCH_SET
,
6086 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6087 .doit
= devlink_nl_cmd_eswitch_set_doit
,
6088 .flags
= GENL_ADMIN_PERM
,
6089 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6090 DEVLINK_NL_FLAG_NO_LOCK
,
6093 .cmd
= DEVLINK_CMD_DPIPE_TABLE_GET
,
6094 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6095 .doit
= devlink_nl_cmd_dpipe_table_get
,
6096 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6097 /* can be retrieved by unprivileged users */
6100 .cmd
= DEVLINK_CMD_DPIPE_ENTRIES_GET
,
6101 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6102 .doit
= devlink_nl_cmd_dpipe_entries_get
,
6103 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6104 /* can be retrieved by unprivileged users */
6107 .cmd
= DEVLINK_CMD_DPIPE_HEADERS_GET
,
6108 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6109 .doit
= devlink_nl_cmd_dpipe_headers_get
,
6110 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6111 /* can be retrieved by unprivileged users */
6114 .cmd
= DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET
,
6115 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6116 .doit
= devlink_nl_cmd_dpipe_table_counters_set
,
6117 .flags
= GENL_ADMIN_PERM
,
6118 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6121 .cmd
= DEVLINK_CMD_RESOURCE_SET
,
6122 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6123 .doit
= devlink_nl_cmd_resource_set
,
6124 .flags
= GENL_ADMIN_PERM
,
6125 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6128 .cmd
= DEVLINK_CMD_RESOURCE_DUMP
,
6129 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6130 .doit
= devlink_nl_cmd_resource_dump
,
6131 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6132 /* can be retrieved by unprivileged users */
6135 .cmd
= DEVLINK_CMD_RELOAD
,
6136 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6137 .doit
= devlink_nl_cmd_reload
,
6138 .flags
= GENL_ADMIN_PERM
,
6139 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6140 DEVLINK_NL_FLAG_NO_LOCK
,
6143 .cmd
= DEVLINK_CMD_PARAM_GET
,
6144 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6145 .doit
= devlink_nl_cmd_param_get_doit
,
6146 .dumpit
= devlink_nl_cmd_param_get_dumpit
,
6147 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6148 /* can be retrieved by unprivileged users */
6151 .cmd
= DEVLINK_CMD_PARAM_SET
,
6152 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6153 .doit
= devlink_nl_cmd_param_set_doit
,
6154 .flags
= GENL_ADMIN_PERM
,
6155 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6158 .cmd
= DEVLINK_CMD_PORT_PARAM_GET
,
6159 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6160 .doit
= devlink_nl_cmd_port_param_get_doit
,
6161 .dumpit
= devlink_nl_cmd_port_param_get_dumpit
,
6162 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
6163 /* can be retrieved by unprivileged users */
6166 .cmd
= DEVLINK_CMD_PORT_PARAM_SET
,
6167 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6168 .doit
= devlink_nl_cmd_port_param_set_doit
,
6169 .flags
= GENL_ADMIN_PERM
,
6170 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
6173 .cmd
= DEVLINK_CMD_REGION_GET
,
6174 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6175 .doit
= devlink_nl_cmd_region_get_doit
,
6176 .dumpit
= devlink_nl_cmd_region_get_dumpit
,
6177 .flags
= GENL_ADMIN_PERM
,
6178 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6181 .cmd
= DEVLINK_CMD_REGION_DEL
,
6182 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6183 .doit
= devlink_nl_cmd_region_del
,
6184 .flags
= GENL_ADMIN_PERM
,
6185 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6188 .cmd
= DEVLINK_CMD_REGION_READ
,
6189 .validate
= GENL_DONT_VALIDATE_STRICT
|
6190 GENL_DONT_VALIDATE_DUMP_STRICT
,
6191 .dumpit
= devlink_nl_cmd_region_read_dumpit
,
6192 .flags
= GENL_ADMIN_PERM
,
6193 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6196 .cmd
= DEVLINK_CMD_INFO_GET
,
6197 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6198 .doit
= devlink_nl_cmd_info_get_doit
,
6199 .dumpit
= devlink_nl_cmd_info_get_dumpit
,
6200 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6201 /* can be retrieved by unprivileged users */
6204 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_GET
,
6205 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6206 .doit
= devlink_nl_cmd_health_reporter_get_doit
,
6207 .dumpit
= devlink_nl_cmd_health_reporter_get_dumpit
,
6208 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6209 DEVLINK_NL_FLAG_NO_LOCK
,
6210 /* can be retrieved by unprivileged users */
6213 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_SET
,
6214 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6215 .doit
= devlink_nl_cmd_health_reporter_set_doit
,
6216 .flags
= GENL_ADMIN_PERM
,
6217 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6218 DEVLINK_NL_FLAG_NO_LOCK
,
6221 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_RECOVER
,
6222 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6223 .doit
= devlink_nl_cmd_health_reporter_recover_doit
,
6224 .flags
= GENL_ADMIN_PERM
,
6225 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6226 DEVLINK_NL_FLAG_NO_LOCK
,
6229 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE
,
6230 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6231 .doit
= devlink_nl_cmd_health_reporter_diagnose_doit
,
6232 .flags
= GENL_ADMIN_PERM
,
6233 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6234 DEVLINK_NL_FLAG_NO_LOCK
,
6237 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET
,
6238 .validate
= GENL_DONT_VALIDATE_STRICT
|
6239 GENL_DONT_VALIDATE_DUMP_STRICT
,
6240 .dumpit
= devlink_nl_cmd_health_reporter_dump_get_dumpit
,
6241 .flags
= GENL_ADMIN_PERM
,
6242 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6243 DEVLINK_NL_FLAG_NO_LOCK
,
6246 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR
,
6247 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6248 .doit
= devlink_nl_cmd_health_reporter_dump_clear_doit
,
6249 .flags
= GENL_ADMIN_PERM
,
6250 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6251 DEVLINK_NL_FLAG_NO_LOCK
,
6254 .cmd
= DEVLINK_CMD_FLASH_UPDATE
,
6255 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6256 .doit
= devlink_nl_cmd_flash_update
,
6257 .flags
= GENL_ADMIN_PERM
,
6258 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6261 .cmd
= DEVLINK_CMD_TRAP_GET
,
6262 .doit
= devlink_nl_cmd_trap_get_doit
,
6263 .dumpit
= devlink_nl_cmd_trap_get_dumpit
,
6264 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6265 /* can be retrieved by unprivileged users */
6268 .cmd
= DEVLINK_CMD_TRAP_SET
,
6269 .doit
= devlink_nl_cmd_trap_set_doit
,
6270 .flags
= GENL_ADMIN_PERM
,
6271 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6274 .cmd
= DEVLINK_CMD_TRAP_GROUP_GET
,
6275 .doit
= devlink_nl_cmd_trap_group_get_doit
,
6276 .dumpit
= devlink_nl_cmd_trap_group_get_dumpit
,
6277 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6278 /* can be retrieved by unprivileged users */
6281 .cmd
= DEVLINK_CMD_TRAP_GROUP_SET
,
6282 .doit
= devlink_nl_cmd_trap_group_set_doit
,
6283 .flags
= GENL_ADMIN_PERM
,
6284 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6288 static struct genl_family devlink_nl_family __ro_after_init
= {
6289 .name
= DEVLINK_GENL_NAME
,
6290 .version
= DEVLINK_GENL_VERSION
,
6291 .maxattr
= DEVLINK_ATTR_MAX
,
6292 .policy
= devlink_nl_policy
,
6294 .pre_doit
= devlink_nl_pre_doit
,
6295 .post_doit
= devlink_nl_post_doit
,
6296 .module
= THIS_MODULE
,
6297 .ops
= devlink_nl_ops
,
6298 .n_ops
= ARRAY_SIZE(devlink_nl_ops
),
6299 .mcgrps
= devlink_nl_mcgrps
,
6300 .n_mcgrps
= ARRAY_SIZE(devlink_nl_mcgrps
),
6304 * devlink_alloc - Allocate new devlink instance resources
6307 * @priv_size: size of user private data
6309 * Allocate new devlink instance resources, including devlink index
6312 struct devlink
*devlink_alloc(const struct devlink_ops
*ops
, size_t priv_size
)
6314 struct devlink
*devlink
;
6319 devlink
= kzalloc(sizeof(*devlink
) + priv_size
, GFP_KERNEL
);
6323 __devlink_net_set(devlink
, &init_net
);
6324 INIT_LIST_HEAD(&devlink
->port_list
);
6325 INIT_LIST_HEAD(&devlink
->sb_list
);
6326 INIT_LIST_HEAD_RCU(&devlink
->dpipe_table_list
);
6327 INIT_LIST_HEAD(&devlink
->resource_list
);
6328 INIT_LIST_HEAD(&devlink
->param_list
);
6329 INIT_LIST_HEAD(&devlink
->region_list
);
6330 INIT_LIST_HEAD(&devlink
->reporter_list
);
6331 INIT_LIST_HEAD(&devlink
->trap_list
);
6332 INIT_LIST_HEAD(&devlink
->trap_group_list
);
6333 mutex_init(&devlink
->lock
);
6334 mutex_init(&devlink
->reporters_lock
);
6337 EXPORT_SYMBOL_GPL(devlink_alloc
);
6340 * devlink_register - Register devlink instance
6343 * @dev: parent device
6345 int devlink_register(struct devlink
*devlink
, struct device
*dev
)
6347 mutex_lock(&devlink_mutex
);
6349 devlink
->registered
= true;
6350 list_add_tail(&devlink
->list
, &devlink_list
);
6351 devlink_notify(devlink
, DEVLINK_CMD_NEW
);
6352 mutex_unlock(&devlink_mutex
);
6355 EXPORT_SYMBOL_GPL(devlink_register
);
6358 * devlink_unregister - Unregister devlink instance
6362 void devlink_unregister(struct devlink
*devlink
)
6364 mutex_lock(&devlink_mutex
);
6365 WARN_ON(devlink_reload_supported(devlink
) &&
6366 devlink
->reload_enabled
);
6367 devlink_notify(devlink
, DEVLINK_CMD_DEL
);
6368 list_del(&devlink
->list
);
6369 mutex_unlock(&devlink_mutex
);
6371 EXPORT_SYMBOL_GPL(devlink_unregister
);
6374 * devlink_reload_enable - Enable reload of devlink instance
6378 * Should be called at end of device initialization
6379 * process when reload operation is supported.
6381 void devlink_reload_enable(struct devlink
*devlink
)
6383 mutex_lock(&devlink_mutex
);
6384 devlink
->reload_enabled
= true;
6385 mutex_unlock(&devlink_mutex
);
6387 EXPORT_SYMBOL_GPL(devlink_reload_enable
);
6390 * devlink_reload_disable - Disable reload of devlink instance
6394 * Should be called at the beginning of device cleanup
6395 * process when reload operation is supported.
6397 void devlink_reload_disable(struct devlink
*devlink
)
6399 mutex_lock(&devlink_mutex
);
6400 /* Mutex is taken which ensures that no reload operation is in
6401 * progress while setting up forbidded flag.
6403 devlink
->reload_enabled
= false;
6404 mutex_unlock(&devlink_mutex
);
6406 EXPORT_SYMBOL_GPL(devlink_reload_disable
);
6409 * devlink_free - Free devlink instance resources
6413 void devlink_free(struct devlink
*devlink
)
6415 mutex_destroy(&devlink
->reporters_lock
);
6416 mutex_destroy(&devlink
->lock
);
6417 WARN_ON(!list_empty(&devlink
->trap_group_list
));
6418 WARN_ON(!list_empty(&devlink
->trap_list
));
6419 WARN_ON(!list_empty(&devlink
->reporter_list
));
6420 WARN_ON(!list_empty(&devlink
->region_list
));
6421 WARN_ON(!list_empty(&devlink
->param_list
));
6422 WARN_ON(!list_empty(&devlink
->resource_list
));
6423 WARN_ON(!list_empty(&devlink
->dpipe_table_list
));
6424 WARN_ON(!list_empty(&devlink
->sb_list
));
6425 WARN_ON(!list_empty(&devlink
->port_list
));
6429 EXPORT_SYMBOL_GPL(devlink_free
);
6431 static void devlink_port_type_warn(struct work_struct
*work
)
6433 WARN(true, "Type was not set for devlink port.");
6436 static bool devlink_port_type_should_warn(struct devlink_port
*devlink_port
)
6438 /* Ignore CPU and DSA flavours. */
6439 return devlink_port
->attrs
.flavour
!= DEVLINK_PORT_FLAVOUR_CPU
&&
6440 devlink_port
->attrs
.flavour
!= DEVLINK_PORT_FLAVOUR_DSA
;
6443 #define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 3600)
6445 static void devlink_port_type_warn_schedule(struct devlink_port
*devlink_port
)
6447 if (!devlink_port_type_should_warn(devlink_port
))
6449 /* Schedule a work to WARN in case driver does not set port
6450 * type within timeout.
6452 schedule_delayed_work(&devlink_port
->type_warn_dw
,
6453 DEVLINK_PORT_TYPE_WARN_TIMEOUT
);
6456 static void devlink_port_type_warn_cancel(struct devlink_port
*devlink_port
)
6458 if (!devlink_port_type_should_warn(devlink_port
))
6460 cancel_delayed_work_sync(&devlink_port
->type_warn_dw
);
6464 * devlink_port_register - Register devlink port
6467 * @devlink_port: devlink port
6468 * @port_index: driver-specific numerical identifier of the port
6470 * Register devlink port with provided port index. User can use
6471 * any indexing, even hw-related one. devlink_port structure
6472 * is convenient to be embedded inside user driver private structure.
6473 * Note that the caller should take care of zeroing the devlink_port
6476 int devlink_port_register(struct devlink
*devlink
,
6477 struct devlink_port
*devlink_port
,
6478 unsigned int port_index
)
6480 mutex_lock(&devlink
->lock
);
6481 if (devlink_port_index_exists(devlink
, port_index
)) {
6482 mutex_unlock(&devlink
->lock
);
6485 devlink_port
->devlink
= devlink
;
6486 devlink_port
->index
= port_index
;
6487 devlink_port
->registered
= true;
6488 spin_lock_init(&devlink_port
->type_lock
);
6489 list_add_tail(&devlink_port
->list
, &devlink
->port_list
);
6490 INIT_LIST_HEAD(&devlink_port
->param_list
);
6491 mutex_unlock(&devlink
->lock
);
6492 INIT_DELAYED_WORK(&devlink_port
->type_warn_dw
, &devlink_port_type_warn
);
6493 devlink_port_type_warn_schedule(devlink_port
);
6494 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
6497 EXPORT_SYMBOL_GPL(devlink_port_register
);
6500 * devlink_port_unregister - Unregister devlink port
6502 * @devlink_port: devlink port
6504 void devlink_port_unregister(struct devlink_port
*devlink_port
)
6506 struct devlink
*devlink
= devlink_port
->devlink
;
6508 devlink_port_type_warn_cancel(devlink_port
);
6509 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_DEL
);
6510 mutex_lock(&devlink
->lock
);
6511 list_del(&devlink_port
->list
);
6512 mutex_unlock(&devlink
->lock
);
6514 EXPORT_SYMBOL_GPL(devlink_port_unregister
);
6516 static void __devlink_port_type_set(struct devlink_port
*devlink_port
,
6517 enum devlink_port_type type
,
6520 if (WARN_ON(!devlink_port
->registered
))
6522 devlink_port_type_warn_cancel(devlink_port
);
6523 spin_lock_bh(&devlink_port
->type_lock
);
6524 devlink_port
->type
= type
;
6525 devlink_port
->type_dev
= type_dev
;
6526 spin_unlock_bh(&devlink_port
->type_lock
);
6527 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
6531 * devlink_port_type_eth_set - Set port type to Ethernet
6533 * @devlink_port: devlink port
6534 * @netdev: related netdevice
6536 void devlink_port_type_eth_set(struct devlink_port
*devlink_port
,
6537 struct net_device
*netdev
)
6539 const struct net_device_ops
*ops
= netdev
->netdev_ops
;
6541 /* If driver registers devlink port, it should set devlink port
6542 * attributes accordingly so the compat functions are called
6543 * and the original ops are not used.
6545 if (ops
->ndo_get_phys_port_name
) {
6546 /* Some drivers use the same set of ndos for netdevs
6547 * that have devlink_port registered and also for
6548 * those who don't. Make sure that ndo_get_phys_port_name
6549 * returns -EOPNOTSUPP here in case it is defined.
6552 char name
[IFNAMSIZ
];
6555 err
= ops
->ndo_get_phys_port_name(netdev
, name
, sizeof(name
));
6556 WARN_ON(err
!= -EOPNOTSUPP
);
6558 if (ops
->ndo_get_port_parent_id
) {
6559 /* Some drivers use the same set of ndos for netdevs
6560 * that have devlink_port registered and also for
6561 * those who don't. Make sure that ndo_get_port_parent_id
6562 * returns -EOPNOTSUPP here in case it is defined.
6565 struct netdev_phys_item_id ppid
;
6568 err
= ops
->ndo_get_port_parent_id(netdev
, &ppid
);
6569 WARN_ON(err
!= -EOPNOTSUPP
);
6571 __devlink_port_type_set(devlink_port
, DEVLINK_PORT_TYPE_ETH
, netdev
);
6573 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set
);
6576 * devlink_port_type_ib_set - Set port type to InfiniBand
6578 * @devlink_port: devlink port
6579 * @ibdev: related IB device
6581 void devlink_port_type_ib_set(struct devlink_port
*devlink_port
,
6582 struct ib_device
*ibdev
)
6584 __devlink_port_type_set(devlink_port
, DEVLINK_PORT_TYPE_IB
, ibdev
);
6586 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set
);
6589 * devlink_port_type_clear - Clear port type
6591 * @devlink_port: devlink port
6593 void devlink_port_type_clear(struct devlink_port
*devlink_port
)
6595 __devlink_port_type_set(devlink_port
, DEVLINK_PORT_TYPE_NOTSET
, NULL
);
6596 devlink_port_type_warn_schedule(devlink_port
);
6598 EXPORT_SYMBOL_GPL(devlink_port_type_clear
);
6600 static int __devlink_port_attrs_set(struct devlink_port
*devlink_port
,
6601 enum devlink_port_flavour flavour
,
6602 const unsigned char *switch_id
,
6603 unsigned char switch_id_len
)
6605 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
6607 if (WARN_ON(devlink_port
->registered
))
6610 attrs
->flavour
= flavour
;
6612 attrs
->switch_port
= true;
6613 if (WARN_ON(switch_id_len
> MAX_PHYS_ITEM_ID_LEN
))
6614 switch_id_len
= MAX_PHYS_ITEM_ID_LEN
;
6615 memcpy(attrs
->switch_id
.id
, switch_id
, switch_id_len
);
6616 attrs
->switch_id
.id_len
= switch_id_len
;
6618 attrs
->switch_port
= false;
6624 * devlink_port_attrs_set - Set port attributes
6626 * @devlink_port: devlink port
6627 * @flavour: flavour of the port
6628 * @port_number: number of the port that is facing user, for example
6629 * the front panel port number
6630 * @split: indicates if this is split port
6631 * @split_subport_number: if the port is split, this is the number
6633 * @switch_id: if the port is part of switch, this is buffer with ID,
6634 * otwerwise this is NULL
6635 * @switch_id_len: length of the switch_id buffer
6637 void devlink_port_attrs_set(struct devlink_port
*devlink_port
,
6638 enum devlink_port_flavour flavour
,
6639 u32 port_number
, bool split
,
6640 u32 split_subport_number
,
6641 const unsigned char *switch_id
,
6642 unsigned char switch_id_len
)
6644 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
6647 ret
= __devlink_port_attrs_set(devlink_port
, flavour
,
6648 switch_id
, switch_id_len
);
6651 attrs
->split
= split
;
6652 attrs
->phys
.port_number
= port_number
;
6653 attrs
->phys
.split_subport_number
= split_subport_number
;
6655 EXPORT_SYMBOL_GPL(devlink_port_attrs_set
);
6658 * devlink_port_attrs_pci_pf_set - Set PCI PF port attributes
6660 * @devlink_port: devlink port
6661 * @pf: associated PF for the devlink port instance
6662 * @switch_id: if the port is part of switch, this is buffer with ID,
6663 * otherwise this is NULL
6664 * @switch_id_len: length of the switch_id buffer
6666 void devlink_port_attrs_pci_pf_set(struct devlink_port
*devlink_port
,
6667 const unsigned char *switch_id
,
6668 unsigned char switch_id_len
, u16 pf
)
6670 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
6673 ret
= __devlink_port_attrs_set(devlink_port
,
6674 DEVLINK_PORT_FLAVOUR_PCI_PF
,
6675 switch_id
, switch_id_len
);
6679 attrs
->pci_pf
.pf
= pf
;
6681 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set
);
6684 * devlink_port_attrs_pci_vf_set - Set PCI VF port attributes
6686 * @devlink_port: devlink port
6687 * @pf: associated PF for the devlink port instance
6688 * @vf: associated VF of a PF for the devlink port instance
6689 * @switch_id: if the port is part of switch, this is buffer with ID,
6690 * otherwise this is NULL
6691 * @switch_id_len: length of the switch_id buffer
6693 void devlink_port_attrs_pci_vf_set(struct devlink_port
*devlink_port
,
6694 const unsigned char *switch_id
,
6695 unsigned char switch_id_len
,
6698 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
6701 ret
= __devlink_port_attrs_set(devlink_port
,
6702 DEVLINK_PORT_FLAVOUR_PCI_VF
,
6703 switch_id
, switch_id_len
);
6706 attrs
->pci_vf
.pf
= pf
;
6707 attrs
->pci_vf
.vf
= vf
;
6709 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set
);
6711 static int __devlink_port_phys_port_name_get(struct devlink_port
*devlink_port
,
6712 char *name
, size_t len
)
6714 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
6720 switch (attrs
->flavour
) {
6721 case DEVLINK_PORT_FLAVOUR_PHYSICAL
:
6723 n
= snprintf(name
, len
, "p%u", attrs
->phys
.port_number
);
6725 n
= snprintf(name
, len
, "p%us%u",
6726 attrs
->phys
.port_number
,
6727 attrs
->phys
.split_subport_number
);
6729 case DEVLINK_PORT_FLAVOUR_CPU
:
6730 case DEVLINK_PORT_FLAVOUR_DSA
:
6731 /* As CPU and DSA ports do not have a netdevice associated
6732 * case should not ever happen.
6736 case DEVLINK_PORT_FLAVOUR_PCI_PF
:
6737 n
= snprintf(name
, len
, "pf%u", attrs
->pci_pf
.pf
);
6739 case DEVLINK_PORT_FLAVOUR_PCI_VF
:
6740 n
= snprintf(name
, len
, "pf%uvf%u",
6741 attrs
->pci_vf
.pf
, attrs
->pci_vf
.vf
);
6751 int devlink_sb_register(struct devlink
*devlink
, unsigned int sb_index
,
6752 u32 size
, u16 ingress_pools_count
,
6753 u16 egress_pools_count
, u16 ingress_tc_count
,
6754 u16 egress_tc_count
)
6756 struct devlink_sb
*devlink_sb
;
6759 mutex_lock(&devlink
->lock
);
6760 if (devlink_sb_index_exists(devlink
, sb_index
)) {
6765 devlink_sb
= kzalloc(sizeof(*devlink_sb
), GFP_KERNEL
);
6770 devlink_sb
->index
= sb_index
;
6771 devlink_sb
->size
= size
;
6772 devlink_sb
->ingress_pools_count
= ingress_pools_count
;
6773 devlink_sb
->egress_pools_count
= egress_pools_count
;
6774 devlink_sb
->ingress_tc_count
= ingress_tc_count
;
6775 devlink_sb
->egress_tc_count
= egress_tc_count
;
6776 list_add_tail(&devlink_sb
->list
, &devlink
->sb_list
);
6778 mutex_unlock(&devlink
->lock
);
6781 EXPORT_SYMBOL_GPL(devlink_sb_register
);
6783 void devlink_sb_unregister(struct devlink
*devlink
, unsigned int sb_index
)
6785 struct devlink_sb
*devlink_sb
;
6787 mutex_lock(&devlink
->lock
);
6788 devlink_sb
= devlink_sb_get_by_index(devlink
, sb_index
);
6789 WARN_ON(!devlink_sb
);
6790 list_del(&devlink_sb
->list
);
6791 mutex_unlock(&devlink
->lock
);
6794 EXPORT_SYMBOL_GPL(devlink_sb_unregister
);
6797 * devlink_dpipe_headers_register - register dpipe headers
6800 * @dpipe_headers: dpipe header array
6802 * Register the headers supported by hardware.
6804 int devlink_dpipe_headers_register(struct devlink
*devlink
,
6805 struct devlink_dpipe_headers
*dpipe_headers
)
6807 mutex_lock(&devlink
->lock
);
6808 devlink
->dpipe_headers
= dpipe_headers
;
6809 mutex_unlock(&devlink
->lock
);
6812 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register
);
6815 * devlink_dpipe_headers_unregister - unregister dpipe headers
6819 * Unregister the headers supported by hardware.
6821 void devlink_dpipe_headers_unregister(struct devlink
*devlink
)
6823 mutex_lock(&devlink
->lock
);
6824 devlink
->dpipe_headers
= NULL
;
6825 mutex_unlock(&devlink
->lock
);
6827 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister
);
6830 * devlink_dpipe_table_counter_enabled - check if counter allocation
6833 * @table_name: tables name
6835 * Used by driver to check if counter allocation is required.
6836 * After counter allocation is turned on the table entries
6837 * are updated to include counter statistics.
6839 * After that point on the driver must respect the counter
6840 * state so that each entry added to the table is added
6843 bool devlink_dpipe_table_counter_enabled(struct devlink
*devlink
,
6844 const char *table_name
)
6846 struct devlink_dpipe_table
*table
;
6850 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
6854 enabled
= table
->counters_enabled
;
6858 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled
);
6861 * devlink_dpipe_table_register - register dpipe table
6864 * @table_name: table name
6865 * @table_ops: table ops
6867 * @counter_control_extern: external control for counters
6869 int devlink_dpipe_table_register(struct devlink
*devlink
,
6870 const char *table_name
,
6871 struct devlink_dpipe_table_ops
*table_ops
,
6872 void *priv
, bool counter_control_extern
)
6874 struct devlink_dpipe_table
*table
;
6876 if (devlink_dpipe_table_find(&devlink
->dpipe_table_list
, table_name
))
6879 if (WARN_ON(!table_ops
->size_get
))
6882 table
= kzalloc(sizeof(*table
), GFP_KERNEL
);
6886 table
->name
= table_name
;
6887 table
->table_ops
= table_ops
;
6889 table
->counter_control_extern
= counter_control_extern
;
6891 mutex_lock(&devlink
->lock
);
6892 list_add_tail_rcu(&table
->list
, &devlink
->dpipe_table_list
);
6893 mutex_unlock(&devlink
->lock
);
6896 EXPORT_SYMBOL_GPL(devlink_dpipe_table_register
);
6899 * devlink_dpipe_table_unregister - unregister dpipe table
6902 * @table_name: table name
6904 void devlink_dpipe_table_unregister(struct devlink
*devlink
,
6905 const char *table_name
)
6907 struct devlink_dpipe_table
*table
;
6909 mutex_lock(&devlink
->lock
);
6910 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
6914 list_del_rcu(&table
->list
);
6915 mutex_unlock(&devlink
->lock
);
6916 kfree_rcu(table
, rcu
);
6919 mutex_unlock(&devlink
->lock
);
6921 EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister
);
6924 * devlink_resource_register - devlink resource register
6927 * @resource_name: resource's name
6928 * @resource_size: resource's size
6929 * @resource_id: resource's id
6930 * @parent_resource_id: resource's parent id
6931 * @size_params: size parameters
6933 int devlink_resource_register(struct devlink
*devlink
,
6934 const char *resource_name
,
6937 u64 parent_resource_id
,
6938 const struct devlink_resource_size_params
*size_params
)
6940 struct devlink_resource
*resource
;
6941 struct list_head
*resource_list
;
6945 top_hierarchy
= parent_resource_id
== DEVLINK_RESOURCE_ID_PARENT_TOP
;
6947 mutex_lock(&devlink
->lock
);
6948 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
6954 resource
= kzalloc(sizeof(*resource
), GFP_KERNEL
);
6960 if (top_hierarchy
) {
6961 resource_list
= &devlink
->resource_list
;
6963 struct devlink_resource
*parent_resource
;
6965 parent_resource
= devlink_resource_find(devlink
, NULL
,
6966 parent_resource_id
);
6967 if (parent_resource
) {
6968 resource_list
= &parent_resource
->resource_list
;
6969 resource
->parent
= parent_resource
;
6977 resource
->name
= resource_name
;
6978 resource
->size
= resource_size
;
6979 resource
->size_new
= resource_size
;
6980 resource
->id
= resource_id
;
6981 resource
->size_valid
= true;
6982 memcpy(&resource
->size_params
, size_params
,
6983 sizeof(resource
->size_params
));
6984 INIT_LIST_HEAD(&resource
->resource_list
);
6985 list_add_tail(&resource
->list
, resource_list
);
6987 mutex_unlock(&devlink
->lock
);
6990 EXPORT_SYMBOL_GPL(devlink_resource_register
);
6993 * devlink_resources_unregister - free all resources
6996 * @resource: resource
6998 void devlink_resources_unregister(struct devlink
*devlink
,
6999 struct devlink_resource
*resource
)
7001 struct devlink_resource
*tmp
, *child_resource
;
7002 struct list_head
*resource_list
;
7005 resource_list
= &resource
->resource_list
;
7007 resource_list
= &devlink
->resource_list
;
7010 mutex_lock(&devlink
->lock
);
7012 list_for_each_entry_safe(child_resource
, tmp
, resource_list
, list
) {
7013 devlink_resources_unregister(devlink
, child_resource
);
7014 list_del(&child_resource
->list
);
7015 kfree(child_resource
);
7019 mutex_unlock(&devlink
->lock
);
7021 EXPORT_SYMBOL_GPL(devlink_resources_unregister
);
7024 * devlink_resource_size_get - get and update size
7027 * @resource_id: the requested resource id
7028 * @p_resource_size: ptr to update
7030 int devlink_resource_size_get(struct devlink
*devlink
,
7032 u64
*p_resource_size
)
7034 struct devlink_resource
*resource
;
7037 mutex_lock(&devlink
->lock
);
7038 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
7043 *p_resource_size
= resource
->size_new
;
7044 resource
->size
= resource
->size_new
;
7046 mutex_unlock(&devlink
->lock
);
7049 EXPORT_SYMBOL_GPL(devlink_resource_size_get
);
7052 * devlink_dpipe_table_resource_set - set the resource id
7055 * @table_name: table name
7056 * @resource_id: resource id
7057 * @resource_units: number of resource's units consumed per table's entry
7059 int devlink_dpipe_table_resource_set(struct devlink
*devlink
,
7060 const char *table_name
, u64 resource_id
,
7063 struct devlink_dpipe_table
*table
;
7066 mutex_lock(&devlink
->lock
);
7067 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
7073 table
->resource_id
= resource_id
;
7074 table
->resource_units
= resource_units
;
7075 table
->resource_valid
= true;
7077 mutex_unlock(&devlink
->lock
);
7080 EXPORT_SYMBOL_GPL(devlink_dpipe_table_resource_set
);
7083 * devlink_resource_occ_get_register - register occupancy getter
7086 * @resource_id: resource id
7087 * @occ_get: occupancy getter callback
7088 * @occ_get_priv: occupancy getter callback priv
7090 void devlink_resource_occ_get_register(struct devlink
*devlink
,
7092 devlink_resource_occ_get_t
*occ_get
,
7095 struct devlink_resource
*resource
;
7097 mutex_lock(&devlink
->lock
);
7098 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
7099 if (WARN_ON(!resource
))
7101 WARN_ON(resource
->occ_get
);
7103 resource
->occ_get
= occ_get
;
7104 resource
->occ_get_priv
= occ_get_priv
;
7106 mutex_unlock(&devlink
->lock
);
7108 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register
);
7111 * devlink_resource_occ_get_unregister - unregister occupancy getter
7114 * @resource_id: resource id
7116 void devlink_resource_occ_get_unregister(struct devlink
*devlink
,
7119 struct devlink_resource
*resource
;
7121 mutex_lock(&devlink
->lock
);
7122 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
7123 if (WARN_ON(!resource
))
7125 WARN_ON(!resource
->occ_get
);
7127 resource
->occ_get
= NULL
;
7128 resource
->occ_get_priv
= NULL
;
7130 mutex_unlock(&devlink
->lock
);
7132 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister
);
7134 static int devlink_param_verify(const struct devlink_param
*param
)
7136 if (!param
|| !param
->name
|| !param
->supported_cmodes
)
7139 return devlink_param_generic_verify(param
);
7141 return devlink_param_driver_verify(param
);
7144 static int __devlink_params_register(struct devlink
*devlink
,
7145 unsigned int port_index
,
7146 struct list_head
*param_list
,
7147 const struct devlink_param
*params
,
7148 size_t params_count
,
7149 enum devlink_command reg_cmd
,
7150 enum devlink_command unreg_cmd
)
7152 const struct devlink_param
*param
= params
;
7156 mutex_lock(&devlink
->lock
);
7157 for (i
= 0; i
< params_count
; i
++, param
++) {
7158 err
= devlink_param_verify(param
);
7162 err
= devlink_param_register_one(devlink
, port_index
,
7163 param_list
, param
, reg_cmd
);
7168 mutex_unlock(&devlink
->lock
);
7174 for (param
--; i
> 0; i
--, param
--)
7175 devlink_param_unregister_one(devlink
, port_index
, param_list
,
7178 mutex_unlock(&devlink
->lock
);
7182 static void __devlink_params_unregister(struct devlink
*devlink
,
7183 unsigned int port_index
,
7184 struct list_head
*param_list
,
7185 const struct devlink_param
*params
,
7186 size_t params_count
,
7187 enum devlink_command cmd
)
7189 const struct devlink_param
*param
= params
;
7192 mutex_lock(&devlink
->lock
);
7193 for (i
= 0; i
< params_count
; i
++, param
++)
7194 devlink_param_unregister_one(devlink
, 0, param_list
, param
,
7196 mutex_unlock(&devlink
->lock
);
7200 * devlink_params_register - register configuration parameters
7203 * @params: configuration parameters array
7204 * @params_count: number of parameters provided
7206 * Register the configuration parameters supported by the driver.
7208 int devlink_params_register(struct devlink
*devlink
,
7209 const struct devlink_param
*params
,
7210 size_t params_count
)
7212 return __devlink_params_register(devlink
, 0, &devlink
->param_list
,
7213 params
, params_count
,
7214 DEVLINK_CMD_PARAM_NEW
,
7215 DEVLINK_CMD_PARAM_DEL
);
7217 EXPORT_SYMBOL_GPL(devlink_params_register
);
7220 * devlink_params_unregister - unregister configuration parameters
7222 * @params: configuration parameters to unregister
7223 * @params_count: number of parameters provided
7225 void devlink_params_unregister(struct devlink
*devlink
,
7226 const struct devlink_param
*params
,
7227 size_t params_count
)
7229 return __devlink_params_unregister(devlink
, 0, &devlink
->param_list
,
7230 params
, params_count
,
7231 DEVLINK_CMD_PARAM_DEL
);
7233 EXPORT_SYMBOL_GPL(devlink_params_unregister
);
7236 * devlink_params_publish - publish configuration parameters
7240 * Publish previously registered configuration parameters.
7242 void devlink_params_publish(struct devlink
*devlink
)
7244 struct devlink_param_item
*param_item
;
7246 list_for_each_entry(param_item
, &devlink
->param_list
, list
) {
7247 if (param_item
->published
)
7249 param_item
->published
= true;
7250 devlink_param_notify(devlink
, 0, param_item
,
7251 DEVLINK_CMD_PARAM_NEW
);
7254 EXPORT_SYMBOL_GPL(devlink_params_publish
);
7257 * devlink_params_unpublish - unpublish configuration parameters
7261 * Unpublish previously registered configuration parameters.
7263 void devlink_params_unpublish(struct devlink
*devlink
)
7265 struct devlink_param_item
*param_item
;
7267 list_for_each_entry(param_item
, &devlink
->param_list
, list
) {
7268 if (!param_item
->published
)
7270 param_item
->published
= false;
7271 devlink_param_notify(devlink
, 0, param_item
,
7272 DEVLINK_CMD_PARAM_DEL
);
7275 EXPORT_SYMBOL_GPL(devlink_params_unpublish
);
7278 * devlink_port_params_register - register port configuration parameters
7280 * @devlink_port: devlink port
7281 * @params: configuration parameters array
7282 * @params_count: number of parameters provided
7284 * Register the configuration parameters supported by the port.
7286 int devlink_port_params_register(struct devlink_port
*devlink_port
,
7287 const struct devlink_param
*params
,
7288 size_t params_count
)
7290 return __devlink_params_register(devlink_port
->devlink
,
7291 devlink_port
->index
,
7292 &devlink_port
->param_list
, params
,
7294 DEVLINK_CMD_PORT_PARAM_NEW
,
7295 DEVLINK_CMD_PORT_PARAM_DEL
);
7297 EXPORT_SYMBOL_GPL(devlink_port_params_register
);
7300 * devlink_port_params_unregister - unregister port configuration
7303 * @devlink_port: devlink port
7304 * @params: configuration parameters array
7305 * @params_count: number of parameters provided
7307 void devlink_port_params_unregister(struct devlink_port
*devlink_port
,
7308 const struct devlink_param
*params
,
7309 size_t params_count
)
7311 return __devlink_params_unregister(devlink_port
->devlink
,
7312 devlink_port
->index
,
7313 &devlink_port
->param_list
,
7314 params
, params_count
,
7315 DEVLINK_CMD_PORT_PARAM_DEL
);
7317 EXPORT_SYMBOL_GPL(devlink_port_params_unregister
);
7320 __devlink_param_driverinit_value_get(struct list_head
*param_list
, u32 param_id
,
7321 union devlink_param_value
*init_val
)
7323 struct devlink_param_item
*param_item
;
7325 param_item
= devlink_param_find_by_id(param_list
, param_id
);
7329 if (!param_item
->driverinit_value_valid
||
7330 !devlink_param_cmode_is_supported(param_item
->param
,
7331 DEVLINK_PARAM_CMODE_DRIVERINIT
))
7334 if (param_item
->param
->type
== DEVLINK_PARAM_TYPE_STRING
)
7335 strcpy(init_val
->vstr
, param_item
->driverinit_value
.vstr
);
7337 *init_val
= param_item
->driverinit_value
;
7343 __devlink_param_driverinit_value_set(struct devlink
*devlink
,
7344 unsigned int port_index
,
7345 struct list_head
*param_list
, u32 param_id
,
7346 union devlink_param_value init_val
,
7347 enum devlink_command cmd
)
7349 struct devlink_param_item
*param_item
;
7351 param_item
= devlink_param_find_by_id(param_list
, param_id
);
7355 if (!devlink_param_cmode_is_supported(param_item
->param
,
7356 DEVLINK_PARAM_CMODE_DRIVERINIT
))
7359 if (param_item
->param
->type
== DEVLINK_PARAM_TYPE_STRING
)
7360 strcpy(param_item
->driverinit_value
.vstr
, init_val
.vstr
);
7362 param_item
->driverinit_value
= init_val
;
7363 param_item
->driverinit_value_valid
= true;
7365 devlink_param_notify(devlink
, port_index
, param_item
, cmd
);
7370 * devlink_param_driverinit_value_get - get configuration parameter
7371 * value for driver initializing
7374 * @param_id: parameter ID
7375 * @init_val: value of parameter in driverinit configuration mode
7377 * This function should be used by the driver to get driverinit
7378 * configuration for initialization after reload command.
7380 int devlink_param_driverinit_value_get(struct devlink
*devlink
, u32 param_id
,
7381 union devlink_param_value
*init_val
)
7383 if (!devlink_reload_supported(devlink
))
7386 return __devlink_param_driverinit_value_get(&devlink
->param_list
,
7387 param_id
, init_val
);
7389 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_get
);
7392 * devlink_param_driverinit_value_set - set value of configuration
7393 * parameter for driverinit
7394 * configuration mode
7397 * @param_id: parameter ID
7398 * @init_val: value of parameter to set for driverinit configuration mode
7400 * This function should be used by the driver to set driverinit
7401 * configuration mode default value.
7403 int devlink_param_driverinit_value_set(struct devlink
*devlink
, u32 param_id
,
7404 union devlink_param_value init_val
)
7406 return __devlink_param_driverinit_value_set(devlink
, 0,
7407 &devlink
->param_list
,
7409 DEVLINK_CMD_PARAM_NEW
);
7411 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set
);
7414 * devlink_port_param_driverinit_value_get - get configuration parameter
7415 * value for driver initializing
7417 * @devlink_port: devlink_port
7418 * @param_id: parameter ID
7419 * @init_val: value of parameter in driverinit configuration mode
7421 * This function should be used by the driver to get driverinit
7422 * configuration for initialization after reload command.
7424 int devlink_port_param_driverinit_value_get(struct devlink_port
*devlink_port
,
7426 union devlink_param_value
*init_val
)
7428 struct devlink
*devlink
= devlink_port
->devlink
;
7430 if (!devlink_reload_supported(devlink
))
7433 return __devlink_param_driverinit_value_get(&devlink_port
->param_list
,
7434 param_id
, init_val
);
7436 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_get
);
7439 * devlink_port_param_driverinit_value_set - set value of configuration
7440 * parameter for driverinit
7441 * configuration mode
7443 * @devlink_port: devlink_port
7444 * @param_id: parameter ID
7445 * @init_val: value of parameter to set for driverinit configuration mode
7447 * This function should be used by the driver to set driverinit
7448 * configuration mode default value.
7450 int devlink_port_param_driverinit_value_set(struct devlink_port
*devlink_port
,
7452 union devlink_param_value init_val
)
7454 return __devlink_param_driverinit_value_set(devlink_port
->devlink
,
7455 devlink_port
->index
,
7456 &devlink_port
->param_list
,
7458 DEVLINK_CMD_PORT_PARAM_NEW
);
7460 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_set
);
7463 * devlink_param_value_changed - notify devlink on a parameter's value
7464 * change. Should be called by the driver
7465 * right after the change.
7468 * @param_id: parameter ID
7470 * This function should be used by the driver to notify devlink on value
7471 * change, excluding driverinit configuration mode.
7472 * For driverinit configuration mode driver should use the function
7474 void devlink_param_value_changed(struct devlink
*devlink
, u32 param_id
)
7476 struct devlink_param_item
*param_item
;
7478 param_item
= devlink_param_find_by_id(&devlink
->param_list
, param_id
);
7479 WARN_ON(!param_item
);
7481 devlink_param_notify(devlink
, 0, param_item
, DEVLINK_CMD_PARAM_NEW
);
7483 EXPORT_SYMBOL_GPL(devlink_param_value_changed
);
7486 * devlink_port_param_value_changed - notify devlink on a parameter's value
7487 * change. Should be called by the driver
7488 * right after the change.
7490 * @devlink_port: devlink_port
7491 * @param_id: parameter ID
7493 * This function should be used by the driver to notify devlink on value
7494 * change, excluding driverinit configuration mode.
7495 * For driverinit configuration mode driver should use the function
7496 * devlink_port_param_driverinit_value_set() instead.
7498 void devlink_port_param_value_changed(struct devlink_port
*devlink_port
,
7501 struct devlink_param_item
*param_item
;
7503 param_item
= devlink_param_find_by_id(&devlink_port
->param_list
,
7505 WARN_ON(!param_item
);
7507 devlink_param_notify(devlink_port
->devlink
, devlink_port
->index
,
7508 param_item
, DEVLINK_CMD_PORT_PARAM_NEW
);
7510 EXPORT_SYMBOL_GPL(devlink_port_param_value_changed
);
7513 * devlink_param_value_str_fill - Safely fill-up the string preventing
7514 * from overflow of the preallocated buffer
7516 * @dst_val: destination devlink_param_value
7517 * @src: source buffer
7519 void devlink_param_value_str_fill(union devlink_param_value
*dst_val
,
7524 len
= strlcpy(dst_val
->vstr
, src
, __DEVLINK_PARAM_MAX_STRING_VALUE
);
7525 WARN_ON(len
>= __DEVLINK_PARAM_MAX_STRING_VALUE
);
7527 EXPORT_SYMBOL_GPL(devlink_param_value_str_fill
);
7530 * devlink_region_create - create a new address region
7533 * @region_name: region name
7534 * @region_max_snapshots: Maximum supported number of snapshots for region
7535 * @region_size: size of region
7537 struct devlink_region
*devlink_region_create(struct devlink
*devlink
,
7538 const char *region_name
,
7539 u32 region_max_snapshots
,
7542 struct devlink_region
*region
;
7545 mutex_lock(&devlink
->lock
);
7547 if (devlink_region_get_by_name(devlink
, region_name
)) {
7552 region
= kzalloc(sizeof(*region
), GFP_KERNEL
);
7558 region
->devlink
= devlink
;
7559 region
->max_snapshots
= region_max_snapshots
;
7560 region
->name
= region_name
;
7561 region
->size
= region_size
;
7562 INIT_LIST_HEAD(®ion
->snapshot_list
);
7563 list_add_tail(®ion
->list
, &devlink
->region_list
);
7564 devlink_nl_region_notify(region
, NULL
, DEVLINK_CMD_REGION_NEW
);
7566 mutex_unlock(&devlink
->lock
);
7570 mutex_unlock(&devlink
->lock
);
7571 return ERR_PTR(err
);
7573 EXPORT_SYMBOL_GPL(devlink_region_create
);
7576 * devlink_region_destroy - destroy address region
7578 * @region: devlink region to destroy
7580 void devlink_region_destroy(struct devlink_region
*region
)
7582 struct devlink
*devlink
= region
->devlink
;
7583 struct devlink_snapshot
*snapshot
, *ts
;
7585 mutex_lock(&devlink
->lock
);
7587 /* Free all snapshots of region */
7588 list_for_each_entry_safe(snapshot
, ts
, ®ion
->snapshot_list
, list
)
7589 devlink_region_snapshot_del(region
, snapshot
);
7591 list_del(®ion
->list
);
7593 devlink_nl_region_notify(region
, NULL
, DEVLINK_CMD_REGION_DEL
);
7594 mutex_unlock(&devlink
->lock
);
7597 EXPORT_SYMBOL_GPL(devlink_region_destroy
);
7600 * devlink_region_snapshot_id_get - get snapshot ID
7602 * This callback should be called when adding a new snapshot,
7603 * Driver should use the same id for multiple snapshots taken
7604 * on multiple regions at the same time/by the same trigger.
7608 u32
devlink_region_snapshot_id_get(struct devlink
*devlink
)
7612 mutex_lock(&devlink
->lock
);
7613 id
= ++devlink
->snapshot_id
;
7614 mutex_unlock(&devlink
->lock
);
7618 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get
);
7621 * devlink_region_snapshot_create - create a new snapshot
7622 * This will add a new snapshot of a region. The snapshot
7623 * will be stored on the region struct and can be accessed
7624 * from devlink. This is useful for future analyses of snapshots.
7625 * Multiple snapshots can be created on a region.
7626 * The @snapshot_id should be obtained using the getter function.
7628 * @region: devlink region of the snapshot
7629 * @data: snapshot data
7630 * @snapshot_id: snapshot id to be created
7631 * @data_destructor: pointer to destructor function to free data
7633 int devlink_region_snapshot_create(struct devlink_region
*region
,
7634 u8
*data
, u32 snapshot_id
,
7635 devlink_snapshot_data_dest_t
*data_destructor
)
7637 struct devlink
*devlink
= region
->devlink
;
7638 struct devlink_snapshot
*snapshot
;
7641 mutex_lock(&devlink
->lock
);
7643 /* check if region can hold one more snapshot */
7644 if (region
->cur_snapshots
== region
->max_snapshots
) {
7649 if (devlink_region_snapshot_get_by_id(region
, snapshot_id
)) {
7654 snapshot
= kzalloc(sizeof(*snapshot
), GFP_KERNEL
);
7660 snapshot
->id
= snapshot_id
;
7661 snapshot
->region
= region
;
7662 snapshot
->data
= data
;
7663 snapshot
->data_destructor
= data_destructor
;
7665 list_add_tail(&snapshot
->list
, ®ion
->snapshot_list
);
7667 region
->cur_snapshots
++;
7669 devlink_nl_region_notify(region
, snapshot
, DEVLINK_CMD_REGION_NEW
);
7670 mutex_unlock(&devlink
->lock
);
7674 mutex_unlock(&devlink
->lock
);
7677 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create
);
7679 #define DEVLINK_TRAP(_id, _type) \
7681 .type = DEVLINK_TRAP_TYPE_##_type, \
7682 .id = DEVLINK_TRAP_GENERIC_ID_##_id, \
7683 .name = DEVLINK_TRAP_GENERIC_NAME_##_id, \
7686 static const struct devlink_trap devlink_trap_generic
[] = {
7687 DEVLINK_TRAP(SMAC_MC
, DROP
),
7688 DEVLINK_TRAP(VLAN_TAG_MISMATCH
, DROP
),
7689 DEVLINK_TRAP(INGRESS_VLAN_FILTER
, DROP
),
7690 DEVLINK_TRAP(INGRESS_STP_FILTER
, DROP
),
7691 DEVLINK_TRAP(EMPTY_TX_LIST
, DROP
),
7692 DEVLINK_TRAP(PORT_LOOPBACK_FILTER
, DROP
),
7693 DEVLINK_TRAP(BLACKHOLE_ROUTE
, DROP
),
7694 DEVLINK_TRAP(TTL_ERROR
, EXCEPTION
),
7695 DEVLINK_TRAP(TAIL_DROP
, DROP
),
7696 DEVLINK_TRAP(NON_IP_PACKET
, DROP
),
7697 DEVLINK_TRAP(UC_DIP_MC_DMAC
, DROP
),
7698 DEVLINK_TRAP(DIP_LB
, DROP
),
7699 DEVLINK_TRAP(SIP_MC
, DROP
),
7700 DEVLINK_TRAP(SIP_LB
, DROP
),
7701 DEVLINK_TRAP(CORRUPTED_IP_HDR
, DROP
),
7702 DEVLINK_TRAP(IPV4_SIP_BC
, DROP
),
7703 DEVLINK_TRAP(IPV6_MC_DIP_RESERVED_SCOPE
, DROP
),
7704 DEVLINK_TRAP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE
, DROP
),
7705 DEVLINK_TRAP(MTU_ERROR
, EXCEPTION
),
7706 DEVLINK_TRAP(UNRESOLVED_NEIGH
, EXCEPTION
),
7707 DEVLINK_TRAP(RPF
, EXCEPTION
),
7708 DEVLINK_TRAP(REJECT_ROUTE
, EXCEPTION
),
7709 DEVLINK_TRAP(IPV4_LPM_UNICAST_MISS
, EXCEPTION
),
7710 DEVLINK_TRAP(IPV6_LPM_UNICAST_MISS
, EXCEPTION
),
7711 DEVLINK_TRAP(NON_ROUTABLE
, DROP
),
7712 DEVLINK_TRAP(DECAP_ERROR
, EXCEPTION
),
7713 DEVLINK_TRAP(OVERLAY_SMAC_MC
, DROP
),
7716 #define DEVLINK_TRAP_GROUP(_id) \
7718 .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \
7719 .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \
7722 static const struct devlink_trap_group devlink_trap_group_generic
[] = {
7723 DEVLINK_TRAP_GROUP(L2_DROPS
),
7724 DEVLINK_TRAP_GROUP(L3_DROPS
),
7725 DEVLINK_TRAP_GROUP(BUFFER_DROPS
),
7726 DEVLINK_TRAP_GROUP(TUNNEL_DROPS
),
7729 static int devlink_trap_generic_verify(const struct devlink_trap
*trap
)
7731 if (trap
->id
> DEVLINK_TRAP_GENERIC_ID_MAX
)
7734 if (strcmp(trap
->name
, devlink_trap_generic
[trap
->id
].name
))
7737 if (trap
->type
!= devlink_trap_generic
[trap
->id
].type
)
7743 static int devlink_trap_driver_verify(const struct devlink_trap
*trap
)
7747 if (trap
->id
<= DEVLINK_TRAP_GENERIC_ID_MAX
)
7750 for (i
= 0; i
< ARRAY_SIZE(devlink_trap_generic
); i
++) {
7751 if (!strcmp(trap
->name
, devlink_trap_generic
[i
].name
))
7758 static int devlink_trap_verify(const struct devlink_trap
*trap
)
7760 if (!trap
|| !trap
->name
|| !trap
->group
.name
)
7764 return devlink_trap_generic_verify(trap
);
7766 return devlink_trap_driver_verify(trap
);
7770 devlink_trap_group_generic_verify(const struct devlink_trap_group
*group
)
7772 if (group
->id
> DEVLINK_TRAP_GROUP_GENERIC_ID_MAX
)
7775 if (strcmp(group
->name
, devlink_trap_group_generic
[group
->id
].name
))
7782 devlink_trap_group_driver_verify(const struct devlink_trap_group
*group
)
7786 if (group
->id
<= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX
)
7789 for (i
= 0; i
< ARRAY_SIZE(devlink_trap_group_generic
); i
++) {
7790 if (!strcmp(group
->name
, devlink_trap_group_generic
[i
].name
))
7797 static int devlink_trap_group_verify(const struct devlink_trap_group
*group
)
7800 return devlink_trap_group_generic_verify(group
);
7802 return devlink_trap_group_driver_verify(group
);
7806 devlink_trap_group_notify(struct devlink
*devlink
,
7807 const struct devlink_trap_group_item
*group_item
,
7808 enum devlink_command cmd
)
7810 struct sk_buff
*msg
;
7813 WARN_ON_ONCE(cmd
!= DEVLINK_CMD_TRAP_GROUP_NEW
&&
7814 cmd
!= DEVLINK_CMD_TRAP_GROUP_DEL
);
7816 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
7820 err
= devlink_nl_trap_group_fill(msg
, devlink
, group_item
, cmd
, 0, 0,
7827 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
7828 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
7831 static struct devlink_trap_group_item
*
7832 devlink_trap_group_item_create(struct devlink
*devlink
,
7833 const struct devlink_trap_group
*group
)
7835 struct devlink_trap_group_item
*group_item
;
7838 err
= devlink_trap_group_verify(group
);
7840 return ERR_PTR(err
);
7842 group_item
= kzalloc(sizeof(*group_item
), GFP_KERNEL
);
7844 return ERR_PTR(-ENOMEM
);
7846 group_item
->stats
= netdev_alloc_pcpu_stats(struct devlink_stats
);
7847 if (!group_item
->stats
) {
7849 goto err_stats_alloc
;
7852 group_item
->group
= group
;
7853 refcount_set(&group_item
->refcount
, 1);
7855 if (devlink
->ops
->trap_group_init
) {
7856 err
= devlink
->ops
->trap_group_init(devlink
, group
);
7858 goto err_group_init
;
7861 list_add_tail(&group_item
->list
, &devlink
->trap_group_list
);
7862 devlink_trap_group_notify(devlink
, group_item
,
7863 DEVLINK_CMD_TRAP_GROUP_NEW
);
7868 free_percpu(group_item
->stats
);
7871 return ERR_PTR(err
);
7875 devlink_trap_group_item_destroy(struct devlink
*devlink
,
7876 struct devlink_trap_group_item
*group_item
)
7878 devlink_trap_group_notify(devlink
, group_item
,
7879 DEVLINK_CMD_TRAP_GROUP_DEL
);
7880 list_del(&group_item
->list
);
7881 free_percpu(group_item
->stats
);
7885 static struct devlink_trap_group_item
*
7886 devlink_trap_group_item_get(struct devlink
*devlink
,
7887 const struct devlink_trap_group
*group
)
7889 struct devlink_trap_group_item
*group_item
;
7891 group_item
= devlink_trap_group_item_lookup(devlink
, group
->name
);
7893 refcount_inc(&group_item
->refcount
);
7897 return devlink_trap_group_item_create(devlink
, group
);
7901 devlink_trap_group_item_put(struct devlink
*devlink
,
7902 struct devlink_trap_group_item
*group_item
)
7904 if (!refcount_dec_and_test(&group_item
->refcount
))
7907 devlink_trap_group_item_destroy(devlink
, group_item
);
7911 devlink_trap_item_group_link(struct devlink
*devlink
,
7912 struct devlink_trap_item
*trap_item
)
7914 struct devlink_trap_group_item
*group_item
;
7916 group_item
= devlink_trap_group_item_get(devlink
,
7917 &trap_item
->trap
->group
);
7918 if (IS_ERR(group_item
))
7919 return PTR_ERR(group_item
);
7921 trap_item
->group_item
= group_item
;
7927 devlink_trap_item_group_unlink(struct devlink
*devlink
,
7928 struct devlink_trap_item
*trap_item
)
7930 devlink_trap_group_item_put(devlink
, trap_item
->group_item
);
7933 static void devlink_trap_notify(struct devlink
*devlink
,
7934 const struct devlink_trap_item
*trap_item
,
7935 enum devlink_command cmd
)
7937 struct sk_buff
*msg
;
7940 WARN_ON_ONCE(cmd
!= DEVLINK_CMD_TRAP_NEW
&&
7941 cmd
!= DEVLINK_CMD_TRAP_DEL
);
7943 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
7947 err
= devlink_nl_trap_fill(msg
, devlink
, trap_item
, cmd
, 0, 0, 0);
7953 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
7954 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
7958 devlink_trap_register(struct devlink
*devlink
,
7959 const struct devlink_trap
*trap
, void *priv
)
7961 struct devlink_trap_item
*trap_item
;
7964 if (devlink_trap_item_lookup(devlink
, trap
->name
))
7967 trap_item
= kzalloc(sizeof(*trap_item
), GFP_KERNEL
);
7971 trap_item
->stats
= netdev_alloc_pcpu_stats(struct devlink_stats
);
7972 if (!trap_item
->stats
) {
7974 goto err_stats_alloc
;
7977 trap_item
->trap
= trap
;
7978 trap_item
->action
= trap
->init_action
;
7979 trap_item
->priv
= priv
;
7981 err
= devlink_trap_item_group_link(devlink
, trap_item
);
7983 goto err_group_link
;
7985 err
= devlink
->ops
->trap_init(devlink
, trap
, trap_item
);
7989 list_add_tail(&trap_item
->list
, &devlink
->trap_list
);
7990 devlink_trap_notify(devlink
, trap_item
, DEVLINK_CMD_TRAP_NEW
);
7995 devlink_trap_item_group_unlink(devlink
, trap_item
);
7997 free_percpu(trap_item
->stats
);
8003 static void devlink_trap_unregister(struct devlink
*devlink
,
8004 const struct devlink_trap
*trap
)
8006 struct devlink_trap_item
*trap_item
;
8008 trap_item
= devlink_trap_item_lookup(devlink
, trap
->name
);
8009 if (WARN_ON_ONCE(!trap_item
))
8012 devlink_trap_notify(devlink
, trap_item
, DEVLINK_CMD_TRAP_DEL
);
8013 list_del(&trap_item
->list
);
8014 if (devlink
->ops
->trap_fini
)
8015 devlink
->ops
->trap_fini(devlink
, trap
, trap_item
);
8016 devlink_trap_item_group_unlink(devlink
, trap_item
);
8017 free_percpu(trap_item
->stats
);
8021 static void devlink_trap_disable(struct devlink
*devlink
,
8022 const struct devlink_trap
*trap
)
8024 struct devlink_trap_item
*trap_item
;
8026 trap_item
= devlink_trap_item_lookup(devlink
, trap
->name
);
8027 if (WARN_ON_ONCE(!trap_item
))
8030 devlink
->ops
->trap_action_set(devlink
, trap
, DEVLINK_TRAP_ACTION_DROP
);
8031 trap_item
->action
= DEVLINK_TRAP_ACTION_DROP
;
8035 * devlink_traps_register - Register packet traps with devlink.
8036 * @devlink: devlink.
8037 * @traps: Packet traps.
8038 * @traps_count: Count of provided packet traps.
8039 * @priv: Driver private information.
8041 * Return: Non-zero value on failure.
8043 int devlink_traps_register(struct devlink
*devlink
,
8044 const struct devlink_trap
*traps
,
8045 size_t traps_count
, void *priv
)
8049 if (!devlink
->ops
->trap_init
|| !devlink
->ops
->trap_action_set
)
8052 mutex_lock(&devlink
->lock
);
8053 for (i
= 0; i
< traps_count
; i
++) {
8054 const struct devlink_trap
*trap
= &traps
[i
];
8056 err
= devlink_trap_verify(trap
);
8058 goto err_trap_verify
;
8060 err
= devlink_trap_register(devlink
, trap
, priv
);
8062 goto err_trap_register
;
8064 mutex_unlock(&devlink
->lock
);
8070 for (i
--; i
>= 0; i
--)
8071 devlink_trap_unregister(devlink
, &traps
[i
]);
8072 mutex_unlock(&devlink
->lock
);
8075 EXPORT_SYMBOL_GPL(devlink_traps_register
);
8078 * devlink_traps_unregister - Unregister packet traps from devlink.
8079 * @devlink: devlink.
8080 * @traps: Packet traps.
8081 * @traps_count: Count of provided packet traps.
8083 void devlink_traps_unregister(struct devlink
*devlink
,
8084 const struct devlink_trap
*traps
,
8089 mutex_lock(&devlink
->lock
);
8090 /* Make sure we do not have any packets in-flight while unregistering
8091 * traps by disabling all of them and waiting for a grace period.
8093 for (i
= traps_count
- 1; i
>= 0; i
--)
8094 devlink_trap_disable(devlink
, &traps
[i
]);
8096 for (i
= traps_count
- 1; i
>= 0; i
--)
8097 devlink_trap_unregister(devlink
, &traps
[i
]);
8098 mutex_unlock(&devlink
->lock
);
8100 EXPORT_SYMBOL_GPL(devlink_traps_unregister
);
8103 devlink_trap_stats_update(struct devlink_stats __percpu
*trap_stats
,
8106 struct devlink_stats
*stats
;
8108 stats
= this_cpu_ptr(trap_stats
);
8109 u64_stats_update_begin(&stats
->syncp
);
8110 stats
->rx_bytes
+= skb_len
;
8111 stats
->rx_packets
++;
8112 u64_stats_update_end(&stats
->syncp
);
8116 devlink_trap_report_metadata_fill(struct net_dm_hw_metadata
*hw_metadata
,
8117 const struct devlink_trap_item
*trap_item
,
8118 struct devlink_port
*in_devlink_port
)
8120 struct devlink_trap_group_item
*group_item
= trap_item
->group_item
;
8122 hw_metadata
->trap_group_name
= group_item
->group
->name
;
8123 hw_metadata
->trap_name
= trap_item
->trap
->name
;
8125 spin_lock(&in_devlink_port
->type_lock
);
8126 if (in_devlink_port
->type
== DEVLINK_PORT_TYPE_ETH
)
8127 hw_metadata
->input_dev
= in_devlink_port
->type_dev
;
8128 spin_unlock(&in_devlink_port
->type_lock
);
8132 * devlink_trap_report - Report trapped packet to drop monitor.
8133 * @devlink: devlink.
8134 * @skb: Trapped packet.
8135 * @trap_ctx: Trap context.
8136 * @in_devlink_port: Input devlink port.
8138 void devlink_trap_report(struct devlink
*devlink
, struct sk_buff
*skb
,
8139 void *trap_ctx
, struct devlink_port
*in_devlink_port
)
8141 struct devlink_trap_item
*trap_item
= trap_ctx
;
8142 struct net_dm_hw_metadata hw_metadata
= {};
8144 devlink_trap_stats_update(trap_item
->stats
, skb
->len
);
8145 devlink_trap_stats_update(trap_item
->group_item
->stats
, skb
->len
);
8147 devlink_trap_report_metadata_fill(&hw_metadata
, trap_item
,
8149 net_dm_hw_report(skb
, &hw_metadata
);
8151 EXPORT_SYMBOL_GPL(devlink_trap_report
);
8154 * devlink_trap_ctx_priv - Trap context to driver private information.
8155 * @trap_ctx: Trap context.
8157 * Return: Driver private information passed during registration.
8159 void *devlink_trap_ctx_priv(void *trap_ctx
)
8161 struct devlink_trap_item
*trap_item
= trap_ctx
;
8163 return trap_item
->priv
;
8165 EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv
);
8167 static void __devlink_compat_running_version(struct devlink
*devlink
,
8168 char *buf
, size_t len
)
8170 const struct nlattr
*nlattr
;
8171 struct devlink_info_req req
;
8172 struct sk_buff
*msg
;
8175 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
8180 err
= devlink
->ops
->info_get(devlink
, &req
, NULL
);
8184 nla_for_each_attr(nlattr
, (void *)msg
->data
, msg
->len
, rem
) {
8185 const struct nlattr
*kv
;
8188 if (nla_type(nlattr
) != DEVLINK_ATTR_INFO_VERSION_RUNNING
)
8191 nla_for_each_nested(kv
, nlattr
, rem_kv
) {
8192 if (nla_type(kv
) != DEVLINK_ATTR_INFO_VERSION_VALUE
)
8195 strlcat(buf
, nla_data(kv
), len
);
8196 strlcat(buf
, " ", len
);
8203 void devlink_compat_running_version(struct net_device
*dev
,
8204 char *buf
, size_t len
)
8206 struct devlink
*devlink
;
8211 devlink
= netdev_to_devlink(dev
);
8212 if (!devlink
|| !devlink
->ops
->info_get
)
8215 mutex_lock(&devlink
->lock
);
8216 __devlink_compat_running_version(devlink
, buf
, len
);
8217 mutex_unlock(&devlink
->lock
);
8224 int devlink_compat_flash_update(struct net_device
*dev
, const char *file_name
)
8226 struct devlink
*devlink
;
8232 devlink
= netdev_to_devlink(dev
);
8233 if (!devlink
|| !devlink
->ops
->flash_update
) {
8238 mutex_lock(&devlink
->lock
);
8239 ret
= devlink
->ops
->flash_update(devlink
, file_name
, NULL
, NULL
);
8240 mutex_unlock(&devlink
->lock
);
8249 int devlink_compat_phys_port_name_get(struct net_device
*dev
,
8250 char *name
, size_t len
)
8252 struct devlink_port
*devlink_port
;
8254 /* RTNL mutex is held here which ensures that devlink_port
8255 * instance cannot disappear in the middle. No need to take
8256 * any devlink lock as only permanent values are accessed.
8260 devlink_port
= netdev_to_devlink_port(dev
);
8264 return __devlink_port_phys_port_name_get(devlink_port
, name
, len
);
8267 int devlink_compat_switch_id_get(struct net_device
*dev
,
8268 struct netdev_phys_item_id
*ppid
)
8270 struct devlink_port
*devlink_port
;
8272 /* Caller must hold RTNL mutex or reference to dev, which ensures that
8273 * devlink_port instance cannot disappear in the middle. No need to take
8274 * any devlink lock as only permanent values are accessed.
8276 devlink_port
= netdev_to_devlink_port(dev
);
8277 if (!devlink_port
|| !devlink_port
->attrs
.switch_port
)
8280 memcpy(ppid
, &devlink_port
->attrs
.switch_id
, sizeof(*ppid
));
8285 static void __net_exit
devlink_pernet_pre_exit(struct net
*net
)
8287 struct devlink
*devlink
;
8290 /* In case network namespace is getting destroyed, reload
8291 * all devlink instances from this namespace into init_net.
8293 mutex_lock(&devlink_mutex
);
8294 list_for_each_entry(devlink
, &devlink_list
, list
) {
8295 if (net_eq(devlink_net(devlink
), net
)) {
8296 if (WARN_ON(!devlink_reload_supported(devlink
)))
8298 err
= devlink_reload(devlink
, &init_net
, NULL
);
8299 if (err
&& err
!= -EOPNOTSUPP
)
8300 pr_warn("Failed to reload devlink instance into init_net\n");
8303 mutex_unlock(&devlink_mutex
);
8306 static struct pernet_operations devlink_pernet_ops __net_initdata
= {
8307 .pre_exit
= devlink_pernet_pre_exit
,
8310 static int __init
devlink_init(void)
8314 err
= genl_register_family(&devlink_nl_family
);
8317 err
= register_pernet_subsys(&devlink_pernet_ops
);
8324 subsys_initcall(devlink_init
);