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 const struct nla_policy devlink_function_nl_policy
[DEVLINK_PORT_FUNCTION_ATTR_MAX
+ 1] = {
89 [DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR
] = { .type
= NLA_BINARY
},
92 static LIST_HEAD(devlink_list
);
96 * An overall lock guarding every operation coming from userspace.
97 * It also guards devlink devices list and it is taken when
98 * driver registers/unregisters it.
100 static DEFINE_MUTEX(devlink_mutex
);
102 struct net
*devlink_net(const struct devlink
*devlink
)
104 return read_pnet(&devlink
->_net
);
106 EXPORT_SYMBOL_GPL(devlink_net
);
108 static void __devlink_net_set(struct devlink
*devlink
, struct net
*net
)
110 write_pnet(&devlink
->_net
, net
);
113 void devlink_net_set(struct devlink
*devlink
, struct net
*net
)
115 if (WARN_ON(devlink
->registered
))
117 __devlink_net_set(devlink
, net
);
119 EXPORT_SYMBOL_GPL(devlink_net_set
);
121 static struct devlink
*devlink_get_from_attrs(struct net
*net
,
122 struct nlattr
**attrs
)
124 struct devlink
*devlink
;
128 if (!attrs
[DEVLINK_ATTR_BUS_NAME
] || !attrs
[DEVLINK_ATTR_DEV_NAME
])
129 return ERR_PTR(-EINVAL
);
131 busname
= nla_data(attrs
[DEVLINK_ATTR_BUS_NAME
]);
132 devname
= nla_data(attrs
[DEVLINK_ATTR_DEV_NAME
]);
134 lockdep_assert_held(&devlink_mutex
);
136 list_for_each_entry(devlink
, &devlink_list
, list
) {
137 if (strcmp(devlink
->dev
->bus
->name
, busname
) == 0 &&
138 strcmp(dev_name(devlink
->dev
), devname
) == 0 &&
139 net_eq(devlink_net(devlink
), net
))
143 return ERR_PTR(-ENODEV
);
146 static struct devlink
*devlink_get_from_info(struct genl_info
*info
)
148 return devlink_get_from_attrs(genl_info_net(info
), info
->attrs
);
151 static struct devlink_port
*devlink_port_get_by_index(struct devlink
*devlink
,
152 unsigned int port_index
)
154 struct devlink_port
*devlink_port
;
156 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
157 if (devlink_port
->index
== port_index
)
163 static bool devlink_port_index_exists(struct devlink
*devlink
,
164 unsigned int port_index
)
166 return devlink_port_get_by_index(devlink
, port_index
);
169 static struct devlink_port
*devlink_port_get_from_attrs(struct devlink
*devlink
,
170 struct nlattr
**attrs
)
172 if (attrs
[DEVLINK_ATTR_PORT_INDEX
]) {
173 u32 port_index
= nla_get_u32(attrs
[DEVLINK_ATTR_PORT_INDEX
]);
174 struct devlink_port
*devlink_port
;
176 devlink_port
= devlink_port_get_by_index(devlink
, port_index
);
178 return ERR_PTR(-ENODEV
);
181 return ERR_PTR(-EINVAL
);
184 static struct devlink_port
*devlink_port_get_from_info(struct devlink
*devlink
,
185 struct genl_info
*info
)
187 return devlink_port_get_from_attrs(devlink
, info
->attrs
);
191 struct list_head list
;
194 u16 ingress_pools_count
;
195 u16 egress_pools_count
;
196 u16 ingress_tc_count
;
200 static u16
devlink_sb_pool_count(struct devlink_sb
*devlink_sb
)
202 return devlink_sb
->ingress_pools_count
+ devlink_sb
->egress_pools_count
;
205 static struct devlink_sb
*devlink_sb_get_by_index(struct devlink
*devlink
,
206 unsigned int sb_index
)
208 struct devlink_sb
*devlink_sb
;
210 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
211 if (devlink_sb
->index
== sb_index
)
217 static bool devlink_sb_index_exists(struct devlink
*devlink
,
218 unsigned int sb_index
)
220 return devlink_sb_get_by_index(devlink
, sb_index
);
223 static struct devlink_sb
*devlink_sb_get_from_attrs(struct devlink
*devlink
,
224 struct nlattr
**attrs
)
226 if (attrs
[DEVLINK_ATTR_SB_INDEX
]) {
227 u32 sb_index
= nla_get_u32(attrs
[DEVLINK_ATTR_SB_INDEX
]);
228 struct devlink_sb
*devlink_sb
;
230 devlink_sb
= devlink_sb_get_by_index(devlink
, sb_index
);
232 return ERR_PTR(-ENODEV
);
235 return ERR_PTR(-EINVAL
);
238 static struct devlink_sb
*devlink_sb_get_from_info(struct devlink
*devlink
,
239 struct genl_info
*info
)
241 return devlink_sb_get_from_attrs(devlink
, info
->attrs
);
244 static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb
*devlink_sb
,
245 struct nlattr
**attrs
,
250 if (!attrs
[DEVLINK_ATTR_SB_POOL_INDEX
])
253 val
= nla_get_u16(attrs
[DEVLINK_ATTR_SB_POOL_INDEX
]);
254 if (val
>= devlink_sb_pool_count(devlink_sb
))
260 static int devlink_sb_pool_index_get_from_info(struct devlink_sb
*devlink_sb
,
261 struct genl_info
*info
,
264 return devlink_sb_pool_index_get_from_attrs(devlink_sb
, info
->attrs
,
269 devlink_sb_pool_type_get_from_attrs(struct nlattr
**attrs
,
270 enum devlink_sb_pool_type
*p_pool_type
)
274 if (!attrs
[DEVLINK_ATTR_SB_POOL_TYPE
])
277 val
= nla_get_u8(attrs
[DEVLINK_ATTR_SB_POOL_TYPE
]);
278 if (val
!= DEVLINK_SB_POOL_TYPE_INGRESS
&&
279 val
!= DEVLINK_SB_POOL_TYPE_EGRESS
)
286 devlink_sb_pool_type_get_from_info(struct genl_info
*info
,
287 enum devlink_sb_pool_type
*p_pool_type
)
289 return devlink_sb_pool_type_get_from_attrs(info
->attrs
, p_pool_type
);
293 devlink_sb_th_type_get_from_attrs(struct nlattr
**attrs
,
294 enum devlink_sb_threshold_type
*p_th_type
)
298 if (!attrs
[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
])
301 val
= nla_get_u8(attrs
[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
]);
302 if (val
!= DEVLINK_SB_THRESHOLD_TYPE_STATIC
&&
303 val
!= DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC
)
310 devlink_sb_th_type_get_from_info(struct genl_info
*info
,
311 enum devlink_sb_threshold_type
*p_th_type
)
313 return devlink_sb_th_type_get_from_attrs(info
->attrs
, p_th_type
);
317 devlink_sb_tc_index_get_from_attrs(struct devlink_sb
*devlink_sb
,
318 struct nlattr
**attrs
,
319 enum devlink_sb_pool_type pool_type
,
324 if (!attrs
[DEVLINK_ATTR_SB_TC_INDEX
])
327 val
= nla_get_u16(attrs
[DEVLINK_ATTR_SB_TC_INDEX
]);
328 if (pool_type
== DEVLINK_SB_POOL_TYPE_INGRESS
&&
329 val
>= devlink_sb
->ingress_tc_count
)
331 if (pool_type
== DEVLINK_SB_POOL_TYPE_EGRESS
&&
332 val
>= devlink_sb
->egress_tc_count
)
339 devlink_sb_tc_index_get_from_info(struct devlink_sb
*devlink_sb
,
340 struct genl_info
*info
,
341 enum devlink_sb_pool_type pool_type
,
344 return devlink_sb_tc_index_get_from_attrs(devlink_sb
, info
->attrs
,
345 pool_type
, p_tc_index
);
348 struct devlink_region
{
349 struct devlink
*devlink
;
350 struct list_head list
;
351 const struct devlink_region_ops
*ops
;
352 struct list_head snapshot_list
;
358 struct devlink_snapshot
{
359 struct list_head list
;
360 struct devlink_region
*region
;
365 static struct devlink_region
*
366 devlink_region_get_by_name(struct devlink
*devlink
, const char *region_name
)
368 struct devlink_region
*region
;
370 list_for_each_entry(region
, &devlink
->region_list
, list
)
371 if (!strcmp(region
->ops
->name
, region_name
))
377 static struct devlink_snapshot
*
378 devlink_region_snapshot_get_by_id(struct devlink_region
*region
, u32 id
)
380 struct devlink_snapshot
*snapshot
;
382 list_for_each_entry(snapshot
, ®ion
->snapshot_list
, list
)
383 if (snapshot
->id
== id
)
389 #define DEVLINK_NL_FLAG_NEED_DEVLINK BIT(0)
390 #define DEVLINK_NL_FLAG_NEED_PORT BIT(1)
391 #define DEVLINK_NL_FLAG_NEED_SB BIT(2)
393 /* The per devlink instance lock is taken by default in the pre-doit
394 * operation, yet several commands do not require this. The global
395 * devlink lock is taken and protects from disruption by user-calls.
397 #define DEVLINK_NL_FLAG_NO_LOCK BIT(3)
399 static int devlink_nl_pre_doit(const struct genl_ops
*ops
,
400 struct sk_buff
*skb
, struct genl_info
*info
)
402 struct devlink
*devlink
;
405 mutex_lock(&devlink_mutex
);
406 devlink
= devlink_get_from_info(info
);
407 if (IS_ERR(devlink
)) {
408 mutex_unlock(&devlink_mutex
);
409 return PTR_ERR(devlink
);
411 if (~ops
->internal_flags
& DEVLINK_NL_FLAG_NO_LOCK
)
412 mutex_lock(&devlink
->lock
);
413 if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_DEVLINK
) {
414 info
->user_ptr
[0] = devlink
;
415 } else if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_PORT
) {
416 struct devlink_port
*devlink_port
;
418 devlink_port
= devlink_port_get_from_info(devlink
, info
);
419 if (IS_ERR(devlink_port
)) {
420 err
= PTR_ERR(devlink_port
);
423 info
->user_ptr
[0] = devlink_port
;
425 if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_SB
) {
426 struct devlink_sb
*devlink_sb
;
428 devlink_sb
= devlink_sb_get_from_info(devlink
, info
);
429 if (IS_ERR(devlink_sb
)) {
430 err
= PTR_ERR(devlink_sb
);
433 info
->user_ptr
[1] = devlink_sb
;
438 if (~ops
->internal_flags
& DEVLINK_NL_FLAG_NO_LOCK
)
439 mutex_unlock(&devlink
->lock
);
440 mutex_unlock(&devlink_mutex
);
444 static void devlink_nl_post_doit(const struct genl_ops
*ops
,
445 struct sk_buff
*skb
, struct genl_info
*info
)
447 struct devlink
*devlink
;
449 /* When devlink changes netns, it would not be found
450 * by devlink_get_from_info(). So try if it is stored first.
452 if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_DEVLINK
) {
453 devlink
= info
->user_ptr
[0];
455 devlink
= devlink_get_from_info(info
);
456 WARN_ON(IS_ERR(devlink
));
458 if (!IS_ERR(devlink
) && ~ops
->internal_flags
& DEVLINK_NL_FLAG_NO_LOCK
)
459 mutex_unlock(&devlink
->lock
);
460 mutex_unlock(&devlink_mutex
);
463 static struct genl_family devlink_nl_family
;
465 enum devlink_multicast_groups
{
466 DEVLINK_MCGRP_CONFIG
,
469 static const struct genl_multicast_group devlink_nl_mcgrps
[] = {
470 [DEVLINK_MCGRP_CONFIG
] = { .name
= DEVLINK_GENL_MCGRP_CONFIG_NAME
},
473 static int devlink_nl_put_handle(struct sk_buff
*msg
, struct devlink
*devlink
)
475 if (nla_put_string(msg
, DEVLINK_ATTR_BUS_NAME
, devlink
->dev
->bus
->name
))
477 if (nla_put_string(msg
, DEVLINK_ATTR_DEV_NAME
, dev_name(devlink
->dev
)))
482 static int devlink_nl_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
483 enum devlink_command cmd
, u32 portid
,
488 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
492 if (devlink_nl_put_handle(msg
, devlink
))
493 goto nla_put_failure
;
494 if (nla_put_u8(msg
, DEVLINK_ATTR_RELOAD_FAILED
, devlink
->reload_failed
))
495 goto nla_put_failure
;
497 genlmsg_end(msg
, hdr
);
501 genlmsg_cancel(msg
, hdr
);
505 static void devlink_notify(struct devlink
*devlink
, enum devlink_command cmd
)
510 WARN_ON(cmd
!= DEVLINK_CMD_NEW
&& cmd
!= DEVLINK_CMD_DEL
);
512 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
516 err
= devlink_nl_fill(msg
, devlink
, cmd
, 0, 0, 0);
522 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
523 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
526 static int devlink_nl_port_attrs_put(struct sk_buff
*msg
,
527 struct devlink_port
*devlink_port
)
529 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
531 if (!devlink_port
->attrs_set
)
534 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_LANES
, attrs
->lanes
))
537 if (nla_put_u8(msg
, DEVLINK_ATTR_PORT_SPLITTABLE
, attrs
->splittable
))
539 if (nla_put_u16(msg
, DEVLINK_ATTR_PORT_FLAVOUR
, attrs
->flavour
))
541 switch (devlink_port
->attrs
.flavour
) {
542 case DEVLINK_PORT_FLAVOUR_PCI_PF
:
543 if (nla_put_u16(msg
, DEVLINK_ATTR_PORT_PCI_PF_NUMBER
,
547 case DEVLINK_PORT_FLAVOUR_PCI_VF
:
548 if (nla_put_u16(msg
, DEVLINK_ATTR_PORT_PCI_PF_NUMBER
,
550 nla_put_u16(msg
, DEVLINK_ATTR_PORT_PCI_VF_NUMBER
,
554 case DEVLINK_PORT_FLAVOUR_PHYSICAL
:
555 case DEVLINK_PORT_FLAVOUR_CPU
:
556 case DEVLINK_PORT_FLAVOUR_DSA
:
557 case DEVLINK_PORT_FLAVOUR_VIRTUAL
:
558 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_NUMBER
,
559 attrs
->phys
.port_number
))
563 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_SPLIT_GROUP
,
564 attrs
->phys
.port_number
))
566 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER
,
567 attrs
->phys
.split_subport_number
))
577 devlink_nl_port_function_attrs_put(struct sk_buff
*msg
, struct devlink_port
*port
,
578 struct netlink_ext_ack
*extack
)
580 struct devlink
*devlink
= port
->devlink
;
581 const struct devlink_ops
*ops
;
582 struct nlattr
*function_attr
;
583 bool empty_nest
= true;
586 function_attr
= nla_nest_start_noflag(msg
, DEVLINK_ATTR_PORT_FUNCTION
);
591 if (ops
->port_function_hw_addr_get
) {
593 u8 hw_addr
[MAX_ADDR_LEN
];
595 err
= ops
->port_function_hw_addr_get(devlink
, port
, hw_addr
, &hw_addr_len
, extack
);
596 if (err
== -EOPNOTSUPP
) {
597 /* Port function attributes are optional for a port. If port doesn't
598 * support function attribute, returning -EOPNOTSUPP is not an error.
605 err
= nla_put(msg
, DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR
, hw_addr_len
, hw_addr
);
612 if (err
|| empty_nest
)
613 nla_nest_cancel(msg
, function_attr
);
615 nla_nest_end(msg
, function_attr
);
619 static int devlink_nl_port_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
620 struct devlink_port
*devlink_port
,
621 enum devlink_command cmd
, u32 portid
,
623 struct netlink_ext_ack
*extack
)
627 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
631 if (devlink_nl_put_handle(msg
, devlink
))
632 goto nla_put_failure
;
633 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, devlink_port
->index
))
634 goto nla_put_failure
;
636 spin_lock_bh(&devlink_port
->type_lock
);
637 if (nla_put_u16(msg
, DEVLINK_ATTR_PORT_TYPE
, devlink_port
->type
))
638 goto nla_put_failure_type_locked
;
639 if (devlink_port
->desired_type
!= DEVLINK_PORT_TYPE_NOTSET
&&
640 nla_put_u16(msg
, DEVLINK_ATTR_PORT_DESIRED_TYPE
,
641 devlink_port
->desired_type
))
642 goto nla_put_failure_type_locked
;
643 if (devlink_port
->type
== DEVLINK_PORT_TYPE_ETH
) {
644 struct net_device
*netdev
= devlink_port
->type_dev
;
647 (nla_put_u32(msg
, DEVLINK_ATTR_PORT_NETDEV_IFINDEX
,
649 nla_put_string(msg
, DEVLINK_ATTR_PORT_NETDEV_NAME
,
651 goto nla_put_failure_type_locked
;
653 if (devlink_port
->type
== DEVLINK_PORT_TYPE_IB
) {
654 struct ib_device
*ibdev
= devlink_port
->type_dev
;
657 nla_put_string(msg
, DEVLINK_ATTR_PORT_IBDEV_NAME
,
659 goto nla_put_failure_type_locked
;
661 spin_unlock_bh(&devlink_port
->type_lock
);
662 if (devlink_nl_port_attrs_put(msg
, devlink_port
))
663 goto nla_put_failure
;
664 if (devlink_nl_port_function_attrs_put(msg
, devlink_port
, extack
))
665 goto nla_put_failure
;
667 genlmsg_end(msg
, hdr
);
670 nla_put_failure_type_locked
:
671 spin_unlock_bh(&devlink_port
->type_lock
);
673 genlmsg_cancel(msg
, hdr
);
677 static void devlink_port_notify(struct devlink_port
*devlink_port
,
678 enum devlink_command cmd
)
680 struct devlink
*devlink
= devlink_port
->devlink
;
684 if (!devlink_port
->registered
)
687 WARN_ON(cmd
!= DEVLINK_CMD_PORT_NEW
&& cmd
!= DEVLINK_CMD_PORT_DEL
);
689 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
693 err
= devlink_nl_port_fill(msg
, devlink
, devlink_port
, cmd
, 0, 0, 0,
700 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
701 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
704 static int devlink_nl_cmd_get_doit(struct sk_buff
*skb
, struct genl_info
*info
)
706 struct devlink
*devlink
= info
->user_ptr
[0];
710 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
714 err
= devlink_nl_fill(msg
, devlink
, DEVLINK_CMD_NEW
,
715 info
->snd_portid
, info
->snd_seq
, 0);
721 return genlmsg_reply(msg
, info
);
724 static int devlink_nl_cmd_get_dumpit(struct sk_buff
*msg
,
725 struct netlink_callback
*cb
)
727 struct devlink
*devlink
;
728 int start
= cb
->args
[0];
732 mutex_lock(&devlink_mutex
);
733 list_for_each_entry(devlink
, &devlink_list
, list
) {
734 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
740 err
= devlink_nl_fill(msg
, devlink
, DEVLINK_CMD_NEW
,
741 NETLINK_CB(cb
->skb
).portid
,
742 cb
->nlh
->nlmsg_seq
, NLM_F_MULTI
);
748 mutex_unlock(&devlink_mutex
);
754 static int devlink_nl_cmd_port_get_doit(struct sk_buff
*skb
,
755 struct genl_info
*info
)
757 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
758 struct devlink
*devlink
= devlink_port
->devlink
;
762 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
766 err
= devlink_nl_port_fill(msg
, devlink
, devlink_port
,
767 DEVLINK_CMD_PORT_NEW
,
768 info
->snd_portid
, info
->snd_seq
, 0,
775 return genlmsg_reply(msg
, info
);
778 static int devlink_nl_cmd_port_get_dumpit(struct sk_buff
*msg
,
779 struct netlink_callback
*cb
)
781 struct devlink
*devlink
;
782 struct devlink_port
*devlink_port
;
783 int start
= cb
->args
[0];
787 mutex_lock(&devlink_mutex
);
788 list_for_each_entry(devlink
, &devlink_list
, list
) {
789 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
791 mutex_lock(&devlink
->lock
);
792 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
797 err
= devlink_nl_port_fill(msg
, devlink
, devlink_port
,
799 NETLINK_CB(cb
->skb
).portid
,
804 mutex_unlock(&devlink
->lock
);
809 mutex_unlock(&devlink
->lock
);
812 mutex_unlock(&devlink_mutex
);
818 static int devlink_port_type_set(struct devlink
*devlink
,
819 struct devlink_port
*devlink_port
,
820 enum devlink_port_type port_type
)
825 if (devlink
->ops
->port_type_set
) {
826 if (port_type
== DEVLINK_PORT_TYPE_NOTSET
)
828 if (port_type
== devlink_port
->type
)
830 err
= devlink
->ops
->port_type_set(devlink_port
, port_type
);
833 devlink_port
->desired_type
= port_type
;
834 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
841 devlink_port_function_hw_addr_set(struct devlink
*devlink
, struct devlink_port
*port
,
842 const struct nlattr
*attr
, struct netlink_ext_ack
*extack
)
844 const struct devlink_ops
*ops
;
849 hw_addr
= nla_data(attr
);
850 hw_addr_len
= nla_len(attr
);
851 if (hw_addr_len
> MAX_ADDR_LEN
) {
852 NL_SET_ERR_MSG_MOD(extack
, "Port function hardware address too long");
855 if (port
->type
== DEVLINK_PORT_TYPE_ETH
) {
856 if (hw_addr_len
!= ETH_ALEN
) {
857 NL_SET_ERR_MSG_MOD(extack
, "Address must be 6 bytes for Ethernet device");
860 if (!is_unicast_ether_addr(hw_addr
)) {
861 NL_SET_ERR_MSG_MOD(extack
, "Non-unicast hardware address unsupported");
867 if (!ops
->port_function_hw_addr_set
) {
868 NL_SET_ERR_MSG_MOD(extack
, "Port doesn't support function attributes");
872 err
= ops
->port_function_hw_addr_set(devlink
, port
, hw_addr
, hw_addr_len
, extack
);
876 devlink_port_notify(port
, DEVLINK_CMD_PORT_NEW
);
881 devlink_port_function_set(struct devlink
*devlink
, struct devlink_port
*port
,
882 const struct nlattr
*attr
, struct netlink_ext_ack
*extack
)
884 struct nlattr
*tb
[DEVLINK_PORT_FUNCTION_ATTR_MAX
+ 1];
887 err
= nla_parse_nested(tb
, DEVLINK_PORT_FUNCTION_ATTR_MAX
, attr
,
888 devlink_function_nl_policy
, extack
);
890 NL_SET_ERR_MSG_MOD(extack
, "Fail to parse port function attributes");
894 attr
= tb
[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR
];
896 err
= devlink_port_function_hw_addr_set(devlink
, port
, attr
, extack
);
901 static int devlink_nl_cmd_port_set_doit(struct sk_buff
*skb
,
902 struct genl_info
*info
)
904 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
905 struct devlink
*devlink
= devlink_port
->devlink
;
908 if (info
->attrs
[DEVLINK_ATTR_PORT_TYPE
]) {
909 enum devlink_port_type port_type
;
911 port_type
= nla_get_u16(info
->attrs
[DEVLINK_ATTR_PORT_TYPE
]);
912 err
= devlink_port_type_set(devlink
, devlink_port
, port_type
);
917 if (info
->attrs
[DEVLINK_ATTR_PORT_FUNCTION
]) {
918 struct nlattr
*attr
= info
->attrs
[DEVLINK_ATTR_PORT_FUNCTION
];
919 struct netlink_ext_ack
*extack
= info
->extack
;
921 err
= devlink_port_function_set(devlink
, devlink_port
, attr
, extack
);
929 static int devlink_port_split(struct devlink
*devlink
, u32 port_index
,
930 u32 count
, struct netlink_ext_ack
*extack
)
933 if (devlink
->ops
->port_split
)
934 return devlink
->ops
->port_split(devlink
, port_index
, count
,
939 static int devlink_nl_cmd_port_split_doit(struct sk_buff
*skb
,
940 struct genl_info
*info
)
942 struct devlink
*devlink
= info
->user_ptr
[0];
943 struct devlink_port
*devlink_port
;
947 if (!info
->attrs
[DEVLINK_ATTR_PORT_INDEX
] ||
948 !info
->attrs
[DEVLINK_ATTR_PORT_SPLIT_COUNT
])
951 devlink_port
= devlink_port_get_from_info(devlink
, info
);
952 port_index
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_PORT_INDEX
]);
953 count
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_PORT_SPLIT_COUNT
]);
955 if (IS_ERR(devlink_port
))
958 if (!devlink_port
->attrs
.splittable
) {
959 /* Split ports cannot be split. */
960 if (devlink_port
->attrs
.split
)
961 NL_SET_ERR_MSG_MOD(info
->extack
, "Port cannot be split further");
963 NL_SET_ERR_MSG_MOD(info
->extack
, "Port cannot be split");
967 if (count
< 2 || !is_power_of_2(count
) || count
> devlink_port
->attrs
.lanes
) {
968 NL_SET_ERR_MSG_MOD(info
->extack
, "Invalid split count");
972 return devlink_port_split(devlink
, port_index
, count
, info
->extack
);
975 static int devlink_port_unsplit(struct devlink
*devlink
, u32 port_index
,
976 struct netlink_ext_ack
*extack
)
979 if (devlink
->ops
->port_unsplit
)
980 return devlink
->ops
->port_unsplit(devlink
, port_index
, extack
);
984 static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff
*skb
,
985 struct genl_info
*info
)
987 struct devlink
*devlink
= info
->user_ptr
[0];
990 if (!info
->attrs
[DEVLINK_ATTR_PORT_INDEX
])
993 port_index
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_PORT_INDEX
]);
994 return devlink_port_unsplit(devlink
, port_index
, info
->extack
);
997 static int devlink_nl_sb_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
998 struct devlink_sb
*devlink_sb
,
999 enum devlink_command cmd
, u32 portid
,
1004 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
1008 if (devlink_nl_put_handle(msg
, devlink
))
1009 goto nla_put_failure
;
1010 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
1011 goto nla_put_failure
;
1012 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_SIZE
, devlink_sb
->size
))
1013 goto nla_put_failure
;
1014 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT
,
1015 devlink_sb
->ingress_pools_count
))
1016 goto nla_put_failure
;
1017 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT
,
1018 devlink_sb
->egress_pools_count
))
1019 goto nla_put_failure
;
1020 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_INGRESS_TC_COUNT
,
1021 devlink_sb
->ingress_tc_count
))
1022 goto nla_put_failure
;
1023 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_EGRESS_TC_COUNT
,
1024 devlink_sb
->egress_tc_count
))
1025 goto nla_put_failure
;
1027 genlmsg_end(msg
, hdr
);
1031 genlmsg_cancel(msg
, hdr
);
1035 static int devlink_nl_cmd_sb_get_doit(struct sk_buff
*skb
,
1036 struct genl_info
*info
)
1038 struct devlink
*devlink
= info
->user_ptr
[0];
1039 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1040 struct sk_buff
*msg
;
1043 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1047 err
= devlink_nl_sb_fill(msg
, devlink
, devlink_sb
,
1049 info
->snd_portid
, info
->snd_seq
, 0);
1055 return genlmsg_reply(msg
, info
);
1058 static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff
*msg
,
1059 struct netlink_callback
*cb
)
1061 struct devlink
*devlink
;
1062 struct devlink_sb
*devlink_sb
;
1063 int start
= cb
->args
[0];
1067 mutex_lock(&devlink_mutex
);
1068 list_for_each_entry(devlink
, &devlink_list
, list
) {
1069 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
1071 mutex_lock(&devlink
->lock
);
1072 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
1077 err
= devlink_nl_sb_fill(msg
, devlink
, devlink_sb
,
1079 NETLINK_CB(cb
->skb
).portid
,
1083 mutex_unlock(&devlink
->lock
);
1088 mutex_unlock(&devlink
->lock
);
1091 mutex_unlock(&devlink_mutex
);
1097 static int devlink_nl_sb_pool_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
1098 struct devlink_sb
*devlink_sb
,
1099 u16 pool_index
, enum devlink_command cmd
,
1100 u32 portid
, u32 seq
, int flags
)
1102 struct devlink_sb_pool_info pool_info
;
1106 err
= devlink
->ops
->sb_pool_get(devlink
, devlink_sb
->index
,
1107 pool_index
, &pool_info
);
1111 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
1115 if (devlink_nl_put_handle(msg
, devlink
))
1116 goto nla_put_failure
;
1117 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
1118 goto nla_put_failure
;
1119 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_POOL_INDEX
, pool_index
))
1120 goto nla_put_failure
;
1121 if (nla_put_u8(msg
, DEVLINK_ATTR_SB_POOL_TYPE
, pool_info
.pool_type
))
1122 goto nla_put_failure
;
1123 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_POOL_SIZE
, pool_info
.size
))
1124 goto nla_put_failure
;
1125 if (nla_put_u8(msg
, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
,
1126 pool_info
.threshold_type
))
1127 goto nla_put_failure
;
1128 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_POOL_CELL_SIZE
,
1129 pool_info
.cell_size
))
1130 goto nla_put_failure
;
1132 genlmsg_end(msg
, hdr
);
1136 genlmsg_cancel(msg
, hdr
);
1140 static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff
*skb
,
1141 struct genl_info
*info
)
1143 struct devlink
*devlink
= info
->user_ptr
[0];
1144 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1145 struct sk_buff
*msg
;
1149 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1154 if (!devlink
->ops
->sb_pool_get
)
1157 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1161 err
= devlink_nl_sb_pool_fill(msg
, devlink
, devlink_sb
, pool_index
,
1162 DEVLINK_CMD_SB_POOL_NEW
,
1163 info
->snd_portid
, info
->snd_seq
, 0);
1169 return genlmsg_reply(msg
, info
);
1172 static int __sb_pool_get_dumpit(struct sk_buff
*msg
, int start
, int *p_idx
,
1173 struct devlink
*devlink
,
1174 struct devlink_sb
*devlink_sb
,
1175 u32 portid
, u32 seq
)
1177 u16 pool_count
= devlink_sb_pool_count(devlink_sb
);
1181 for (pool_index
= 0; pool_index
< pool_count
; pool_index
++) {
1182 if (*p_idx
< start
) {
1186 err
= devlink_nl_sb_pool_fill(msg
, devlink
,
1189 DEVLINK_CMD_SB_POOL_NEW
,
1190 portid
, seq
, NLM_F_MULTI
);
1198 static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff
*msg
,
1199 struct netlink_callback
*cb
)
1201 struct devlink
*devlink
;
1202 struct devlink_sb
*devlink_sb
;
1203 int start
= cb
->args
[0];
1207 mutex_lock(&devlink_mutex
);
1208 list_for_each_entry(devlink
, &devlink_list
, list
) {
1209 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)) ||
1210 !devlink
->ops
->sb_pool_get
)
1212 mutex_lock(&devlink
->lock
);
1213 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
1214 err
= __sb_pool_get_dumpit(msg
, start
, &idx
, devlink
,
1216 NETLINK_CB(cb
->skb
).portid
,
1217 cb
->nlh
->nlmsg_seq
);
1218 if (err
&& err
!= -EOPNOTSUPP
) {
1219 mutex_unlock(&devlink
->lock
);
1223 mutex_unlock(&devlink
->lock
);
1226 mutex_unlock(&devlink_mutex
);
1228 if (err
!= -EMSGSIZE
)
1235 static int devlink_sb_pool_set(struct devlink
*devlink
, unsigned int sb_index
,
1236 u16 pool_index
, u32 size
,
1237 enum devlink_sb_threshold_type threshold_type
,
1238 struct netlink_ext_ack
*extack
)
1241 const struct devlink_ops
*ops
= devlink
->ops
;
1243 if (ops
->sb_pool_set
)
1244 return ops
->sb_pool_set(devlink
, sb_index
, pool_index
,
1245 size
, threshold_type
, extack
);
1249 static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff
*skb
,
1250 struct genl_info
*info
)
1252 struct devlink
*devlink
= info
->user_ptr
[0];
1253 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1254 enum devlink_sb_threshold_type threshold_type
;
1259 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1264 err
= devlink_sb_th_type_get_from_info(info
, &threshold_type
);
1268 if (!info
->attrs
[DEVLINK_ATTR_SB_POOL_SIZE
])
1271 size
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_SB_POOL_SIZE
]);
1272 return devlink_sb_pool_set(devlink
, devlink_sb
->index
,
1273 pool_index
, size
, threshold_type
,
1277 static int devlink_nl_sb_port_pool_fill(struct sk_buff
*msg
,
1278 struct devlink
*devlink
,
1279 struct devlink_port
*devlink_port
,
1280 struct devlink_sb
*devlink_sb
,
1282 enum devlink_command cmd
,
1283 u32 portid
, u32 seq
, int flags
)
1285 const struct devlink_ops
*ops
= devlink
->ops
;
1290 err
= ops
->sb_port_pool_get(devlink_port
, devlink_sb
->index
,
1291 pool_index
, &threshold
);
1295 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
1299 if (devlink_nl_put_handle(msg
, devlink
))
1300 goto nla_put_failure
;
1301 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, devlink_port
->index
))
1302 goto nla_put_failure
;
1303 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
1304 goto nla_put_failure
;
1305 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_POOL_INDEX
, pool_index
))
1306 goto nla_put_failure
;
1307 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_THRESHOLD
, threshold
))
1308 goto nla_put_failure
;
1310 if (ops
->sb_occ_port_pool_get
) {
1314 err
= ops
->sb_occ_port_pool_get(devlink_port
, devlink_sb
->index
,
1315 pool_index
, &cur
, &max
);
1316 if (err
&& err
!= -EOPNOTSUPP
)
1319 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_CUR
, cur
))
1320 goto nla_put_failure
;
1321 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_MAX
, max
))
1322 goto nla_put_failure
;
1326 genlmsg_end(msg
, hdr
);
1330 genlmsg_cancel(msg
, hdr
);
1334 static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff
*skb
,
1335 struct genl_info
*info
)
1337 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1338 struct devlink
*devlink
= devlink_port
->devlink
;
1339 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1340 struct sk_buff
*msg
;
1344 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1349 if (!devlink
->ops
->sb_port_pool_get
)
1352 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1356 err
= devlink_nl_sb_port_pool_fill(msg
, devlink
, devlink_port
,
1357 devlink_sb
, pool_index
,
1358 DEVLINK_CMD_SB_PORT_POOL_NEW
,
1359 info
->snd_portid
, info
->snd_seq
, 0);
1365 return genlmsg_reply(msg
, info
);
1368 static int __sb_port_pool_get_dumpit(struct sk_buff
*msg
, int start
, int *p_idx
,
1369 struct devlink
*devlink
,
1370 struct devlink_sb
*devlink_sb
,
1371 u32 portid
, u32 seq
)
1373 struct devlink_port
*devlink_port
;
1374 u16 pool_count
= devlink_sb_pool_count(devlink_sb
);
1378 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
1379 for (pool_index
= 0; pool_index
< pool_count
; pool_index
++) {
1380 if (*p_idx
< start
) {
1384 err
= devlink_nl_sb_port_pool_fill(msg
, devlink
,
1388 DEVLINK_CMD_SB_PORT_POOL_NEW
,
1399 static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff
*msg
,
1400 struct netlink_callback
*cb
)
1402 struct devlink
*devlink
;
1403 struct devlink_sb
*devlink_sb
;
1404 int start
= cb
->args
[0];
1408 mutex_lock(&devlink_mutex
);
1409 list_for_each_entry(devlink
, &devlink_list
, list
) {
1410 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)) ||
1411 !devlink
->ops
->sb_port_pool_get
)
1413 mutex_lock(&devlink
->lock
);
1414 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
1415 err
= __sb_port_pool_get_dumpit(msg
, start
, &idx
,
1416 devlink
, devlink_sb
,
1417 NETLINK_CB(cb
->skb
).portid
,
1418 cb
->nlh
->nlmsg_seq
);
1419 if (err
&& err
!= -EOPNOTSUPP
) {
1420 mutex_unlock(&devlink
->lock
);
1424 mutex_unlock(&devlink
->lock
);
1427 mutex_unlock(&devlink_mutex
);
1429 if (err
!= -EMSGSIZE
)
1436 static int devlink_sb_port_pool_set(struct devlink_port
*devlink_port
,
1437 unsigned int sb_index
, u16 pool_index
,
1439 struct netlink_ext_ack
*extack
)
1442 const struct devlink_ops
*ops
= devlink_port
->devlink
->ops
;
1444 if (ops
->sb_port_pool_set
)
1445 return ops
->sb_port_pool_set(devlink_port
, sb_index
,
1446 pool_index
, threshold
, extack
);
1450 static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff
*skb
,
1451 struct genl_info
*info
)
1453 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1454 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1459 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1464 if (!info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
])
1467 threshold
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
]);
1468 return devlink_sb_port_pool_set(devlink_port
, devlink_sb
->index
,
1469 pool_index
, threshold
, info
->extack
);
1473 devlink_nl_sb_tc_pool_bind_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
1474 struct devlink_port
*devlink_port
,
1475 struct devlink_sb
*devlink_sb
, u16 tc_index
,
1476 enum devlink_sb_pool_type pool_type
,
1477 enum devlink_command cmd
,
1478 u32 portid
, u32 seq
, int flags
)
1480 const struct devlink_ops
*ops
= devlink
->ops
;
1486 err
= ops
->sb_tc_pool_bind_get(devlink_port
, devlink_sb
->index
,
1487 tc_index
, pool_type
,
1488 &pool_index
, &threshold
);
1492 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
1496 if (devlink_nl_put_handle(msg
, devlink
))
1497 goto nla_put_failure
;
1498 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, devlink_port
->index
))
1499 goto nla_put_failure
;
1500 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
1501 goto nla_put_failure
;
1502 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_TC_INDEX
, tc_index
))
1503 goto nla_put_failure
;
1504 if (nla_put_u8(msg
, DEVLINK_ATTR_SB_POOL_TYPE
, pool_type
))
1505 goto nla_put_failure
;
1506 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_POOL_INDEX
, pool_index
))
1507 goto nla_put_failure
;
1508 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_THRESHOLD
, threshold
))
1509 goto nla_put_failure
;
1511 if (ops
->sb_occ_tc_port_bind_get
) {
1515 err
= ops
->sb_occ_tc_port_bind_get(devlink_port
,
1517 tc_index
, pool_type
,
1519 if (err
&& err
!= -EOPNOTSUPP
)
1522 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_CUR
, cur
))
1523 goto nla_put_failure
;
1524 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_MAX
, max
))
1525 goto nla_put_failure
;
1529 genlmsg_end(msg
, hdr
);
1533 genlmsg_cancel(msg
, hdr
);
1537 static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff
*skb
,
1538 struct genl_info
*info
)
1540 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1541 struct devlink
*devlink
= devlink_port
->devlink
;
1542 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1543 struct sk_buff
*msg
;
1544 enum devlink_sb_pool_type pool_type
;
1548 err
= devlink_sb_pool_type_get_from_info(info
, &pool_type
);
1552 err
= devlink_sb_tc_index_get_from_info(devlink_sb
, info
,
1553 pool_type
, &tc_index
);
1557 if (!devlink
->ops
->sb_tc_pool_bind_get
)
1560 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1564 err
= devlink_nl_sb_tc_pool_bind_fill(msg
, devlink
, devlink_port
,
1565 devlink_sb
, tc_index
, pool_type
,
1566 DEVLINK_CMD_SB_TC_POOL_BIND_NEW
,
1574 return genlmsg_reply(msg
, info
);
1577 static int __sb_tc_pool_bind_get_dumpit(struct sk_buff
*msg
,
1578 int start
, int *p_idx
,
1579 struct devlink
*devlink
,
1580 struct devlink_sb
*devlink_sb
,
1581 u32 portid
, u32 seq
)
1583 struct devlink_port
*devlink_port
;
1587 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
1589 tc_index
< devlink_sb
->ingress_tc_count
; tc_index
++) {
1590 if (*p_idx
< start
) {
1594 err
= devlink_nl_sb_tc_pool_bind_fill(msg
, devlink
,
1598 DEVLINK_SB_POOL_TYPE_INGRESS
,
1599 DEVLINK_CMD_SB_TC_POOL_BIND_NEW
,
1607 tc_index
< devlink_sb
->egress_tc_count
; tc_index
++) {
1608 if (*p_idx
< start
) {
1612 err
= devlink_nl_sb_tc_pool_bind_fill(msg
, devlink
,
1616 DEVLINK_SB_POOL_TYPE_EGRESS
,
1617 DEVLINK_CMD_SB_TC_POOL_BIND_NEW
,
1629 devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff
*msg
,
1630 struct netlink_callback
*cb
)
1632 struct devlink
*devlink
;
1633 struct devlink_sb
*devlink_sb
;
1634 int start
= cb
->args
[0];
1638 mutex_lock(&devlink_mutex
);
1639 list_for_each_entry(devlink
, &devlink_list
, list
) {
1640 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)) ||
1641 !devlink
->ops
->sb_tc_pool_bind_get
)
1644 mutex_lock(&devlink
->lock
);
1645 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
1646 err
= __sb_tc_pool_bind_get_dumpit(msg
, start
, &idx
,
1649 NETLINK_CB(cb
->skb
).portid
,
1650 cb
->nlh
->nlmsg_seq
);
1651 if (err
&& err
!= -EOPNOTSUPP
) {
1652 mutex_unlock(&devlink
->lock
);
1656 mutex_unlock(&devlink
->lock
);
1659 mutex_unlock(&devlink_mutex
);
1661 if (err
!= -EMSGSIZE
)
1668 static int devlink_sb_tc_pool_bind_set(struct devlink_port
*devlink_port
,
1669 unsigned int sb_index
, u16 tc_index
,
1670 enum devlink_sb_pool_type pool_type
,
1671 u16 pool_index
, u32 threshold
,
1672 struct netlink_ext_ack
*extack
)
1675 const struct devlink_ops
*ops
= devlink_port
->devlink
->ops
;
1677 if (ops
->sb_tc_pool_bind_set
)
1678 return ops
->sb_tc_pool_bind_set(devlink_port
, sb_index
,
1679 tc_index
, pool_type
,
1680 pool_index
, threshold
, extack
);
1684 static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff
*skb
,
1685 struct genl_info
*info
)
1687 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1688 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1689 enum devlink_sb_pool_type pool_type
;
1695 err
= devlink_sb_pool_type_get_from_info(info
, &pool_type
);
1699 err
= devlink_sb_tc_index_get_from_info(devlink_sb
, info
,
1700 pool_type
, &tc_index
);
1704 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1709 if (!info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
])
1712 threshold
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
]);
1713 return devlink_sb_tc_pool_bind_set(devlink_port
, devlink_sb
->index
,
1714 tc_index
, pool_type
,
1715 pool_index
, threshold
, info
->extack
);
1718 static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff
*skb
,
1719 struct genl_info
*info
)
1721 struct devlink
*devlink
= info
->user_ptr
[0];
1722 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1723 const struct devlink_ops
*ops
= devlink
->ops
;
1725 if (ops
->sb_occ_snapshot
)
1726 return ops
->sb_occ_snapshot(devlink
, devlink_sb
->index
);
1730 static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff
*skb
,
1731 struct genl_info
*info
)
1733 struct devlink
*devlink
= info
->user_ptr
[0];
1734 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1735 const struct devlink_ops
*ops
= devlink
->ops
;
1737 if (ops
->sb_occ_max_clear
)
1738 return ops
->sb_occ_max_clear(devlink
, devlink_sb
->index
);
1742 static int devlink_nl_eswitch_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
1743 enum devlink_command cmd
, u32 portid
,
1746 const struct devlink_ops
*ops
= devlink
->ops
;
1747 enum devlink_eswitch_encap_mode encap_mode
;
1753 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
1757 err
= devlink_nl_put_handle(msg
, devlink
);
1759 goto nla_put_failure
;
1761 if (ops
->eswitch_mode_get
) {
1762 err
= ops
->eswitch_mode_get(devlink
, &mode
);
1764 goto nla_put_failure
;
1765 err
= nla_put_u16(msg
, DEVLINK_ATTR_ESWITCH_MODE
, mode
);
1767 goto nla_put_failure
;
1770 if (ops
->eswitch_inline_mode_get
) {
1771 err
= ops
->eswitch_inline_mode_get(devlink
, &inline_mode
);
1773 goto nla_put_failure
;
1774 err
= nla_put_u8(msg
, DEVLINK_ATTR_ESWITCH_INLINE_MODE
,
1777 goto nla_put_failure
;
1780 if (ops
->eswitch_encap_mode_get
) {
1781 err
= ops
->eswitch_encap_mode_get(devlink
, &encap_mode
);
1783 goto nla_put_failure
;
1784 err
= nla_put_u8(msg
, DEVLINK_ATTR_ESWITCH_ENCAP_MODE
, encap_mode
);
1786 goto nla_put_failure
;
1789 genlmsg_end(msg
, hdr
);
1793 genlmsg_cancel(msg
, hdr
);
1797 static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff
*skb
,
1798 struct genl_info
*info
)
1800 struct devlink
*devlink
= info
->user_ptr
[0];
1801 struct sk_buff
*msg
;
1804 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1808 err
= devlink_nl_eswitch_fill(msg
, devlink
, DEVLINK_CMD_ESWITCH_GET
,
1809 info
->snd_portid
, info
->snd_seq
, 0);
1816 return genlmsg_reply(msg
, info
);
1819 static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff
*skb
,
1820 struct genl_info
*info
)
1822 struct devlink
*devlink
= info
->user_ptr
[0];
1823 const struct devlink_ops
*ops
= devlink
->ops
;
1824 enum devlink_eswitch_encap_mode encap_mode
;
1829 if (info
->attrs
[DEVLINK_ATTR_ESWITCH_MODE
]) {
1830 if (!ops
->eswitch_mode_set
)
1832 mode
= nla_get_u16(info
->attrs
[DEVLINK_ATTR_ESWITCH_MODE
]);
1833 err
= ops
->eswitch_mode_set(devlink
, mode
, info
->extack
);
1838 if (info
->attrs
[DEVLINK_ATTR_ESWITCH_INLINE_MODE
]) {
1839 if (!ops
->eswitch_inline_mode_set
)
1841 inline_mode
= nla_get_u8(
1842 info
->attrs
[DEVLINK_ATTR_ESWITCH_INLINE_MODE
]);
1843 err
= ops
->eswitch_inline_mode_set(devlink
, inline_mode
,
1849 if (info
->attrs
[DEVLINK_ATTR_ESWITCH_ENCAP_MODE
]) {
1850 if (!ops
->eswitch_encap_mode_set
)
1852 encap_mode
= nla_get_u8(info
->attrs
[DEVLINK_ATTR_ESWITCH_ENCAP_MODE
]);
1853 err
= ops
->eswitch_encap_mode_set(devlink
, encap_mode
,
1862 int devlink_dpipe_match_put(struct sk_buff
*skb
,
1863 struct devlink_dpipe_match
*match
)
1865 struct devlink_dpipe_header
*header
= match
->header
;
1866 struct devlink_dpipe_field
*field
= &header
->fields
[match
->field_id
];
1867 struct nlattr
*match_attr
;
1869 match_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_MATCH
);
1873 if (nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_MATCH_TYPE
, match
->type
) ||
1874 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_INDEX
, match
->header_index
) ||
1875 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_ID
, header
->id
) ||
1876 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_ID
, field
->id
) ||
1877 nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL
, header
->global
))
1878 goto nla_put_failure
;
1880 nla_nest_end(skb
, match_attr
);
1884 nla_nest_cancel(skb
, match_attr
);
1887 EXPORT_SYMBOL_GPL(devlink_dpipe_match_put
);
1889 static int devlink_dpipe_matches_put(struct devlink_dpipe_table
*table
,
1890 struct sk_buff
*skb
)
1892 struct nlattr
*matches_attr
;
1894 matches_attr
= nla_nest_start_noflag(skb
,
1895 DEVLINK_ATTR_DPIPE_TABLE_MATCHES
);
1899 if (table
->table_ops
->matches_dump(table
->priv
, skb
))
1900 goto nla_put_failure
;
1902 nla_nest_end(skb
, matches_attr
);
1906 nla_nest_cancel(skb
, matches_attr
);
1910 int devlink_dpipe_action_put(struct sk_buff
*skb
,
1911 struct devlink_dpipe_action
*action
)
1913 struct devlink_dpipe_header
*header
= action
->header
;
1914 struct devlink_dpipe_field
*field
= &header
->fields
[action
->field_id
];
1915 struct nlattr
*action_attr
;
1917 action_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_ACTION
);
1921 if (nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_ACTION_TYPE
, action
->type
) ||
1922 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_INDEX
, action
->header_index
) ||
1923 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_ID
, header
->id
) ||
1924 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_ID
, field
->id
) ||
1925 nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL
, header
->global
))
1926 goto nla_put_failure
;
1928 nla_nest_end(skb
, action_attr
);
1932 nla_nest_cancel(skb
, action_attr
);
1935 EXPORT_SYMBOL_GPL(devlink_dpipe_action_put
);
1937 static int devlink_dpipe_actions_put(struct devlink_dpipe_table
*table
,
1938 struct sk_buff
*skb
)
1940 struct nlattr
*actions_attr
;
1942 actions_attr
= nla_nest_start_noflag(skb
,
1943 DEVLINK_ATTR_DPIPE_TABLE_ACTIONS
);
1947 if (table
->table_ops
->actions_dump(table
->priv
, skb
))
1948 goto nla_put_failure
;
1950 nla_nest_end(skb
, actions_attr
);
1954 nla_nest_cancel(skb
, actions_attr
);
1958 static int devlink_dpipe_table_put(struct sk_buff
*skb
,
1959 struct devlink_dpipe_table
*table
)
1961 struct nlattr
*table_attr
;
1964 table_size
= table
->table_ops
->size_get(table
->priv
);
1965 table_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_TABLE
);
1969 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_TABLE_NAME
, table
->name
) ||
1970 nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_TABLE_SIZE
, table_size
,
1972 goto nla_put_failure
;
1973 if (nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
,
1974 table
->counters_enabled
))
1975 goto nla_put_failure
;
1977 if (table
->resource_valid
) {
1978 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID
,
1979 table
->resource_id
, DEVLINK_ATTR_PAD
) ||
1980 nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS
,
1981 table
->resource_units
, DEVLINK_ATTR_PAD
))
1982 goto nla_put_failure
;
1984 if (devlink_dpipe_matches_put(table
, skb
))
1985 goto nla_put_failure
;
1987 if (devlink_dpipe_actions_put(table
, skb
))
1988 goto nla_put_failure
;
1990 nla_nest_end(skb
, table_attr
);
1994 nla_nest_cancel(skb
, table_attr
);
1998 static int devlink_dpipe_send_and_alloc_skb(struct sk_buff
**pskb
,
1999 struct genl_info
*info
)
2004 err
= genlmsg_reply(*pskb
, info
);
2008 *pskb
= genlmsg_new(GENLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
2014 static int devlink_dpipe_tables_fill(struct genl_info
*info
,
2015 enum devlink_command cmd
, int flags
,
2016 struct list_head
*dpipe_tables
,
2017 const char *table_name
)
2019 struct devlink
*devlink
= info
->user_ptr
[0];
2020 struct devlink_dpipe_table
*table
;
2021 struct nlattr
*tables_attr
;
2022 struct sk_buff
*skb
= NULL
;
2023 struct nlmsghdr
*nlh
;
2029 table
= list_first_entry(dpipe_tables
,
2030 struct devlink_dpipe_table
, list
);
2032 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2036 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2037 &devlink_nl_family
, NLM_F_MULTI
, cmd
);
2043 if (devlink_nl_put_handle(skb
, devlink
))
2044 goto nla_put_failure
;
2045 tables_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_TABLES
);
2047 goto nla_put_failure
;
2051 list_for_each_entry_from(table
, dpipe_tables
, list
) {
2053 err
= devlink_dpipe_table_put(skb
, table
);
2061 if (!strcmp(table
->name
, table_name
)) {
2062 err
= devlink_dpipe_table_put(skb
, table
);
2070 nla_nest_end(skb
, tables_attr
);
2071 genlmsg_end(skb
, hdr
);
2076 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2077 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
2079 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2085 return genlmsg_reply(skb
, info
);
2094 static int devlink_nl_cmd_dpipe_table_get(struct sk_buff
*skb
,
2095 struct genl_info
*info
)
2097 struct devlink
*devlink
= info
->user_ptr
[0];
2098 const char *table_name
= NULL
;
2100 if (info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
])
2101 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
2103 return devlink_dpipe_tables_fill(info
, DEVLINK_CMD_DPIPE_TABLE_GET
, 0,
2104 &devlink
->dpipe_table_list
,
2108 static int devlink_dpipe_value_put(struct sk_buff
*skb
,
2109 struct devlink_dpipe_value
*value
)
2111 if (nla_put(skb
, DEVLINK_ATTR_DPIPE_VALUE
,
2112 value
->value_size
, value
->value
))
2115 if (nla_put(skb
, DEVLINK_ATTR_DPIPE_VALUE_MASK
,
2116 value
->value_size
, value
->mask
))
2118 if (value
->mapping_valid
)
2119 if (nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_VALUE_MAPPING
,
2120 value
->mapping_value
))
2125 static int devlink_dpipe_action_value_put(struct sk_buff
*skb
,
2126 struct devlink_dpipe_value
*value
)
2130 if (devlink_dpipe_action_put(skb
, value
->action
))
2132 if (devlink_dpipe_value_put(skb
, value
))
2137 static int devlink_dpipe_action_values_put(struct sk_buff
*skb
,
2138 struct devlink_dpipe_value
*values
,
2139 unsigned int values_count
)
2141 struct nlattr
*action_attr
;
2145 for (i
= 0; i
< values_count
; i
++) {
2146 action_attr
= nla_nest_start_noflag(skb
,
2147 DEVLINK_ATTR_DPIPE_ACTION_VALUE
);
2150 err
= devlink_dpipe_action_value_put(skb
, &values
[i
]);
2152 goto err_action_value_put
;
2153 nla_nest_end(skb
, action_attr
);
2157 err_action_value_put
:
2158 nla_nest_cancel(skb
, action_attr
);
2162 static int devlink_dpipe_match_value_put(struct sk_buff
*skb
,
2163 struct devlink_dpipe_value
*value
)
2167 if (devlink_dpipe_match_put(skb
, value
->match
))
2169 if (devlink_dpipe_value_put(skb
, value
))
2174 static int devlink_dpipe_match_values_put(struct sk_buff
*skb
,
2175 struct devlink_dpipe_value
*values
,
2176 unsigned int values_count
)
2178 struct nlattr
*match_attr
;
2182 for (i
= 0; i
< values_count
; i
++) {
2183 match_attr
= nla_nest_start_noflag(skb
,
2184 DEVLINK_ATTR_DPIPE_MATCH_VALUE
);
2187 err
= devlink_dpipe_match_value_put(skb
, &values
[i
]);
2189 goto err_match_value_put
;
2190 nla_nest_end(skb
, match_attr
);
2194 err_match_value_put
:
2195 nla_nest_cancel(skb
, match_attr
);
2199 static int devlink_dpipe_entry_put(struct sk_buff
*skb
,
2200 struct devlink_dpipe_entry
*entry
)
2202 struct nlattr
*entry_attr
, *matches_attr
, *actions_attr
;
2205 entry_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_ENTRY
);
2209 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_ENTRY_INDEX
, entry
->index
,
2211 goto nla_put_failure
;
2212 if (entry
->counter_valid
)
2213 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER
,
2214 entry
->counter
, DEVLINK_ATTR_PAD
))
2215 goto nla_put_failure
;
2217 matches_attr
= nla_nest_start_noflag(skb
,
2218 DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES
);
2220 goto nla_put_failure
;
2222 err
= devlink_dpipe_match_values_put(skb
, entry
->match_values
,
2223 entry
->match_values_count
);
2225 nla_nest_cancel(skb
, matches_attr
);
2226 goto err_match_values_put
;
2228 nla_nest_end(skb
, matches_attr
);
2230 actions_attr
= nla_nest_start_noflag(skb
,
2231 DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES
);
2233 goto nla_put_failure
;
2235 err
= devlink_dpipe_action_values_put(skb
, entry
->action_values
,
2236 entry
->action_values_count
);
2238 nla_nest_cancel(skb
, actions_attr
);
2239 goto err_action_values_put
;
2241 nla_nest_end(skb
, actions_attr
);
2243 nla_nest_end(skb
, entry_attr
);
2248 err_match_values_put
:
2249 err_action_values_put
:
2250 nla_nest_cancel(skb
, entry_attr
);
2254 static struct devlink_dpipe_table
*
2255 devlink_dpipe_table_find(struct list_head
*dpipe_tables
,
2256 const char *table_name
, struct devlink
*devlink
)
2258 struct devlink_dpipe_table
*table
;
2259 list_for_each_entry_rcu(table
, dpipe_tables
, list
,
2260 lockdep_is_held(&devlink
->lock
)) {
2261 if (!strcmp(table
->name
, table_name
))
2267 int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx
*dump_ctx
)
2269 struct devlink
*devlink
;
2272 err
= devlink_dpipe_send_and_alloc_skb(&dump_ctx
->skb
,
2277 dump_ctx
->hdr
= genlmsg_put(dump_ctx
->skb
,
2278 dump_ctx
->info
->snd_portid
,
2279 dump_ctx
->info
->snd_seq
,
2280 &devlink_nl_family
, NLM_F_MULTI
,
2283 goto nla_put_failure
;
2285 devlink
= dump_ctx
->info
->user_ptr
[0];
2286 if (devlink_nl_put_handle(dump_ctx
->skb
, devlink
))
2287 goto nla_put_failure
;
2288 dump_ctx
->nest
= nla_nest_start_noflag(dump_ctx
->skb
,
2289 DEVLINK_ATTR_DPIPE_ENTRIES
);
2290 if (!dump_ctx
->nest
)
2291 goto nla_put_failure
;
2295 nlmsg_free(dump_ctx
->skb
);
2298 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare
);
2300 int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx
*dump_ctx
,
2301 struct devlink_dpipe_entry
*entry
)
2303 return devlink_dpipe_entry_put(dump_ctx
->skb
, entry
);
2305 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append
);
2307 int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx
*dump_ctx
)
2309 nla_nest_end(dump_ctx
->skb
, dump_ctx
->nest
);
2310 genlmsg_end(dump_ctx
->skb
, dump_ctx
->hdr
);
2313 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close
);
2315 void devlink_dpipe_entry_clear(struct devlink_dpipe_entry
*entry
)
2318 unsigned int value_count
, value_index
;
2319 struct devlink_dpipe_value
*value
;
2321 value
= entry
->action_values
;
2322 value_count
= entry
->action_values_count
;
2323 for (value_index
= 0; value_index
< value_count
; value_index
++) {
2324 kfree(value
[value_index
].value
);
2325 kfree(value
[value_index
].mask
);
2328 value
= entry
->match_values
;
2329 value_count
= entry
->match_values_count
;
2330 for (value_index
= 0; value_index
< value_count
; value_index
++) {
2331 kfree(value
[value_index
].value
);
2332 kfree(value
[value_index
].mask
);
2335 EXPORT_SYMBOL(devlink_dpipe_entry_clear
);
2337 static int devlink_dpipe_entries_fill(struct genl_info
*info
,
2338 enum devlink_command cmd
, int flags
,
2339 struct devlink_dpipe_table
*table
)
2341 struct devlink_dpipe_dump_ctx dump_ctx
;
2342 struct nlmsghdr
*nlh
;
2345 dump_ctx
.skb
= NULL
;
2347 dump_ctx
.info
= info
;
2349 err
= table
->table_ops
->entries_dump(table
->priv
,
2350 table
->counters_enabled
,
2356 nlh
= nlmsg_put(dump_ctx
.skb
, info
->snd_portid
, info
->snd_seq
,
2357 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
2359 err
= devlink_dpipe_send_and_alloc_skb(&dump_ctx
.skb
, info
);
2364 return genlmsg_reply(dump_ctx
.skb
, info
);
2367 static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff
*skb
,
2368 struct genl_info
*info
)
2370 struct devlink
*devlink
= info
->user_ptr
[0];
2371 struct devlink_dpipe_table
*table
;
2372 const char *table_name
;
2374 if (!info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
])
2377 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
2378 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
2379 table_name
, devlink
);
2383 if (!table
->table_ops
->entries_dump
)
2386 return devlink_dpipe_entries_fill(info
, DEVLINK_CMD_DPIPE_ENTRIES_GET
,
2390 static int devlink_dpipe_fields_put(struct sk_buff
*skb
,
2391 const struct devlink_dpipe_header
*header
)
2393 struct devlink_dpipe_field
*field
;
2394 struct nlattr
*field_attr
;
2397 for (i
= 0; i
< header
->fields_count
; i
++) {
2398 field
= &header
->fields
[i
];
2399 field_attr
= nla_nest_start_noflag(skb
,
2400 DEVLINK_ATTR_DPIPE_FIELD
);
2403 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_FIELD_NAME
, field
->name
) ||
2404 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_ID
, field
->id
) ||
2405 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH
, field
->bitwidth
) ||
2406 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE
, field
->mapping_type
))
2407 goto nla_put_failure
;
2408 nla_nest_end(skb
, field_attr
);
2413 nla_nest_cancel(skb
, field_attr
);
2417 static int devlink_dpipe_header_put(struct sk_buff
*skb
,
2418 struct devlink_dpipe_header
*header
)
2420 struct nlattr
*fields_attr
, *header_attr
;
2423 header_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_HEADER
);
2427 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_HEADER_NAME
, header
->name
) ||
2428 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_ID
, header
->id
) ||
2429 nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL
, header
->global
))
2430 goto nla_put_failure
;
2432 fields_attr
= nla_nest_start_noflag(skb
,
2433 DEVLINK_ATTR_DPIPE_HEADER_FIELDS
);
2435 goto nla_put_failure
;
2437 err
= devlink_dpipe_fields_put(skb
, header
);
2439 nla_nest_cancel(skb
, fields_attr
);
2440 goto nla_put_failure
;
2442 nla_nest_end(skb
, fields_attr
);
2443 nla_nest_end(skb
, header_attr
);
2448 nla_nest_cancel(skb
, header_attr
);
2452 static int devlink_dpipe_headers_fill(struct genl_info
*info
,
2453 enum devlink_command cmd
, int flags
,
2454 struct devlink_dpipe_headers
*
2457 struct devlink
*devlink
= info
->user_ptr
[0];
2458 struct nlattr
*headers_attr
;
2459 struct sk_buff
*skb
= NULL
;
2460 struct nlmsghdr
*nlh
;
2467 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2471 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2472 &devlink_nl_family
, NLM_F_MULTI
, cmd
);
2478 if (devlink_nl_put_handle(skb
, devlink
))
2479 goto nla_put_failure
;
2480 headers_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_HEADERS
);
2482 goto nla_put_failure
;
2485 for (; i
< dpipe_headers
->headers_count
; i
++) {
2486 err
= devlink_dpipe_header_put(skb
, dpipe_headers
->headers
[i
]);
2494 nla_nest_end(skb
, headers_attr
);
2495 genlmsg_end(skb
, hdr
);
2496 if (i
!= dpipe_headers
->headers_count
)
2500 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2501 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
2503 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2508 return genlmsg_reply(skb
, info
);
2517 static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff
*skb
,
2518 struct genl_info
*info
)
2520 struct devlink
*devlink
= info
->user_ptr
[0];
2522 if (!devlink
->dpipe_headers
)
2524 return devlink_dpipe_headers_fill(info
, DEVLINK_CMD_DPIPE_HEADERS_GET
,
2525 0, devlink
->dpipe_headers
);
2528 static int devlink_dpipe_table_counters_set(struct devlink
*devlink
,
2529 const char *table_name
,
2532 struct devlink_dpipe_table
*table
;
2534 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
2535 table_name
, devlink
);
2539 if (table
->counter_control_extern
)
2542 if (!(table
->counters_enabled
^ enable
))
2545 table
->counters_enabled
= enable
;
2546 if (table
->table_ops
->counters_set_update
)
2547 table
->table_ops
->counters_set_update(table
->priv
, enable
);
2551 static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff
*skb
,
2552 struct genl_info
*info
)
2554 struct devlink
*devlink
= info
->user_ptr
[0];
2555 const char *table_name
;
2556 bool counters_enable
;
2558 if (!info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
] ||
2559 !info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
])
2562 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
2563 counters_enable
= !!nla_get_u8(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
]);
2565 return devlink_dpipe_table_counters_set(devlink
, table_name
,
2569 static struct devlink_resource
*
2570 devlink_resource_find(struct devlink
*devlink
,
2571 struct devlink_resource
*resource
, u64 resource_id
)
2573 struct list_head
*resource_list
;
2576 resource_list
= &resource
->resource_list
;
2578 resource_list
= &devlink
->resource_list
;
2580 list_for_each_entry(resource
, resource_list
, list
) {
2581 struct devlink_resource
*child_resource
;
2583 if (resource
->id
== resource_id
)
2586 child_resource
= devlink_resource_find(devlink
, resource
,
2589 return child_resource
;
2595 devlink_resource_validate_children(struct devlink_resource
*resource
)
2597 struct devlink_resource
*child_resource
;
2598 bool size_valid
= true;
2601 if (list_empty(&resource
->resource_list
))
2604 list_for_each_entry(child_resource
, &resource
->resource_list
, list
)
2605 parts_size
+= child_resource
->size_new
;
2607 if (parts_size
> resource
->size_new
)
2610 resource
->size_valid
= size_valid
;
2614 devlink_resource_validate_size(struct devlink_resource
*resource
, u64 size
,
2615 struct netlink_ext_ack
*extack
)
2620 if (size
> resource
->size_params
.size_max
) {
2621 NL_SET_ERR_MSG_MOD(extack
, "Size larger than maximum");
2625 if (size
< resource
->size_params
.size_min
) {
2626 NL_SET_ERR_MSG_MOD(extack
, "Size smaller than minimum");
2630 div64_u64_rem(size
, resource
->size_params
.size_granularity
, &reminder
);
2632 NL_SET_ERR_MSG_MOD(extack
, "Wrong granularity");
2639 static int devlink_nl_cmd_resource_set(struct sk_buff
*skb
,
2640 struct genl_info
*info
)
2642 struct devlink
*devlink
= info
->user_ptr
[0];
2643 struct devlink_resource
*resource
;
2648 if (!info
->attrs
[DEVLINK_ATTR_RESOURCE_ID
] ||
2649 !info
->attrs
[DEVLINK_ATTR_RESOURCE_SIZE
])
2651 resource_id
= nla_get_u64(info
->attrs
[DEVLINK_ATTR_RESOURCE_ID
]);
2653 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
2657 size
= nla_get_u64(info
->attrs
[DEVLINK_ATTR_RESOURCE_SIZE
]);
2658 err
= devlink_resource_validate_size(resource
, size
, info
->extack
);
2662 resource
->size_new
= size
;
2663 devlink_resource_validate_children(resource
);
2664 if (resource
->parent
)
2665 devlink_resource_validate_children(resource
->parent
);
2670 devlink_resource_size_params_put(struct devlink_resource
*resource
,
2671 struct sk_buff
*skb
)
2673 struct devlink_resource_size_params
*size_params
;
2675 size_params
= &resource
->size_params
;
2676 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_GRAN
,
2677 size_params
->size_granularity
, DEVLINK_ATTR_PAD
) ||
2678 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_MAX
,
2679 size_params
->size_max
, DEVLINK_ATTR_PAD
) ||
2680 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_MIN
,
2681 size_params
->size_min
, DEVLINK_ATTR_PAD
) ||
2682 nla_put_u8(skb
, DEVLINK_ATTR_RESOURCE_UNIT
, size_params
->unit
))
2687 static int devlink_resource_occ_put(struct devlink_resource
*resource
,
2688 struct sk_buff
*skb
)
2690 if (!resource
->occ_get
)
2692 return nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_OCC
,
2693 resource
->occ_get(resource
->occ_get_priv
),
2697 static int devlink_resource_put(struct devlink
*devlink
, struct sk_buff
*skb
,
2698 struct devlink_resource
*resource
)
2700 struct devlink_resource
*child_resource
;
2701 struct nlattr
*child_resource_attr
;
2702 struct nlattr
*resource_attr
;
2704 resource_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_RESOURCE
);
2708 if (nla_put_string(skb
, DEVLINK_ATTR_RESOURCE_NAME
, resource
->name
) ||
2709 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE
, resource
->size
,
2710 DEVLINK_ATTR_PAD
) ||
2711 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_ID
, resource
->id
,
2713 goto nla_put_failure
;
2714 if (resource
->size
!= resource
->size_new
)
2715 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_NEW
,
2716 resource
->size_new
, DEVLINK_ATTR_PAD
);
2717 if (devlink_resource_occ_put(resource
, skb
))
2718 goto nla_put_failure
;
2719 if (devlink_resource_size_params_put(resource
, skb
))
2720 goto nla_put_failure
;
2721 if (list_empty(&resource
->resource_list
))
2724 if (nla_put_u8(skb
, DEVLINK_ATTR_RESOURCE_SIZE_VALID
,
2725 resource
->size_valid
))
2726 goto nla_put_failure
;
2728 child_resource_attr
= nla_nest_start_noflag(skb
,
2729 DEVLINK_ATTR_RESOURCE_LIST
);
2730 if (!child_resource_attr
)
2731 goto nla_put_failure
;
2733 list_for_each_entry(child_resource
, &resource
->resource_list
, list
) {
2734 if (devlink_resource_put(devlink
, skb
, child_resource
))
2735 goto resource_put_failure
;
2738 nla_nest_end(skb
, child_resource_attr
);
2740 nla_nest_end(skb
, resource_attr
);
2743 resource_put_failure
:
2744 nla_nest_cancel(skb
, child_resource_attr
);
2746 nla_nest_cancel(skb
, resource_attr
);
2750 static int devlink_resource_fill(struct genl_info
*info
,
2751 enum devlink_command cmd
, int flags
)
2753 struct devlink
*devlink
= info
->user_ptr
[0];
2754 struct devlink_resource
*resource
;
2755 struct nlattr
*resources_attr
;
2756 struct sk_buff
*skb
= NULL
;
2757 struct nlmsghdr
*nlh
;
2763 resource
= list_first_entry(&devlink
->resource_list
,
2764 struct devlink_resource
, list
);
2766 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2770 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2771 &devlink_nl_family
, NLM_F_MULTI
, cmd
);
2777 if (devlink_nl_put_handle(skb
, devlink
))
2778 goto nla_put_failure
;
2780 resources_attr
= nla_nest_start_noflag(skb
,
2781 DEVLINK_ATTR_RESOURCE_LIST
);
2782 if (!resources_attr
)
2783 goto nla_put_failure
;
2787 list_for_each_entry_from(resource
, &devlink
->resource_list
, list
) {
2788 err
= devlink_resource_put(devlink
, skb
, resource
);
2791 goto err_resource_put
;
2797 nla_nest_end(skb
, resources_attr
);
2798 genlmsg_end(skb
, hdr
);
2802 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2803 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
2805 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2810 return genlmsg_reply(skb
, info
);
2819 static int devlink_nl_cmd_resource_dump(struct sk_buff
*skb
,
2820 struct genl_info
*info
)
2822 struct devlink
*devlink
= info
->user_ptr
[0];
2824 if (list_empty(&devlink
->resource_list
))
2827 return devlink_resource_fill(info
, DEVLINK_CMD_RESOURCE_DUMP
, 0);
2831 devlink_resources_validate(struct devlink
*devlink
,
2832 struct devlink_resource
*resource
,
2833 struct genl_info
*info
)
2835 struct list_head
*resource_list
;
2839 resource_list
= &resource
->resource_list
;
2841 resource_list
= &devlink
->resource_list
;
2843 list_for_each_entry(resource
, resource_list
, list
) {
2844 if (!resource
->size_valid
)
2846 err
= devlink_resources_validate(devlink
, resource
, info
);
2853 static struct net
*devlink_netns_get(struct sk_buff
*skb
,
2854 struct genl_info
*info
)
2856 struct nlattr
*netns_pid_attr
= info
->attrs
[DEVLINK_ATTR_NETNS_PID
];
2857 struct nlattr
*netns_fd_attr
= info
->attrs
[DEVLINK_ATTR_NETNS_FD
];
2858 struct nlattr
*netns_id_attr
= info
->attrs
[DEVLINK_ATTR_NETNS_ID
];
2861 if (!!netns_pid_attr
+ !!netns_fd_attr
+ !!netns_id_attr
> 1) {
2862 NL_SET_ERR_MSG_MOD(info
->extack
, "multiple netns identifying attributes specified");
2863 return ERR_PTR(-EINVAL
);
2866 if (netns_pid_attr
) {
2867 net
= get_net_ns_by_pid(nla_get_u32(netns_pid_attr
));
2868 } else if (netns_fd_attr
) {
2869 net
= get_net_ns_by_fd(nla_get_u32(netns_fd_attr
));
2870 } else if (netns_id_attr
) {
2871 net
= get_net_ns_by_id(sock_net(skb
->sk
),
2872 nla_get_u32(netns_id_attr
));
2874 net
= ERR_PTR(-EINVAL
);
2877 net
= ERR_PTR(-EINVAL
);
2880 NL_SET_ERR_MSG_MOD(info
->extack
, "Unknown network namespace");
2881 return ERR_PTR(-EINVAL
);
2883 if (!netlink_ns_capable(skb
, net
->user_ns
, CAP_NET_ADMIN
)) {
2885 return ERR_PTR(-EPERM
);
2890 static void devlink_param_notify(struct devlink
*devlink
,
2891 unsigned int port_index
,
2892 struct devlink_param_item
*param_item
,
2893 enum devlink_command cmd
);
2895 static void devlink_reload_netns_change(struct devlink
*devlink
,
2896 struct net
*dest_net
)
2898 struct devlink_param_item
*param_item
;
2900 /* Userspace needs to be notified about devlink objects
2901 * removed from original and entering new network namespace.
2902 * The rest of the devlink objects are re-created during
2903 * reload process so the notifications are generated separatelly.
2906 list_for_each_entry(param_item
, &devlink
->param_list
, list
)
2907 devlink_param_notify(devlink
, 0, param_item
,
2908 DEVLINK_CMD_PARAM_DEL
);
2909 devlink_notify(devlink
, DEVLINK_CMD_DEL
);
2911 __devlink_net_set(devlink
, dest_net
);
2913 devlink_notify(devlink
, DEVLINK_CMD_NEW
);
2914 list_for_each_entry(param_item
, &devlink
->param_list
, list
)
2915 devlink_param_notify(devlink
, 0, param_item
,
2916 DEVLINK_CMD_PARAM_NEW
);
2919 static bool devlink_reload_supported(struct devlink
*devlink
)
2921 return devlink
->ops
->reload_down
&& devlink
->ops
->reload_up
;
2924 static void devlink_reload_failed_set(struct devlink
*devlink
,
2927 if (devlink
->reload_failed
== reload_failed
)
2929 devlink
->reload_failed
= reload_failed
;
2930 devlink_notify(devlink
, DEVLINK_CMD_NEW
);
2933 bool devlink_is_reload_failed(const struct devlink
*devlink
)
2935 return devlink
->reload_failed
;
2937 EXPORT_SYMBOL_GPL(devlink_is_reload_failed
);
2939 static int devlink_reload(struct devlink
*devlink
, struct net
*dest_net
,
2940 struct netlink_ext_ack
*extack
)
2944 if (!devlink
->reload_enabled
)
2947 err
= devlink
->ops
->reload_down(devlink
, !!dest_net
, extack
);
2951 if (dest_net
&& !net_eq(dest_net
, devlink_net(devlink
)))
2952 devlink_reload_netns_change(devlink
, dest_net
);
2954 err
= devlink
->ops
->reload_up(devlink
, extack
);
2955 devlink_reload_failed_set(devlink
, !!err
);
2959 static int devlink_nl_cmd_reload(struct sk_buff
*skb
, struct genl_info
*info
)
2961 struct devlink
*devlink
= info
->user_ptr
[0];
2962 struct net
*dest_net
= NULL
;
2965 if (!devlink_reload_supported(devlink
) || !devlink
->reload_enabled
)
2968 err
= devlink_resources_validate(devlink
, NULL
, info
);
2970 NL_SET_ERR_MSG_MOD(info
->extack
, "resources size validation failed");
2974 if (info
->attrs
[DEVLINK_ATTR_NETNS_PID
] ||
2975 info
->attrs
[DEVLINK_ATTR_NETNS_FD
] ||
2976 info
->attrs
[DEVLINK_ATTR_NETNS_ID
]) {
2977 dest_net
= devlink_netns_get(skb
, info
);
2978 if (IS_ERR(dest_net
))
2979 return PTR_ERR(dest_net
);
2982 err
= devlink_reload(devlink
, dest_net
, info
->extack
);
2990 static int devlink_nl_flash_update_fill(struct sk_buff
*msg
,
2991 struct devlink
*devlink
,
2992 enum devlink_command cmd
,
2993 const char *status_msg
,
2994 const char *component
,
2995 unsigned long done
, unsigned long total
)
2999 hdr
= genlmsg_put(msg
, 0, 0, &devlink_nl_family
, 0, cmd
);
3003 if (devlink_nl_put_handle(msg
, devlink
))
3004 goto nla_put_failure
;
3006 if (cmd
!= DEVLINK_CMD_FLASH_UPDATE_STATUS
)
3010 nla_put_string(msg
, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG
,
3012 goto nla_put_failure
;
3014 nla_put_string(msg
, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT
,
3016 goto nla_put_failure
;
3017 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE
,
3018 done
, DEVLINK_ATTR_PAD
))
3019 goto nla_put_failure
;
3020 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL
,
3021 total
, DEVLINK_ATTR_PAD
))
3022 goto nla_put_failure
;
3025 genlmsg_end(msg
, hdr
);
3029 genlmsg_cancel(msg
, hdr
);
3033 static void __devlink_flash_update_notify(struct devlink
*devlink
,
3034 enum devlink_command cmd
,
3035 const char *status_msg
,
3036 const char *component
,
3038 unsigned long total
)
3040 struct sk_buff
*msg
;
3043 WARN_ON(cmd
!= DEVLINK_CMD_FLASH_UPDATE
&&
3044 cmd
!= DEVLINK_CMD_FLASH_UPDATE_END
&&
3045 cmd
!= DEVLINK_CMD_FLASH_UPDATE_STATUS
);
3047 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
3051 err
= devlink_nl_flash_update_fill(msg
, devlink
, cmd
, status_msg
,
3052 component
, done
, total
);
3056 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
3057 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
3064 void devlink_flash_update_begin_notify(struct devlink
*devlink
)
3066 __devlink_flash_update_notify(devlink
,
3067 DEVLINK_CMD_FLASH_UPDATE
,
3070 EXPORT_SYMBOL_GPL(devlink_flash_update_begin_notify
);
3072 void devlink_flash_update_end_notify(struct devlink
*devlink
)
3074 __devlink_flash_update_notify(devlink
,
3075 DEVLINK_CMD_FLASH_UPDATE_END
,
3078 EXPORT_SYMBOL_GPL(devlink_flash_update_end_notify
);
3080 void devlink_flash_update_status_notify(struct devlink
*devlink
,
3081 const char *status_msg
,
3082 const char *component
,
3084 unsigned long total
)
3086 __devlink_flash_update_notify(devlink
,
3087 DEVLINK_CMD_FLASH_UPDATE_STATUS
,
3088 status_msg
, component
, done
, total
);
3090 EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify
);
3092 static int devlink_nl_cmd_flash_update(struct sk_buff
*skb
,
3093 struct genl_info
*info
)
3095 struct devlink
*devlink
= info
->user_ptr
[0];
3096 const char *file_name
, *component
;
3097 struct nlattr
*nla_component
;
3099 if (!devlink
->ops
->flash_update
)
3102 if (!info
->attrs
[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME
])
3104 file_name
= nla_data(info
->attrs
[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME
]);
3106 nla_component
= info
->attrs
[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT
];
3107 component
= nla_component
? nla_data(nla_component
) : NULL
;
3109 return devlink
->ops
->flash_update(devlink
, file_name
, component
,
3113 static const struct devlink_param devlink_param_generic
[] = {
3115 .id
= DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET
,
3116 .name
= DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME
,
3117 .type
= DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE
,
3120 .id
= DEVLINK_PARAM_GENERIC_ID_MAX_MACS
,
3121 .name
= DEVLINK_PARAM_GENERIC_MAX_MACS_NAME
,
3122 .type
= DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE
,
3125 .id
= DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV
,
3126 .name
= DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME
,
3127 .type
= DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE
,
3130 .id
= DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT
,
3131 .name
= DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME
,
3132 .type
= DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE
,
3135 .id
= DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI
,
3136 .name
= DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME
,
3137 .type
= DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE
,
3140 .id
= DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX
,
3141 .name
= DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME
,
3142 .type
= DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE
,
3145 .id
= DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN
,
3146 .name
= DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME
,
3147 .type
= DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE
,
3150 .id
= DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY
,
3151 .name
= DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME
,
3152 .type
= DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE
,
3155 .id
= DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE
,
3156 .name
= DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME
,
3157 .type
= DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE
,
3160 .id
= DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE
,
3161 .name
= DEVLINK_PARAM_GENERIC_ENABLE_ROCE_NAME
,
3162 .type
= DEVLINK_PARAM_GENERIC_ENABLE_ROCE_TYPE
,
3166 static int devlink_param_generic_verify(const struct devlink_param
*param
)
3168 /* verify it match generic parameter by id and name */
3169 if (param
->id
> DEVLINK_PARAM_GENERIC_ID_MAX
)
3171 if (strcmp(param
->name
, devlink_param_generic
[param
->id
].name
))
3174 WARN_ON(param
->type
!= devlink_param_generic
[param
->id
].type
);
3179 static int devlink_param_driver_verify(const struct devlink_param
*param
)
3183 if (param
->id
<= DEVLINK_PARAM_GENERIC_ID_MAX
)
3185 /* verify no such name in generic params */
3186 for (i
= 0; i
<= DEVLINK_PARAM_GENERIC_ID_MAX
; i
++)
3187 if (!strcmp(param
->name
, devlink_param_generic
[i
].name
))
3193 static struct devlink_param_item
*
3194 devlink_param_find_by_name(struct list_head
*param_list
,
3195 const char *param_name
)
3197 struct devlink_param_item
*param_item
;
3199 list_for_each_entry(param_item
, param_list
, list
)
3200 if (!strcmp(param_item
->param
->name
, param_name
))
3205 static struct devlink_param_item
*
3206 devlink_param_find_by_id(struct list_head
*param_list
, u32 param_id
)
3208 struct devlink_param_item
*param_item
;
3210 list_for_each_entry(param_item
, param_list
, list
)
3211 if (param_item
->param
->id
== param_id
)
3217 devlink_param_cmode_is_supported(const struct devlink_param
*param
,
3218 enum devlink_param_cmode cmode
)
3220 return test_bit(cmode
, ¶m
->supported_cmodes
);
3223 static int devlink_param_get(struct devlink
*devlink
,
3224 const struct devlink_param
*param
,
3225 struct devlink_param_gset_ctx
*ctx
)
3229 return param
->get(devlink
, param
->id
, ctx
);
3232 static int devlink_param_set(struct devlink
*devlink
,
3233 const struct devlink_param
*param
,
3234 struct devlink_param_gset_ctx
*ctx
)
3238 return param
->set(devlink
, param
->id
, ctx
);
3242 devlink_param_type_to_nla_type(enum devlink_param_type param_type
)
3244 switch (param_type
) {
3245 case DEVLINK_PARAM_TYPE_U8
:
3247 case DEVLINK_PARAM_TYPE_U16
:
3249 case DEVLINK_PARAM_TYPE_U32
:
3251 case DEVLINK_PARAM_TYPE_STRING
:
3253 case DEVLINK_PARAM_TYPE_BOOL
:
3261 devlink_nl_param_value_fill_one(struct sk_buff
*msg
,
3262 enum devlink_param_type type
,
3263 enum devlink_param_cmode cmode
,
3264 union devlink_param_value val
)
3266 struct nlattr
*param_value_attr
;
3268 param_value_attr
= nla_nest_start_noflag(msg
,
3269 DEVLINK_ATTR_PARAM_VALUE
);
3270 if (!param_value_attr
)
3271 goto nla_put_failure
;
3273 if (nla_put_u8(msg
, DEVLINK_ATTR_PARAM_VALUE_CMODE
, cmode
))
3274 goto value_nest_cancel
;
3277 case DEVLINK_PARAM_TYPE_U8
:
3278 if (nla_put_u8(msg
, DEVLINK_ATTR_PARAM_VALUE_DATA
, val
.vu8
))
3279 goto value_nest_cancel
;
3281 case DEVLINK_PARAM_TYPE_U16
:
3282 if (nla_put_u16(msg
, DEVLINK_ATTR_PARAM_VALUE_DATA
, val
.vu16
))
3283 goto value_nest_cancel
;
3285 case DEVLINK_PARAM_TYPE_U32
:
3286 if (nla_put_u32(msg
, DEVLINK_ATTR_PARAM_VALUE_DATA
, val
.vu32
))
3287 goto value_nest_cancel
;
3289 case DEVLINK_PARAM_TYPE_STRING
:
3290 if (nla_put_string(msg
, DEVLINK_ATTR_PARAM_VALUE_DATA
,
3292 goto value_nest_cancel
;
3294 case DEVLINK_PARAM_TYPE_BOOL
:
3296 nla_put_flag(msg
, DEVLINK_ATTR_PARAM_VALUE_DATA
))
3297 goto value_nest_cancel
;
3301 nla_nest_end(msg
, param_value_attr
);
3305 nla_nest_cancel(msg
, param_value_attr
);
3310 static int devlink_nl_param_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
3311 unsigned int port_index
,
3312 struct devlink_param_item
*param_item
,
3313 enum devlink_command cmd
,
3314 u32 portid
, u32 seq
, int flags
)
3316 union devlink_param_value param_value
[DEVLINK_PARAM_CMODE_MAX
+ 1];
3317 bool param_value_set
[DEVLINK_PARAM_CMODE_MAX
+ 1] = {};
3318 const struct devlink_param
*param
= param_item
->param
;
3319 struct devlink_param_gset_ctx ctx
;
3320 struct nlattr
*param_values_list
;
3321 struct nlattr
*param_attr
;
3327 /* Get value from driver part to driverinit configuration mode */
3328 for (i
= 0; i
<= DEVLINK_PARAM_CMODE_MAX
; i
++) {
3329 if (!devlink_param_cmode_is_supported(param
, i
))
3331 if (i
== DEVLINK_PARAM_CMODE_DRIVERINIT
) {
3332 if (!param_item
->driverinit_value_valid
)
3334 param_value
[i
] = param_item
->driverinit_value
;
3336 if (!param_item
->published
)
3339 err
= devlink_param_get(devlink
, param
, &ctx
);
3342 param_value
[i
] = ctx
.val
;
3344 param_value_set
[i
] = true;
3347 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
3351 if (devlink_nl_put_handle(msg
, devlink
))
3352 goto genlmsg_cancel
;
3354 if (cmd
== DEVLINK_CMD_PORT_PARAM_GET
||
3355 cmd
== DEVLINK_CMD_PORT_PARAM_NEW
||
3356 cmd
== DEVLINK_CMD_PORT_PARAM_DEL
)
3357 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, port_index
))
3358 goto genlmsg_cancel
;
3360 param_attr
= nla_nest_start_noflag(msg
, DEVLINK_ATTR_PARAM
);
3362 goto genlmsg_cancel
;
3363 if (nla_put_string(msg
, DEVLINK_ATTR_PARAM_NAME
, param
->name
))
3364 goto param_nest_cancel
;
3365 if (param
->generic
&& nla_put_flag(msg
, DEVLINK_ATTR_PARAM_GENERIC
))
3366 goto param_nest_cancel
;
3368 nla_type
= devlink_param_type_to_nla_type(param
->type
);
3370 goto param_nest_cancel
;
3371 if (nla_put_u8(msg
, DEVLINK_ATTR_PARAM_TYPE
, nla_type
))
3372 goto param_nest_cancel
;
3374 param_values_list
= nla_nest_start_noflag(msg
,
3375 DEVLINK_ATTR_PARAM_VALUES_LIST
);
3376 if (!param_values_list
)
3377 goto param_nest_cancel
;
3379 for (i
= 0; i
<= DEVLINK_PARAM_CMODE_MAX
; i
++) {
3380 if (!param_value_set
[i
])
3382 err
= devlink_nl_param_value_fill_one(msg
, param
->type
,
3385 goto values_list_nest_cancel
;
3388 nla_nest_end(msg
, param_values_list
);
3389 nla_nest_end(msg
, param_attr
);
3390 genlmsg_end(msg
, hdr
);
3393 values_list_nest_cancel
:
3394 nla_nest_end(msg
, param_values_list
);
3396 nla_nest_cancel(msg
, param_attr
);
3398 genlmsg_cancel(msg
, hdr
);
3402 static void devlink_param_notify(struct devlink
*devlink
,
3403 unsigned int port_index
,
3404 struct devlink_param_item
*param_item
,
3405 enum devlink_command cmd
)
3407 struct sk_buff
*msg
;
3410 WARN_ON(cmd
!= DEVLINK_CMD_PARAM_NEW
&& cmd
!= DEVLINK_CMD_PARAM_DEL
&&
3411 cmd
!= DEVLINK_CMD_PORT_PARAM_NEW
&&
3412 cmd
!= DEVLINK_CMD_PORT_PARAM_DEL
);
3414 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
3417 err
= devlink_nl_param_fill(msg
, devlink
, port_index
, param_item
, cmd
,
3424 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
3425 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
3428 static int devlink_nl_cmd_param_get_dumpit(struct sk_buff
*msg
,
3429 struct netlink_callback
*cb
)
3431 struct devlink_param_item
*param_item
;
3432 struct devlink
*devlink
;
3433 int start
= cb
->args
[0];
3437 mutex_lock(&devlink_mutex
);
3438 list_for_each_entry(devlink
, &devlink_list
, list
) {
3439 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
3441 mutex_lock(&devlink
->lock
);
3442 list_for_each_entry(param_item
, &devlink
->param_list
, list
) {
3447 err
= devlink_nl_param_fill(msg
, devlink
, 0, param_item
,
3448 DEVLINK_CMD_PARAM_GET
,
3449 NETLINK_CB(cb
->skb
).portid
,
3452 if (err
&& err
!= -EOPNOTSUPP
) {
3453 mutex_unlock(&devlink
->lock
);
3458 mutex_unlock(&devlink
->lock
);
3461 mutex_unlock(&devlink_mutex
);
3463 if (err
!= -EMSGSIZE
)
3471 devlink_param_type_get_from_info(struct genl_info
*info
,
3472 enum devlink_param_type
*param_type
)
3474 if (!info
->attrs
[DEVLINK_ATTR_PARAM_TYPE
])
3477 switch (nla_get_u8(info
->attrs
[DEVLINK_ATTR_PARAM_TYPE
])) {
3479 *param_type
= DEVLINK_PARAM_TYPE_U8
;
3482 *param_type
= DEVLINK_PARAM_TYPE_U16
;
3485 *param_type
= DEVLINK_PARAM_TYPE_U32
;
3488 *param_type
= DEVLINK_PARAM_TYPE_STRING
;
3491 *param_type
= DEVLINK_PARAM_TYPE_BOOL
;
3501 devlink_param_value_get_from_info(const struct devlink_param
*param
,
3502 struct genl_info
*info
,
3503 union devlink_param_value
*value
)
3505 struct nlattr
*param_data
;
3508 param_data
= info
->attrs
[DEVLINK_ATTR_PARAM_VALUE_DATA
];
3510 if (param
->type
!= DEVLINK_PARAM_TYPE_BOOL
&& !param_data
)
3513 switch (param
->type
) {
3514 case DEVLINK_PARAM_TYPE_U8
:
3515 if (nla_len(param_data
) != sizeof(u8
))
3517 value
->vu8
= nla_get_u8(param_data
);
3519 case DEVLINK_PARAM_TYPE_U16
:
3520 if (nla_len(param_data
) != sizeof(u16
))
3522 value
->vu16
= nla_get_u16(param_data
);
3524 case DEVLINK_PARAM_TYPE_U32
:
3525 if (nla_len(param_data
) != sizeof(u32
))
3527 value
->vu32
= nla_get_u32(param_data
);
3529 case DEVLINK_PARAM_TYPE_STRING
:
3530 len
= strnlen(nla_data(param_data
), nla_len(param_data
));
3531 if (len
== nla_len(param_data
) ||
3532 len
>= __DEVLINK_PARAM_MAX_STRING_VALUE
)
3534 strcpy(value
->vstr
, nla_data(param_data
));
3536 case DEVLINK_PARAM_TYPE_BOOL
:
3537 if (param_data
&& nla_len(param_data
))
3539 value
->vbool
= nla_get_flag(param_data
);
3545 static struct devlink_param_item
*
3546 devlink_param_get_from_info(struct list_head
*param_list
,
3547 struct genl_info
*info
)
3551 if (!info
->attrs
[DEVLINK_ATTR_PARAM_NAME
])
3554 param_name
= nla_data(info
->attrs
[DEVLINK_ATTR_PARAM_NAME
]);
3555 return devlink_param_find_by_name(param_list
, param_name
);
3558 static int devlink_nl_cmd_param_get_doit(struct sk_buff
*skb
,
3559 struct genl_info
*info
)
3561 struct devlink
*devlink
= info
->user_ptr
[0];
3562 struct devlink_param_item
*param_item
;
3563 struct sk_buff
*msg
;
3566 param_item
= devlink_param_get_from_info(&devlink
->param_list
, info
);
3570 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
3574 err
= devlink_nl_param_fill(msg
, devlink
, 0, param_item
,
3575 DEVLINK_CMD_PARAM_GET
,
3576 info
->snd_portid
, info
->snd_seq
, 0);
3582 return genlmsg_reply(msg
, info
);
3585 static int __devlink_nl_cmd_param_set_doit(struct devlink
*devlink
,
3586 unsigned int port_index
,
3587 struct list_head
*param_list
,
3588 struct genl_info
*info
,
3589 enum devlink_command cmd
)
3591 enum devlink_param_type param_type
;
3592 struct devlink_param_gset_ctx ctx
;
3593 enum devlink_param_cmode cmode
;
3594 struct devlink_param_item
*param_item
;
3595 const struct devlink_param
*param
;
3596 union devlink_param_value value
;
3599 param_item
= devlink_param_get_from_info(param_list
, info
);
3602 param
= param_item
->param
;
3603 err
= devlink_param_type_get_from_info(info
, ¶m_type
);
3606 if (param_type
!= param
->type
)
3608 err
= devlink_param_value_get_from_info(param
, info
, &value
);
3611 if (param
->validate
) {
3612 err
= param
->validate(devlink
, param
->id
, value
, info
->extack
);
3617 if (!info
->attrs
[DEVLINK_ATTR_PARAM_VALUE_CMODE
])
3619 cmode
= nla_get_u8(info
->attrs
[DEVLINK_ATTR_PARAM_VALUE_CMODE
]);
3620 if (!devlink_param_cmode_is_supported(param
, cmode
))
3623 if (cmode
== DEVLINK_PARAM_CMODE_DRIVERINIT
) {
3624 if (param
->type
== DEVLINK_PARAM_TYPE_STRING
)
3625 strcpy(param_item
->driverinit_value
.vstr
, value
.vstr
);
3627 param_item
->driverinit_value
= value
;
3628 param_item
->driverinit_value_valid
= true;
3634 err
= devlink_param_set(devlink
, param
, &ctx
);
3639 devlink_param_notify(devlink
, port_index
, param_item
, cmd
);
3643 static int devlink_nl_cmd_param_set_doit(struct sk_buff
*skb
,
3644 struct genl_info
*info
)
3646 struct devlink
*devlink
= info
->user_ptr
[0];
3648 return __devlink_nl_cmd_param_set_doit(devlink
, 0, &devlink
->param_list
,
3649 info
, DEVLINK_CMD_PARAM_NEW
);
3652 static int devlink_param_register_one(struct devlink
*devlink
,
3653 unsigned int port_index
,
3654 struct list_head
*param_list
,
3655 const struct devlink_param
*param
,
3656 enum devlink_command cmd
)
3658 struct devlink_param_item
*param_item
;
3660 if (devlink_param_find_by_name(param_list
, param
->name
))
3663 if (param
->supported_cmodes
== BIT(DEVLINK_PARAM_CMODE_DRIVERINIT
))
3664 WARN_ON(param
->get
|| param
->set
);
3666 WARN_ON(!param
->get
|| !param
->set
);
3668 param_item
= kzalloc(sizeof(*param_item
), GFP_KERNEL
);
3671 param_item
->param
= param
;
3673 list_add_tail(¶m_item
->list
, param_list
);
3674 devlink_param_notify(devlink
, port_index
, param_item
, cmd
);
3678 static void devlink_param_unregister_one(struct devlink
*devlink
,
3679 unsigned int port_index
,
3680 struct list_head
*param_list
,
3681 const struct devlink_param
*param
,
3682 enum devlink_command cmd
)
3684 struct devlink_param_item
*param_item
;
3686 param_item
= devlink_param_find_by_name(param_list
, param
->name
);
3687 WARN_ON(!param_item
);
3688 devlink_param_notify(devlink
, port_index
, param_item
, cmd
);
3689 list_del(¶m_item
->list
);
3693 static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff
*msg
,
3694 struct netlink_callback
*cb
)
3696 struct devlink_param_item
*param_item
;
3697 struct devlink_port
*devlink_port
;
3698 struct devlink
*devlink
;
3699 int start
= cb
->args
[0];
3703 mutex_lock(&devlink_mutex
);
3704 list_for_each_entry(devlink
, &devlink_list
, list
) {
3705 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
3707 mutex_lock(&devlink
->lock
);
3708 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
3709 list_for_each_entry(param_item
,
3710 &devlink_port
->param_list
, list
) {
3715 err
= devlink_nl_param_fill(msg
,
3716 devlink_port
->devlink
,
3717 devlink_port
->index
, param_item
,
3718 DEVLINK_CMD_PORT_PARAM_GET
,
3719 NETLINK_CB(cb
->skb
).portid
,
3722 if (err
&& err
!= -EOPNOTSUPP
) {
3723 mutex_unlock(&devlink
->lock
);
3729 mutex_unlock(&devlink
->lock
);
3732 mutex_unlock(&devlink_mutex
);
3734 if (err
!= -EMSGSIZE
)
3741 static int devlink_nl_cmd_port_param_get_doit(struct sk_buff
*skb
,
3742 struct genl_info
*info
)
3744 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
3745 struct devlink_param_item
*param_item
;
3746 struct sk_buff
*msg
;
3749 param_item
= devlink_param_get_from_info(&devlink_port
->param_list
,
3754 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
3758 err
= devlink_nl_param_fill(msg
, devlink_port
->devlink
,
3759 devlink_port
->index
, param_item
,
3760 DEVLINK_CMD_PORT_PARAM_GET
,
3761 info
->snd_portid
, info
->snd_seq
, 0);
3767 return genlmsg_reply(msg
, info
);
3770 static int devlink_nl_cmd_port_param_set_doit(struct sk_buff
*skb
,
3771 struct genl_info
*info
)
3773 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
3775 return __devlink_nl_cmd_param_set_doit(devlink_port
->devlink
,
3776 devlink_port
->index
,
3777 &devlink_port
->param_list
, info
,
3778 DEVLINK_CMD_PORT_PARAM_NEW
);
3781 static int devlink_nl_region_snapshot_id_put(struct sk_buff
*msg
,
3782 struct devlink
*devlink
,
3783 struct devlink_snapshot
*snapshot
)
3785 struct nlattr
*snap_attr
;
3788 snap_attr
= nla_nest_start_noflag(msg
, DEVLINK_ATTR_REGION_SNAPSHOT
);
3792 err
= nla_put_u32(msg
, DEVLINK_ATTR_REGION_SNAPSHOT_ID
, snapshot
->id
);
3794 goto nla_put_failure
;
3796 nla_nest_end(msg
, snap_attr
);
3800 nla_nest_cancel(msg
, snap_attr
);
3804 static int devlink_nl_region_snapshots_id_put(struct sk_buff
*msg
,
3805 struct devlink
*devlink
,
3806 struct devlink_region
*region
)
3808 struct devlink_snapshot
*snapshot
;
3809 struct nlattr
*snapshots_attr
;
3812 snapshots_attr
= nla_nest_start_noflag(msg
,
3813 DEVLINK_ATTR_REGION_SNAPSHOTS
);
3814 if (!snapshots_attr
)
3817 list_for_each_entry(snapshot
, ®ion
->snapshot_list
, list
) {
3818 err
= devlink_nl_region_snapshot_id_put(msg
, devlink
, snapshot
);
3820 goto nla_put_failure
;
3823 nla_nest_end(msg
, snapshots_attr
);
3827 nla_nest_cancel(msg
, snapshots_attr
);
3831 static int devlink_nl_region_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
3832 enum devlink_command cmd
, u32 portid
,
3834 struct devlink_region
*region
)
3839 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
3843 err
= devlink_nl_put_handle(msg
, devlink
);
3845 goto nla_put_failure
;
3847 err
= nla_put_string(msg
, DEVLINK_ATTR_REGION_NAME
, region
->ops
->name
);
3849 goto nla_put_failure
;
3851 err
= nla_put_u64_64bit(msg
, DEVLINK_ATTR_REGION_SIZE
,
3855 goto nla_put_failure
;
3857 err
= devlink_nl_region_snapshots_id_put(msg
, devlink
, region
);
3859 goto nla_put_failure
;
3861 genlmsg_end(msg
, hdr
);
3865 genlmsg_cancel(msg
, hdr
);
3869 static struct sk_buff
*
3870 devlink_nl_region_notify_build(struct devlink_region
*region
,
3871 struct devlink_snapshot
*snapshot
,
3872 enum devlink_command cmd
, u32 portid
, u32 seq
)
3874 struct devlink
*devlink
= region
->devlink
;
3875 struct sk_buff
*msg
;
3880 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
3882 return ERR_PTR(-ENOMEM
);
3884 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, 0, cmd
);
3890 err
= devlink_nl_put_handle(msg
, devlink
);
3892 goto out_cancel_msg
;
3894 err
= nla_put_string(msg
, DEVLINK_ATTR_REGION_NAME
,
3897 goto out_cancel_msg
;
3900 err
= nla_put_u32(msg
, DEVLINK_ATTR_REGION_SNAPSHOT_ID
,
3903 goto out_cancel_msg
;
3905 err
= nla_put_u64_64bit(msg
, DEVLINK_ATTR_REGION_SIZE
,
3906 region
->size
, DEVLINK_ATTR_PAD
);
3908 goto out_cancel_msg
;
3910 genlmsg_end(msg
, hdr
);
3915 genlmsg_cancel(msg
, hdr
);
3918 return ERR_PTR(err
);
3921 static void devlink_nl_region_notify(struct devlink_region
*region
,
3922 struct devlink_snapshot
*snapshot
,
3923 enum devlink_command cmd
)
3925 struct devlink
*devlink
= region
->devlink
;
3926 struct sk_buff
*msg
;
3928 WARN_ON(cmd
!= DEVLINK_CMD_REGION_NEW
&& cmd
!= DEVLINK_CMD_REGION_DEL
);
3930 msg
= devlink_nl_region_notify_build(region
, snapshot
, cmd
, 0, 0);
3934 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
3935 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
3939 * __devlink_snapshot_id_increment - Increment number of snapshots using an id
3940 * @devlink: devlink instance
3941 * @id: the snapshot id
3943 * Track when a new snapshot begins using an id. Load the count for the
3944 * given id from the snapshot xarray, increment it, and store it back.
3946 * Called when a new snapshot is created with the given id.
3948 * The id *must* have been previously allocated by
3949 * devlink_region_snapshot_id_get().
3951 * Returns 0 on success, or an error on failure.
3953 static int __devlink_snapshot_id_increment(struct devlink
*devlink
, u32 id
)
3955 unsigned long count
;
3958 lockdep_assert_held(&devlink
->lock
);
3960 p
= xa_load(&devlink
->snapshot_ids
, id
);
3964 if (WARN_ON(!xa_is_value(p
)))
3967 count
= xa_to_value(p
);
3970 return xa_err(xa_store(&devlink
->snapshot_ids
, id
, xa_mk_value(count
),
3975 * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id
3976 * @devlink: devlink instance
3977 * @id: the snapshot id
3979 * Track when a snapshot is deleted and stops using an id. Load the count
3980 * for the given id from the snapshot xarray, decrement it, and store it
3983 * If the count reaches zero, erase this id from the xarray, freeing it
3984 * up for future re-use by devlink_region_snapshot_id_get().
3986 * Called when a snapshot using the given id is deleted, and when the
3987 * initial allocator of the id is finished using it.
3989 static void __devlink_snapshot_id_decrement(struct devlink
*devlink
, u32 id
)
3991 unsigned long count
;
3994 lockdep_assert_held(&devlink
->lock
);
3996 p
= xa_load(&devlink
->snapshot_ids
, id
);
4000 if (WARN_ON(!xa_is_value(p
)))
4003 count
= xa_to_value(p
);
4007 xa_store(&devlink
->snapshot_ids
, id
, xa_mk_value(count
),
4010 /* If this was the last user, we can erase this id */
4011 xa_erase(&devlink
->snapshot_ids
, id
);
4016 * __devlink_snapshot_id_insert - Insert a specific snapshot ID
4017 * @devlink: devlink instance
4018 * @id: the snapshot id
4020 * Mark the given snapshot id as used by inserting a zero value into the
4023 * This must be called while holding the devlink instance lock. Unlike
4024 * devlink_snapshot_id_get, the initial reference count is zero, not one.
4025 * It is expected that the id will immediately be used before
4026 * releasing the devlink instance lock.
4028 * Returns zero on success, or an error code if the snapshot id could not
4031 static int __devlink_snapshot_id_insert(struct devlink
*devlink
, u32 id
)
4033 lockdep_assert_held(&devlink
->lock
);
4035 if (WARN_ON(xa_load(&devlink
->snapshot_ids
, id
)))
4038 return xa_err(xa_store(&devlink
->snapshot_ids
, id
, xa_mk_value(0),
4043 * __devlink_region_snapshot_id_get - get snapshot ID
4044 * @devlink: devlink instance
4045 * @id: storage to return snapshot id
4047 * Allocates a new snapshot id. Returns zero on success, or a negative
4048 * error on failure. Must be called while holding the devlink instance
4051 * Snapshot IDs are tracked using an xarray which stores the number of
4052 * users of the snapshot id.
4054 * Note that the caller of this function counts as a 'user', in order to
4055 * avoid race conditions. The caller must release its hold on the
4056 * snapshot by using devlink_region_snapshot_id_put.
4058 static int __devlink_region_snapshot_id_get(struct devlink
*devlink
, u32
*id
)
4060 lockdep_assert_held(&devlink
->lock
);
4062 return xa_alloc(&devlink
->snapshot_ids
, id
, xa_mk_value(1),
4063 xa_limit_32b
, GFP_KERNEL
);
4067 * __devlink_region_snapshot_create - create a new snapshot
4068 * This will add a new snapshot of a region. The snapshot
4069 * will be stored on the region struct and can be accessed
4070 * from devlink. This is useful for future analyses of snapshots.
4071 * Multiple snapshots can be created on a region.
4072 * The @snapshot_id should be obtained using the getter function.
4074 * Must be called only while holding the devlink instance lock.
4076 * @region: devlink region of the snapshot
4077 * @data: snapshot data
4078 * @snapshot_id: snapshot id to be created
4081 __devlink_region_snapshot_create(struct devlink_region
*region
,
4082 u8
*data
, u32 snapshot_id
)
4084 struct devlink
*devlink
= region
->devlink
;
4085 struct devlink_snapshot
*snapshot
;
4088 lockdep_assert_held(&devlink
->lock
);
4090 /* check if region can hold one more snapshot */
4091 if (region
->cur_snapshots
== region
->max_snapshots
)
4094 if (devlink_region_snapshot_get_by_id(region
, snapshot_id
))
4097 snapshot
= kzalloc(sizeof(*snapshot
), GFP_KERNEL
);
4101 err
= __devlink_snapshot_id_increment(devlink
, snapshot_id
);
4103 goto err_snapshot_id_increment
;
4105 snapshot
->id
= snapshot_id
;
4106 snapshot
->region
= region
;
4107 snapshot
->data
= data
;
4109 list_add_tail(&snapshot
->list
, ®ion
->snapshot_list
);
4111 region
->cur_snapshots
++;
4113 devlink_nl_region_notify(region
, snapshot
, DEVLINK_CMD_REGION_NEW
);
4116 err_snapshot_id_increment
:
4121 static void devlink_region_snapshot_del(struct devlink_region
*region
,
4122 struct devlink_snapshot
*snapshot
)
4124 struct devlink
*devlink
= region
->devlink
;
4126 lockdep_assert_held(&devlink
->lock
);
4128 devlink_nl_region_notify(region
, snapshot
, DEVLINK_CMD_REGION_DEL
);
4129 region
->cur_snapshots
--;
4130 list_del(&snapshot
->list
);
4131 region
->ops
->destructor(snapshot
->data
);
4132 __devlink_snapshot_id_decrement(devlink
, snapshot
->id
);
4136 static int devlink_nl_cmd_region_get_doit(struct sk_buff
*skb
,
4137 struct genl_info
*info
)
4139 struct devlink
*devlink
= info
->user_ptr
[0];
4140 struct devlink_region
*region
;
4141 const char *region_name
;
4142 struct sk_buff
*msg
;
4145 if (!info
->attrs
[DEVLINK_ATTR_REGION_NAME
])
4148 region_name
= nla_data(info
->attrs
[DEVLINK_ATTR_REGION_NAME
]);
4149 region
= devlink_region_get_by_name(devlink
, region_name
);
4153 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
4157 err
= devlink_nl_region_fill(msg
, devlink
, DEVLINK_CMD_REGION_GET
,
4158 info
->snd_portid
, info
->snd_seq
, 0,
4165 return genlmsg_reply(msg
, info
);
4168 static int devlink_nl_cmd_region_get_dumpit(struct sk_buff
*msg
,
4169 struct netlink_callback
*cb
)
4171 struct devlink_region
*region
;
4172 struct devlink
*devlink
;
4173 int start
= cb
->args
[0];
4177 mutex_lock(&devlink_mutex
);
4178 list_for_each_entry(devlink
, &devlink_list
, list
) {
4179 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
4182 mutex_lock(&devlink
->lock
);
4183 list_for_each_entry(region
, &devlink
->region_list
, list
) {
4188 err
= devlink_nl_region_fill(msg
, devlink
,
4189 DEVLINK_CMD_REGION_GET
,
4190 NETLINK_CB(cb
->skb
).portid
,
4192 NLM_F_MULTI
, region
);
4194 mutex_unlock(&devlink
->lock
);
4199 mutex_unlock(&devlink
->lock
);
4202 mutex_unlock(&devlink_mutex
);
4207 static int devlink_nl_cmd_region_del(struct sk_buff
*skb
,
4208 struct genl_info
*info
)
4210 struct devlink
*devlink
= info
->user_ptr
[0];
4211 struct devlink_snapshot
*snapshot
;
4212 struct devlink_region
*region
;
4213 const char *region_name
;
4216 if (!info
->attrs
[DEVLINK_ATTR_REGION_NAME
] ||
4217 !info
->attrs
[DEVLINK_ATTR_REGION_SNAPSHOT_ID
])
4220 region_name
= nla_data(info
->attrs
[DEVLINK_ATTR_REGION_NAME
]);
4221 snapshot_id
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_REGION_SNAPSHOT_ID
]);
4223 region
= devlink_region_get_by_name(devlink
, region_name
);
4227 snapshot
= devlink_region_snapshot_get_by_id(region
, snapshot_id
);
4231 devlink_region_snapshot_del(region
, snapshot
);
4236 devlink_nl_cmd_region_new(struct sk_buff
*skb
, struct genl_info
*info
)
4238 struct devlink
*devlink
= info
->user_ptr
[0];
4239 struct devlink_snapshot
*snapshot
;
4240 struct nlattr
*snapshot_id_attr
;
4241 struct devlink_region
*region
;
4242 const char *region_name
;
4247 if (!info
->attrs
[DEVLINK_ATTR_REGION_NAME
]) {
4248 NL_SET_ERR_MSG_MOD(info
->extack
, "No region name provided");
4252 region_name
= nla_data(info
->attrs
[DEVLINK_ATTR_REGION_NAME
]);
4253 region
= devlink_region_get_by_name(devlink
, region_name
);
4255 NL_SET_ERR_MSG_MOD(info
->extack
, "The requested region does not exist");
4259 if (!region
->ops
->snapshot
) {
4260 NL_SET_ERR_MSG_MOD(info
->extack
, "The requested region does not support taking an immediate snapshot");
4264 if (region
->cur_snapshots
== region
->max_snapshots
) {
4265 NL_SET_ERR_MSG_MOD(info
->extack
, "The region has reached the maximum number of stored snapshots");
4269 snapshot_id_attr
= info
->attrs
[DEVLINK_ATTR_REGION_SNAPSHOT_ID
];
4270 if (snapshot_id_attr
) {
4271 snapshot_id
= nla_get_u32(snapshot_id_attr
);
4273 if (devlink_region_snapshot_get_by_id(region
, snapshot_id
)) {
4274 NL_SET_ERR_MSG_MOD(info
->extack
, "The requested snapshot id is already in use");
4278 err
= __devlink_snapshot_id_insert(devlink
, snapshot_id
);
4282 err
= __devlink_region_snapshot_id_get(devlink
, &snapshot_id
);
4284 NL_SET_ERR_MSG_MOD(info
->extack
, "Failed to allocate a new snapshot id");
4289 err
= region
->ops
->snapshot(devlink
, info
->extack
, &data
);
4291 goto err_snapshot_capture
;
4293 err
= __devlink_region_snapshot_create(region
, data
, snapshot_id
);
4295 goto err_snapshot_create
;
4297 if (!snapshot_id_attr
) {
4298 struct sk_buff
*msg
;
4300 snapshot
= devlink_region_snapshot_get_by_id(region
,
4302 if (WARN_ON(!snapshot
))
4305 msg
= devlink_nl_region_notify_build(region
, snapshot
,
4306 DEVLINK_CMD_REGION_NEW
,
4309 err
= PTR_ERR_OR_ZERO(msg
);
4313 err
= genlmsg_reply(msg
, info
);
4320 err_snapshot_create
:
4321 region
->ops
->destructor(data
);
4322 err_snapshot_capture
:
4323 __devlink_snapshot_id_decrement(devlink
, snapshot_id
);
4327 devlink_region_snapshot_del(region
, snapshot
);
4331 static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff
*msg
,
4332 struct devlink
*devlink
,
4333 u8
*chunk
, u32 chunk_size
,
4336 struct nlattr
*chunk_attr
;
4339 chunk_attr
= nla_nest_start_noflag(msg
, DEVLINK_ATTR_REGION_CHUNK
);
4343 err
= nla_put(msg
, DEVLINK_ATTR_REGION_CHUNK_DATA
, chunk_size
, chunk
);
4345 goto nla_put_failure
;
4347 err
= nla_put_u64_64bit(msg
, DEVLINK_ATTR_REGION_CHUNK_ADDR
, addr
,
4350 goto nla_put_failure
;
4352 nla_nest_end(msg
, chunk_attr
);
4356 nla_nest_cancel(msg
, chunk_attr
);
4360 #define DEVLINK_REGION_READ_CHUNK_SIZE 256
4362 static int devlink_nl_region_read_snapshot_fill(struct sk_buff
*skb
,
4363 struct devlink
*devlink
,
4364 struct devlink_region
*region
,
4365 struct nlattr
**attrs
,
4370 struct devlink_snapshot
*snapshot
;
4371 u64 curr_offset
= start_offset
;
4375 *new_offset
= start_offset
;
4377 snapshot_id
= nla_get_u32(attrs
[DEVLINK_ATTR_REGION_SNAPSHOT_ID
]);
4378 snapshot
= devlink_region_snapshot_get_by_id(region
, snapshot_id
);
4382 while (curr_offset
< end_offset
) {
4386 if (end_offset
- curr_offset
< DEVLINK_REGION_READ_CHUNK_SIZE
)
4387 data_size
= end_offset
- curr_offset
;
4389 data_size
= DEVLINK_REGION_READ_CHUNK_SIZE
;
4391 data
= &snapshot
->data
[curr_offset
];
4392 err
= devlink_nl_cmd_region_read_chunk_fill(skb
, devlink
,
4398 curr_offset
+= data_size
;
4400 *new_offset
= curr_offset
;
4405 static int devlink_nl_cmd_region_read_dumpit(struct sk_buff
*skb
,
4406 struct netlink_callback
*cb
)
4408 const struct genl_dumpit_info
*info
= genl_dumpit_info(cb
);
4409 u64 ret_offset
, start_offset
, end_offset
= U64_MAX
;
4410 struct nlattr
**attrs
= info
->attrs
;
4411 struct devlink_region
*region
;
4412 struct nlattr
*chunks_attr
;
4413 const char *region_name
;
4414 struct devlink
*devlink
;
4418 start_offset
= *((u64
*)&cb
->args
[0]);
4420 mutex_lock(&devlink_mutex
);
4421 devlink
= devlink_get_from_attrs(sock_net(cb
->skb
->sk
), attrs
);
4422 if (IS_ERR(devlink
)) {
4423 err
= PTR_ERR(devlink
);
4427 mutex_lock(&devlink
->lock
);
4429 if (!attrs
[DEVLINK_ATTR_REGION_NAME
] ||
4430 !attrs
[DEVLINK_ATTR_REGION_SNAPSHOT_ID
]) {
4435 region_name
= nla_data(attrs
[DEVLINK_ATTR_REGION_NAME
]);
4436 region
= devlink_region_get_by_name(devlink
, region_name
);
4442 if (attrs
[DEVLINK_ATTR_REGION_CHUNK_ADDR
] &&
4443 attrs
[DEVLINK_ATTR_REGION_CHUNK_LEN
]) {
4446 nla_get_u64(attrs
[DEVLINK_ATTR_REGION_CHUNK_ADDR
]);
4448 end_offset
= nla_get_u64(attrs
[DEVLINK_ATTR_REGION_CHUNK_ADDR
]);
4449 end_offset
+= nla_get_u64(attrs
[DEVLINK_ATTR_REGION_CHUNK_LEN
]);
4452 if (end_offset
> region
->size
)
4453 end_offset
= region
->size
;
4455 /* return 0 if there is no further data to read */
4456 if (start_offset
== end_offset
) {
4461 hdr
= genlmsg_put(skb
, NETLINK_CB(cb
->skb
).portid
, cb
->nlh
->nlmsg_seq
,
4462 &devlink_nl_family
, NLM_F_ACK
| NLM_F_MULTI
,
4463 DEVLINK_CMD_REGION_READ
);
4469 err
= devlink_nl_put_handle(skb
, devlink
);
4471 goto nla_put_failure
;
4473 err
= nla_put_string(skb
, DEVLINK_ATTR_REGION_NAME
, region_name
);
4475 goto nla_put_failure
;
4477 chunks_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_REGION_CHUNKS
);
4480 goto nla_put_failure
;
4483 err
= devlink_nl_region_read_snapshot_fill(skb
, devlink
,
4486 end_offset
, &ret_offset
);
4488 if (err
&& err
!= -EMSGSIZE
)
4489 goto nla_put_failure
;
4491 /* Check if there was any progress done to prevent infinite loop */
4492 if (ret_offset
== start_offset
) {
4494 goto nla_put_failure
;
4497 *((u64
*)&cb
->args
[0]) = ret_offset
;
4499 nla_nest_end(skb
, chunks_attr
);
4500 genlmsg_end(skb
, hdr
);
4501 mutex_unlock(&devlink
->lock
);
4502 mutex_unlock(&devlink_mutex
);
4507 genlmsg_cancel(skb
, hdr
);
4509 mutex_unlock(&devlink
->lock
);
4511 mutex_unlock(&devlink_mutex
);
4515 struct devlink_info_req
{
4516 struct sk_buff
*msg
;
4519 int devlink_info_driver_name_put(struct devlink_info_req
*req
, const char *name
)
4521 return nla_put_string(req
->msg
, DEVLINK_ATTR_INFO_DRIVER_NAME
, name
);
4523 EXPORT_SYMBOL_GPL(devlink_info_driver_name_put
);
4525 int devlink_info_serial_number_put(struct devlink_info_req
*req
, const char *sn
)
4527 return nla_put_string(req
->msg
, DEVLINK_ATTR_INFO_SERIAL_NUMBER
, sn
);
4529 EXPORT_SYMBOL_GPL(devlink_info_serial_number_put
);
4531 int devlink_info_board_serial_number_put(struct devlink_info_req
*req
,
4534 return nla_put_string(req
->msg
, DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER
,
4537 EXPORT_SYMBOL_GPL(devlink_info_board_serial_number_put
);
4539 static int devlink_info_version_put(struct devlink_info_req
*req
, int attr
,
4540 const char *version_name
,
4541 const char *version_value
)
4543 struct nlattr
*nest
;
4546 nest
= nla_nest_start_noflag(req
->msg
, attr
);
4550 err
= nla_put_string(req
->msg
, DEVLINK_ATTR_INFO_VERSION_NAME
,
4553 goto nla_put_failure
;
4555 err
= nla_put_string(req
->msg
, DEVLINK_ATTR_INFO_VERSION_VALUE
,
4558 goto nla_put_failure
;
4560 nla_nest_end(req
->msg
, nest
);
4565 nla_nest_cancel(req
->msg
, nest
);
4569 int devlink_info_version_fixed_put(struct devlink_info_req
*req
,
4570 const char *version_name
,
4571 const char *version_value
)
4573 return devlink_info_version_put(req
, DEVLINK_ATTR_INFO_VERSION_FIXED
,
4574 version_name
, version_value
);
4576 EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put
);
4578 int devlink_info_version_stored_put(struct devlink_info_req
*req
,
4579 const char *version_name
,
4580 const char *version_value
)
4582 return devlink_info_version_put(req
, DEVLINK_ATTR_INFO_VERSION_STORED
,
4583 version_name
, version_value
);
4585 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put
);
4587 int devlink_info_version_running_put(struct devlink_info_req
*req
,
4588 const char *version_name
,
4589 const char *version_value
)
4591 return devlink_info_version_put(req
, DEVLINK_ATTR_INFO_VERSION_RUNNING
,
4592 version_name
, version_value
);
4594 EXPORT_SYMBOL_GPL(devlink_info_version_running_put
);
4597 devlink_nl_info_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
4598 enum devlink_command cmd
, u32 portid
,
4599 u32 seq
, int flags
, struct netlink_ext_ack
*extack
)
4601 struct devlink_info_req req
;
4605 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
4610 if (devlink_nl_put_handle(msg
, devlink
))
4611 goto err_cancel_msg
;
4614 err
= devlink
->ops
->info_get(devlink
, &req
, extack
);
4616 goto err_cancel_msg
;
4618 genlmsg_end(msg
, hdr
);
4622 genlmsg_cancel(msg
, hdr
);
4626 static int devlink_nl_cmd_info_get_doit(struct sk_buff
*skb
,
4627 struct genl_info
*info
)
4629 struct devlink
*devlink
= info
->user_ptr
[0];
4630 struct sk_buff
*msg
;
4633 if (!devlink
->ops
->info_get
)
4636 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
4640 err
= devlink_nl_info_fill(msg
, devlink
, DEVLINK_CMD_INFO_GET
,
4641 info
->snd_portid
, info
->snd_seq
, 0,
4648 return genlmsg_reply(msg
, info
);
4651 static int devlink_nl_cmd_info_get_dumpit(struct sk_buff
*msg
,
4652 struct netlink_callback
*cb
)
4654 struct devlink
*devlink
;
4655 int start
= cb
->args
[0];
4659 mutex_lock(&devlink_mutex
);
4660 list_for_each_entry(devlink
, &devlink_list
, list
) {
4661 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
4668 if (!devlink
->ops
->info_get
) {
4673 mutex_lock(&devlink
->lock
);
4674 err
= devlink_nl_info_fill(msg
, devlink
, DEVLINK_CMD_INFO_GET
,
4675 NETLINK_CB(cb
->skb
).portid
,
4676 cb
->nlh
->nlmsg_seq
, NLM_F_MULTI
,
4678 mutex_unlock(&devlink
->lock
);
4679 if (err
&& err
!= -EOPNOTSUPP
)
4683 mutex_unlock(&devlink_mutex
);
4685 if (err
!= -EMSGSIZE
)
4692 struct devlink_fmsg_item
{
4693 struct list_head list
;
4700 struct devlink_fmsg
{
4701 struct list_head item_list
;
4702 bool putting_binary
; /* This flag forces enclosing of binary data
4703 * in an array brackets. It forces using
4704 * of designated API:
4705 * devlink_fmsg_binary_pair_nest_start()
4706 * devlink_fmsg_binary_pair_nest_end()
4710 static struct devlink_fmsg
*devlink_fmsg_alloc(void)
4712 struct devlink_fmsg
*fmsg
;
4714 fmsg
= kzalloc(sizeof(*fmsg
), GFP_KERNEL
);
4718 INIT_LIST_HEAD(&fmsg
->item_list
);
4723 static void devlink_fmsg_free(struct devlink_fmsg
*fmsg
)
4725 struct devlink_fmsg_item
*item
, *tmp
;
4727 list_for_each_entry_safe(item
, tmp
, &fmsg
->item_list
, list
) {
4728 list_del(&item
->list
);
4734 static int devlink_fmsg_nest_common(struct devlink_fmsg
*fmsg
,
4737 struct devlink_fmsg_item
*item
;
4739 item
= kzalloc(sizeof(*item
), GFP_KERNEL
);
4743 item
->attrtype
= attrtype
;
4744 list_add_tail(&item
->list
, &fmsg
->item_list
);
4749 int devlink_fmsg_obj_nest_start(struct devlink_fmsg
*fmsg
)
4751 if (fmsg
->putting_binary
)
4754 return devlink_fmsg_nest_common(fmsg
, DEVLINK_ATTR_FMSG_OBJ_NEST_START
);
4756 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start
);
4758 static int devlink_fmsg_nest_end(struct devlink_fmsg
*fmsg
)
4760 if (fmsg
->putting_binary
)
4763 return devlink_fmsg_nest_common(fmsg
, DEVLINK_ATTR_FMSG_NEST_END
);
4766 int devlink_fmsg_obj_nest_end(struct devlink_fmsg
*fmsg
)
4768 if (fmsg
->putting_binary
)
4771 return devlink_fmsg_nest_end(fmsg
);
4773 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end
);
4775 #define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN)
4777 static int devlink_fmsg_put_name(struct devlink_fmsg
*fmsg
, const char *name
)
4779 struct devlink_fmsg_item
*item
;
4781 if (fmsg
->putting_binary
)
4784 if (strlen(name
) + 1 > DEVLINK_FMSG_MAX_SIZE
)
4787 item
= kzalloc(sizeof(*item
) + strlen(name
) + 1, GFP_KERNEL
);
4791 item
->nla_type
= NLA_NUL_STRING
;
4792 item
->len
= strlen(name
) + 1;
4793 item
->attrtype
= DEVLINK_ATTR_FMSG_OBJ_NAME
;
4794 memcpy(&item
->value
, name
, item
->len
);
4795 list_add_tail(&item
->list
, &fmsg
->item_list
);
4800 int devlink_fmsg_pair_nest_start(struct devlink_fmsg
*fmsg
, const char *name
)
4804 if (fmsg
->putting_binary
)
4807 err
= devlink_fmsg_nest_common(fmsg
, DEVLINK_ATTR_FMSG_PAIR_NEST_START
);
4811 err
= devlink_fmsg_put_name(fmsg
, name
);
4817 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start
);
4819 int devlink_fmsg_pair_nest_end(struct devlink_fmsg
*fmsg
)
4821 if (fmsg
->putting_binary
)
4824 return devlink_fmsg_nest_end(fmsg
);
4826 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end
);
4828 int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg
*fmsg
,
4833 if (fmsg
->putting_binary
)
4836 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
4840 err
= devlink_fmsg_nest_common(fmsg
, DEVLINK_ATTR_FMSG_ARR_NEST_START
);
4846 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start
);
4848 int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg
*fmsg
)
4852 if (fmsg
->putting_binary
)
4855 err
= devlink_fmsg_nest_end(fmsg
);
4859 err
= devlink_fmsg_nest_end(fmsg
);
4865 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end
);
4867 int devlink_fmsg_binary_pair_nest_start(struct devlink_fmsg
*fmsg
,
4872 err
= devlink_fmsg_arr_pair_nest_start(fmsg
, name
);
4876 fmsg
->putting_binary
= true;
4879 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_start
);
4881 int devlink_fmsg_binary_pair_nest_end(struct devlink_fmsg
*fmsg
)
4883 if (!fmsg
->putting_binary
)
4886 fmsg
->putting_binary
= false;
4887 return devlink_fmsg_arr_pair_nest_end(fmsg
);
4889 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_end
);
4891 static int devlink_fmsg_put_value(struct devlink_fmsg
*fmsg
,
4892 const void *value
, u16 value_len
,
4895 struct devlink_fmsg_item
*item
;
4897 if (value_len
> DEVLINK_FMSG_MAX_SIZE
)
4900 item
= kzalloc(sizeof(*item
) + value_len
, GFP_KERNEL
);
4904 item
->nla_type
= value_nla_type
;
4905 item
->len
= value_len
;
4906 item
->attrtype
= DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA
;
4907 memcpy(&item
->value
, value
, item
->len
);
4908 list_add_tail(&item
->list
, &fmsg
->item_list
);
4913 int devlink_fmsg_bool_put(struct devlink_fmsg
*fmsg
, bool value
)
4915 if (fmsg
->putting_binary
)
4918 return devlink_fmsg_put_value(fmsg
, &value
, sizeof(value
), NLA_FLAG
);
4920 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_put
);
4922 int devlink_fmsg_u8_put(struct devlink_fmsg
*fmsg
, u8 value
)
4924 if (fmsg
->putting_binary
)
4927 return devlink_fmsg_put_value(fmsg
, &value
, sizeof(value
), NLA_U8
);
4929 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_put
);
4931 int devlink_fmsg_u32_put(struct devlink_fmsg
*fmsg
, u32 value
)
4933 if (fmsg
->putting_binary
)
4936 return devlink_fmsg_put_value(fmsg
, &value
, sizeof(value
), NLA_U32
);
4938 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put
);
4940 int devlink_fmsg_u64_put(struct devlink_fmsg
*fmsg
, u64 value
)
4942 if (fmsg
->putting_binary
)
4945 return devlink_fmsg_put_value(fmsg
, &value
, sizeof(value
), NLA_U64
);
4947 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_put
);
4949 int devlink_fmsg_string_put(struct devlink_fmsg
*fmsg
, const char *value
)
4951 if (fmsg
->putting_binary
)
4954 return devlink_fmsg_put_value(fmsg
, value
, strlen(value
) + 1,
4957 EXPORT_SYMBOL_GPL(devlink_fmsg_string_put
);
4959 int devlink_fmsg_binary_put(struct devlink_fmsg
*fmsg
, const void *value
,
4962 if (!fmsg
->putting_binary
)
4965 return devlink_fmsg_put_value(fmsg
, value
, value_len
, NLA_BINARY
);
4967 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put
);
4969 int devlink_fmsg_bool_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
4974 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
4978 err
= devlink_fmsg_bool_put(fmsg
, value
);
4982 err
= devlink_fmsg_pair_nest_end(fmsg
);
4988 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put
);
4990 int devlink_fmsg_u8_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
4995 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
4999 err
= devlink_fmsg_u8_put(fmsg
, value
);
5003 err
= devlink_fmsg_pair_nest_end(fmsg
);
5009 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put
);
5011 int devlink_fmsg_u32_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
5016 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
5020 err
= devlink_fmsg_u32_put(fmsg
, value
);
5024 err
= devlink_fmsg_pair_nest_end(fmsg
);
5030 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put
);
5032 int devlink_fmsg_u64_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
5037 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
5041 err
= devlink_fmsg_u64_put(fmsg
, value
);
5045 err
= devlink_fmsg_pair_nest_end(fmsg
);
5051 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put
);
5053 int devlink_fmsg_string_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
5058 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
5062 err
= devlink_fmsg_string_put(fmsg
, value
);
5066 err
= devlink_fmsg_pair_nest_end(fmsg
);
5072 EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put
);
5074 int devlink_fmsg_binary_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
5075 const void *value
, u32 value_len
)
5082 err
= devlink_fmsg_binary_pair_nest_start(fmsg
, name
);
5086 for (offset
= 0; offset
< value_len
; offset
+= data_size
) {
5087 data_size
= value_len
- offset
;
5088 if (data_size
> DEVLINK_FMSG_MAX_SIZE
)
5089 data_size
= DEVLINK_FMSG_MAX_SIZE
;
5090 err
= devlink_fmsg_binary_put(fmsg
, value
+ offset
, data_size
);
5093 /* Exit from loop with a break (instead of
5094 * return) to make sure putting_binary is turned off in
5095 * devlink_fmsg_binary_pair_nest_end
5099 end_err
= devlink_fmsg_binary_pair_nest_end(fmsg
);
5105 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put
);
5108 devlink_fmsg_item_fill_type(struct devlink_fmsg_item
*msg
, struct sk_buff
*skb
)
5110 switch (msg
->nla_type
) {
5115 case NLA_NUL_STRING
:
5117 return nla_put_u8(skb
, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE
,
5125 devlink_fmsg_item_fill_data(struct devlink_fmsg_item
*msg
, struct sk_buff
*skb
)
5127 int attrtype
= DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA
;
5130 switch (msg
->nla_type
) {
5132 /* Always provide flag data, regardless of its value */
5133 tmp
= *(bool *) msg
->value
;
5135 return nla_put_u8(skb
, attrtype
, tmp
);
5137 return nla_put_u8(skb
, attrtype
, *(u8
*) msg
->value
);
5139 return nla_put_u32(skb
, attrtype
, *(u32
*) msg
->value
);
5141 return nla_put_u64_64bit(skb
, attrtype
, *(u64
*) msg
->value
,
5143 case NLA_NUL_STRING
:
5144 return nla_put_string(skb
, attrtype
, (char *) &msg
->value
);
5146 return nla_put(skb
, attrtype
, msg
->len
, (void *) &msg
->value
);
5153 devlink_fmsg_prepare_skb(struct devlink_fmsg
*fmsg
, struct sk_buff
*skb
,
5156 struct devlink_fmsg_item
*item
;
5157 struct nlattr
*fmsg_nlattr
;
5161 fmsg_nlattr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_FMSG
);
5165 list_for_each_entry(item
, &fmsg
->item_list
, list
) {
5171 switch (item
->attrtype
) {
5172 case DEVLINK_ATTR_FMSG_OBJ_NEST_START
:
5173 case DEVLINK_ATTR_FMSG_PAIR_NEST_START
:
5174 case DEVLINK_ATTR_FMSG_ARR_NEST_START
:
5175 case DEVLINK_ATTR_FMSG_NEST_END
:
5176 err
= nla_put_flag(skb
, item
->attrtype
);
5178 case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA
:
5179 err
= devlink_fmsg_item_fill_type(item
, skb
);
5182 err
= devlink_fmsg_item_fill_data(item
, skb
);
5184 case DEVLINK_ATTR_FMSG_OBJ_NAME
:
5185 err
= nla_put_string(skb
, item
->attrtype
,
5186 (char *) &item
->value
);
5198 nla_nest_end(skb
, fmsg_nlattr
);
5202 static int devlink_fmsg_snd(struct devlink_fmsg
*fmsg
,
5203 struct genl_info
*info
,
5204 enum devlink_command cmd
, int flags
)
5206 struct nlmsghdr
*nlh
;
5207 struct sk_buff
*skb
;
5214 int tmp_index
= index
;
5216 skb
= genlmsg_new(GENLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
5220 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
5221 &devlink_nl_family
, flags
| NLM_F_MULTI
, cmd
);
5224 goto nla_put_failure
;
5227 err
= devlink_fmsg_prepare_skb(fmsg
, skb
, &index
);
5230 else if (err
!= -EMSGSIZE
|| tmp_index
== index
)
5231 goto nla_put_failure
;
5233 genlmsg_end(skb
, hdr
);
5234 err
= genlmsg_reply(skb
, info
);
5239 skb
= genlmsg_new(GENLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
5242 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
5243 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
5246 goto nla_put_failure
;
5249 return genlmsg_reply(skb
, info
);
5256 static int devlink_fmsg_dumpit(struct devlink_fmsg
*fmsg
, struct sk_buff
*skb
,
5257 struct netlink_callback
*cb
,
5258 enum devlink_command cmd
)
5260 int index
= cb
->args
[0];
5261 int tmp_index
= index
;
5265 hdr
= genlmsg_put(skb
, NETLINK_CB(cb
->skb
).portid
, cb
->nlh
->nlmsg_seq
,
5266 &devlink_nl_family
, NLM_F_ACK
| NLM_F_MULTI
, cmd
);
5269 goto nla_put_failure
;
5272 err
= devlink_fmsg_prepare_skb(fmsg
, skb
, &index
);
5273 if ((err
&& err
!= -EMSGSIZE
) || tmp_index
== index
)
5274 goto nla_put_failure
;
5276 cb
->args
[0] = index
;
5277 genlmsg_end(skb
, hdr
);
5281 genlmsg_cancel(skb
, hdr
);
5285 struct devlink_health_reporter
{
5286 struct list_head list
;
5288 const struct devlink_health_reporter_ops
*ops
;
5289 struct devlink
*devlink
;
5290 struct devlink_fmsg
*dump_fmsg
;
5291 struct mutex dump_lock
; /* lock parallel read/write from dump buffers */
5292 u64 graceful_period
;
5300 u64 last_recovery_ts
;
5301 refcount_t refcount
;
5305 devlink_health_reporter_priv(struct devlink_health_reporter
*reporter
)
5307 return reporter
->priv
;
5309 EXPORT_SYMBOL_GPL(devlink_health_reporter_priv
);
5311 static struct devlink_health_reporter
*
5312 devlink_health_reporter_find_by_name(struct devlink
*devlink
,
5313 const char *reporter_name
)
5315 struct devlink_health_reporter
*reporter
;
5317 lockdep_assert_held(&devlink
->reporters_lock
);
5318 list_for_each_entry(reporter
, &devlink
->reporter_list
, list
)
5319 if (!strcmp(reporter
->ops
->name
, reporter_name
))
5324 static struct devlink_health_reporter
*
5325 __devlink_health_reporter_create(struct devlink
*devlink
,
5326 const struct devlink_health_reporter_ops
*ops
,
5327 u64 graceful_period
, void *priv
)
5329 struct devlink_health_reporter
*reporter
;
5331 if (WARN_ON(graceful_period
&& !ops
->recover
))
5332 return ERR_PTR(-EINVAL
);
5334 reporter
= kzalloc(sizeof(*reporter
), GFP_KERNEL
);
5336 return ERR_PTR(-ENOMEM
);
5338 reporter
->priv
= priv
;
5339 reporter
->ops
= ops
;
5340 reporter
->devlink
= devlink
;
5341 reporter
->graceful_period
= graceful_period
;
5342 reporter
->auto_recover
= !!ops
->recover
;
5343 reporter
->auto_dump
= !!ops
->dump
;
5344 mutex_init(&reporter
->dump_lock
);
5345 refcount_set(&reporter
->refcount
, 1);
5350 * devlink_health_reporter_create - create devlink health reporter
5354 * @graceful_period: to avoid recovery loops, in msecs
5357 struct devlink_health_reporter
*
5358 devlink_health_reporter_create(struct devlink
*devlink
,
5359 const struct devlink_health_reporter_ops
*ops
,
5360 u64 graceful_period
, void *priv
)
5362 struct devlink_health_reporter
*reporter
;
5364 mutex_lock(&devlink
->reporters_lock
);
5365 if (devlink_health_reporter_find_by_name(devlink
, ops
->name
)) {
5366 reporter
= ERR_PTR(-EEXIST
);
5370 reporter
= __devlink_health_reporter_create(devlink
, ops
,
5371 graceful_period
, priv
);
5372 if (IS_ERR(reporter
))
5375 list_add_tail(&reporter
->list
, &devlink
->reporter_list
);
5377 mutex_unlock(&devlink
->reporters_lock
);
5380 EXPORT_SYMBOL_GPL(devlink_health_reporter_create
);
5383 devlink_health_reporter_free(struct devlink_health_reporter
*reporter
)
5385 mutex_destroy(&reporter
->dump_lock
);
5386 if (reporter
->dump_fmsg
)
5387 devlink_fmsg_free(reporter
->dump_fmsg
);
5392 devlink_health_reporter_put(struct devlink_health_reporter
*reporter
)
5394 if (refcount_dec_and_test(&reporter
->refcount
))
5395 devlink_health_reporter_free(reporter
);
5399 __devlink_health_reporter_destroy(struct devlink_health_reporter
*reporter
)
5401 list_del(&reporter
->list
);
5402 devlink_health_reporter_put(reporter
);
5406 * devlink_health_reporter_destroy - destroy devlink health reporter
5408 * @reporter: devlink health reporter to destroy
5411 devlink_health_reporter_destroy(struct devlink_health_reporter
*reporter
)
5413 mutex_lock(&reporter
->devlink
->reporters_lock
);
5414 __devlink_health_reporter_destroy(reporter
);
5415 mutex_unlock(&reporter
->devlink
->reporters_lock
);
5417 EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy
);
5420 devlink_nl_health_reporter_fill(struct sk_buff
*msg
,
5421 struct devlink
*devlink
,
5422 struct devlink_health_reporter
*reporter
,
5423 enum devlink_command cmd
, u32 portid
,
5426 struct nlattr
*reporter_attr
;
5429 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
5433 if (devlink_nl_put_handle(msg
, devlink
))
5434 goto genlmsg_cancel
;
5436 reporter_attr
= nla_nest_start_noflag(msg
,
5437 DEVLINK_ATTR_HEALTH_REPORTER
);
5439 goto genlmsg_cancel
;
5440 if (nla_put_string(msg
, DEVLINK_ATTR_HEALTH_REPORTER_NAME
,
5441 reporter
->ops
->name
))
5442 goto reporter_nest_cancel
;
5443 if (nla_put_u8(msg
, DEVLINK_ATTR_HEALTH_REPORTER_STATE
,
5444 reporter
->health_state
))
5445 goto reporter_nest_cancel
;
5446 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT
,
5447 reporter
->error_count
, DEVLINK_ATTR_PAD
))
5448 goto reporter_nest_cancel
;
5449 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT
,
5450 reporter
->recovery_count
, DEVLINK_ATTR_PAD
))
5451 goto reporter_nest_cancel
;
5452 if (reporter
->ops
->recover
&&
5453 nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
,
5454 reporter
->graceful_period
,
5456 goto reporter_nest_cancel
;
5457 if (reporter
->ops
->recover
&&
5458 nla_put_u8(msg
, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
,
5459 reporter
->auto_recover
))
5460 goto reporter_nest_cancel
;
5461 if (reporter
->dump_fmsg
&&
5462 nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS
,
5463 jiffies_to_msecs(reporter
->dump_ts
),
5465 goto reporter_nest_cancel
;
5466 if (reporter
->dump_fmsg
&&
5467 nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS
,
5468 reporter
->dump_real_ts
, DEVLINK_ATTR_PAD
))
5469 goto reporter_nest_cancel
;
5470 if (reporter
->ops
->dump
&&
5471 nla_put_u8(msg
, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP
,
5472 reporter
->auto_dump
))
5473 goto reporter_nest_cancel
;
5475 nla_nest_end(msg
, reporter_attr
);
5476 genlmsg_end(msg
, hdr
);
5479 reporter_nest_cancel
:
5480 nla_nest_end(msg
, reporter_attr
);
5482 genlmsg_cancel(msg
, hdr
);
5486 static void devlink_recover_notify(struct devlink_health_reporter
*reporter
,
5487 enum devlink_command cmd
)
5489 struct sk_buff
*msg
;
5492 WARN_ON(cmd
!= DEVLINK_CMD_HEALTH_REPORTER_RECOVER
);
5494 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
5498 err
= devlink_nl_health_reporter_fill(msg
, reporter
->devlink
,
5499 reporter
, cmd
, 0, 0, 0);
5505 genlmsg_multicast_netns(&devlink_nl_family
,
5506 devlink_net(reporter
->devlink
),
5507 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
5511 devlink_health_reporter_recovery_done(struct devlink_health_reporter
*reporter
)
5513 reporter
->recovery_count
++;
5514 reporter
->last_recovery_ts
= jiffies
;
5516 EXPORT_SYMBOL_GPL(devlink_health_reporter_recovery_done
);
5519 devlink_health_reporter_recover(struct devlink_health_reporter
*reporter
,
5520 void *priv_ctx
, struct netlink_ext_ack
*extack
)
5524 if (reporter
->health_state
== DEVLINK_HEALTH_REPORTER_STATE_HEALTHY
)
5527 if (!reporter
->ops
->recover
)
5530 err
= reporter
->ops
->recover(reporter
, priv_ctx
, extack
);
5534 devlink_health_reporter_recovery_done(reporter
);
5535 reporter
->health_state
= DEVLINK_HEALTH_REPORTER_STATE_HEALTHY
;
5536 devlink_recover_notify(reporter
, DEVLINK_CMD_HEALTH_REPORTER_RECOVER
);
5542 devlink_health_dump_clear(struct devlink_health_reporter
*reporter
)
5544 if (!reporter
->dump_fmsg
)
5546 devlink_fmsg_free(reporter
->dump_fmsg
);
5547 reporter
->dump_fmsg
= NULL
;
5550 static int devlink_health_do_dump(struct devlink_health_reporter
*reporter
,
5552 struct netlink_ext_ack
*extack
)
5556 if (!reporter
->ops
->dump
)
5559 if (reporter
->dump_fmsg
)
5562 reporter
->dump_fmsg
= devlink_fmsg_alloc();
5563 if (!reporter
->dump_fmsg
) {
5568 err
= devlink_fmsg_obj_nest_start(reporter
->dump_fmsg
);
5572 err
= reporter
->ops
->dump(reporter
, reporter
->dump_fmsg
,
5577 err
= devlink_fmsg_obj_nest_end(reporter
->dump_fmsg
);
5581 reporter
->dump_ts
= jiffies
;
5582 reporter
->dump_real_ts
= ktime_get_real_ns();
5587 devlink_health_dump_clear(reporter
);
5591 int devlink_health_report(struct devlink_health_reporter
*reporter
,
5592 const char *msg
, void *priv_ctx
)
5594 enum devlink_health_reporter_state prev_health_state
;
5595 struct devlink
*devlink
= reporter
->devlink
;
5596 unsigned long recover_ts_threshold
;
5598 /* write a log message of the current error */
5600 trace_devlink_health_report(devlink
, reporter
->ops
->name
, msg
);
5601 reporter
->error_count
++;
5602 prev_health_state
= reporter
->health_state
;
5603 reporter
->health_state
= DEVLINK_HEALTH_REPORTER_STATE_ERROR
;
5604 devlink_recover_notify(reporter
, DEVLINK_CMD_HEALTH_REPORTER_RECOVER
);
5606 /* abort if the previous error wasn't recovered */
5607 recover_ts_threshold
= reporter
->last_recovery_ts
+
5608 msecs_to_jiffies(reporter
->graceful_period
);
5609 if (reporter
->auto_recover
&&
5610 (prev_health_state
!= DEVLINK_HEALTH_REPORTER_STATE_HEALTHY
||
5611 (reporter
->last_recovery_ts
&& reporter
->recovery_count
&&
5612 time_is_after_jiffies(recover_ts_threshold
)))) {
5613 trace_devlink_health_recover_aborted(devlink
,
5614 reporter
->ops
->name
,
5615 reporter
->health_state
,
5617 reporter
->last_recovery_ts
);
5621 reporter
->health_state
= DEVLINK_HEALTH_REPORTER_STATE_ERROR
;
5623 if (reporter
->auto_dump
) {
5624 mutex_lock(&reporter
->dump_lock
);
5625 /* store current dump of current error, for later analysis */
5626 devlink_health_do_dump(reporter
, priv_ctx
, NULL
);
5627 mutex_unlock(&reporter
->dump_lock
);
5630 if (reporter
->auto_recover
)
5631 return devlink_health_reporter_recover(reporter
,
5636 EXPORT_SYMBOL_GPL(devlink_health_report
);
5638 static struct devlink_health_reporter
*
5639 devlink_health_reporter_get_from_attrs(struct devlink
*devlink
,
5640 struct nlattr
**attrs
)
5642 struct devlink_health_reporter
*reporter
;
5643 char *reporter_name
;
5645 if (!attrs
[DEVLINK_ATTR_HEALTH_REPORTER_NAME
])
5648 reporter_name
= nla_data(attrs
[DEVLINK_ATTR_HEALTH_REPORTER_NAME
]);
5649 mutex_lock(&devlink
->reporters_lock
);
5650 reporter
= devlink_health_reporter_find_by_name(devlink
, reporter_name
);
5652 refcount_inc(&reporter
->refcount
);
5653 mutex_unlock(&devlink
->reporters_lock
);
5657 static struct devlink_health_reporter
*
5658 devlink_health_reporter_get_from_info(struct devlink
*devlink
,
5659 struct genl_info
*info
)
5661 return devlink_health_reporter_get_from_attrs(devlink
, info
->attrs
);
5664 static struct devlink_health_reporter
*
5665 devlink_health_reporter_get_from_cb(struct netlink_callback
*cb
)
5667 const struct genl_dumpit_info
*info
= genl_dumpit_info(cb
);
5668 struct devlink_health_reporter
*reporter
;
5669 struct nlattr
**attrs
= info
->attrs
;
5670 struct devlink
*devlink
;
5672 mutex_lock(&devlink_mutex
);
5673 devlink
= devlink_get_from_attrs(sock_net(cb
->skb
->sk
), attrs
);
5674 if (IS_ERR(devlink
))
5677 reporter
= devlink_health_reporter_get_from_attrs(devlink
, attrs
);
5678 mutex_unlock(&devlink_mutex
);
5681 mutex_unlock(&devlink_mutex
);
5686 devlink_health_reporter_state_update(struct devlink_health_reporter
*reporter
,
5687 enum devlink_health_reporter_state state
)
5689 if (WARN_ON(state
!= DEVLINK_HEALTH_REPORTER_STATE_HEALTHY
&&
5690 state
!= DEVLINK_HEALTH_REPORTER_STATE_ERROR
))
5693 if (reporter
->health_state
== state
)
5696 reporter
->health_state
= state
;
5697 trace_devlink_health_reporter_state_update(reporter
->devlink
,
5698 reporter
->ops
->name
, state
);
5699 devlink_recover_notify(reporter
, DEVLINK_CMD_HEALTH_REPORTER_RECOVER
);
5701 EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update
);
5703 static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff
*skb
,
5704 struct genl_info
*info
)
5706 struct devlink
*devlink
= info
->user_ptr
[0];
5707 struct devlink_health_reporter
*reporter
;
5708 struct sk_buff
*msg
;
5711 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5715 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
5721 err
= devlink_nl_health_reporter_fill(msg
, devlink
, reporter
,
5722 DEVLINK_CMD_HEALTH_REPORTER_GET
,
5723 info
->snd_portid
, info
->snd_seq
,
5730 err
= genlmsg_reply(msg
, info
);
5732 devlink_health_reporter_put(reporter
);
5737 devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff
*msg
,
5738 struct netlink_callback
*cb
)
5740 struct devlink_health_reporter
*reporter
;
5741 struct devlink
*devlink
;
5742 int start
= cb
->args
[0];
5746 mutex_lock(&devlink_mutex
);
5747 list_for_each_entry(devlink
, &devlink_list
, list
) {
5748 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
5750 mutex_lock(&devlink
->reporters_lock
);
5751 list_for_each_entry(reporter
, &devlink
->reporter_list
,
5757 err
= devlink_nl_health_reporter_fill(msg
, devlink
,
5759 DEVLINK_CMD_HEALTH_REPORTER_GET
,
5760 NETLINK_CB(cb
->skb
).portid
,
5764 mutex_unlock(&devlink
->reporters_lock
);
5769 mutex_unlock(&devlink
->reporters_lock
);
5772 mutex_unlock(&devlink_mutex
);
5779 devlink_nl_cmd_health_reporter_set_doit(struct sk_buff
*skb
,
5780 struct genl_info
*info
)
5782 struct devlink
*devlink
= info
->user_ptr
[0];
5783 struct devlink_health_reporter
*reporter
;
5786 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5790 if (!reporter
->ops
->recover
&&
5791 (info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
] ||
5792 info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
])) {
5796 if (!reporter
->ops
->dump
&&
5797 info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP
]) {
5802 if (info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
])
5803 reporter
->graceful_period
=
5804 nla_get_u64(info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
]);
5806 if (info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
])
5807 reporter
->auto_recover
=
5808 nla_get_u8(info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
]);
5810 if (info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP
])
5811 reporter
->auto_dump
=
5812 nla_get_u8(info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP
]);
5814 devlink_health_reporter_put(reporter
);
5817 devlink_health_reporter_put(reporter
);
5821 static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff
*skb
,
5822 struct genl_info
*info
)
5824 struct devlink
*devlink
= info
->user_ptr
[0];
5825 struct devlink_health_reporter
*reporter
;
5828 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5832 err
= devlink_health_reporter_recover(reporter
, NULL
, info
->extack
);
5834 devlink_health_reporter_put(reporter
);
5838 static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff
*skb
,
5839 struct genl_info
*info
)
5841 struct devlink
*devlink
= info
->user_ptr
[0];
5842 struct devlink_health_reporter
*reporter
;
5843 struct devlink_fmsg
*fmsg
;
5846 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5850 if (!reporter
->ops
->diagnose
) {
5851 devlink_health_reporter_put(reporter
);
5855 fmsg
= devlink_fmsg_alloc();
5857 devlink_health_reporter_put(reporter
);
5861 err
= devlink_fmsg_obj_nest_start(fmsg
);
5865 err
= reporter
->ops
->diagnose(reporter
, fmsg
, info
->extack
);
5869 err
= devlink_fmsg_obj_nest_end(fmsg
);
5873 err
= devlink_fmsg_snd(fmsg
, info
,
5874 DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE
, 0);
5877 devlink_fmsg_free(fmsg
);
5878 devlink_health_reporter_put(reporter
);
5883 devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff
*skb
,
5884 struct netlink_callback
*cb
)
5886 struct devlink_health_reporter
*reporter
;
5887 u64 start
= cb
->args
[0];
5890 reporter
= devlink_health_reporter_get_from_cb(cb
);
5894 if (!reporter
->ops
->dump
) {
5898 mutex_lock(&reporter
->dump_lock
);
5900 err
= devlink_health_do_dump(reporter
, NULL
, cb
->extack
);
5903 cb
->args
[1] = reporter
->dump_ts
;
5905 if (!reporter
->dump_fmsg
|| cb
->args
[1] != reporter
->dump_ts
) {
5906 NL_SET_ERR_MSG_MOD(cb
->extack
, "Dump trampled, please retry");
5911 err
= devlink_fmsg_dumpit(reporter
->dump_fmsg
, skb
, cb
,
5912 DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET
);
5914 mutex_unlock(&reporter
->dump_lock
);
5916 devlink_health_reporter_put(reporter
);
5921 devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff
*skb
,
5922 struct genl_info
*info
)
5924 struct devlink
*devlink
= info
->user_ptr
[0];
5925 struct devlink_health_reporter
*reporter
;
5927 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5931 if (!reporter
->ops
->dump
) {
5932 devlink_health_reporter_put(reporter
);
5936 mutex_lock(&reporter
->dump_lock
);
5937 devlink_health_dump_clear(reporter
);
5938 mutex_unlock(&reporter
->dump_lock
);
5939 devlink_health_reporter_put(reporter
);
5943 struct devlink_stats
{
5946 struct u64_stats_sync syncp
;
5950 * struct devlink_trap_policer_item - Packet trap policer attributes.
5951 * @policer: Immutable packet trap policer attributes.
5952 * @rate: Rate in packets / sec.
5953 * @burst: Burst size in packets.
5954 * @list: trap_policer_list member.
5956 * Describes packet trap policer attributes. Created by devlink during trap
5957 * policer registration.
5959 struct devlink_trap_policer_item
{
5960 const struct devlink_trap_policer
*policer
;
5963 struct list_head list
;
5967 * struct devlink_trap_group_item - Packet trap group attributes.
5968 * @group: Immutable packet trap group attributes.
5969 * @policer_item: Associated policer item. Can be NULL.
5970 * @list: trap_group_list member.
5971 * @stats: Trap group statistics.
5973 * Describes packet trap group attributes. Created by devlink during trap
5974 * group registration.
5976 struct devlink_trap_group_item
{
5977 const struct devlink_trap_group
*group
;
5978 struct devlink_trap_policer_item
*policer_item
;
5979 struct list_head list
;
5980 struct devlink_stats __percpu
*stats
;
5984 * struct devlink_trap_item - Packet trap attributes.
5985 * @trap: Immutable packet trap attributes.
5986 * @group_item: Associated group item.
5987 * @list: trap_list member.
5988 * @action: Trap action.
5989 * @stats: Trap statistics.
5990 * @priv: Driver private information.
5992 * Describes both mutable and immutable packet trap attributes. Created by
5993 * devlink during trap registration and used for all trap related operations.
5995 struct devlink_trap_item
{
5996 const struct devlink_trap
*trap
;
5997 struct devlink_trap_group_item
*group_item
;
5998 struct list_head list
;
5999 enum devlink_trap_action action
;
6000 struct devlink_stats __percpu
*stats
;
6004 static struct devlink_trap_policer_item
*
6005 devlink_trap_policer_item_lookup(struct devlink
*devlink
, u32 id
)
6007 struct devlink_trap_policer_item
*policer_item
;
6009 list_for_each_entry(policer_item
, &devlink
->trap_policer_list
, list
) {
6010 if (policer_item
->policer
->id
== id
)
6011 return policer_item
;
6017 static struct devlink_trap_item
*
6018 devlink_trap_item_lookup(struct devlink
*devlink
, const char *name
)
6020 struct devlink_trap_item
*trap_item
;
6022 list_for_each_entry(trap_item
, &devlink
->trap_list
, list
) {
6023 if (!strcmp(trap_item
->trap
->name
, name
))
6030 static struct devlink_trap_item
*
6031 devlink_trap_item_get_from_info(struct devlink
*devlink
,
6032 struct genl_info
*info
)
6034 struct nlattr
*attr
;
6036 if (!info
->attrs
[DEVLINK_ATTR_TRAP_NAME
])
6038 attr
= info
->attrs
[DEVLINK_ATTR_TRAP_NAME
];
6040 return devlink_trap_item_lookup(devlink
, nla_data(attr
));
6044 devlink_trap_action_get_from_info(struct genl_info
*info
,
6045 enum devlink_trap_action
*p_trap_action
)
6049 val
= nla_get_u8(info
->attrs
[DEVLINK_ATTR_TRAP_ACTION
]);
6051 case DEVLINK_TRAP_ACTION_DROP
: /* fall-through */
6052 case DEVLINK_TRAP_ACTION_TRAP
: /* fall-through */
6053 case DEVLINK_TRAP_ACTION_MIRROR
:
6054 *p_trap_action
= val
;
6063 static int devlink_trap_metadata_put(struct sk_buff
*msg
,
6064 const struct devlink_trap
*trap
)
6066 struct nlattr
*attr
;
6068 attr
= nla_nest_start(msg
, DEVLINK_ATTR_TRAP_METADATA
);
6072 if ((trap
->metadata_cap
& DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT
) &&
6073 nla_put_flag(msg
, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT
))
6074 goto nla_put_failure
;
6075 if ((trap
->metadata_cap
& DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE
) &&
6076 nla_put_flag(msg
, DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE
))
6077 goto nla_put_failure
;
6079 nla_nest_end(msg
, attr
);
6084 nla_nest_cancel(msg
, attr
);
6088 static void devlink_trap_stats_read(struct devlink_stats __percpu
*trap_stats
,
6089 struct devlink_stats
*stats
)
6093 memset(stats
, 0, sizeof(*stats
));
6094 for_each_possible_cpu(i
) {
6095 struct devlink_stats
*cpu_stats
;
6096 u64 rx_packets
, rx_bytes
;
6099 cpu_stats
= per_cpu_ptr(trap_stats
, i
);
6101 start
= u64_stats_fetch_begin_irq(&cpu_stats
->syncp
);
6102 rx_packets
= cpu_stats
->rx_packets
;
6103 rx_bytes
= cpu_stats
->rx_bytes
;
6104 } while (u64_stats_fetch_retry_irq(&cpu_stats
->syncp
, start
));
6106 stats
->rx_packets
+= rx_packets
;
6107 stats
->rx_bytes
+= rx_bytes
;
6111 static int devlink_trap_stats_put(struct sk_buff
*msg
,
6112 struct devlink_stats __percpu
*trap_stats
)
6114 struct devlink_stats stats
;
6115 struct nlattr
*attr
;
6117 devlink_trap_stats_read(trap_stats
, &stats
);
6119 attr
= nla_nest_start(msg
, DEVLINK_ATTR_STATS
);
6123 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_STATS_RX_PACKETS
,
6124 stats
.rx_packets
, DEVLINK_ATTR_PAD
))
6125 goto nla_put_failure
;
6127 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_STATS_RX_BYTES
,
6128 stats
.rx_bytes
, DEVLINK_ATTR_PAD
))
6129 goto nla_put_failure
;
6131 nla_nest_end(msg
, attr
);
6136 nla_nest_cancel(msg
, attr
);
6140 static int devlink_nl_trap_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
6141 const struct devlink_trap_item
*trap_item
,
6142 enum devlink_command cmd
, u32 portid
, u32 seq
,
6145 struct devlink_trap_group_item
*group_item
= trap_item
->group_item
;
6149 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
6153 if (devlink_nl_put_handle(msg
, devlink
))
6154 goto nla_put_failure
;
6156 if (nla_put_string(msg
, DEVLINK_ATTR_TRAP_GROUP_NAME
,
6157 group_item
->group
->name
))
6158 goto nla_put_failure
;
6160 if (nla_put_string(msg
, DEVLINK_ATTR_TRAP_NAME
, trap_item
->trap
->name
))
6161 goto nla_put_failure
;
6163 if (nla_put_u8(msg
, DEVLINK_ATTR_TRAP_TYPE
, trap_item
->trap
->type
))
6164 goto nla_put_failure
;
6166 if (trap_item
->trap
->generic
&&
6167 nla_put_flag(msg
, DEVLINK_ATTR_TRAP_GENERIC
))
6168 goto nla_put_failure
;
6170 if (nla_put_u8(msg
, DEVLINK_ATTR_TRAP_ACTION
, trap_item
->action
))
6171 goto nla_put_failure
;
6173 err
= devlink_trap_metadata_put(msg
, trap_item
->trap
);
6175 goto nla_put_failure
;
6177 err
= devlink_trap_stats_put(msg
, trap_item
->stats
);
6179 goto nla_put_failure
;
6181 genlmsg_end(msg
, hdr
);
6186 genlmsg_cancel(msg
, hdr
);
6190 static int devlink_nl_cmd_trap_get_doit(struct sk_buff
*skb
,
6191 struct genl_info
*info
)
6193 struct netlink_ext_ack
*extack
= info
->extack
;
6194 struct devlink
*devlink
= info
->user_ptr
[0];
6195 struct devlink_trap_item
*trap_item
;
6196 struct sk_buff
*msg
;
6199 if (list_empty(&devlink
->trap_list
))
6202 trap_item
= devlink_trap_item_get_from_info(devlink
, info
);
6204 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap");
6208 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
6212 err
= devlink_nl_trap_fill(msg
, devlink
, trap_item
,
6213 DEVLINK_CMD_TRAP_NEW
, info
->snd_portid
,
6218 return genlmsg_reply(msg
, info
);
6225 static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff
*msg
,
6226 struct netlink_callback
*cb
)
6228 struct devlink_trap_item
*trap_item
;
6229 struct devlink
*devlink
;
6230 int start
= cb
->args
[0];
6234 mutex_lock(&devlink_mutex
);
6235 list_for_each_entry(devlink
, &devlink_list
, list
) {
6236 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
6238 mutex_lock(&devlink
->lock
);
6239 list_for_each_entry(trap_item
, &devlink
->trap_list
, list
) {
6244 err
= devlink_nl_trap_fill(msg
, devlink
, trap_item
,
6245 DEVLINK_CMD_TRAP_NEW
,
6246 NETLINK_CB(cb
->skb
).portid
,
6250 mutex_unlock(&devlink
->lock
);
6255 mutex_unlock(&devlink
->lock
);
6258 mutex_unlock(&devlink_mutex
);
6264 static int __devlink_trap_action_set(struct devlink
*devlink
,
6265 struct devlink_trap_item
*trap_item
,
6266 enum devlink_trap_action trap_action
,
6267 struct netlink_ext_ack
*extack
)
6271 if (trap_item
->action
!= trap_action
&&
6272 trap_item
->trap
->type
!= DEVLINK_TRAP_TYPE_DROP
) {
6273 NL_SET_ERR_MSG_MOD(extack
, "Cannot change action of non-drop traps. Skipping");
6277 err
= devlink
->ops
->trap_action_set(devlink
, trap_item
->trap
,
6282 trap_item
->action
= trap_action
;
6287 static int devlink_trap_action_set(struct devlink
*devlink
,
6288 struct devlink_trap_item
*trap_item
,
6289 struct genl_info
*info
)
6291 enum devlink_trap_action trap_action
;
6294 if (!info
->attrs
[DEVLINK_ATTR_TRAP_ACTION
])
6297 err
= devlink_trap_action_get_from_info(info
, &trap_action
);
6299 NL_SET_ERR_MSG_MOD(info
->extack
, "Invalid trap action");
6303 return __devlink_trap_action_set(devlink
, trap_item
, trap_action
,
6307 static int devlink_nl_cmd_trap_set_doit(struct sk_buff
*skb
,
6308 struct genl_info
*info
)
6310 struct netlink_ext_ack
*extack
= info
->extack
;
6311 struct devlink
*devlink
= info
->user_ptr
[0];
6312 struct devlink_trap_item
*trap_item
;
6315 if (list_empty(&devlink
->trap_list
))
6318 trap_item
= devlink_trap_item_get_from_info(devlink
, info
);
6320 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap");
6324 err
= devlink_trap_action_set(devlink
, trap_item
, info
);
6331 static struct devlink_trap_group_item
*
6332 devlink_trap_group_item_lookup(struct devlink
*devlink
, const char *name
)
6334 struct devlink_trap_group_item
*group_item
;
6336 list_for_each_entry(group_item
, &devlink
->trap_group_list
, list
) {
6337 if (!strcmp(group_item
->group
->name
, name
))
6344 static struct devlink_trap_group_item
*
6345 devlink_trap_group_item_lookup_by_id(struct devlink
*devlink
, u16 id
)
6347 struct devlink_trap_group_item
*group_item
;
6349 list_for_each_entry(group_item
, &devlink
->trap_group_list
, list
) {
6350 if (group_item
->group
->id
== id
)
6357 static struct devlink_trap_group_item
*
6358 devlink_trap_group_item_get_from_info(struct devlink
*devlink
,
6359 struct genl_info
*info
)
6363 if (!info
->attrs
[DEVLINK_ATTR_TRAP_GROUP_NAME
])
6365 name
= nla_data(info
->attrs
[DEVLINK_ATTR_TRAP_GROUP_NAME
]);
6367 return devlink_trap_group_item_lookup(devlink
, name
);
6371 devlink_nl_trap_group_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
6372 const struct devlink_trap_group_item
*group_item
,
6373 enum devlink_command cmd
, u32 portid
, u32 seq
,
6379 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
6383 if (devlink_nl_put_handle(msg
, devlink
))
6384 goto nla_put_failure
;
6386 if (nla_put_string(msg
, DEVLINK_ATTR_TRAP_GROUP_NAME
,
6387 group_item
->group
->name
))
6388 goto nla_put_failure
;
6390 if (group_item
->group
->generic
&&
6391 nla_put_flag(msg
, DEVLINK_ATTR_TRAP_GENERIC
))
6392 goto nla_put_failure
;
6394 if (group_item
->policer_item
&&
6395 nla_put_u32(msg
, DEVLINK_ATTR_TRAP_POLICER_ID
,
6396 group_item
->policer_item
->policer
->id
))
6397 goto nla_put_failure
;
6399 err
= devlink_trap_stats_put(msg
, group_item
->stats
);
6401 goto nla_put_failure
;
6403 genlmsg_end(msg
, hdr
);
6408 genlmsg_cancel(msg
, hdr
);
6412 static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff
*skb
,
6413 struct genl_info
*info
)
6415 struct netlink_ext_ack
*extack
= info
->extack
;
6416 struct devlink
*devlink
= info
->user_ptr
[0];
6417 struct devlink_trap_group_item
*group_item
;
6418 struct sk_buff
*msg
;
6421 if (list_empty(&devlink
->trap_group_list
))
6424 group_item
= devlink_trap_group_item_get_from_info(devlink
, info
);
6426 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap group");
6430 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
6434 err
= devlink_nl_trap_group_fill(msg
, devlink
, group_item
,
6435 DEVLINK_CMD_TRAP_GROUP_NEW
,
6436 info
->snd_portid
, info
->snd_seq
, 0);
6438 goto err_trap_group_fill
;
6440 return genlmsg_reply(msg
, info
);
6442 err_trap_group_fill
:
6447 static int devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff
*msg
,
6448 struct netlink_callback
*cb
)
6450 enum devlink_command cmd
= DEVLINK_CMD_TRAP_GROUP_NEW
;
6451 struct devlink_trap_group_item
*group_item
;
6452 u32 portid
= NETLINK_CB(cb
->skb
).portid
;
6453 struct devlink
*devlink
;
6454 int start
= cb
->args
[0];
6458 mutex_lock(&devlink_mutex
);
6459 list_for_each_entry(devlink
, &devlink_list
, list
) {
6460 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
6462 mutex_lock(&devlink
->lock
);
6463 list_for_each_entry(group_item
, &devlink
->trap_group_list
,
6469 err
= devlink_nl_trap_group_fill(msg
, devlink
,
6475 mutex_unlock(&devlink
->lock
);
6480 mutex_unlock(&devlink
->lock
);
6483 mutex_unlock(&devlink_mutex
);
6490 __devlink_trap_group_action_set(struct devlink
*devlink
,
6491 struct devlink_trap_group_item
*group_item
,
6492 enum devlink_trap_action trap_action
,
6493 struct netlink_ext_ack
*extack
)
6495 const char *group_name
= group_item
->group
->name
;
6496 struct devlink_trap_item
*trap_item
;
6499 list_for_each_entry(trap_item
, &devlink
->trap_list
, list
) {
6500 if (strcmp(trap_item
->group_item
->group
->name
, group_name
))
6502 err
= __devlink_trap_action_set(devlink
, trap_item
,
6503 trap_action
, extack
);
6512 devlink_trap_group_action_set(struct devlink
*devlink
,
6513 struct devlink_trap_group_item
*group_item
,
6514 struct genl_info
*info
, bool *p_modified
)
6516 enum devlink_trap_action trap_action
;
6519 if (!info
->attrs
[DEVLINK_ATTR_TRAP_ACTION
])
6522 err
= devlink_trap_action_get_from_info(info
, &trap_action
);
6524 NL_SET_ERR_MSG_MOD(info
->extack
, "Invalid trap action");
6528 err
= __devlink_trap_group_action_set(devlink
, group_item
, trap_action
,
6538 static int devlink_trap_group_set(struct devlink
*devlink
,
6539 struct devlink_trap_group_item
*group_item
,
6540 struct genl_info
*info
)
6542 struct devlink_trap_policer_item
*policer_item
;
6543 struct netlink_ext_ack
*extack
= info
->extack
;
6544 const struct devlink_trap_policer
*policer
;
6545 struct nlattr
**attrs
= info
->attrs
;
6548 if (!attrs
[DEVLINK_ATTR_TRAP_POLICER_ID
])
6551 if (!devlink
->ops
->trap_group_set
)
6554 policer_item
= group_item
->policer_item
;
6555 if (attrs
[DEVLINK_ATTR_TRAP_POLICER_ID
]) {
6558 policer_id
= nla_get_u32(attrs
[DEVLINK_ATTR_TRAP_POLICER_ID
]);
6559 policer_item
= devlink_trap_policer_item_lookup(devlink
,
6561 if (policer_id
&& !policer_item
) {
6562 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap policer");
6566 policer
= policer_item
? policer_item
->policer
: NULL
;
6568 err
= devlink
->ops
->trap_group_set(devlink
, group_item
->group
, policer
);
6572 group_item
->policer_item
= policer_item
;
6577 static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff
*skb
,
6578 struct genl_info
*info
)
6580 struct netlink_ext_ack
*extack
= info
->extack
;
6581 struct devlink
*devlink
= info
->user_ptr
[0];
6582 struct devlink_trap_group_item
*group_item
;
6583 bool modified
= false;
6586 if (list_empty(&devlink
->trap_group_list
))
6589 group_item
= devlink_trap_group_item_get_from_info(devlink
, info
);
6591 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap group");
6595 err
= devlink_trap_group_action_set(devlink
, group_item
, info
,
6600 err
= devlink_trap_group_set(devlink
, group_item
, info
);
6602 goto err_trap_group_set
;
6608 NL_SET_ERR_MSG_MOD(extack
, "Trap group set failed, but some changes were committed already");
6612 static struct devlink_trap_policer_item
*
6613 devlink_trap_policer_item_get_from_info(struct devlink
*devlink
,
6614 struct genl_info
*info
)
6618 if (!info
->attrs
[DEVLINK_ATTR_TRAP_POLICER_ID
])
6620 id
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_TRAP_POLICER_ID
]);
6622 return devlink_trap_policer_item_lookup(devlink
, id
);
6626 devlink_trap_policer_stats_put(struct sk_buff
*msg
, struct devlink
*devlink
,
6627 const struct devlink_trap_policer
*policer
)
6629 struct nlattr
*attr
;
6633 if (!devlink
->ops
->trap_policer_counter_get
)
6636 err
= devlink
->ops
->trap_policer_counter_get(devlink
, policer
, &drops
);
6640 attr
= nla_nest_start(msg
, DEVLINK_ATTR_STATS
);
6644 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_STATS_RX_DROPPED
, drops
,
6646 goto nla_put_failure
;
6648 nla_nest_end(msg
, attr
);
6653 nla_nest_cancel(msg
, attr
);
6658 devlink_nl_trap_policer_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
6659 const struct devlink_trap_policer_item
*policer_item
,
6660 enum devlink_command cmd
, u32 portid
, u32 seq
,
6666 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
6670 if (devlink_nl_put_handle(msg
, devlink
))
6671 goto nla_put_failure
;
6673 if (nla_put_u32(msg
, DEVLINK_ATTR_TRAP_POLICER_ID
,
6674 policer_item
->policer
->id
))
6675 goto nla_put_failure
;
6677 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_TRAP_POLICER_RATE
,
6678 policer_item
->rate
, DEVLINK_ATTR_PAD
))
6679 goto nla_put_failure
;
6681 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_TRAP_POLICER_BURST
,
6682 policer_item
->burst
, DEVLINK_ATTR_PAD
))
6683 goto nla_put_failure
;
6685 err
= devlink_trap_policer_stats_put(msg
, devlink
,
6686 policer_item
->policer
);
6688 goto nla_put_failure
;
6690 genlmsg_end(msg
, hdr
);
6695 genlmsg_cancel(msg
, hdr
);
6699 static int devlink_nl_cmd_trap_policer_get_doit(struct sk_buff
*skb
,
6700 struct genl_info
*info
)
6702 struct devlink_trap_policer_item
*policer_item
;
6703 struct netlink_ext_ack
*extack
= info
->extack
;
6704 struct devlink
*devlink
= info
->user_ptr
[0];
6705 struct sk_buff
*msg
;
6708 if (list_empty(&devlink
->trap_policer_list
))
6711 policer_item
= devlink_trap_policer_item_get_from_info(devlink
, info
);
6712 if (!policer_item
) {
6713 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap policer");
6717 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
6721 err
= devlink_nl_trap_policer_fill(msg
, devlink
, policer_item
,
6722 DEVLINK_CMD_TRAP_POLICER_NEW
,
6723 info
->snd_portid
, info
->snd_seq
, 0);
6725 goto err_trap_policer_fill
;
6727 return genlmsg_reply(msg
, info
);
6729 err_trap_policer_fill
:
6734 static int devlink_nl_cmd_trap_policer_get_dumpit(struct sk_buff
*msg
,
6735 struct netlink_callback
*cb
)
6737 enum devlink_command cmd
= DEVLINK_CMD_TRAP_POLICER_NEW
;
6738 struct devlink_trap_policer_item
*policer_item
;
6739 u32 portid
= NETLINK_CB(cb
->skb
).portid
;
6740 struct devlink
*devlink
;
6741 int start
= cb
->args
[0];
6745 mutex_lock(&devlink_mutex
);
6746 list_for_each_entry(devlink
, &devlink_list
, list
) {
6747 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
6749 mutex_lock(&devlink
->lock
);
6750 list_for_each_entry(policer_item
, &devlink
->trap_policer_list
,
6756 err
= devlink_nl_trap_policer_fill(msg
, devlink
,
6762 mutex_unlock(&devlink
->lock
);
6767 mutex_unlock(&devlink
->lock
);
6770 mutex_unlock(&devlink_mutex
);
6777 devlink_trap_policer_set(struct devlink
*devlink
,
6778 struct devlink_trap_policer_item
*policer_item
,
6779 struct genl_info
*info
)
6781 struct netlink_ext_ack
*extack
= info
->extack
;
6782 struct nlattr
**attrs
= info
->attrs
;
6786 rate
= policer_item
->rate
;
6787 burst
= policer_item
->burst
;
6789 if (attrs
[DEVLINK_ATTR_TRAP_POLICER_RATE
])
6790 rate
= nla_get_u64(attrs
[DEVLINK_ATTR_TRAP_POLICER_RATE
]);
6792 if (attrs
[DEVLINK_ATTR_TRAP_POLICER_BURST
])
6793 burst
= nla_get_u64(attrs
[DEVLINK_ATTR_TRAP_POLICER_BURST
]);
6795 if (rate
< policer_item
->policer
->min_rate
) {
6796 NL_SET_ERR_MSG_MOD(extack
, "Policer rate lower than limit");
6800 if (rate
> policer_item
->policer
->max_rate
) {
6801 NL_SET_ERR_MSG_MOD(extack
, "Policer rate higher than limit");
6805 if (burst
< policer_item
->policer
->min_burst
) {
6806 NL_SET_ERR_MSG_MOD(extack
, "Policer burst size lower than limit");
6810 if (burst
> policer_item
->policer
->max_burst
) {
6811 NL_SET_ERR_MSG_MOD(extack
, "Policer burst size higher than limit");
6815 err
= devlink
->ops
->trap_policer_set(devlink
, policer_item
->policer
,
6816 rate
, burst
, info
->extack
);
6820 policer_item
->rate
= rate
;
6821 policer_item
->burst
= burst
;
6826 static int devlink_nl_cmd_trap_policer_set_doit(struct sk_buff
*skb
,
6827 struct genl_info
*info
)
6829 struct devlink_trap_policer_item
*policer_item
;
6830 struct netlink_ext_ack
*extack
= info
->extack
;
6831 struct devlink
*devlink
= info
->user_ptr
[0];
6833 if (list_empty(&devlink
->trap_policer_list
))
6836 if (!devlink
->ops
->trap_policer_set
)
6839 policer_item
= devlink_trap_policer_item_get_from_info(devlink
, info
);
6840 if (!policer_item
) {
6841 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap policer");
6845 return devlink_trap_policer_set(devlink
, policer_item
, info
);
6848 static const struct nla_policy devlink_nl_policy
[DEVLINK_ATTR_MAX
+ 1] = {
6849 [DEVLINK_ATTR_UNSPEC
] = { .strict_start_type
=
6850 DEVLINK_ATTR_TRAP_POLICER_ID
},
6851 [DEVLINK_ATTR_BUS_NAME
] = { .type
= NLA_NUL_STRING
},
6852 [DEVLINK_ATTR_DEV_NAME
] = { .type
= NLA_NUL_STRING
},
6853 [DEVLINK_ATTR_PORT_INDEX
] = { .type
= NLA_U32
},
6854 [DEVLINK_ATTR_PORT_TYPE
] = { .type
= NLA_U16
},
6855 [DEVLINK_ATTR_PORT_SPLIT_COUNT
] = { .type
= NLA_U32
},
6856 [DEVLINK_ATTR_SB_INDEX
] = { .type
= NLA_U32
},
6857 [DEVLINK_ATTR_SB_POOL_INDEX
] = { .type
= NLA_U16
},
6858 [DEVLINK_ATTR_SB_POOL_TYPE
] = { .type
= NLA_U8
},
6859 [DEVLINK_ATTR_SB_POOL_SIZE
] = { .type
= NLA_U32
},
6860 [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
] = { .type
= NLA_U8
},
6861 [DEVLINK_ATTR_SB_THRESHOLD
] = { .type
= NLA_U32
},
6862 [DEVLINK_ATTR_SB_TC_INDEX
] = { .type
= NLA_U16
},
6863 [DEVLINK_ATTR_ESWITCH_MODE
] = { .type
= NLA_U16
},
6864 [DEVLINK_ATTR_ESWITCH_INLINE_MODE
] = { .type
= NLA_U8
},
6865 [DEVLINK_ATTR_ESWITCH_ENCAP_MODE
] = { .type
= NLA_U8
},
6866 [DEVLINK_ATTR_DPIPE_TABLE_NAME
] = { .type
= NLA_NUL_STRING
},
6867 [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
] = { .type
= NLA_U8
},
6868 [DEVLINK_ATTR_RESOURCE_ID
] = { .type
= NLA_U64
},
6869 [DEVLINK_ATTR_RESOURCE_SIZE
] = { .type
= NLA_U64
},
6870 [DEVLINK_ATTR_PARAM_NAME
] = { .type
= NLA_NUL_STRING
},
6871 [DEVLINK_ATTR_PARAM_TYPE
] = { .type
= NLA_U8
},
6872 [DEVLINK_ATTR_PARAM_VALUE_CMODE
] = { .type
= NLA_U8
},
6873 [DEVLINK_ATTR_REGION_NAME
] = { .type
= NLA_NUL_STRING
},
6874 [DEVLINK_ATTR_REGION_SNAPSHOT_ID
] = { .type
= NLA_U32
},
6875 [DEVLINK_ATTR_REGION_CHUNK_ADDR
] = { .type
= NLA_U64
},
6876 [DEVLINK_ATTR_REGION_CHUNK_LEN
] = { .type
= NLA_U64
},
6877 [DEVLINK_ATTR_HEALTH_REPORTER_NAME
] = { .type
= NLA_NUL_STRING
},
6878 [DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
] = { .type
= NLA_U64
},
6879 [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
] = { .type
= NLA_U8
},
6880 [DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME
] = { .type
= NLA_NUL_STRING
},
6881 [DEVLINK_ATTR_FLASH_UPDATE_COMPONENT
] = { .type
= NLA_NUL_STRING
},
6882 [DEVLINK_ATTR_TRAP_NAME
] = { .type
= NLA_NUL_STRING
},
6883 [DEVLINK_ATTR_TRAP_ACTION
] = { .type
= NLA_U8
},
6884 [DEVLINK_ATTR_TRAP_GROUP_NAME
] = { .type
= NLA_NUL_STRING
},
6885 [DEVLINK_ATTR_NETNS_PID
] = { .type
= NLA_U32
},
6886 [DEVLINK_ATTR_NETNS_FD
] = { .type
= NLA_U32
},
6887 [DEVLINK_ATTR_NETNS_ID
] = { .type
= NLA_U32
},
6888 [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP
] = { .type
= NLA_U8
},
6889 [DEVLINK_ATTR_TRAP_POLICER_ID
] = { .type
= NLA_U32
},
6890 [DEVLINK_ATTR_TRAP_POLICER_RATE
] = { .type
= NLA_U64
},
6891 [DEVLINK_ATTR_TRAP_POLICER_BURST
] = { .type
= NLA_U64
},
6892 [DEVLINK_ATTR_PORT_FUNCTION
] = { .type
= NLA_NESTED
},
6895 static const struct genl_ops devlink_nl_ops
[] = {
6897 .cmd
= DEVLINK_CMD_GET
,
6898 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6899 .doit
= devlink_nl_cmd_get_doit
,
6900 .dumpit
= devlink_nl_cmd_get_dumpit
,
6901 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
6902 /* can be retrieved by unprivileged users */
6905 .cmd
= DEVLINK_CMD_PORT_GET
,
6906 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6907 .doit
= devlink_nl_cmd_port_get_doit
,
6908 .dumpit
= devlink_nl_cmd_port_get_dumpit
,
6909 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
6910 /* can be retrieved by unprivileged users */
6913 .cmd
= DEVLINK_CMD_PORT_SET
,
6914 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6915 .doit
= devlink_nl_cmd_port_set_doit
,
6916 .flags
= GENL_ADMIN_PERM
,
6917 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
6920 .cmd
= DEVLINK_CMD_PORT_SPLIT
,
6921 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6922 .doit
= devlink_nl_cmd_port_split_doit
,
6923 .flags
= GENL_ADMIN_PERM
,
6924 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6925 DEVLINK_NL_FLAG_NO_LOCK
,
6928 .cmd
= DEVLINK_CMD_PORT_UNSPLIT
,
6929 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6930 .doit
= devlink_nl_cmd_port_unsplit_doit
,
6931 .flags
= GENL_ADMIN_PERM
,
6932 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6933 DEVLINK_NL_FLAG_NO_LOCK
,
6936 .cmd
= DEVLINK_CMD_SB_GET
,
6937 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6938 .doit
= devlink_nl_cmd_sb_get_doit
,
6939 .dumpit
= devlink_nl_cmd_sb_get_dumpit
,
6940 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6941 DEVLINK_NL_FLAG_NEED_SB
,
6942 /* can be retrieved by unprivileged users */
6945 .cmd
= DEVLINK_CMD_SB_POOL_GET
,
6946 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6947 .doit
= devlink_nl_cmd_sb_pool_get_doit
,
6948 .dumpit
= devlink_nl_cmd_sb_pool_get_dumpit
,
6949 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6950 DEVLINK_NL_FLAG_NEED_SB
,
6951 /* can be retrieved by unprivileged users */
6954 .cmd
= DEVLINK_CMD_SB_POOL_SET
,
6955 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6956 .doit
= devlink_nl_cmd_sb_pool_set_doit
,
6957 .flags
= GENL_ADMIN_PERM
,
6958 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
6959 DEVLINK_NL_FLAG_NEED_SB
,
6962 .cmd
= DEVLINK_CMD_SB_PORT_POOL_GET
,
6963 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6964 .doit
= devlink_nl_cmd_sb_port_pool_get_doit
,
6965 .dumpit
= devlink_nl_cmd_sb_port_pool_get_dumpit
,
6966 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
6967 DEVLINK_NL_FLAG_NEED_SB
,
6968 /* can be retrieved by unprivileged users */
6971 .cmd
= DEVLINK_CMD_SB_PORT_POOL_SET
,
6972 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6973 .doit
= devlink_nl_cmd_sb_port_pool_set_doit
,
6974 .flags
= GENL_ADMIN_PERM
,
6975 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
6976 DEVLINK_NL_FLAG_NEED_SB
,
6979 .cmd
= DEVLINK_CMD_SB_TC_POOL_BIND_GET
,
6980 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6981 .doit
= devlink_nl_cmd_sb_tc_pool_bind_get_doit
,
6982 .dumpit
= devlink_nl_cmd_sb_tc_pool_bind_get_dumpit
,
6983 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
6984 DEVLINK_NL_FLAG_NEED_SB
,
6985 /* can be retrieved by unprivileged users */
6988 .cmd
= DEVLINK_CMD_SB_TC_POOL_BIND_SET
,
6989 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6990 .doit
= devlink_nl_cmd_sb_tc_pool_bind_set_doit
,
6991 .flags
= GENL_ADMIN_PERM
,
6992 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
6993 DEVLINK_NL_FLAG_NEED_SB
,
6996 .cmd
= DEVLINK_CMD_SB_OCC_SNAPSHOT
,
6997 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
6998 .doit
= devlink_nl_cmd_sb_occ_snapshot_doit
,
6999 .flags
= GENL_ADMIN_PERM
,
7000 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
7001 DEVLINK_NL_FLAG_NEED_SB
,
7004 .cmd
= DEVLINK_CMD_SB_OCC_MAX_CLEAR
,
7005 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7006 .doit
= devlink_nl_cmd_sb_occ_max_clear_doit
,
7007 .flags
= GENL_ADMIN_PERM
,
7008 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
7009 DEVLINK_NL_FLAG_NEED_SB
,
7012 .cmd
= DEVLINK_CMD_ESWITCH_GET
,
7013 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7014 .doit
= devlink_nl_cmd_eswitch_get_doit
,
7015 .flags
= GENL_ADMIN_PERM
,
7016 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
7017 DEVLINK_NL_FLAG_NO_LOCK
,
7020 .cmd
= DEVLINK_CMD_ESWITCH_SET
,
7021 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7022 .doit
= devlink_nl_cmd_eswitch_set_doit
,
7023 .flags
= GENL_ADMIN_PERM
,
7024 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
7025 DEVLINK_NL_FLAG_NO_LOCK
,
7028 .cmd
= DEVLINK_CMD_DPIPE_TABLE_GET
,
7029 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7030 .doit
= devlink_nl_cmd_dpipe_table_get
,
7031 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7032 /* can be retrieved by unprivileged users */
7035 .cmd
= DEVLINK_CMD_DPIPE_ENTRIES_GET
,
7036 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7037 .doit
= devlink_nl_cmd_dpipe_entries_get
,
7038 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7039 /* can be retrieved by unprivileged users */
7042 .cmd
= DEVLINK_CMD_DPIPE_HEADERS_GET
,
7043 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7044 .doit
= devlink_nl_cmd_dpipe_headers_get
,
7045 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7046 /* can be retrieved by unprivileged users */
7049 .cmd
= DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET
,
7050 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7051 .doit
= devlink_nl_cmd_dpipe_table_counters_set
,
7052 .flags
= GENL_ADMIN_PERM
,
7053 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7056 .cmd
= DEVLINK_CMD_RESOURCE_SET
,
7057 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7058 .doit
= devlink_nl_cmd_resource_set
,
7059 .flags
= GENL_ADMIN_PERM
,
7060 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7063 .cmd
= DEVLINK_CMD_RESOURCE_DUMP
,
7064 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7065 .doit
= devlink_nl_cmd_resource_dump
,
7066 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7067 /* can be retrieved by unprivileged users */
7070 .cmd
= DEVLINK_CMD_RELOAD
,
7071 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7072 .doit
= devlink_nl_cmd_reload
,
7073 .flags
= GENL_ADMIN_PERM
,
7074 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
7075 DEVLINK_NL_FLAG_NO_LOCK
,
7078 .cmd
= DEVLINK_CMD_PARAM_GET
,
7079 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7080 .doit
= devlink_nl_cmd_param_get_doit
,
7081 .dumpit
= devlink_nl_cmd_param_get_dumpit
,
7082 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7083 /* can be retrieved by unprivileged users */
7086 .cmd
= DEVLINK_CMD_PARAM_SET
,
7087 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7088 .doit
= devlink_nl_cmd_param_set_doit
,
7089 .flags
= GENL_ADMIN_PERM
,
7090 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7093 .cmd
= DEVLINK_CMD_PORT_PARAM_GET
,
7094 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7095 .doit
= devlink_nl_cmd_port_param_get_doit
,
7096 .dumpit
= devlink_nl_cmd_port_param_get_dumpit
,
7097 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
7098 /* can be retrieved by unprivileged users */
7101 .cmd
= DEVLINK_CMD_PORT_PARAM_SET
,
7102 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7103 .doit
= devlink_nl_cmd_port_param_set_doit
,
7104 .flags
= GENL_ADMIN_PERM
,
7105 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
7108 .cmd
= DEVLINK_CMD_REGION_GET
,
7109 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7110 .doit
= devlink_nl_cmd_region_get_doit
,
7111 .dumpit
= devlink_nl_cmd_region_get_dumpit
,
7112 .flags
= GENL_ADMIN_PERM
,
7113 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7116 .cmd
= DEVLINK_CMD_REGION_NEW
,
7117 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7118 .doit
= devlink_nl_cmd_region_new
,
7119 .flags
= GENL_ADMIN_PERM
,
7120 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7123 .cmd
= DEVLINK_CMD_REGION_DEL
,
7124 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7125 .doit
= devlink_nl_cmd_region_del
,
7126 .flags
= GENL_ADMIN_PERM
,
7127 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7130 .cmd
= DEVLINK_CMD_REGION_READ
,
7131 .validate
= GENL_DONT_VALIDATE_STRICT
|
7132 GENL_DONT_VALIDATE_DUMP_STRICT
,
7133 .dumpit
= devlink_nl_cmd_region_read_dumpit
,
7134 .flags
= GENL_ADMIN_PERM
,
7135 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7138 .cmd
= DEVLINK_CMD_INFO_GET
,
7139 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7140 .doit
= devlink_nl_cmd_info_get_doit
,
7141 .dumpit
= devlink_nl_cmd_info_get_dumpit
,
7142 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7143 /* can be retrieved by unprivileged users */
7146 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_GET
,
7147 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7148 .doit
= devlink_nl_cmd_health_reporter_get_doit
,
7149 .dumpit
= devlink_nl_cmd_health_reporter_get_dumpit
,
7150 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
7151 DEVLINK_NL_FLAG_NO_LOCK
,
7152 /* can be retrieved by unprivileged users */
7155 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_SET
,
7156 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7157 .doit
= devlink_nl_cmd_health_reporter_set_doit
,
7158 .flags
= GENL_ADMIN_PERM
,
7159 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
7160 DEVLINK_NL_FLAG_NO_LOCK
,
7163 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_RECOVER
,
7164 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7165 .doit
= devlink_nl_cmd_health_reporter_recover_doit
,
7166 .flags
= GENL_ADMIN_PERM
,
7167 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
7168 DEVLINK_NL_FLAG_NO_LOCK
,
7171 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE
,
7172 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7173 .doit
= devlink_nl_cmd_health_reporter_diagnose_doit
,
7174 .flags
= GENL_ADMIN_PERM
,
7175 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
7176 DEVLINK_NL_FLAG_NO_LOCK
,
7179 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET
,
7180 .validate
= GENL_DONT_VALIDATE_STRICT
|
7181 GENL_DONT_VALIDATE_DUMP_STRICT
,
7182 .dumpit
= devlink_nl_cmd_health_reporter_dump_get_dumpit
,
7183 .flags
= GENL_ADMIN_PERM
,
7184 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
7185 DEVLINK_NL_FLAG_NO_LOCK
,
7188 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR
,
7189 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7190 .doit
= devlink_nl_cmd_health_reporter_dump_clear_doit
,
7191 .flags
= GENL_ADMIN_PERM
,
7192 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
7193 DEVLINK_NL_FLAG_NO_LOCK
,
7196 .cmd
= DEVLINK_CMD_FLASH_UPDATE
,
7197 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7198 .doit
= devlink_nl_cmd_flash_update
,
7199 .flags
= GENL_ADMIN_PERM
,
7200 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7203 .cmd
= DEVLINK_CMD_TRAP_GET
,
7204 .doit
= devlink_nl_cmd_trap_get_doit
,
7205 .dumpit
= devlink_nl_cmd_trap_get_dumpit
,
7206 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7207 /* can be retrieved by unprivileged users */
7210 .cmd
= DEVLINK_CMD_TRAP_SET
,
7211 .doit
= devlink_nl_cmd_trap_set_doit
,
7212 .flags
= GENL_ADMIN_PERM
,
7213 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7216 .cmd
= DEVLINK_CMD_TRAP_GROUP_GET
,
7217 .doit
= devlink_nl_cmd_trap_group_get_doit
,
7218 .dumpit
= devlink_nl_cmd_trap_group_get_dumpit
,
7219 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7220 /* can be retrieved by unprivileged users */
7223 .cmd
= DEVLINK_CMD_TRAP_GROUP_SET
,
7224 .doit
= devlink_nl_cmd_trap_group_set_doit
,
7225 .flags
= GENL_ADMIN_PERM
,
7226 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7229 .cmd
= DEVLINK_CMD_TRAP_POLICER_GET
,
7230 .doit
= devlink_nl_cmd_trap_policer_get_doit
,
7231 .dumpit
= devlink_nl_cmd_trap_policer_get_dumpit
,
7232 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7233 /* can be retrieved by unprivileged users */
7236 .cmd
= DEVLINK_CMD_TRAP_POLICER_SET
,
7237 .doit
= devlink_nl_cmd_trap_policer_set_doit
,
7238 .flags
= GENL_ADMIN_PERM
,
7239 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7243 static struct genl_family devlink_nl_family __ro_after_init
= {
7244 .name
= DEVLINK_GENL_NAME
,
7245 .version
= DEVLINK_GENL_VERSION
,
7246 .maxattr
= DEVLINK_ATTR_MAX
,
7247 .policy
= devlink_nl_policy
,
7249 .pre_doit
= devlink_nl_pre_doit
,
7250 .post_doit
= devlink_nl_post_doit
,
7251 .module
= THIS_MODULE
,
7252 .ops
= devlink_nl_ops
,
7253 .n_ops
= ARRAY_SIZE(devlink_nl_ops
),
7254 .mcgrps
= devlink_nl_mcgrps
,
7255 .n_mcgrps
= ARRAY_SIZE(devlink_nl_mcgrps
),
7259 * devlink_alloc - Allocate new devlink instance resources
7262 * @priv_size: size of user private data
7264 * Allocate new devlink instance resources, including devlink index
7267 struct devlink
*devlink_alloc(const struct devlink_ops
*ops
, size_t priv_size
)
7269 struct devlink
*devlink
;
7274 devlink
= kzalloc(sizeof(*devlink
) + priv_size
, GFP_KERNEL
);
7278 xa_init_flags(&devlink
->snapshot_ids
, XA_FLAGS_ALLOC
);
7279 __devlink_net_set(devlink
, &init_net
);
7280 INIT_LIST_HEAD(&devlink
->port_list
);
7281 INIT_LIST_HEAD(&devlink
->sb_list
);
7282 INIT_LIST_HEAD_RCU(&devlink
->dpipe_table_list
);
7283 INIT_LIST_HEAD(&devlink
->resource_list
);
7284 INIT_LIST_HEAD(&devlink
->param_list
);
7285 INIT_LIST_HEAD(&devlink
->region_list
);
7286 INIT_LIST_HEAD(&devlink
->reporter_list
);
7287 INIT_LIST_HEAD(&devlink
->trap_list
);
7288 INIT_LIST_HEAD(&devlink
->trap_group_list
);
7289 INIT_LIST_HEAD(&devlink
->trap_policer_list
);
7290 mutex_init(&devlink
->lock
);
7291 mutex_init(&devlink
->reporters_lock
);
7294 EXPORT_SYMBOL_GPL(devlink_alloc
);
7297 * devlink_register - Register devlink instance
7300 * @dev: parent device
7302 int devlink_register(struct devlink
*devlink
, struct device
*dev
)
7304 mutex_lock(&devlink_mutex
);
7306 devlink
->registered
= true;
7307 list_add_tail(&devlink
->list
, &devlink_list
);
7308 devlink_notify(devlink
, DEVLINK_CMD_NEW
);
7309 mutex_unlock(&devlink_mutex
);
7312 EXPORT_SYMBOL_GPL(devlink_register
);
7315 * devlink_unregister - Unregister devlink instance
7319 void devlink_unregister(struct devlink
*devlink
)
7321 mutex_lock(&devlink_mutex
);
7322 WARN_ON(devlink_reload_supported(devlink
) &&
7323 devlink
->reload_enabled
);
7324 devlink_notify(devlink
, DEVLINK_CMD_DEL
);
7325 list_del(&devlink
->list
);
7326 mutex_unlock(&devlink_mutex
);
7328 EXPORT_SYMBOL_GPL(devlink_unregister
);
7331 * devlink_reload_enable - Enable reload of devlink instance
7335 * Should be called at end of device initialization
7336 * process when reload operation is supported.
7338 void devlink_reload_enable(struct devlink
*devlink
)
7340 mutex_lock(&devlink_mutex
);
7341 devlink
->reload_enabled
= true;
7342 mutex_unlock(&devlink_mutex
);
7344 EXPORT_SYMBOL_GPL(devlink_reload_enable
);
7347 * devlink_reload_disable - Disable reload of devlink instance
7351 * Should be called at the beginning of device cleanup
7352 * process when reload operation is supported.
7354 void devlink_reload_disable(struct devlink
*devlink
)
7356 mutex_lock(&devlink_mutex
);
7357 /* Mutex is taken which ensures that no reload operation is in
7358 * progress while setting up forbidded flag.
7360 devlink
->reload_enabled
= false;
7361 mutex_unlock(&devlink_mutex
);
7363 EXPORT_SYMBOL_GPL(devlink_reload_disable
);
7366 * devlink_free - Free devlink instance resources
7370 void devlink_free(struct devlink
*devlink
)
7372 mutex_destroy(&devlink
->reporters_lock
);
7373 mutex_destroy(&devlink
->lock
);
7374 WARN_ON(!list_empty(&devlink
->trap_policer_list
));
7375 WARN_ON(!list_empty(&devlink
->trap_group_list
));
7376 WARN_ON(!list_empty(&devlink
->trap_list
));
7377 WARN_ON(!list_empty(&devlink
->reporter_list
));
7378 WARN_ON(!list_empty(&devlink
->region_list
));
7379 WARN_ON(!list_empty(&devlink
->param_list
));
7380 WARN_ON(!list_empty(&devlink
->resource_list
));
7381 WARN_ON(!list_empty(&devlink
->dpipe_table_list
));
7382 WARN_ON(!list_empty(&devlink
->sb_list
));
7383 WARN_ON(!list_empty(&devlink
->port_list
));
7385 xa_destroy(&devlink
->snapshot_ids
);
7389 EXPORT_SYMBOL_GPL(devlink_free
);
7391 static void devlink_port_type_warn(struct work_struct
*work
)
7393 WARN(true, "Type was not set for devlink port.");
7396 static bool devlink_port_type_should_warn(struct devlink_port
*devlink_port
)
7398 /* Ignore CPU and DSA flavours. */
7399 return devlink_port
->attrs
.flavour
!= DEVLINK_PORT_FLAVOUR_CPU
&&
7400 devlink_port
->attrs
.flavour
!= DEVLINK_PORT_FLAVOUR_DSA
;
7403 #define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 3600)
7405 static void devlink_port_type_warn_schedule(struct devlink_port
*devlink_port
)
7407 if (!devlink_port_type_should_warn(devlink_port
))
7409 /* Schedule a work to WARN in case driver does not set port
7410 * type within timeout.
7412 schedule_delayed_work(&devlink_port
->type_warn_dw
,
7413 DEVLINK_PORT_TYPE_WARN_TIMEOUT
);
7416 static void devlink_port_type_warn_cancel(struct devlink_port
*devlink_port
)
7418 if (!devlink_port_type_should_warn(devlink_port
))
7420 cancel_delayed_work_sync(&devlink_port
->type_warn_dw
);
7424 * devlink_port_register - Register devlink port
7427 * @devlink_port: devlink port
7428 * @port_index: driver-specific numerical identifier of the port
7430 * Register devlink port with provided port index. User can use
7431 * any indexing, even hw-related one. devlink_port structure
7432 * is convenient to be embedded inside user driver private structure.
7433 * Note that the caller should take care of zeroing the devlink_port
7436 int devlink_port_register(struct devlink
*devlink
,
7437 struct devlink_port
*devlink_port
,
7438 unsigned int port_index
)
7440 mutex_lock(&devlink
->lock
);
7441 if (devlink_port_index_exists(devlink
, port_index
)) {
7442 mutex_unlock(&devlink
->lock
);
7445 devlink_port
->devlink
= devlink
;
7446 devlink_port
->index
= port_index
;
7447 devlink_port
->registered
= true;
7448 spin_lock_init(&devlink_port
->type_lock
);
7449 list_add_tail(&devlink_port
->list
, &devlink
->port_list
);
7450 INIT_LIST_HEAD(&devlink_port
->param_list
);
7451 mutex_unlock(&devlink
->lock
);
7452 INIT_DELAYED_WORK(&devlink_port
->type_warn_dw
, &devlink_port_type_warn
);
7453 devlink_port_type_warn_schedule(devlink_port
);
7454 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
7457 EXPORT_SYMBOL_GPL(devlink_port_register
);
7460 * devlink_port_unregister - Unregister devlink port
7462 * @devlink_port: devlink port
7464 void devlink_port_unregister(struct devlink_port
*devlink_port
)
7466 struct devlink
*devlink
= devlink_port
->devlink
;
7468 devlink_port_type_warn_cancel(devlink_port
);
7469 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_DEL
);
7470 mutex_lock(&devlink
->lock
);
7471 list_del(&devlink_port
->list
);
7472 mutex_unlock(&devlink
->lock
);
7474 EXPORT_SYMBOL_GPL(devlink_port_unregister
);
7476 static void __devlink_port_type_set(struct devlink_port
*devlink_port
,
7477 enum devlink_port_type type
,
7480 if (WARN_ON(!devlink_port
->registered
))
7482 devlink_port_type_warn_cancel(devlink_port
);
7483 spin_lock_bh(&devlink_port
->type_lock
);
7484 devlink_port
->type
= type
;
7485 devlink_port
->type_dev
= type_dev
;
7486 spin_unlock_bh(&devlink_port
->type_lock
);
7487 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
7491 * devlink_port_type_eth_set - Set port type to Ethernet
7493 * @devlink_port: devlink port
7494 * @netdev: related netdevice
7496 void devlink_port_type_eth_set(struct devlink_port
*devlink_port
,
7497 struct net_device
*netdev
)
7499 const struct net_device_ops
*ops
= netdev
->netdev_ops
;
7501 /* If driver registers devlink port, it should set devlink port
7502 * attributes accordingly so the compat functions are called
7503 * and the original ops are not used.
7505 if (ops
->ndo_get_phys_port_name
) {
7506 /* Some drivers use the same set of ndos for netdevs
7507 * that have devlink_port registered and also for
7508 * those who don't. Make sure that ndo_get_phys_port_name
7509 * returns -EOPNOTSUPP here in case it is defined.
7512 char name
[IFNAMSIZ
];
7515 err
= ops
->ndo_get_phys_port_name(netdev
, name
, sizeof(name
));
7516 WARN_ON(err
!= -EOPNOTSUPP
);
7518 if (ops
->ndo_get_port_parent_id
) {
7519 /* Some drivers use the same set of ndos for netdevs
7520 * that have devlink_port registered and also for
7521 * those who don't. Make sure that ndo_get_port_parent_id
7522 * returns -EOPNOTSUPP here in case it is defined.
7525 struct netdev_phys_item_id ppid
;
7528 err
= ops
->ndo_get_port_parent_id(netdev
, &ppid
);
7529 WARN_ON(err
!= -EOPNOTSUPP
);
7531 __devlink_port_type_set(devlink_port
, DEVLINK_PORT_TYPE_ETH
, netdev
);
7533 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set
);
7536 * devlink_port_type_ib_set - Set port type to InfiniBand
7538 * @devlink_port: devlink port
7539 * @ibdev: related IB device
7541 void devlink_port_type_ib_set(struct devlink_port
*devlink_port
,
7542 struct ib_device
*ibdev
)
7544 __devlink_port_type_set(devlink_port
, DEVLINK_PORT_TYPE_IB
, ibdev
);
7546 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set
);
7549 * devlink_port_type_clear - Clear port type
7551 * @devlink_port: devlink port
7553 void devlink_port_type_clear(struct devlink_port
*devlink_port
)
7555 __devlink_port_type_set(devlink_port
, DEVLINK_PORT_TYPE_NOTSET
, NULL
);
7556 devlink_port_type_warn_schedule(devlink_port
);
7558 EXPORT_SYMBOL_GPL(devlink_port_type_clear
);
7560 static int __devlink_port_attrs_set(struct devlink_port
*devlink_port
,
7561 enum devlink_port_flavour flavour
)
7563 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
7565 if (WARN_ON(devlink_port
->registered
))
7567 devlink_port
->attrs_set
= true;
7568 attrs
->flavour
= flavour
;
7569 if (attrs
->switch_id
.id_len
) {
7570 devlink_port
->switch_port
= true;
7571 if (WARN_ON(attrs
->switch_id
.id_len
> MAX_PHYS_ITEM_ID_LEN
))
7572 attrs
->switch_id
.id_len
= MAX_PHYS_ITEM_ID_LEN
;
7574 devlink_port
->switch_port
= false;
7580 * devlink_port_attrs_set - Set port attributes
7582 * @devlink_port: devlink port
7583 * @attrs: devlink port attrs
7585 void devlink_port_attrs_set(struct devlink_port
*devlink_port
,
7586 struct devlink_port_attrs
*attrs
)
7590 devlink_port
->attrs
= *attrs
;
7591 ret
= __devlink_port_attrs_set(devlink_port
, attrs
->flavour
);
7594 WARN_ON(attrs
->splittable
&& attrs
->split
);
7596 EXPORT_SYMBOL_GPL(devlink_port_attrs_set
);
7599 * devlink_port_attrs_pci_pf_set - Set PCI PF port attributes
7601 * @devlink_port: devlink port
7602 * @pf: associated PF for the devlink port instance
7604 void devlink_port_attrs_pci_pf_set(struct devlink_port
*devlink_port
, u16 pf
)
7606 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
7609 ret
= __devlink_port_attrs_set(devlink_port
,
7610 DEVLINK_PORT_FLAVOUR_PCI_PF
);
7614 attrs
->pci_pf
.pf
= pf
;
7616 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set
);
7619 * devlink_port_attrs_pci_vf_set - Set PCI VF port attributes
7621 * @devlink_port: devlink port
7622 * @pf: associated PF for the devlink port instance
7623 * @vf: associated VF of a PF for the devlink port instance
7625 void devlink_port_attrs_pci_vf_set(struct devlink_port
*devlink_port
,
7628 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
7631 ret
= __devlink_port_attrs_set(devlink_port
,
7632 DEVLINK_PORT_FLAVOUR_PCI_VF
);
7635 attrs
->pci_vf
.pf
= pf
;
7636 attrs
->pci_vf
.vf
= vf
;
7638 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set
);
7640 static int __devlink_port_phys_port_name_get(struct devlink_port
*devlink_port
,
7641 char *name
, size_t len
)
7643 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
7646 if (!devlink_port
->attrs_set
)
7649 switch (attrs
->flavour
) {
7650 case DEVLINK_PORT_FLAVOUR_PHYSICAL
:
7651 case DEVLINK_PORT_FLAVOUR_VIRTUAL
:
7653 n
= snprintf(name
, len
, "p%u", attrs
->phys
.port_number
);
7655 n
= snprintf(name
, len
, "p%us%u",
7656 attrs
->phys
.port_number
,
7657 attrs
->phys
.split_subport_number
);
7659 case DEVLINK_PORT_FLAVOUR_CPU
:
7660 case DEVLINK_PORT_FLAVOUR_DSA
:
7661 /* As CPU and DSA ports do not have a netdevice associated
7662 * case should not ever happen.
7666 case DEVLINK_PORT_FLAVOUR_PCI_PF
:
7667 n
= snprintf(name
, len
, "pf%u", attrs
->pci_pf
.pf
);
7669 case DEVLINK_PORT_FLAVOUR_PCI_VF
:
7670 n
= snprintf(name
, len
, "pf%uvf%u",
7671 attrs
->pci_vf
.pf
, attrs
->pci_vf
.vf
);
7681 int devlink_sb_register(struct devlink
*devlink
, unsigned int sb_index
,
7682 u32 size
, u16 ingress_pools_count
,
7683 u16 egress_pools_count
, u16 ingress_tc_count
,
7684 u16 egress_tc_count
)
7686 struct devlink_sb
*devlink_sb
;
7689 mutex_lock(&devlink
->lock
);
7690 if (devlink_sb_index_exists(devlink
, sb_index
)) {
7695 devlink_sb
= kzalloc(sizeof(*devlink_sb
), GFP_KERNEL
);
7700 devlink_sb
->index
= sb_index
;
7701 devlink_sb
->size
= size
;
7702 devlink_sb
->ingress_pools_count
= ingress_pools_count
;
7703 devlink_sb
->egress_pools_count
= egress_pools_count
;
7704 devlink_sb
->ingress_tc_count
= ingress_tc_count
;
7705 devlink_sb
->egress_tc_count
= egress_tc_count
;
7706 list_add_tail(&devlink_sb
->list
, &devlink
->sb_list
);
7708 mutex_unlock(&devlink
->lock
);
7711 EXPORT_SYMBOL_GPL(devlink_sb_register
);
7713 void devlink_sb_unregister(struct devlink
*devlink
, unsigned int sb_index
)
7715 struct devlink_sb
*devlink_sb
;
7717 mutex_lock(&devlink
->lock
);
7718 devlink_sb
= devlink_sb_get_by_index(devlink
, sb_index
);
7719 WARN_ON(!devlink_sb
);
7720 list_del(&devlink_sb
->list
);
7721 mutex_unlock(&devlink
->lock
);
7724 EXPORT_SYMBOL_GPL(devlink_sb_unregister
);
7727 * devlink_dpipe_headers_register - register dpipe headers
7730 * @dpipe_headers: dpipe header array
7732 * Register the headers supported by hardware.
7734 int devlink_dpipe_headers_register(struct devlink
*devlink
,
7735 struct devlink_dpipe_headers
*dpipe_headers
)
7737 mutex_lock(&devlink
->lock
);
7738 devlink
->dpipe_headers
= dpipe_headers
;
7739 mutex_unlock(&devlink
->lock
);
7742 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register
);
7745 * devlink_dpipe_headers_unregister - unregister dpipe headers
7749 * Unregister the headers supported by hardware.
7751 void devlink_dpipe_headers_unregister(struct devlink
*devlink
)
7753 mutex_lock(&devlink
->lock
);
7754 devlink
->dpipe_headers
= NULL
;
7755 mutex_unlock(&devlink
->lock
);
7757 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister
);
7760 * devlink_dpipe_table_counter_enabled - check if counter allocation
7763 * @table_name: tables name
7765 * Used by driver to check if counter allocation is required.
7766 * After counter allocation is turned on the table entries
7767 * are updated to include counter statistics.
7769 * After that point on the driver must respect the counter
7770 * state so that each entry added to the table is added
7773 bool devlink_dpipe_table_counter_enabled(struct devlink
*devlink
,
7774 const char *table_name
)
7776 struct devlink_dpipe_table
*table
;
7780 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
7781 table_name
, devlink
);
7784 enabled
= table
->counters_enabled
;
7788 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled
);
7791 * devlink_dpipe_table_register - register dpipe table
7794 * @table_name: table name
7795 * @table_ops: table ops
7797 * @counter_control_extern: external control for counters
7799 int devlink_dpipe_table_register(struct devlink
*devlink
,
7800 const char *table_name
,
7801 struct devlink_dpipe_table_ops
*table_ops
,
7802 void *priv
, bool counter_control_extern
)
7804 struct devlink_dpipe_table
*table
;
7807 if (WARN_ON(!table_ops
->size_get
))
7810 mutex_lock(&devlink
->lock
);
7812 if (devlink_dpipe_table_find(&devlink
->dpipe_table_list
, table_name
,
7818 table
= kzalloc(sizeof(*table
), GFP_KERNEL
);
7824 table
->name
= table_name
;
7825 table
->table_ops
= table_ops
;
7827 table
->counter_control_extern
= counter_control_extern
;
7829 list_add_tail_rcu(&table
->list
, &devlink
->dpipe_table_list
);
7831 mutex_unlock(&devlink
->lock
);
7834 EXPORT_SYMBOL_GPL(devlink_dpipe_table_register
);
7837 * devlink_dpipe_table_unregister - unregister dpipe table
7840 * @table_name: table name
7842 void devlink_dpipe_table_unregister(struct devlink
*devlink
,
7843 const char *table_name
)
7845 struct devlink_dpipe_table
*table
;
7847 mutex_lock(&devlink
->lock
);
7848 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
7849 table_name
, devlink
);
7852 list_del_rcu(&table
->list
);
7853 mutex_unlock(&devlink
->lock
);
7854 kfree_rcu(table
, rcu
);
7857 mutex_unlock(&devlink
->lock
);
7859 EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister
);
7862 * devlink_resource_register - devlink resource register
7865 * @resource_name: resource's name
7866 * @resource_size: resource's size
7867 * @resource_id: resource's id
7868 * @parent_resource_id: resource's parent id
7869 * @size_params: size parameters
7871 int devlink_resource_register(struct devlink
*devlink
,
7872 const char *resource_name
,
7875 u64 parent_resource_id
,
7876 const struct devlink_resource_size_params
*size_params
)
7878 struct devlink_resource
*resource
;
7879 struct list_head
*resource_list
;
7883 top_hierarchy
= parent_resource_id
== DEVLINK_RESOURCE_ID_PARENT_TOP
;
7885 mutex_lock(&devlink
->lock
);
7886 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
7892 resource
= kzalloc(sizeof(*resource
), GFP_KERNEL
);
7898 if (top_hierarchy
) {
7899 resource_list
= &devlink
->resource_list
;
7901 struct devlink_resource
*parent_resource
;
7903 parent_resource
= devlink_resource_find(devlink
, NULL
,
7904 parent_resource_id
);
7905 if (parent_resource
) {
7906 resource_list
= &parent_resource
->resource_list
;
7907 resource
->parent
= parent_resource
;
7915 resource
->name
= resource_name
;
7916 resource
->size
= resource_size
;
7917 resource
->size_new
= resource_size
;
7918 resource
->id
= resource_id
;
7919 resource
->size_valid
= true;
7920 memcpy(&resource
->size_params
, size_params
,
7921 sizeof(resource
->size_params
));
7922 INIT_LIST_HEAD(&resource
->resource_list
);
7923 list_add_tail(&resource
->list
, resource_list
);
7925 mutex_unlock(&devlink
->lock
);
7928 EXPORT_SYMBOL_GPL(devlink_resource_register
);
7931 * devlink_resources_unregister - free all resources
7934 * @resource: resource
7936 void devlink_resources_unregister(struct devlink
*devlink
,
7937 struct devlink_resource
*resource
)
7939 struct devlink_resource
*tmp
, *child_resource
;
7940 struct list_head
*resource_list
;
7943 resource_list
= &resource
->resource_list
;
7945 resource_list
= &devlink
->resource_list
;
7948 mutex_lock(&devlink
->lock
);
7950 list_for_each_entry_safe(child_resource
, tmp
, resource_list
, list
) {
7951 devlink_resources_unregister(devlink
, child_resource
);
7952 list_del(&child_resource
->list
);
7953 kfree(child_resource
);
7957 mutex_unlock(&devlink
->lock
);
7959 EXPORT_SYMBOL_GPL(devlink_resources_unregister
);
7962 * devlink_resource_size_get - get and update size
7965 * @resource_id: the requested resource id
7966 * @p_resource_size: ptr to update
7968 int devlink_resource_size_get(struct devlink
*devlink
,
7970 u64
*p_resource_size
)
7972 struct devlink_resource
*resource
;
7975 mutex_lock(&devlink
->lock
);
7976 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
7981 *p_resource_size
= resource
->size_new
;
7982 resource
->size
= resource
->size_new
;
7984 mutex_unlock(&devlink
->lock
);
7987 EXPORT_SYMBOL_GPL(devlink_resource_size_get
);
7990 * devlink_dpipe_table_resource_set - set the resource id
7993 * @table_name: table name
7994 * @resource_id: resource id
7995 * @resource_units: number of resource's units consumed per table's entry
7997 int devlink_dpipe_table_resource_set(struct devlink
*devlink
,
7998 const char *table_name
, u64 resource_id
,
8001 struct devlink_dpipe_table
*table
;
8004 mutex_lock(&devlink
->lock
);
8005 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
8006 table_name
, devlink
);
8011 table
->resource_id
= resource_id
;
8012 table
->resource_units
= resource_units
;
8013 table
->resource_valid
= true;
8015 mutex_unlock(&devlink
->lock
);
8018 EXPORT_SYMBOL_GPL(devlink_dpipe_table_resource_set
);
8021 * devlink_resource_occ_get_register - register occupancy getter
8024 * @resource_id: resource id
8025 * @occ_get: occupancy getter callback
8026 * @occ_get_priv: occupancy getter callback priv
8028 void devlink_resource_occ_get_register(struct devlink
*devlink
,
8030 devlink_resource_occ_get_t
*occ_get
,
8033 struct devlink_resource
*resource
;
8035 mutex_lock(&devlink
->lock
);
8036 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
8037 if (WARN_ON(!resource
))
8039 WARN_ON(resource
->occ_get
);
8041 resource
->occ_get
= occ_get
;
8042 resource
->occ_get_priv
= occ_get_priv
;
8044 mutex_unlock(&devlink
->lock
);
8046 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register
);
8049 * devlink_resource_occ_get_unregister - unregister occupancy getter
8052 * @resource_id: resource id
8054 void devlink_resource_occ_get_unregister(struct devlink
*devlink
,
8057 struct devlink_resource
*resource
;
8059 mutex_lock(&devlink
->lock
);
8060 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
8061 if (WARN_ON(!resource
))
8063 WARN_ON(!resource
->occ_get
);
8065 resource
->occ_get
= NULL
;
8066 resource
->occ_get_priv
= NULL
;
8068 mutex_unlock(&devlink
->lock
);
8070 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister
);
8072 static int devlink_param_verify(const struct devlink_param
*param
)
8074 if (!param
|| !param
->name
|| !param
->supported_cmodes
)
8077 return devlink_param_generic_verify(param
);
8079 return devlink_param_driver_verify(param
);
8082 static int __devlink_params_register(struct devlink
*devlink
,
8083 unsigned int port_index
,
8084 struct list_head
*param_list
,
8085 const struct devlink_param
*params
,
8086 size_t params_count
,
8087 enum devlink_command reg_cmd
,
8088 enum devlink_command unreg_cmd
)
8090 const struct devlink_param
*param
= params
;
8094 mutex_lock(&devlink
->lock
);
8095 for (i
= 0; i
< params_count
; i
++, param
++) {
8096 err
= devlink_param_verify(param
);
8100 err
= devlink_param_register_one(devlink
, port_index
,
8101 param_list
, param
, reg_cmd
);
8106 mutex_unlock(&devlink
->lock
);
8112 for (param
--; i
> 0; i
--, param
--)
8113 devlink_param_unregister_one(devlink
, port_index
, param_list
,
8116 mutex_unlock(&devlink
->lock
);
8120 static void __devlink_params_unregister(struct devlink
*devlink
,
8121 unsigned int port_index
,
8122 struct list_head
*param_list
,
8123 const struct devlink_param
*params
,
8124 size_t params_count
,
8125 enum devlink_command cmd
)
8127 const struct devlink_param
*param
= params
;
8130 mutex_lock(&devlink
->lock
);
8131 for (i
= 0; i
< params_count
; i
++, param
++)
8132 devlink_param_unregister_one(devlink
, 0, param_list
, param
,
8134 mutex_unlock(&devlink
->lock
);
8138 * devlink_params_register - register configuration parameters
8141 * @params: configuration parameters array
8142 * @params_count: number of parameters provided
8144 * Register the configuration parameters supported by the driver.
8146 int devlink_params_register(struct devlink
*devlink
,
8147 const struct devlink_param
*params
,
8148 size_t params_count
)
8150 return __devlink_params_register(devlink
, 0, &devlink
->param_list
,
8151 params
, params_count
,
8152 DEVLINK_CMD_PARAM_NEW
,
8153 DEVLINK_CMD_PARAM_DEL
);
8155 EXPORT_SYMBOL_GPL(devlink_params_register
);
8158 * devlink_params_unregister - unregister configuration parameters
8160 * @params: configuration parameters to unregister
8161 * @params_count: number of parameters provided
8163 void devlink_params_unregister(struct devlink
*devlink
,
8164 const struct devlink_param
*params
,
8165 size_t params_count
)
8167 return __devlink_params_unregister(devlink
, 0, &devlink
->param_list
,
8168 params
, params_count
,
8169 DEVLINK_CMD_PARAM_DEL
);
8171 EXPORT_SYMBOL_GPL(devlink_params_unregister
);
8174 * devlink_params_publish - publish configuration parameters
8178 * Publish previously registered configuration parameters.
8180 void devlink_params_publish(struct devlink
*devlink
)
8182 struct devlink_param_item
*param_item
;
8184 list_for_each_entry(param_item
, &devlink
->param_list
, list
) {
8185 if (param_item
->published
)
8187 param_item
->published
= true;
8188 devlink_param_notify(devlink
, 0, param_item
,
8189 DEVLINK_CMD_PARAM_NEW
);
8192 EXPORT_SYMBOL_GPL(devlink_params_publish
);
8195 * devlink_params_unpublish - unpublish configuration parameters
8199 * Unpublish previously registered configuration parameters.
8201 void devlink_params_unpublish(struct devlink
*devlink
)
8203 struct devlink_param_item
*param_item
;
8205 list_for_each_entry(param_item
, &devlink
->param_list
, list
) {
8206 if (!param_item
->published
)
8208 param_item
->published
= false;
8209 devlink_param_notify(devlink
, 0, param_item
,
8210 DEVLINK_CMD_PARAM_DEL
);
8213 EXPORT_SYMBOL_GPL(devlink_params_unpublish
);
8216 * devlink_port_params_register - register port configuration parameters
8218 * @devlink_port: devlink port
8219 * @params: configuration parameters array
8220 * @params_count: number of parameters provided
8222 * Register the configuration parameters supported by the port.
8224 int devlink_port_params_register(struct devlink_port
*devlink_port
,
8225 const struct devlink_param
*params
,
8226 size_t params_count
)
8228 return __devlink_params_register(devlink_port
->devlink
,
8229 devlink_port
->index
,
8230 &devlink_port
->param_list
, params
,
8232 DEVLINK_CMD_PORT_PARAM_NEW
,
8233 DEVLINK_CMD_PORT_PARAM_DEL
);
8235 EXPORT_SYMBOL_GPL(devlink_port_params_register
);
8238 * devlink_port_params_unregister - unregister port configuration
8241 * @devlink_port: devlink port
8242 * @params: configuration parameters array
8243 * @params_count: number of parameters provided
8245 void devlink_port_params_unregister(struct devlink_port
*devlink_port
,
8246 const struct devlink_param
*params
,
8247 size_t params_count
)
8249 return __devlink_params_unregister(devlink_port
->devlink
,
8250 devlink_port
->index
,
8251 &devlink_port
->param_list
,
8252 params
, params_count
,
8253 DEVLINK_CMD_PORT_PARAM_DEL
);
8255 EXPORT_SYMBOL_GPL(devlink_port_params_unregister
);
8258 __devlink_param_driverinit_value_get(struct list_head
*param_list
, u32 param_id
,
8259 union devlink_param_value
*init_val
)
8261 struct devlink_param_item
*param_item
;
8263 param_item
= devlink_param_find_by_id(param_list
, param_id
);
8267 if (!param_item
->driverinit_value_valid
||
8268 !devlink_param_cmode_is_supported(param_item
->param
,
8269 DEVLINK_PARAM_CMODE_DRIVERINIT
))
8272 if (param_item
->param
->type
== DEVLINK_PARAM_TYPE_STRING
)
8273 strcpy(init_val
->vstr
, param_item
->driverinit_value
.vstr
);
8275 *init_val
= param_item
->driverinit_value
;
8281 __devlink_param_driverinit_value_set(struct devlink
*devlink
,
8282 unsigned int port_index
,
8283 struct list_head
*param_list
, u32 param_id
,
8284 union devlink_param_value init_val
,
8285 enum devlink_command cmd
)
8287 struct devlink_param_item
*param_item
;
8289 param_item
= devlink_param_find_by_id(param_list
, param_id
);
8293 if (!devlink_param_cmode_is_supported(param_item
->param
,
8294 DEVLINK_PARAM_CMODE_DRIVERINIT
))
8297 if (param_item
->param
->type
== DEVLINK_PARAM_TYPE_STRING
)
8298 strcpy(param_item
->driverinit_value
.vstr
, init_val
.vstr
);
8300 param_item
->driverinit_value
= init_val
;
8301 param_item
->driverinit_value_valid
= true;
8303 devlink_param_notify(devlink
, port_index
, param_item
, cmd
);
8308 * devlink_param_driverinit_value_get - get configuration parameter
8309 * value for driver initializing
8312 * @param_id: parameter ID
8313 * @init_val: value of parameter in driverinit configuration mode
8315 * This function should be used by the driver to get driverinit
8316 * configuration for initialization after reload command.
8318 int devlink_param_driverinit_value_get(struct devlink
*devlink
, u32 param_id
,
8319 union devlink_param_value
*init_val
)
8321 if (!devlink_reload_supported(devlink
))
8324 return __devlink_param_driverinit_value_get(&devlink
->param_list
,
8325 param_id
, init_val
);
8327 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_get
);
8330 * devlink_param_driverinit_value_set - set value of configuration
8331 * parameter for driverinit
8332 * configuration mode
8335 * @param_id: parameter ID
8336 * @init_val: value of parameter to set for driverinit configuration mode
8338 * This function should be used by the driver to set driverinit
8339 * configuration mode default value.
8341 int devlink_param_driverinit_value_set(struct devlink
*devlink
, u32 param_id
,
8342 union devlink_param_value init_val
)
8344 return __devlink_param_driverinit_value_set(devlink
, 0,
8345 &devlink
->param_list
,
8347 DEVLINK_CMD_PARAM_NEW
);
8349 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set
);
8352 * devlink_port_param_driverinit_value_get - get configuration parameter
8353 * value for driver initializing
8355 * @devlink_port: devlink_port
8356 * @param_id: parameter ID
8357 * @init_val: value of parameter in driverinit configuration mode
8359 * This function should be used by the driver to get driverinit
8360 * configuration for initialization after reload command.
8362 int devlink_port_param_driverinit_value_get(struct devlink_port
*devlink_port
,
8364 union devlink_param_value
*init_val
)
8366 struct devlink
*devlink
= devlink_port
->devlink
;
8368 if (!devlink_reload_supported(devlink
))
8371 return __devlink_param_driverinit_value_get(&devlink_port
->param_list
,
8372 param_id
, init_val
);
8374 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_get
);
8377 * devlink_port_param_driverinit_value_set - set value of configuration
8378 * parameter for driverinit
8379 * configuration mode
8381 * @devlink_port: devlink_port
8382 * @param_id: parameter ID
8383 * @init_val: value of parameter to set for driverinit configuration mode
8385 * This function should be used by the driver to set driverinit
8386 * configuration mode default value.
8388 int devlink_port_param_driverinit_value_set(struct devlink_port
*devlink_port
,
8390 union devlink_param_value init_val
)
8392 return __devlink_param_driverinit_value_set(devlink_port
->devlink
,
8393 devlink_port
->index
,
8394 &devlink_port
->param_list
,
8396 DEVLINK_CMD_PORT_PARAM_NEW
);
8398 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_set
);
8401 * devlink_param_value_changed - notify devlink on a parameter's value
8402 * change. Should be called by the driver
8403 * right after the change.
8406 * @param_id: parameter ID
8408 * This function should be used by the driver to notify devlink on value
8409 * change, excluding driverinit configuration mode.
8410 * For driverinit configuration mode driver should use the function
8412 void devlink_param_value_changed(struct devlink
*devlink
, u32 param_id
)
8414 struct devlink_param_item
*param_item
;
8416 param_item
= devlink_param_find_by_id(&devlink
->param_list
, param_id
);
8417 WARN_ON(!param_item
);
8419 devlink_param_notify(devlink
, 0, param_item
, DEVLINK_CMD_PARAM_NEW
);
8421 EXPORT_SYMBOL_GPL(devlink_param_value_changed
);
8424 * devlink_port_param_value_changed - notify devlink on a parameter's value
8425 * change. Should be called by the driver
8426 * right after the change.
8428 * @devlink_port: devlink_port
8429 * @param_id: parameter ID
8431 * This function should be used by the driver to notify devlink on value
8432 * change, excluding driverinit configuration mode.
8433 * For driverinit configuration mode driver should use the function
8434 * devlink_port_param_driverinit_value_set() instead.
8436 void devlink_port_param_value_changed(struct devlink_port
*devlink_port
,
8439 struct devlink_param_item
*param_item
;
8441 param_item
= devlink_param_find_by_id(&devlink_port
->param_list
,
8443 WARN_ON(!param_item
);
8445 devlink_param_notify(devlink_port
->devlink
, devlink_port
->index
,
8446 param_item
, DEVLINK_CMD_PORT_PARAM_NEW
);
8448 EXPORT_SYMBOL_GPL(devlink_port_param_value_changed
);
8451 * devlink_param_value_str_fill - Safely fill-up the string preventing
8452 * from overflow of the preallocated buffer
8454 * @dst_val: destination devlink_param_value
8455 * @src: source buffer
8457 void devlink_param_value_str_fill(union devlink_param_value
*dst_val
,
8462 len
= strlcpy(dst_val
->vstr
, src
, __DEVLINK_PARAM_MAX_STRING_VALUE
);
8463 WARN_ON(len
>= __DEVLINK_PARAM_MAX_STRING_VALUE
);
8465 EXPORT_SYMBOL_GPL(devlink_param_value_str_fill
);
8468 * devlink_region_create - create a new address region
8471 * @ops: region operations and name
8472 * @region_max_snapshots: Maximum supported number of snapshots for region
8473 * @region_size: size of region
8475 struct devlink_region
*
8476 devlink_region_create(struct devlink
*devlink
,
8477 const struct devlink_region_ops
*ops
,
8478 u32 region_max_snapshots
, u64 region_size
)
8480 struct devlink_region
*region
;
8483 if (WARN_ON(!ops
) || WARN_ON(!ops
->destructor
))
8484 return ERR_PTR(-EINVAL
);
8486 mutex_lock(&devlink
->lock
);
8488 if (devlink_region_get_by_name(devlink
, ops
->name
)) {
8493 region
= kzalloc(sizeof(*region
), GFP_KERNEL
);
8499 region
->devlink
= devlink
;
8500 region
->max_snapshots
= region_max_snapshots
;
8502 region
->size
= region_size
;
8503 INIT_LIST_HEAD(®ion
->snapshot_list
);
8504 list_add_tail(®ion
->list
, &devlink
->region_list
);
8505 devlink_nl_region_notify(region
, NULL
, DEVLINK_CMD_REGION_NEW
);
8507 mutex_unlock(&devlink
->lock
);
8511 mutex_unlock(&devlink
->lock
);
8512 return ERR_PTR(err
);
8514 EXPORT_SYMBOL_GPL(devlink_region_create
);
8517 * devlink_region_destroy - destroy address region
8519 * @region: devlink region to destroy
8521 void devlink_region_destroy(struct devlink_region
*region
)
8523 struct devlink
*devlink
= region
->devlink
;
8524 struct devlink_snapshot
*snapshot
, *ts
;
8526 mutex_lock(&devlink
->lock
);
8528 /* Free all snapshots of region */
8529 list_for_each_entry_safe(snapshot
, ts
, ®ion
->snapshot_list
, list
)
8530 devlink_region_snapshot_del(region
, snapshot
);
8532 list_del(®ion
->list
);
8534 devlink_nl_region_notify(region
, NULL
, DEVLINK_CMD_REGION_DEL
);
8535 mutex_unlock(&devlink
->lock
);
8538 EXPORT_SYMBOL_GPL(devlink_region_destroy
);
8541 * devlink_region_snapshot_id_get - get snapshot ID
8543 * This callback should be called when adding a new snapshot,
8544 * Driver should use the same id for multiple snapshots taken
8545 * on multiple regions at the same time/by the same trigger.
8547 * The caller of this function must use devlink_region_snapshot_id_put
8548 * when finished creating regions using this id.
8550 * Returns zero on success, or a negative error code on failure.
8553 * @id: storage to return id
8555 int devlink_region_snapshot_id_get(struct devlink
*devlink
, u32
*id
)
8559 mutex_lock(&devlink
->lock
);
8560 err
= __devlink_region_snapshot_id_get(devlink
, id
);
8561 mutex_unlock(&devlink
->lock
);
8565 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get
);
8568 * devlink_region_snapshot_id_put - put snapshot ID reference
8570 * This should be called by a driver after finishing creating snapshots
8571 * with an id. Doing so ensures that the ID can later be released in the
8572 * event that all snapshots using it have been destroyed.
8575 * @id: id to release reference on
8577 void devlink_region_snapshot_id_put(struct devlink
*devlink
, u32 id
)
8579 mutex_lock(&devlink
->lock
);
8580 __devlink_snapshot_id_decrement(devlink
, id
);
8581 mutex_unlock(&devlink
->lock
);
8583 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put
);
8586 * devlink_region_snapshot_create - create a new snapshot
8587 * This will add a new snapshot of a region. The snapshot
8588 * will be stored on the region struct and can be accessed
8589 * from devlink. This is useful for future analyses of snapshots.
8590 * Multiple snapshots can be created on a region.
8591 * The @snapshot_id should be obtained using the getter function.
8593 * @region: devlink region of the snapshot
8594 * @data: snapshot data
8595 * @snapshot_id: snapshot id to be created
8597 int devlink_region_snapshot_create(struct devlink_region
*region
,
8598 u8
*data
, u32 snapshot_id
)
8600 struct devlink
*devlink
= region
->devlink
;
8603 mutex_lock(&devlink
->lock
);
8604 err
= __devlink_region_snapshot_create(region
, data
, snapshot_id
);
8605 mutex_unlock(&devlink
->lock
);
8609 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create
);
8611 #define DEVLINK_TRAP(_id, _type) \
8613 .type = DEVLINK_TRAP_TYPE_##_type, \
8614 .id = DEVLINK_TRAP_GENERIC_ID_##_id, \
8615 .name = DEVLINK_TRAP_GENERIC_NAME_##_id, \
8618 static const struct devlink_trap devlink_trap_generic
[] = {
8619 DEVLINK_TRAP(SMAC_MC
, DROP
),
8620 DEVLINK_TRAP(VLAN_TAG_MISMATCH
, DROP
),
8621 DEVLINK_TRAP(INGRESS_VLAN_FILTER
, DROP
),
8622 DEVLINK_TRAP(INGRESS_STP_FILTER
, DROP
),
8623 DEVLINK_TRAP(EMPTY_TX_LIST
, DROP
),
8624 DEVLINK_TRAP(PORT_LOOPBACK_FILTER
, DROP
),
8625 DEVLINK_TRAP(BLACKHOLE_ROUTE
, DROP
),
8626 DEVLINK_TRAP(TTL_ERROR
, EXCEPTION
),
8627 DEVLINK_TRAP(TAIL_DROP
, DROP
),
8628 DEVLINK_TRAP(NON_IP_PACKET
, DROP
),
8629 DEVLINK_TRAP(UC_DIP_MC_DMAC
, DROP
),
8630 DEVLINK_TRAP(DIP_LB
, DROP
),
8631 DEVLINK_TRAP(SIP_MC
, DROP
),
8632 DEVLINK_TRAP(SIP_LB
, DROP
),
8633 DEVLINK_TRAP(CORRUPTED_IP_HDR
, DROP
),
8634 DEVLINK_TRAP(IPV4_SIP_BC
, DROP
),
8635 DEVLINK_TRAP(IPV6_MC_DIP_RESERVED_SCOPE
, DROP
),
8636 DEVLINK_TRAP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE
, DROP
),
8637 DEVLINK_TRAP(MTU_ERROR
, EXCEPTION
),
8638 DEVLINK_TRAP(UNRESOLVED_NEIGH
, EXCEPTION
),
8639 DEVLINK_TRAP(RPF
, EXCEPTION
),
8640 DEVLINK_TRAP(REJECT_ROUTE
, EXCEPTION
),
8641 DEVLINK_TRAP(IPV4_LPM_UNICAST_MISS
, EXCEPTION
),
8642 DEVLINK_TRAP(IPV6_LPM_UNICAST_MISS
, EXCEPTION
),
8643 DEVLINK_TRAP(NON_ROUTABLE
, DROP
),
8644 DEVLINK_TRAP(DECAP_ERROR
, EXCEPTION
),
8645 DEVLINK_TRAP(OVERLAY_SMAC_MC
, DROP
),
8646 DEVLINK_TRAP(INGRESS_FLOW_ACTION_DROP
, DROP
),
8647 DEVLINK_TRAP(EGRESS_FLOW_ACTION_DROP
, DROP
),
8648 DEVLINK_TRAP(STP
, CONTROL
),
8649 DEVLINK_TRAP(LACP
, CONTROL
),
8650 DEVLINK_TRAP(LLDP
, CONTROL
),
8651 DEVLINK_TRAP(IGMP_QUERY
, CONTROL
),
8652 DEVLINK_TRAP(IGMP_V1_REPORT
, CONTROL
),
8653 DEVLINK_TRAP(IGMP_V2_REPORT
, CONTROL
),
8654 DEVLINK_TRAP(IGMP_V3_REPORT
, CONTROL
),
8655 DEVLINK_TRAP(IGMP_V2_LEAVE
, CONTROL
),
8656 DEVLINK_TRAP(MLD_QUERY
, CONTROL
),
8657 DEVLINK_TRAP(MLD_V1_REPORT
, CONTROL
),
8658 DEVLINK_TRAP(MLD_V2_REPORT
, CONTROL
),
8659 DEVLINK_TRAP(MLD_V1_DONE
, CONTROL
),
8660 DEVLINK_TRAP(IPV4_DHCP
, CONTROL
),
8661 DEVLINK_TRAP(IPV6_DHCP
, CONTROL
),
8662 DEVLINK_TRAP(ARP_REQUEST
, CONTROL
),
8663 DEVLINK_TRAP(ARP_RESPONSE
, CONTROL
),
8664 DEVLINK_TRAP(ARP_OVERLAY
, CONTROL
),
8665 DEVLINK_TRAP(IPV6_NEIGH_SOLICIT
, CONTROL
),
8666 DEVLINK_TRAP(IPV6_NEIGH_ADVERT
, CONTROL
),
8667 DEVLINK_TRAP(IPV4_BFD
, CONTROL
),
8668 DEVLINK_TRAP(IPV6_BFD
, CONTROL
),
8669 DEVLINK_TRAP(IPV4_OSPF
, CONTROL
),
8670 DEVLINK_TRAP(IPV6_OSPF
, CONTROL
),
8671 DEVLINK_TRAP(IPV4_BGP
, CONTROL
),
8672 DEVLINK_TRAP(IPV6_BGP
, CONTROL
),
8673 DEVLINK_TRAP(IPV4_VRRP
, CONTROL
),
8674 DEVLINK_TRAP(IPV6_VRRP
, CONTROL
),
8675 DEVLINK_TRAP(IPV4_PIM
, CONTROL
),
8676 DEVLINK_TRAP(IPV6_PIM
, CONTROL
),
8677 DEVLINK_TRAP(UC_LB
, CONTROL
),
8678 DEVLINK_TRAP(LOCAL_ROUTE
, CONTROL
),
8679 DEVLINK_TRAP(EXTERNAL_ROUTE
, CONTROL
),
8680 DEVLINK_TRAP(IPV6_UC_DIP_LINK_LOCAL_SCOPE
, CONTROL
),
8681 DEVLINK_TRAP(IPV6_DIP_ALL_NODES
, CONTROL
),
8682 DEVLINK_TRAP(IPV6_DIP_ALL_ROUTERS
, CONTROL
),
8683 DEVLINK_TRAP(IPV6_ROUTER_SOLICIT
, CONTROL
),
8684 DEVLINK_TRAP(IPV6_ROUTER_ADVERT
, CONTROL
),
8685 DEVLINK_TRAP(IPV6_REDIRECT
, CONTROL
),
8686 DEVLINK_TRAP(IPV4_ROUTER_ALERT
, CONTROL
),
8687 DEVLINK_TRAP(IPV6_ROUTER_ALERT
, CONTROL
),
8688 DEVLINK_TRAP(PTP_EVENT
, CONTROL
),
8689 DEVLINK_TRAP(PTP_GENERAL
, CONTROL
),
8690 DEVLINK_TRAP(FLOW_ACTION_SAMPLE
, CONTROL
),
8691 DEVLINK_TRAP(FLOW_ACTION_TRAP
, CONTROL
),
8694 #define DEVLINK_TRAP_GROUP(_id) \
8696 .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \
8697 .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \
8700 static const struct devlink_trap_group devlink_trap_group_generic
[] = {
8701 DEVLINK_TRAP_GROUP(L2_DROPS
),
8702 DEVLINK_TRAP_GROUP(L3_DROPS
),
8703 DEVLINK_TRAP_GROUP(L3_EXCEPTIONS
),
8704 DEVLINK_TRAP_GROUP(BUFFER_DROPS
),
8705 DEVLINK_TRAP_GROUP(TUNNEL_DROPS
),
8706 DEVLINK_TRAP_GROUP(ACL_DROPS
),
8707 DEVLINK_TRAP_GROUP(STP
),
8708 DEVLINK_TRAP_GROUP(LACP
),
8709 DEVLINK_TRAP_GROUP(LLDP
),
8710 DEVLINK_TRAP_GROUP(MC_SNOOPING
),
8711 DEVLINK_TRAP_GROUP(DHCP
),
8712 DEVLINK_TRAP_GROUP(NEIGH_DISCOVERY
),
8713 DEVLINK_TRAP_GROUP(BFD
),
8714 DEVLINK_TRAP_GROUP(OSPF
),
8715 DEVLINK_TRAP_GROUP(BGP
),
8716 DEVLINK_TRAP_GROUP(VRRP
),
8717 DEVLINK_TRAP_GROUP(PIM
),
8718 DEVLINK_TRAP_GROUP(UC_LB
),
8719 DEVLINK_TRAP_GROUP(LOCAL_DELIVERY
),
8720 DEVLINK_TRAP_GROUP(IPV6
),
8721 DEVLINK_TRAP_GROUP(PTP_EVENT
),
8722 DEVLINK_TRAP_GROUP(PTP_GENERAL
),
8723 DEVLINK_TRAP_GROUP(ACL_SAMPLE
),
8724 DEVLINK_TRAP_GROUP(ACL_TRAP
),
8727 static int devlink_trap_generic_verify(const struct devlink_trap
*trap
)
8729 if (trap
->id
> DEVLINK_TRAP_GENERIC_ID_MAX
)
8732 if (strcmp(trap
->name
, devlink_trap_generic
[trap
->id
].name
))
8735 if (trap
->type
!= devlink_trap_generic
[trap
->id
].type
)
8741 static int devlink_trap_driver_verify(const struct devlink_trap
*trap
)
8745 if (trap
->id
<= DEVLINK_TRAP_GENERIC_ID_MAX
)
8748 for (i
= 0; i
< ARRAY_SIZE(devlink_trap_generic
); i
++) {
8749 if (!strcmp(trap
->name
, devlink_trap_generic
[i
].name
))
8756 static int devlink_trap_verify(const struct devlink_trap
*trap
)
8758 if (!trap
|| !trap
->name
)
8762 return devlink_trap_generic_verify(trap
);
8764 return devlink_trap_driver_verify(trap
);
8768 devlink_trap_group_generic_verify(const struct devlink_trap_group
*group
)
8770 if (group
->id
> DEVLINK_TRAP_GROUP_GENERIC_ID_MAX
)
8773 if (strcmp(group
->name
, devlink_trap_group_generic
[group
->id
].name
))
8780 devlink_trap_group_driver_verify(const struct devlink_trap_group
*group
)
8784 if (group
->id
<= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX
)
8787 for (i
= 0; i
< ARRAY_SIZE(devlink_trap_group_generic
); i
++) {
8788 if (!strcmp(group
->name
, devlink_trap_group_generic
[i
].name
))
8795 static int devlink_trap_group_verify(const struct devlink_trap_group
*group
)
8798 return devlink_trap_group_generic_verify(group
);
8800 return devlink_trap_group_driver_verify(group
);
8804 devlink_trap_group_notify(struct devlink
*devlink
,
8805 const struct devlink_trap_group_item
*group_item
,
8806 enum devlink_command cmd
)
8808 struct sk_buff
*msg
;
8811 WARN_ON_ONCE(cmd
!= DEVLINK_CMD_TRAP_GROUP_NEW
&&
8812 cmd
!= DEVLINK_CMD_TRAP_GROUP_DEL
);
8814 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
8818 err
= devlink_nl_trap_group_fill(msg
, devlink
, group_item
, cmd
, 0, 0,
8825 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
8826 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
8830 devlink_trap_item_group_link(struct devlink
*devlink
,
8831 struct devlink_trap_item
*trap_item
)
8833 u16 group_id
= trap_item
->trap
->init_group_id
;
8834 struct devlink_trap_group_item
*group_item
;
8836 group_item
= devlink_trap_group_item_lookup_by_id(devlink
, group_id
);
8837 if (WARN_ON_ONCE(!group_item
))
8840 trap_item
->group_item
= group_item
;
8845 static void devlink_trap_notify(struct devlink
*devlink
,
8846 const struct devlink_trap_item
*trap_item
,
8847 enum devlink_command cmd
)
8849 struct sk_buff
*msg
;
8852 WARN_ON_ONCE(cmd
!= DEVLINK_CMD_TRAP_NEW
&&
8853 cmd
!= DEVLINK_CMD_TRAP_DEL
);
8855 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
8859 err
= devlink_nl_trap_fill(msg
, devlink
, trap_item
, cmd
, 0, 0, 0);
8865 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
8866 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
8870 devlink_trap_register(struct devlink
*devlink
,
8871 const struct devlink_trap
*trap
, void *priv
)
8873 struct devlink_trap_item
*trap_item
;
8876 if (devlink_trap_item_lookup(devlink
, trap
->name
))
8879 trap_item
= kzalloc(sizeof(*trap_item
), GFP_KERNEL
);
8883 trap_item
->stats
= netdev_alloc_pcpu_stats(struct devlink_stats
);
8884 if (!trap_item
->stats
) {
8886 goto err_stats_alloc
;
8889 trap_item
->trap
= trap
;
8890 trap_item
->action
= trap
->init_action
;
8891 trap_item
->priv
= priv
;
8893 err
= devlink_trap_item_group_link(devlink
, trap_item
);
8895 goto err_group_link
;
8897 err
= devlink
->ops
->trap_init(devlink
, trap
, trap_item
);
8901 list_add_tail(&trap_item
->list
, &devlink
->trap_list
);
8902 devlink_trap_notify(devlink
, trap_item
, DEVLINK_CMD_TRAP_NEW
);
8908 free_percpu(trap_item
->stats
);
8914 static void devlink_trap_unregister(struct devlink
*devlink
,
8915 const struct devlink_trap
*trap
)
8917 struct devlink_trap_item
*trap_item
;
8919 trap_item
= devlink_trap_item_lookup(devlink
, trap
->name
);
8920 if (WARN_ON_ONCE(!trap_item
))
8923 devlink_trap_notify(devlink
, trap_item
, DEVLINK_CMD_TRAP_DEL
);
8924 list_del(&trap_item
->list
);
8925 if (devlink
->ops
->trap_fini
)
8926 devlink
->ops
->trap_fini(devlink
, trap
, trap_item
);
8927 free_percpu(trap_item
->stats
);
8931 static void devlink_trap_disable(struct devlink
*devlink
,
8932 const struct devlink_trap
*trap
)
8934 struct devlink_trap_item
*trap_item
;
8936 trap_item
= devlink_trap_item_lookup(devlink
, trap
->name
);
8937 if (WARN_ON_ONCE(!trap_item
))
8940 devlink
->ops
->trap_action_set(devlink
, trap
, DEVLINK_TRAP_ACTION_DROP
);
8941 trap_item
->action
= DEVLINK_TRAP_ACTION_DROP
;
8945 * devlink_traps_register - Register packet traps with devlink.
8946 * @devlink: devlink.
8947 * @traps: Packet traps.
8948 * @traps_count: Count of provided packet traps.
8949 * @priv: Driver private information.
8951 * Return: Non-zero value on failure.
8953 int devlink_traps_register(struct devlink
*devlink
,
8954 const struct devlink_trap
*traps
,
8955 size_t traps_count
, void *priv
)
8959 if (!devlink
->ops
->trap_init
|| !devlink
->ops
->trap_action_set
)
8962 mutex_lock(&devlink
->lock
);
8963 for (i
= 0; i
< traps_count
; i
++) {
8964 const struct devlink_trap
*trap
= &traps
[i
];
8966 err
= devlink_trap_verify(trap
);
8968 goto err_trap_verify
;
8970 err
= devlink_trap_register(devlink
, trap
, priv
);
8972 goto err_trap_register
;
8974 mutex_unlock(&devlink
->lock
);
8980 for (i
--; i
>= 0; i
--)
8981 devlink_trap_unregister(devlink
, &traps
[i
]);
8982 mutex_unlock(&devlink
->lock
);
8985 EXPORT_SYMBOL_GPL(devlink_traps_register
);
8988 * devlink_traps_unregister - Unregister packet traps from devlink.
8989 * @devlink: devlink.
8990 * @traps: Packet traps.
8991 * @traps_count: Count of provided packet traps.
8993 void devlink_traps_unregister(struct devlink
*devlink
,
8994 const struct devlink_trap
*traps
,
8999 mutex_lock(&devlink
->lock
);
9000 /* Make sure we do not have any packets in-flight while unregistering
9001 * traps by disabling all of them and waiting for a grace period.
9003 for (i
= traps_count
- 1; i
>= 0; i
--)
9004 devlink_trap_disable(devlink
, &traps
[i
]);
9006 for (i
= traps_count
- 1; i
>= 0; i
--)
9007 devlink_trap_unregister(devlink
, &traps
[i
]);
9008 mutex_unlock(&devlink
->lock
);
9010 EXPORT_SYMBOL_GPL(devlink_traps_unregister
);
9013 devlink_trap_stats_update(struct devlink_stats __percpu
*trap_stats
,
9016 struct devlink_stats
*stats
;
9018 stats
= this_cpu_ptr(trap_stats
);
9019 u64_stats_update_begin(&stats
->syncp
);
9020 stats
->rx_bytes
+= skb_len
;
9021 stats
->rx_packets
++;
9022 u64_stats_update_end(&stats
->syncp
);
9026 devlink_trap_report_metadata_fill(struct net_dm_hw_metadata
*hw_metadata
,
9027 const struct devlink_trap_item
*trap_item
,
9028 struct devlink_port
*in_devlink_port
,
9029 const struct flow_action_cookie
*fa_cookie
)
9031 struct devlink_trap_group_item
*group_item
= trap_item
->group_item
;
9033 hw_metadata
->trap_group_name
= group_item
->group
->name
;
9034 hw_metadata
->trap_name
= trap_item
->trap
->name
;
9035 hw_metadata
->fa_cookie
= fa_cookie
;
9037 spin_lock(&in_devlink_port
->type_lock
);
9038 if (in_devlink_port
->type
== DEVLINK_PORT_TYPE_ETH
)
9039 hw_metadata
->input_dev
= in_devlink_port
->type_dev
;
9040 spin_unlock(&in_devlink_port
->type_lock
);
9044 * devlink_trap_report - Report trapped packet to drop monitor.
9045 * @devlink: devlink.
9046 * @skb: Trapped packet.
9047 * @trap_ctx: Trap context.
9048 * @in_devlink_port: Input devlink port.
9049 * @fa_cookie: Flow action cookie. Could be NULL.
9051 void devlink_trap_report(struct devlink
*devlink
, struct sk_buff
*skb
,
9052 void *trap_ctx
, struct devlink_port
*in_devlink_port
,
9053 const struct flow_action_cookie
*fa_cookie
)
9056 struct devlink_trap_item
*trap_item
= trap_ctx
;
9057 struct net_dm_hw_metadata hw_metadata
= {};
9059 devlink_trap_stats_update(trap_item
->stats
, skb
->len
);
9060 devlink_trap_stats_update(trap_item
->group_item
->stats
, skb
->len
);
9062 /* Control packets were not dropped by the device or encountered an
9063 * exception during forwarding and therefore should not be reported to
9064 * the kernel's drop monitor.
9066 if (trap_item
->trap
->type
== DEVLINK_TRAP_TYPE_CONTROL
)
9069 devlink_trap_report_metadata_fill(&hw_metadata
, trap_item
,
9070 in_devlink_port
, fa_cookie
);
9071 net_dm_hw_report(skb
, &hw_metadata
);
9073 EXPORT_SYMBOL_GPL(devlink_trap_report
);
9076 * devlink_trap_ctx_priv - Trap context to driver private information.
9077 * @trap_ctx: Trap context.
9079 * Return: Driver private information passed during registration.
9081 void *devlink_trap_ctx_priv(void *trap_ctx
)
9083 struct devlink_trap_item
*trap_item
= trap_ctx
;
9085 return trap_item
->priv
;
9087 EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv
);
9090 devlink_trap_group_item_policer_link(struct devlink
*devlink
,
9091 struct devlink_trap_group_item
*group_item
)
9093 u32 policer_id
= group_item
->group
->init_policer_id
;
9094 struct devlink_trap_policer_item
*policer_item
;
9096 if (policer_id
== 0)
9099 policer_item
= devlink_trap_policer_item_lookup(devlink
, policer_id
);
9100 if (WARN_ON_ONCE(!policer_item
))
9103 group_item
->policer_item
= policer_item
;
9109 devlink_trap_group_register(struct devlink
*devlink
,
9110 const struct devlink_trap_group
*group
)
9112 struct devlink_trap_group_item
*group_item
;
9115 if (devlink_trap_group_item_lookup(devlink
, group
->name
))
9118 group_item
= kzalloc(sizeof(*group_item
), GFP_KERNEL
);
9122 group_item
->stats
= netdev_alloc_pcpu_stats(struct devlink_stats
);
9123 if (!group_item
->stats
) {
9125 goto err_stats_alloc
;
9128 group_item
->group
= group
;
9130 err
= devlink_trap_group_item_policer_link(devlink
, group_item
);
9132 goto err_policer_link
;
9134 if (devlink
->ops
->trap_group_init
) {
9135 err
= devlink
->ops
->trap_group_init(devlink
, group
);
9137 goto err_group_init
;
9140 list_add_tail(&group_item
->list
, &devlink
->trap_group_list
);
9141 devlink_trap_group_notify(devlink
, group_item
,
9142 DEVLINK_CMD_TRAP_GROUP_NEW
);
9148 free_percpu(group_item
->stats
);
9155 devlink_trap_group_unregister(struct devlink
*devlink
,
9156 const struct devlink_trap_group
*group
)
9158 struct devlink_trap_group_item
*group_item
;
9160 group_item
= devlink_trap_group_item_lookup(devlink
, group
->name
);
9161 if (WARN_ON_ONCE(!group_item
))
9164 devlink_trap_group_notify(devlink
, group_item
,
9165 DEVLINK_CMD_TRAP_GROUP_DEL
);
9166 list_del(&group_item
->list
);
9167 free_percpu(group_item
->stats
);
9172 * devlink_trap_groups_register - Register packet trap groups with devlink.
9173 * @devlink: devlink.
9174 * @groups: Packet trap groups.
9175 * @groups_count: Count of provided packet trap groups.
9177 * Return: Non-zero value on failure.
9179 int devlink_trap_groups_register(struct devlink
*devlink
,
9180 const struct devlink_trap_group
*groups
,
9181 size_t groups_count
)
9185 mutex_lock(&devlink
->lock
);
9186 for (i
= 0; i
< groups_count
; i
++) {
9187 const struct devlink_trap_group
*group
= &groups
[i
];
9189 err
= devlink_trap_group_verify(group
);
9191 goto err_trap_group_verify
;
9193 err
= devlink_trap_group_register(devlink
, group
);
9195 goto err_trap_group_register
;
9197 mutex_unlock(&devlink
->lock
);
9201 err_trap_group_register
:
9202 err_trap_group_verify
:
9203 for (i
--; i
>= 0; i
--)
9204 devlink_trap_group_unregister(devlink
, &groups
[i
]);
9205 mutex_unlock(&devlink
->lock
);
9208 EXPORT_SYMBOL_GPL(devlink_trap_groups_register
);
9211 * devlink_trap_groups_unregister - Unregister packet trap groups from devlink.
9212 * @devlink: devlink.
9213 * @groups: Packet trap groups.
9214 * @groups_count: Count of provided packet trap groups.
9216 void devlink_trap_groups_unregister(struct devlink
*devlink
,
9217 const struct devlink_trap_group
*groups
,
9218 size_t groups_count
)
9222 mutex_lock(&devlink
->lock
);
9223 for (i
= groups_count
- 1; i
>= 0; i
--)
9224 devlink_trap_group_unregister(devlink
, &groups
[i
]);
9225 mutex_unlock(&devlink
->lock
);
9227 EXPORT_SYMBOL_GPL(devlink_trap_groups_unregister
);
9230 devlink_trap_policer_notify(struct devlink
*devlink
,
9231 const struct devlink_trap_policer_item
*policer_item
,
9232 enum devlink_command cmd
)
9234 struct sk_buff
*msg
;
9237 WARN_ON_ONCE(cmd
!= DEVLINK_CMD_TRAP_POLICER_NEW
&&
9238 cmd
!= DEVLINK_CMD_TRAP_POLICER_DEL
);
9240 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
9244 err
= devlink_nl_trap_policer_fill(msg
, devlink
, policer_item
, cmd
, 0,
9251 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
9252 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
9256 devlink_trap_policer_register(struct devlink
*devlink
,
9257 const struct devlink_trap_policer
*policer
)
9259 struct devlink_trap_policer_item
*policer_item
;
9262 if (devlink_trap_policer_item_lookup(devlink
, policer
->id
))
9265 policer_item
= kzalloc(sizeof(*policer_item
), GFP_KERNEL
);
9269 policer_item
->policer
= policer
;
9270 policer_item
->rate
= policer
->init_rate
;
9271 policer_item
->burst
= policer
->init_burst
;
9273 if (devlink
->ops
->trap_policer_init
) {
9274 err
= devlink
->ops
->trap_policer_init(devlink
, policer
);
9276 goto err_policer_init
;
9279 list_add_tail(&policer_item
->list
, &devlink
->trap_policer_list
);
9280 devlink_trap_policer_notify(devlink
, policer_item
,
9281 DEVLINK_CMD_TRAP_POLICER_NEW
);
9286 kfree(policer_item
);
9291 devlink_trap_policer_unregister(struct devlink
*devlink
,
9292 const struct devlink_trap_policer
*policer
)
9294 struct devlink_trap_policer_item
*policer_item
;
9296 policer_item
= devlink_trap_policer_item_lookup(devlink
, policer
->id
);
9297 if (WARN_ON_ONCE(!policer_item
))
9300 devlink_trap_policer_notify(devlink
, policer_item
,
9301 DEVLINK_CMD_TRAP_POLICER_DEL
);
9302 list_del(&policer_item
->list
);
9303 if (devlink
->ops
->trap_policer_fini
)
9304 devlink
->ops
->trap_policer_fini(devlink
, policer
);
9305 kfree(policer_item
);
9309 * devlink_trap_policers_register - Register packet trap policers with devlink.
9310 * @devlink: devlink.
9311 * @policers: Packet trap policers.
9312 * @policers_count: Count of provided packet trap policers.
9314 * Return: Non-zero value on failure.
9317 devlink_trap_policers_register(struct devlink
*devlink
,
9318 const struct devlink_trap_policer
*policers
,
9319 size_t policers_count
)
9323 mutex_lock(&devlink
->lock
);
9324 for (i
= 0; i
< policers_count
; i
++) {
9325 const struct devlink_trap_policer
*policer
= &policers
[i
];
9327 if (WARN_ON(policer
->id
== 0 ||
9328 policer
->max_rate
< policer
->min_rate
||
9329 policer
->max_burst
< policer
->min_burst
)) {
9331 goto err_trap_policer_verify
;
9334 err
= devlink_trap_policer_register(devlink
, policer
);
9336 goto err_trap_policer_register
;
9338 mutex_unlock(&devlink
->lock
);
9342 err_trap_policer_register
:
9343 err_trap_policer_verify
:
9344 for (i
--; i
>= 0; i
--)
9345 devlink_trap_policer_unregister(devlink
, &policers
[i
]);
9346 mutex_unlock(&devlink
->lock
);
9349 EXPORT_SYMBOL_GPL(devlink_trap_policers_register
);
9352 * devlink_trap_policers_unregister - Unregister packet trap policers from devlink.
9353 * @devlink: devlink.
9354 * @policers: Packet trap policers.
9355 * @policers_count: Count of provided packet trap policers.
9358 devlink_trap_policers_unregister(struct devlink
*devlink
,
9359 const struct devlink_trap_policer
*policers
,
9360 size_t policers_count
)
9364 mutex_lock(&devlink
->lock
);
9365 for (i
= policers_count
- 1; i
>= 0; i
--)
9366 devlink_trap_policer_unregister(devlink
, &policers
[i
]);
9367 mutex_unlock(&devlink
->lock
);
9369 EXPORT_SYMBOL_GPL(devlink_trap_policers_unregister
);
9371 static void __devlink_compat_running_version(struct devlink
*devlink
,
9372 char *buf
, size_t len
)
9374 const struct nlattr
*nlattr
;
9375 struct devlink_info_req req
;
9376 struct sk_buff
*msg
;
9379 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
9384 err
= devlink
->ops
->info_get(devlink
, &req
, NULL
);
9388 nla_for_each_attr(nlattr
, (void *)msg
->data
, msg
->len
, rem
) {
9389 const struct nlattr
*kv
;
9392 if (nla_type(nlattr
) != DEVLINK_ATTR_INFO_VERSION_RUNNING
)
9395 nla_for_each_nested(kv
, nlattr
, rem_kv
) {
9396 if (nla_type(kv
) != DEVLINK_ATTR_INFO_VERSION_VALUE
)
9399 strlcat(buf
, nla_data(kv
), len
);
9400 strlcat(buf
, " ", len
);
9407 void devlink_compat_running_version(struct net_device
*dev
,
9408 char *buf
, size_t len
)
9410 struct devlink
*devlink
;
9415 devlink
= netdev_to_devlink(dev
);
9416 if (!devlink
|| !devlink
->ops
->info_get
)
9419 mutex_lock(&devlink
->lock
);
9420 __devlink_compat_running_version(devlink
, buf
, len
);
9421 mutex_unlock(&devlink
->lock
);
9428 int devlink_compat_flash_update(struct net_device
*dev
, const char *file_name
)
9430 struct devlink
*devlink
;
9436 devlink
= netdev_to_devlink(dev
);
9437 if (!devlink
|| !devlink
->ops
->flash_update
) {
9442 mutex_lock(&devlink
->lock
);
9443 ret
= devlink
->ops
->flash_update(devlink
, file_name
, NULL
, NULL
);
9444 mutex_unlock(&devlink
->lock
);
9453 int devlink_compat_phys_port_name_get(struct net_device
*dev
,
9454 char *name
, size_t len
)
9456 struct devlink_port
*devlink_port
;
9458 /* RTNL mutex is held here which ensures that devlink_port
9459 * instance cannot disappear in the middle. No need to take
9460 * any devlink lock as only permanent values are accessed.
9464 devlink_port
= netdev_to_devlink_port(dev
);
9468 return __devlink_port_phys_port_name_get(devlink_port
, name
, len
);
9471 int devlink_compat_switch_id_get(struct net_device
*dev
,
9472 struct netdev_phys_item_id
*ppid
)
9474 struct devlink_port
*devlink_port
;
9476 /* Caller must hold RTNL mutex or reference to dev, which ensures that
9477 * devlink_port instance cannot disappear in the middle. No need to take
9478 * any devlink lock as only permanent values are accessed.
9480 devlink_port
= netdev_to_devlink_port(dev
);
9481 if (!devlink_port
|| !devlink_port
->switch_port
)
9484 memcpy(ppid
, &devlink_port
->attrs
.switch_id
, sizeof(*ppid
));
9489 static void __net_exit
devlink_pernet_pre_exit(struct net
*net
)
9491 struct devlink
*devlink
;
9494 /* In case network namespace is getting destroyed, reload
9495 * all devlink instances from this namespace into init_net.
9497 mutex_lock(&devlink_mutex
);
9498 list_for_each_entry(devlink
, &devlink_list
, list
) {
9499 if (net_eq(devlink_net(devlink
), net
)) {
9500 if (WARN_ON(!devlink_reload_supported(devlink
)))
9502 err
= devlink_reload(devlink
, &init_net
, NULL
);
9503 if (err
&& err
!= -EOPNOTSUPP
)
9504 pr_warn("Failed to reload devlink instance into init_net\n");
9507 mutex_unlock(&devlink_mutex
);
9510 static struct pernet_operations devlink_pernet_ops __net_initdata
= {
9511 .pre_exit
= devlink_pernet_pre_exit
,
9514 static int __init
devlink_init(void)
9518 err
= genl_register_family(&devlink_nl_family
);
9521 err
= register_pernet_subsys(&devlink_pernet_ops
);
9528 subsys_initcall(devlink_init
);