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_DEVLINK_OR_PORT BIT(2)
392 #define DEVLINK_NL_FLAG_NEED_SB BIT(3)
394 /* The per devlink instance lock is taken by default in the pre-doit
395 * operation, yet several commands do not require this. The global
396 * devlink lock is taken and protects from disruption by user-calls.
398 #define DEVLINK_NL_FLAG_NO_LOCK BIT(4)
400 static int devlink_nl_pre_doit(const struct genl_ops
*ops
,
401 struct sk_buff
*skb
, struct genl_info
*info
)
403 struct devlink_port
*devlink_port
;
404 struct devlink
*devlink
;
407 mutex_lock(&devlink_mutex
);
408 devlink
= devlink_get_from_info(info
);
409 if (IS_ERR(devlink
)) {
410 mutex_unlock(&devlink_mutex
);
411 return PTR_ERR(devlink
);
413 if (~ops
->internal_flags
& DEVLINK_NL_FLAG_NO_LOCK
)
414 mutex_lock(&devlink
->lock
);
415 if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_DEVLINK
) {
416 info
->user_ptr
[0] = devlink
;
417 } else if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_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
;
424 } else if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT
) {
425 info
->user_ptr
[0] = devlink
;
426 devlink_port
= devlink_port_get_from_info(devlink
, info
);
427 if (!IS_ERR(devlink_port
))
428 info
->user_ptr
[1] = devlink_port
;
430 if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_SB
) {
431 struct devlink_sb
*devlink_sb
;
433 devlink_sb
= devlink_sb_get_from_info(devlink
, info
);
434 if (IS_ERR(devlink_sb
)) {
435 err
= PTR_ERR(devlink_sb
);
438 info
->user_ptr
[1] = devlink_sb
;
443 if (~ops
->internal_flags
& DEVLINK_NL_FLAG_NO_LOCK
)
444 mutex_unlock(&devlink
->lock
);
445 mutex_unlock(&devlink_mutex
);
449 static void devlink_nl_post_doit(const struct genl_ops
*ops
,
450 struct sk_buff
*skb
, struct genl_info
*info
)
452 struct devlink
*devlink
;
454 /* When devlink changes netns, it would not be found
455 * by devlink_get_from_info(). So try if it is stored first.
457 if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_DEVLINK
) {
458 devlink
= info
->user_ptr
[0];
460 devlink
= devlink_get_from_info(info
);
461 WARN_ON(IS_ERR(devlink
));
463 if (!IS_ERR(devlink
) && ~ops
->internal_flags
& DEVLINK_NL_FLAG_NO_LOCK
)
464 mutex_unlock(&devlink
->lock
);
465 mutex_unlock(&devlink_mutex
);
468 static struct genl_family devlink_nl_family
;
470 enum devlink_multicast_groups
{
471 DEVLINK_MCGRP_CONFIG
,
474 static const struct genl_multicast_group devlink_nl_mcgrps
[] = {
475 [DEVLINK_MCGRP_CONFIG
] = { .name
= DEVLINK_GENL_MCGRP_CONFIG_NAME
},
478 static int devlink_nl_put_handle(struct sk_buff
*msg
, struct devlink
*devlink
)
480 if (nla_put_string(msg
, DEVLINK_ATTR_BUS_NAME
, devlink
->dev
->bus
->name
))
482 if (nla_put_string(msg
, DEVLINK_ATTR_DEV_NAME
, dev_name(devlink
->dev
)))
487 static int devlink_nl_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
488 enum devlink_command cmd
, u32 portid
,
493 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
497 if (devlink_nl_put_handle(msg
, devlink
))
498 goto nla_put_failure
;
499 if (nla_put_u8(msg
, DEVLINK_ATTR_RELOAD_FAILED
, devlink
->reload_failed
))
500 goto nla_put_failure
;
502 genlmsg_end(msg
, hdr
);
506 genlmsg_cancel(msg
, hdr
);
510 static void devlink_notify(struct devlink
*devlink
, enum devlink_command cmd
)
515 WARN_ON(cmd
!= DEVLINK_CMD_NEW
&& cmd
!= DEVLINK_CMD_DEL
);
517 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
521 err
= devlink_nl_fill(msg
, devlink
, cmd
, 0, 0, 0);
527 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
528 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
531 static int devlink_nl_port_attrs_put(struct sk_buff
*msg
,
532 struct devlink_port
*devlink_port
)
534 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
536 if (!devlink_port
->attrs_set
)
539 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_LANES
, attrs
->lanes
))
542 if (nla_put_u8(msg
, DEVLINK_ATTR_PORT_SPLITTABLE
, attrs
->splittable
))
544 if (nla_put_u16(msg
, DEVLINK_ATTR_PORT_FLAVOUR
, attrs
->flavour
))
546 switch (devlink_port
->attrs
.flavour
) {
547 case DEVLINK_PORT_FLAVOUR_PCI_PF
:
548 if (nla_put_u16(msg
, DEVLINK_ATTR_PORT_PCI_PF_NUMBER
,
552 case DEVLINK_PORT_FLAVOUR_PCI_VF
:
553 if (nla_put_u16(msg
, DEVLINK_ATTR_PORT_PCI_PF_NUMBER
,
555 nla_put_u16(msg
, DEVLINK_ATTR_PORT_PCI_VF_NUMBER
,
559 case DEVLINK_PORT_FLAVOUR_PHYSICAL
:
560 case DEVLINK_PORT_FLAVOUR_CPU
:
561 case DEVLINK_PORT_FLAVOUR_DSA
:
562 case DEVLINK_PORT_FLAVOUR_VIRTUAL
:
563 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_NUMBER
,
564 attrs
->phys
.port_number
))
568 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_SPLIT_GROUP
,
569 attrs
->phys
.port_number
))
571 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER
,
572 attrs
->phys
.split_subport_number
))
582 devlink_nl_port_function_attrs_put(struct sk_buff
*msg
, struct devlink_port
*port
,
583 struct netlink_ext_ack
*extack
)
585 struct devlink
*devlink
= port
->devlink
;
586 const struct devlink_ops
*ops
;
587 struct nlattr
*function_attr
;
588 bool empty_nest
= true;
591 function_attr
= nla_nest_start_noflag(msg
, DEVLINK_ATTR_PORT_FUNCTION
);
596 if (ops
->port_function_hw_addr_get
) {
598 u8 hw_addr
[MAX_ADDR_LEN
];
600 err
= ops
->port_function_hw_addr_get(devlink
, port
, hw_addr
, &hw_addr_len
, extack
);
601 if (err
== -EOPNOTSUPP
) {
602 /* Port function attributes are optional for a port. If port doesn't
603 * support function attribute, returning -EOPNOTSUPP is not an error.
610 err
= nla_put(msg
, DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR
, hw_addr_len
, hw_addr
);
617 if (err
|| empty_nest
)
618 nla_nest_cancel(msg
, function_attr
);
620 nla_nest_end(msg
, function_attr
);
624 static int devlink_nl_port_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
625 struct devlink_port
*devlink_port
,
626 enum devlink_command cmd
, u32 portid
,
628 struct netlink_ext_ack
*extack
)
632 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
636 if (devlink_nl_put_handle(msg
, devlink
))
637 goto nla_put_failure
;
638 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, devlink_port
->index
))
639 goto nla_put_failure
;
641 spin_lock_bh(&devlink_port
->type_lock
);
642 if (nla_put_u16(msg
, DEVLINK_ATTR_PORT_TYPE
, devlink_port
->type
))
643 goto nla_put_failure_type_locked
;
644 if (devlink_port
->desired_type
!= DEVLINK_PORT_TYPE_NOTSET
&&
645 nla_put_u16(msg
, DEVLINK_ATTR_PORT_DESIRED_TYPE
,
646 devlink_port
->desired_type
))
647 goto nla_put_failure_type_locked
;
648 if (devlink_port
->type
== DEVLINK_PORT_TYPE_ETH
) {
649 struct net_device
*netdev
= devlink_port
->type_dev
;
652 (nla_put_u32(msg
, DEVLINK_ATTR_PORT_NETDEV_IFINDEX
,
654 nla_put_string(msg
, DEVLINK_ATTR_PORT_NETDEV_NAME
,
656 goto nla_put_failure_type_locked
;
658 if (devlink_port
->type
== DEVLINK_PORT_TYPE_IB
) {
659 struct ib_device
*ibdev
= devlink_port
->type_dev
;
662 nla_put_string(msg
, DEVLINK_ATTR_PORT_IBDEV_NAME
,
664 goto nla_put_failure_type_locked
;
666 spin_unlock_bh(&devlink_port
->type_lock
);
667 if (devlink_nl_port_attrs_put(msg
, devlink_port
))
668 goto nla_put_failure
;
669 if (devlink_nl_port_function_attrs_put(msg
, devlink_port
, extack
))
670 goto nla_put_failure
;
672 genlmsg_end(msg
, hdr
);
675 nla_put_failure_type_locked
:
676 spin_unlock_bh(&devlink_port
->type_lock
);
678 genlmsg_cancel(msg
, hdr
);
682 static void devlink_port_notify(struct devlink_port
*devlink_port
,
683 enum devlink_command cmd
)
685 struct devlink
*devlink
= devlink_port
->devlink
;
689 if (!devlink_port
->registered
)
692 WARN_ON(cmd
!= DEVLINK_CMD_PORT_NEW
&& cmd
!= DEVLINK_CMD_PORT_DEL
);
694 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
698 err
= devlink_nl_port_fill(msg
, devlink
, devlink_port
, cmd
, 0, 0, 0,
705 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
706 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
709 static int devlink_nl_cmd_get_doit(struct sk_buff
*skb
, struct genl_info
*info
)
711 struct devlink
*devlink
= info
->user_ptr
[0];
715 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
719 err
= devlink_nl_fill(msg
, devlink
, DEVLINK_CMD_NEW
,
720 info
->snd_portid
, info
->snd_seq
, 0);
726 return genlmsg_reply(msg
, info
);
729 static int devlink_nl_cmd_get_dumpit(struct sk_buff
*msg
,
730 struct netlink_callback
*cb
)
732 struct devlink
*devlink
;
733 int start
= cb
->args
[0];
737 mutex_lock(&devlink_mutex
);
738 list_for_each_entry(devlink
, &devlink_list
, list
) {
739 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
745 err
= devlink_nl_fill(msg
, devlink
, DEVLINK_CMD_NEW
,
746 NETLINK_CB(cb
->skb
).portid
,
747 cb
->nlh
->nlmsg_seq
, NLM_F_MULTI
);
753 mutex_unlock(&devlink_mutex
);
759 static int devlink_nl_cmd_port_get_doit(struct sk_buff
*skb
,
760 struct genl_info
*info
)
762 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
763 struct devlink
*devlink
= devlink_port
->devlink
;
767 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
771 err
= devlink_nl_port_fill(msg
, devlink
, devlink_port
,
772 DEVLINK_CMD_PORT_NEW
,
773 info
->snd_portid
, info
->snd_seq
, 0,
780 return genlmsg_reply(msg
, info
);
783 static int devlink_nl_cmd_port_get_dumpit(struct sk_buff
*msg
,
784 struct netlink_callback
*cb
)
786 struct devlink
*devlink
;
787 struct devlink_port
*devlink_port
;
788 int start
= cb
->args
[0];
792 mutex_lock(&devlink_mutex
);
793 list_for_each_entry(devlink
, &devlink_list
, list
) {
794 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
796 mutex_lock(&devlink
->lock
);
797 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
802 err
= devlink_nl_port_fill(msg
, devlink
, devlink_port
,
804 NETLINK_CB(cb
->skb
).portid
,
809 mutex_unlock(&devlink
->lock
);
814 mutex_unlock(&devlink
->lock
);
817 mutex_unlock(&devlink_mutex
);
823 static int devlink_port_type_set(struct devlink
*devlink
,
824 struct devlink_port
*devlink_port
,
825 enum devlink_port_type port_type
)
830 if (devlink
->ops
->port_type_set
) {
831 if (port_type
== DEVLINK_PORT_TYPE_NOTSET
)
833 if (port_type
== devlink_port
->type
)
835 err
= devlink
->ops
->port_type_set(devlink_port
, port_type
);
838 devlink_port
->desired_type
= port_type
;
839 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
846 devlink_port_function_hw_addr_set(struct devlink
*devlink
, struct devlink_port
*port
,
847 const struct nlattr
*attr
, struct netlink_ext_ack
*extack
)
849 const struct devlink_ops
*ops
;
854 hw_addr
= nla_data(attr
);
855 hw_addr_len
= nla_len(attr
);
856 if (hw_addr_len
> MAX_ADDR_LEN
) {
857 NL_SET_ERR_MSG_MOD(extack
, "Port function hardware address too long");
860 if (port
->type
== DEVLINK_PORT_TYPE_ETH
) {
861 if (hw_addr_len
!= ETH_ALEN
) {
862 NL_SET_ERR_MSG_MOD(extack
, "Address must be 6 bytes for Ethernet device");
865 if (!is_unicast_ether_addr(hw_addr
)) {
866 NL_SET_ERR_MSG_MOD(extack
, "Non-unicast hardware address unsupported");
872 if (!ops
->port_function_hw_addr_set
) {
873 NL_SET_ERR_MSG_MOD(extack
, "Port doesn't support function attributes");
877 err
= ops
->port_function_hw_addr_set(devlink
, port
, hw_addr
, hw_addr_len
, extack
);
881 devlink_port_notify(port
, DEVLINK_CMD_PORT_NEW
);
886 devlink_port_function_set(struct devlink
*devlink
, struct devlink_port
*port
,
887 const struct nlattr
*attr
, struct netlink_ext_ack
*extack
)
889 struct nlattr
*tb
[DEVLINK_PORT_FUNCTION_ATTR_MAX
+ 1];
892 err
= nla_parse_nested(tb
, DEVLINK_PORT_FUNCTION_ATTR_MAX
, attr
,
893 devlink_function_nl_policy
, extack
);
895 NL_SET_ERR_MSG_MOD(extack
, "Fail to parse port function attributes");
899 attr
= tb
[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR
];
901 err
= devlink_port_function_hw_addr_set(devlink
, port
, attr
, extack
);
906 static int devlink_nl_cmd_port_set_doit(struct sk_buff
*skb
,
907 struct genl_info
*info
)
909 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
910 struct devlink
*devlink
= devlink_port
->devlink
;
913 if (info
->attrs
[DEVLINK_ATTR_PORT_TYPE
]) {
914 enum devlink_port_type port_type
;
916 port_type
= nla_get_u16(info
->attrs
[DEVLINK_ATTR_PORT_TYPE
]);
917 err
= devlink_port_type_set(devlink
, devlink_port
, port_type
);
922 if (info
->attrs
[DEVLINK_ATTR_PORT_FUNCTION
]) {
923 struct nlattr
*attr
= info
->attrs
[DEVLINK_ATTR_PORT_FUNCTION
];
924 struct netlink_ext_ack
*extack
= info
->extack
;
926 err
= devlink_port_function_set(devlink
, devlink_port
, attr
, extack
);
934 static int devlink_port_split(struct devlink
*devlink
, u32 port_index
,
935 u32 count
, struct netlink_ext_ack
*extack
)
938 if (devlink
->ops
->port_split
)
939 return devlink
->ops
->port_split(devlink
, port_index
, count
,
944 static int devlink_nl_cmd_port_split_doit(struct sk_buff
*skb
,
945 struct genl_info
*info
)
947 struct devlink
*devlink
= info
->user_ptr
[0];
948 struct devlink_port
*devlink_port
;
952 if (!info
->attrs
[DEVLINK_ATTR_PORT_INDEX
] ||
953 !info
->attrs
[DEVLINK_ATTR_PORT_SPLIT_COUNT
])
956 devlink_port
= devlink_port_get_from_info(devlink
, info
);
957 port_index
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_PORT_INDEX
]);
958 count
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_PORT_SPLIT_COUNT
]);
960 if (IS_ERR(devlink_port
))
963 if (!devlink_port
->attrs
.splittable
) {
964 /* Split ports cannot be split. */
965 if (devlink_port
->attrs
.split
)
966 NL_SET_ERR_MSG_MOD(info
->extack
, "Port cannot be split further");
968 NL_SET_ERR_MSG_MOD(info
->extack
, "Port cannot be split");
972 if (count
< 2 || !is_power_of_2(count
) || count
> devlink_port
->attrs
.lanes
) {
973 NL_SET_ERR_MSG_MOD(info
->extack
, "Invalid split count");
977 return devlink_port_split(devlink
, port_index
, count
, info
->extack
);
980 static int devlink_port_unsplit(struct devlink
*devlink
, u32 port_index
,
981 struct netlink_ext_ack
*extack
)
984 if (devlink
->ops
->port_unsplit
)
985 return devlink
->ops
->port_unsplit(devlink
, port_index
, extack
);
989 static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff
*skb
,
990 struct genl_info
*info
)
992 struct devlink
*devlink
= info
->user_ptr
[0];
995 if (!info
->attrs
[DEVLINK_ATTR_PORT_INDEX
])
998 port_index
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_PORT_INDEX
]);
999 return devlink_port_unsplit(devlink
, port_index
, info
->extack
);
1002 static int devlink_nl_sb_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
1003 struct devlink_sb
*devlink_sb
,
1004 enum devlink_command cmd
, u32 portid
,
1009 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
1013 if (devlink_nl_put_handle(msg
, devlink
))
1014 goto nla_put_failure
;
1015 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
1016 goto nla_put_failure
;
1017 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_SIZE
, devlink_sb
->size
))
1018 goto nla_put_failure
;
1019 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT
,
1020 devlink_sb
->ingress_pools_count
))
1021 goto nla_put_failure
;
1022 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT
,
1023 devlink_sb
->egress_pools_count
))
1024 goto nla_put_failure
;
1025 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_INGRESS_TC_COUNT
,
1026 devlink_sb
->ingress_tc_count
))
1027 goto nla_put_failure
;
1028 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_EGRESS_TC_COUNT
,
1029 devlink_sb
->egress_tc_count
))
1030 goto nla_put_failure
;
1032 genlmsg_end(msg
, hdr
);
1036 genlmsg_cancel(msg
, hdr
);
1040 static int devlink_nl_cmd_sb_get_doit(struct sk_buff
*skb
,
1041 struct genl_info
*info
)
1043 struct devlink
*devlink
= info
->user_ptr
[0];
1044 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1045 struct sk_buff
*msg
;
1048 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1052 err
= devlink_nl_sb_fill(msg
, devlink
, devlink_sb
,
1054 info
->snd_portid
, info
->snd_seq
, 0);
1060 return genlmsg_reply(msg
, info
);
1063 static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff
*msg
,
1064 struct netlink_callback
*cb
)
1066 struct devlink
*devlink
;
1067 struct devlink_sb
*devlink_sb
;
1068 int start
= cb
->args
[0];
1072 mutex_lock(&devlink_mutex
);
1073 list_for_each_entry(devlink
, &devlink_list
, list
) {
1074 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
1076 mutex_lock(&devlink
->lock
);
1077 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
1082 err
= devlink_nl_sb_fill(msg
, devlink
, devlink_sb
,
1084 NETLINK_CB(cb
->skb
).portid
,
1088 mutex_unlock(&devlink
->lock
);
1093 mutex_unlock(&devlink
->lock
);
1096 mutex_unlock(&devlink_mutex
);
1102 static int devlink_nl_sb_pool_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
1103 struct devlink_sb
*devlink_sb
,
1104 u16 pool_index
, enum devlink_command cmd
,
1105 u32 portid
, u32 seq
, int flags
)
1107 struct devlink_sb_pool_info pool_info
;
1111 err
= devlink
->ops
->sb_pool_get(devlink
, devlink_sb
->index
,
1112 pool_index
, &pool_info
);
1116 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
1120 if (devlink_nl_put_handle(msg
, devlink
))
1121 goto nla_put_failure
;
1122 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
1123 goto nla_put_failure
;
1124 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_POOL_INDEX
, pool_index
))
1125 goto nla_put_failure
;
1126 if (nla_put_u8(msg
, DEVLINK_ATTR_SB_POOL_TYPE
, pool_info
.pool_type
))
1127 goto nla_put_failure
;
1128 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_POOL_SIZE
, pool_info
.size
))
1129 goto nla_put_failure
;
1130 if (nla_put_u8(msg
, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
,
1131 pool_info
.threshold_type
))
1132 goto nla_put_failure
;
1133 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_POOL_CELL_SIZE
,
1134 pool_info
.cell_size
))
1135 goto nla_put_failure
;
1137 genlmsg_end(msg
, hdr
);
1141 genlmsg_cancel(msg
, hdr
);
1145 static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff
*skb
,
1146 struct genl_info
*info
)
1148 struct devlink
*devlink
= info
->user_ptr
[0];
1149 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1150 struct sk_buff
*msg
;
1154 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1159 if (!devlink
->ops
->sb_pool_get
)
1162 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1166 err
= devlink_nl_sb_pool_fill(msg
, devlink
, devlink_sb
, pool_index
,
1167 DEVLINK_CMD_SB_POOL_NEW
,
1168 info
->snd_portid
, info
->snd_seq
, 0);
1174 return genlmsg_reply(msg
, info
);
1177 static int __sb_pool_get_dumpit(struct sk_buff
*msg
, int start
, int *p_idx
,
1178 struct devlink
*devlink
,
1179 struct devlink_sb
*devlink_sb
,
1180 u32 portid
, u32 seq
)
1182 u16 pool_count
= devlink_sb_pool_count(devlink_sb
);
1186 for (pool_index
= 0; pool_index
< pool_count
; pool_index
++) {
1187 if (*p_idx
< start
) {
1191 err
= devlink_nl_sb_pool_fill(msg
, devlink
,
1194 DEVLINK_CMD_SB_POOL_NEW
,
1195 portid
, seq
, NLM_F_MULTI
);
1203 static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff
*msg
,
1204 struct netlink_callback
*cb
)
1206 struct devlink
*devlink
;
1207 struct devlink_sb
*devlink_sb
;
1208 int start
= cb
->args
[0];
1212 mutex_lock(&devlink_mutex
);
1213 list_for_each_entry(devlink
, &devlink_list
, list
) {
1214 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)) ||
1215 !devlink
->ops
->sb_pool_get
)
1217 mutex_lock(&devlink
->lock
);
1218 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
1219 err
= __sb_pool_get_dumpit(msg
, start
, &idx
, devlink
,
1221 NETLINK_CB(cb
->skb
).portid
,
1222 cb
->nlh
->nlmsg_seq
);
1223 if (err
&& err
!= -EOPNOTSUPP
) {
1224 mutex_unlock(&devlink
->lock
);
1228 mutex_unlock(&devlink
->lock
);
1231 mutex_unlock(&devlink_mutex
);
1233 if (err
!= -EMSGSIZE
)
1240 static int devlink_sb_pool_set(struct devlink
*devlink
, unsigned int sb_index
,
1241 u16 pool_index
, u32 size
,
1242 enum devlink_sb_threshold_type threshold_type
,
1243 struct netlink_ext_ack
*extack
)
1246 const struct devlink_ops
*ops
= devlink
->ops
;
1248 if (ops
->sb_pool_set
)
1249 return ops
->sb_pool_set(devlink
, sb_index
, pool_index
,
1250 size
, threshold_type
, extack
);
1254 static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff
*skb
,
1255 struct genl_info
*info
)
1257 struct devlink
*devlink
= info
->user_ptr
[0];
1258 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1259 enum devlink_sb_threshold_type threshold_type
;
1264 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1269 err
= devlink_sb_th_type_get_from_info(info
, &threshold_type
);
1273 if (!info
->attrs
[DEVLINK_ATTR_SB_POOL_SIZE
])
1276 size
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_SB_POOL_SIZE
]);
1277 return devlink_sb_pool_set(devlink
, devlink_sb
->index
,
1278 pool_index
, size
, threshold_type
,
1282 static int devlink_nl_sb_port_pool_fill(struct sk_buff
*msg
,
1283 struct devlink
*devlink
,
1284 struct devlink_port
*devlink_port
,
1285 struct devlink_sb
*devlink_sb
,
1287 enum devlink_command cmd
,
1288 u32 portid
, u32 seq
, int flags
)
1290 const struct devlink_ops
*ops
= devlink
->ops
;
1295 err
= ops
->sb_port_pool_get(devlink_port
, devlink_sb
->index
,
1296 pool_index
, &threshold
);
1300 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
1304 if (devlink_nl_put_handle(msg
, devlink
))
1305 goto nla_put_failure
;
1306 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, devlink_port
->index
))
1307 goto nla_put_failure
;
1308 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
1309 goto nla_put_failure
;
1310 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_POOL_INDEX
, pool_index
))
1311 goto nla_put_failure
;
1312 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_THRESHOLD
, threshold
))
1313 goto nla_put_failure
;
1315 if (ops
->sb_occ_port_pool_get
) {
1319 err
= ops
->sb_occ_port_pool_get(devlink_port
, devlink_sb
->index
,
1320 pool_index
, &cur
, &max
);
1321 if (err
&& err
!= -EOPNOTSUPP
)
1324 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_CUR
, cur
))
1325 goto nla_put_failure
;
1326 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_MAX
, max
))
1327 goto nla_put_failure
;
1331 genlmsg_end(msg
, hdr
);
1335 genlmsg_cancel(msg
, hdr
);
1339 static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff
*skb
,
1340 struct genl_info
*info
)
1342 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1343 struct devlink
*devlink
= devlink_port
->devlink
;
1344 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1345 struct sk_buff
*msg
;
1349 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1354 if (!devlink
->ops
->sb_port_pool_get
)
1357 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1361 err
= devlink_nl_sb_port_pool_fill(msg
, devlink
, devlink_port
,
1362 devlink_sb
, pool_index
,
1363 DEVLINK_CMD_SB_PORT_POOL_NEW
,
1364 info
->snd_portid
, info
->snd_seq
, 0);
1370 return genlmsg_reply(msg
, info
);
1373 static int __sb_port_pool_get_dumpit(struct sk_buff
*msg
, int start
, int *p_idx
,
1374 struct devlink
*devlink
,
1375 struct devlink_sb
*devlink_sb
,
1376 u32 portid
, u32 seq
)
1378 struct devlink_port
*devlink_port
;
1379 u16 pool_count
= devlink_sb_pool_count(devlink_sb
);
1383 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
1384 for (pool_index
= 0; pool_index
< pool_count
; pool_index
++) {
1385 if (*p_idx
< start
) {
1389 err
= devlink_nl_sb_port_pool_fill(msg
, devlink
,
1393 DEVLINK_CMD_SB_PORT_POOL_NEW
,
1404 static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff
*msg
,
1405 struct netlink_callback
*cb
)
1407 struct devlink
*devlink
;
1408 struct devlink_sb
*devlink_sb
;
1409 int start
= cb
->args
[0];
1413 mutex_lock(&devlink_mutex
);
1414 list_for_each_entry(devlink
, &devlink_list
, list
) {
1415 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)) ||
1416 !devlink
->ops
->sb_port_pool_get
)
1418 mutex_lock(&devlink
->lock
);
1419 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
1420 err
= __sb_port_pool_get_dumpit(msg
, start
, &idx
,
1421 devlink
, devlink_sb
,
1422 NETLINK_CB(cb
->skb
).portid
,
1423 cb
->nlh
->nlmsg_seq
);
1424 if (err
&& err
!= -EOPNOTSUPP
) {
1425 mutex_unlock(&devlink
->lock
);
1429 mutex_unlock(&devlink
->lock
);
1432 mutex_unlock(&devlink_mutex
);
1434 if (err
!= -EMSGSIZE
)
1441 static int devlink_sb_port_pool_set(struct devlink_port
*devlink_port
,
1442 unsigned int sb_index
, u16 pool_index
,
1444 struct netlink_ext_ack
*extack
)
1447 const struct devlink_ops
*ops
= devlink_port
->devlink
->ops
;
1449 if (ops
->sb_port_pool_set
)
1450 return ops
->sb_port_pool_set(devlink_port
, sb_index
,
1451 pool_index
, threshold
, extack
);
1455 static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff
*skb
,
1456 struct genl_info
*info
)
1458 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1459 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1464 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1469 if (!info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
])
1472 threshold
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
]);
1473 return devlink_sb_port_pool_set(devlink_port
, devlink_sb
->index
,
1474 pool_index
, threshold
, info
->extack
);
1478 devlink_nl_sb_tc_pool_bind_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
1479 struct devlink_port
*devlink_port
,
1480 struct devlink_sb
*devlink_sb
, u16 tc_index
,
1481 enum devlink_sb_pool_type pool_type
,
1482 enum devlink_command cmd
,
1483 u32 portid
, u32 seq
, int flags
)
1485 const struct devlink_ops
*ops
= devlink
->ops
;
1491 err
= ops
->sb_tc_pool_bind_get(devlink_port
, devlink_sb
->index
,
1492 tc_index
, pool_type
,
1493 &pool_index
, &threshold
);
1497 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
1501 if (devlink_nl_put_handle(msg
, devlink
))
1502 goto nla_put_failure
;
1503 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, devlink_port
->index
))
1504 goto nla_put_failure
;
1505 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
1506 goto nla_put_failure
;
1507 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_TC_INDEX
, tc_index
))
1508 goto nla_put_failure
;
1509 if (nla_put_u8(msg
, DEVLINK_ATTR_SB_POOL_TYPE
, pool_type
))
1510 goto nla_put_failure
;
1511 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_POOL_INDEX
, pool_index
))
1512 goto nla_put_failure
;
1513 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_THRESHOLD
, threshold
))
1514 goto nla_put_failure
;
1516 if (ops
->sb_occ_tc_port_bind_get
) {
1520 err
= ops
->sb_occ_tc_port_bind_get(devlink_port
,
1522 tc_index
, pool_type
,
1524 if (err
&& err
!= -EOPNOTSUPP
)
1527 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_CUR
, cur
))
1528 goto nla_put_failure
;
1529 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_MAX
, max
))
1530 goto nla_put_failure
;
1534 genlmsg_end(msg
, hdr
);
1538 genlmsg_cancel(msg
, hdr
);
1542 static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff
*skb
,
1543 struct genl_info
*info
)
1545 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1546 struct devlink
*devlink
= devlink_port
->devlink
;
1547 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1548 struct sk_buff
*msg
;
1549 enum devlink_sb_pool_type pool_type
;
1553 err
= devlink_sb_pool_type_get_from_info(info
, &pool_type
);
1557 err
= devlink_sb_tc_index_get_from_info(devlink_sb
, info
,
1558 pool_type
, &tc_index
);
1562 if (!devlink
->ops
->sb_tc_pool_bind_get
)
1565 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1569 err
= devlink_nl_sb_tc_pool_bind_fill(msg
, devlink
, devlink_port
,
1570 devlink_sb
, tc_index
, pool_type
,
1571 DEVLINK_CMD_SB_TC_POOL_BIND_NEW
,
1579 return genlmsg_reply(msg
, info
);
1582 static int __sb_tc_pool_bind_get_dumpit(struct sk_buff
*msg
,
1583 int start
, int *p_idx
,
1584 struct devlink
*devlink
,
1585 struct devlink_sb
*devlink_sb
,
1586 u32 portid
, u32 seq
)
1588 struct devlink_port
*devlink_port
;
1592 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
1594 tc_index
< devlink_sb
->ingress_tc_count
; tc_index
++) {
1595 if (*p_idx
< start
) {
1599 err
= devlink_nl_sb_tc_pool_bind_fill(msg
, devlink
,
1603 DEVLINK_SB_POOL_TYPE_INGRESS
,
1604 DEVLINK_CMD_SB_TC_POOL_BIND_NEW
,
1612 tc_index
< devlink_sb
->egress_tc_count
; tc_index
++) {
1613 if (*p_idx
< start
) {
1617 err
= devlink_nl_sb_tc_pool_bind_fill(msg
, devlink
,
1621 DEVLINK_SB_POOL_TYPE_EGRESS
,
1622 DEVLINK_CMD_SB_TC_POOL_BIND_NEW
,
1634 devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff
*msg
,
1635 struct netlink_callback
*cb
)
1637 struct devlink
*devlink
;
1638 struct devlink_sb
*devlink_sb
;
1639 int start
= cb
->args
[0];
1643 mutex_lock(&devlink_mutex
);
1644 list_for_each_entry(devlink
, &devlink_list
, list
) {
1645 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)) ||
1646 !devlink
->ops
->sb_tc_pool_bind_get
)
1649 mutex_lock(&devlink
->lock
);
1650 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
1651 err
= __sb_tc_pool_bind_get_dumpit(msg
, start
, &idx
,
1654 NETLINK_CB(cb
->skb
).portid
,
1655 cb
->nlh
->nlmsg_seq
);
1656 if (err
&& err
!= -EOPNOTSUPP
) {
1657 mutex_unlock(&devlink
->lock
);
1661 mutex_unlock(&devlink
->lock
);
1664 mutex_unlock(&devlink_mutex
);
1666 if (err
!= -EMSGSIZE
)
1673 static int devlink_sb_tc_pool_bind_set(struct devlink_port
*devlink_port
,
1674 unsigned int sb_index
, u16 tc_index
,
1675 enum devlink_sb_pool_type pool_type
,
1676 u16 pool_index
, u32 threshold
,
1677 struct netlink_ext_ack
*extack
)
1680 const struct devlink_ops
*ops
= devlink_port
->devlink
->ops
;
1682 if (ops
->sb_tc_pool_bind_set
)
1683 return ops
->sb_tc_pool_bind_set(devlink_port
, sb_index
,
1684 tc_index
, pool_type
,
1685 pool_index
, threshold
, extack
);
1689 static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff
*skb
,
1690 struct genl_info
*info
)
1692 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1693 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1694 enum devlink_sb_pool_type pool_type
;
1700 err
= devlink_sb_pool_type_get_from_info(info
, &pool_type
);
1704 err
= devlink_sb_tc_index_get_from_info(devlink_sb
, info
,
1705 pool_type
, &tc_index
);
1709 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1714 if (!info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
])
1717 threshold
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
]);
1718 return devlink_sb_tc_pool_bind_set(devlink_port
, devlink_sb
->index
,
1719 tc_index
, pool_type
,
1720 pool_index
, threshold
, info
->extack
);
1723 static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff
*skb
,
1724 struct genl_info
*info
)
1726 struct devlink
*devlink
= info
->user_ptr
[0];
1727 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1728 const struct devlink_ops
*ops
= devlink
->ops
;
1730 if (ops
->sb_occ_snapshot
)
1731 return ops
->sb_occ_snapshot(devlink
, devlink_sb
->index
);
1735 static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff
*skb
,
1736 struct genl_info
*info
)
1738 struct devlink
*devlink
= info
->user_ptr
[0];
1739 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1740 const struct devlink_ops
*ops
= devlink
->ops
;
1742 if (ops
->sb_occ_max_clear
)
1743 return ops
->sb_occ_max_clear(devlink
, devlink_sb
->index
);
1747 static int devlink_nl_eswitch_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
1748 enum devlink_command cmd
, u32 portid
,
1751 const struct devlink_ops
*ops
= devlink
->ops
;
1752 enum devlink_eswitch_encap_mode encap_mode
;
1758 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
1762 err
= devlink_nl_put_handle(msg
, devlink
);
1764 goto nla_put_failure
;
1766 if (ops
->eswitch_mode_get
) {
1767 err
= ops
->eswitch_mode_get(devlink
, &mode
);
1769 goto nla_put_failure
;
1770 err
= nla_put_u16(msg
, DEVLINK_ATTR_ESWITCH_MODE
, mode
);
1772 goto nla_put_failure
;
1775 if (ops
->eswitch_inline_mode_get
) {
1776 err
= ops
->eswitch_inline_mode_get(devlink
, &inline_mode
);
1778 goto nla_put_failure
;
1779 err
= nla_put_u8(msg
, DEVLINK_ATTR_ESWITCH_INLINE_MODE
,
1782 goto nla_put_failure
;
1785 if (ops
->eswitch_encap_mode_get
) {
1786 err
= ops
->eswitch_encap_mode_get(devlink
, &encap_mode
);
1788 goto nla_put_failure
;
1789 err
= nla_put_u8(msg
, DEVLINK_ATTR_ESWITCH_ENCAP_MODE
, encap_mode
);
1791 goto nla_put_failure
;
1794 genlmsg_end(msg
, hdr
);
1798 genlmsg_cancel(msg
, hdr
);
1802 static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff
*skb
,
1803 struct genl_info
*info
)
1805 struct devlink
*devlink
= info
->user_ptr
[0];
1806 struct sk_buff
*msg
;
1809 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1813 err
= devlink_nl_eswitch_fill(msg
, devlink
, DEVLINK_CMD_ESWITCH_GET
,
1814 info
->snd_portid
, info
->snd_seq
, 0);
1821 return genlmsg_reply(msg
, info
);
1824 static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff
*skb
,
1825 struct genl_info
*info
)
1827 struct devlink
*devlink
= info
->user_ptr
[0];
1828 const struct devlink_ops
*ops
= devlink
->ops
;
1829 enum devlink_eswitch_encap_mode encap_mode
;
1834 if (info
->attrs
[DEVLINK_ATTR_ESWITCH_MODE
]) {
1835 if (!ops
->eswitch_mode_set
)
1837 mode
= nla_get_u16(info
->attrs
[DEVLINK_ATTR_ESWITCH_MODE
]);
1838 err
= ops
->eswitch_mode_set(devlink
, mode
, info
->extack
);
1843 if (info
->attrs
[DEVLINK_ATTR_ESWITCH_INLINE_MODE
]) {
1844 if (!ops
->eswitch_inline_mode_set
)
1846 inline_mode
= nla_get_u8(
1847 info
->attrs
[DEVLINK_ATTR_ESWITCH_INLINE_MODE
]);
1848 err
= ops
->eswitch_inline_mode_set(devlink
, inline_mode
,
1854 if (info
->attrs
[DEVLINK_ATTR_ESWITCH_ENCAP_MODE
]) {
1855 if (!ops
->eswitch_encap_mode_set
)
1857 encap_mode
= nla_get_u8(info
->attrs
[DEVLINK_ATTR_ESWITCH_ENCAP_MODE
]);
1858 err
= ops
->eswitch_encap_mode_set(devlink
, encap_mode
,
1867 int devlink_dpipe_match_put(struct sk_buff
*skb
,
1868 struct devlink_dpipe_match
*match
)
1870 struct devlink_dpipe_header
*header
= match
->header
;
1871 struct devlink_dpipe_field
*field
= &header
->fields
[match
->field_id
];
1872 struct nlattr
*match_attr
;
1874 match_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_MATCH
);
1878 if (nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_MATCH_TYPE
, match
->type
) ||
1879 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_INDEX
, match
->header_index
) ||
1880 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_ID
, header
->id
) ||
1881 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_ID
, field
->id
) ||
1882 nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL
, header
->global
))
1883 goto nla_put_failure
;
1885 nla_nest_end(skb
, match_attr
);
1889 nla_nest_cancel(skb
, match_attr
);
1892 EXPORT_SYMBOL_GPL(devlink_dpipe_match_put
);
1894 static int devlink_dpipe_matches_put(struct devlink_dpipe_table
*table
,
1895 struct sk_buff
*skb
)
1897 struct nlattr
*matches_attr
;
1899 matches_attr
= nla_nest_start_noflag(skb
,
1900 DEVLINK_ATTR_DPIPE_TABLE_MATCHES
);
1904 if (table
->table_ops
->matches_dump(table
->priv
, skb
))
1905 goto nla_put_failure
;
1907 nla_nest_end(skb
, matches_attr
);
1911 nla_nest_cancel(skb
, matches_attr
);
1915 int devlink_dpipe_action_put(struct sk_buff
*skb
,
1916 struct devlink_dpipe_action
*action
)
1918 struct devlink_dpipe_header
*header
= action
->header
;
1919 struct devlink_dpipe_field
*field
= &header
->fields
[action
->field_id
];
1920 struct nlattr
*action_attr
;
1922 action_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_ACTION
);
1926 if (nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_ACTION_TYPE
, action
->type
) ||
1927 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_INDEX
, action
->header_index
) ||
1928 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_ID
, header
->id
) ||
1929 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_ID
, field
->id
) ||
1930 nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL
, header
->global
))
1931 goto nla_put_failure
;
1933 nla_nest_end(skb
, action_attr
);
1937 nla_nest_cancel(skb
, action_attr
);
1940 EXPORT_SYMBOL_GPL(devlink_dpipe_action_put
);
1942 static int devlink_dpipe_actions_put(struct devlink_dpipe_table
*table
,
1943 struct sk_buff
*skb
)
1945 struct nlattr
*actions_attr
;
1947 actions_attr
= nla_nest_start_noflag(skb
,
1948 DEVLINK_ATTR_DPIPE_TABLE_ACTIONS
);
1952 if (table
->table_ops
->actions_dump(table
->priv
, skb
))
1953 goto nla_put_failure
;
1955 nla_nest_end(skb
, actions_attr
);
1959 nla_nest_cancel(skb
, actions_attr
);
1963 static int devlink_dpipe_table_put(struct sk_buff
*skb
,
1964 struct devlink_dpipe_table
*table
)
1966 struct nlattr
*table_attr
;
1969 table_size
= table
->table_ops
->size_get(table
->priv
);
1970 table_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_TABLE
);
1974 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_TABLE_NAME
, table
->name
) ||
1975 nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_TABLE_SIZE
, table_size
,
1977 goto nla_put_failure
;
1978 if (nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
,
1979 table
->counters_enabled
))
1980 goto nla_put_failure
;
1982 if (table
->resource_valid
) {
1983 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID
,
1984 table
->resource_id
, DEVLINK_ATTR_PAD
) ||
1985 nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS
,
1986 table
->resource_units
, DEVLINK_ATTR_PAD
))
1987 goto nla_put_failure
;
1989 if (devlink_dpipe_matches_put(table
, skb
))
1990 goto nla_put_failure
;
1992 if (devlink_dpipe_actions_put(table
, skb
))
1993 goto nla_put_failure
;
1995 nla_nest_end(skb
, table_attr
);
1999 nla_nest_cancel(skb
, table_attr
);
2003 static int devlink_dpipe_send_and_alloc_skb(struct sk_buff
**pskb
,
2004 struct genl_info
*info
)
2009 err
= genlmsg_reply(*pskb
, info
);
2013 *pskb
= genlmsg_new(GENLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
2019 static int devlink_dpipe_tables_fill(struct genl_info
*info
,
2020 enum devlink_command cmd
, int flags
,
2021 struct list_head
*dpipe_tables
,
2022 const char *table_name
)
2024 struct devlink
*devlink
= info
->user_ptr
[0];
2025 struct devlink_dpipe_table
*table
;
2026 struct nlattr
*tables_attr
;
2027 struct sk_buff
*skb
= NULL
;
2028 struct nlmsghdr
*nlh
;
2034 table
= list_first_entry(dpipe_tables
,
2035 struct devlink_dpipe_table
, list
);
2037 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2041 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2042 &devlink_nl_family
, NLM_F_MULTI
, cmd
);
2048 if (devlink_nl_put_handle(skb
, devlink
))
2049 goto nla_put_failure
;
2050 tables_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_TABLES
);
2052 goto nla_put_failure
;
2056 list_for_each_entry_from(table
, dpipe_tables
, list
) {
2058 err
= devlink_dpipe_table_put(skb
, table
);
2066 if (!strcmp(table
->name
, table_name
)) {
2067 err
= devlink_dpipe_table_put(skb
, table
);
2075 nla_nest_end(skb
, tables_attr
);
2076 genlmsg_end(skb
, hdr
);
2081 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2082 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
2084 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2090 return genlmsg_reply(skb
, info
);
2099 static int devlink_nl_cmd_dpipe_table_get(struct sk_buff
*skb
,
2100 struct genl_info
*info
)
2102 struct devlink
*devlink
= info
->user_ptr
[0];
2103 const char *table_name
= NULL
;
2105 if (info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
])
2106 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
2108 return devlink_dpipe_tables_fill(info
, DEVLINK_CMD_DPIPE_TABLE_GET
, 0,
2109 &devlink
->dpipe_table_list
,
2113 static int devlink_dpipe_value_put(struct sk_buff
*skb
,
2114 struct devlink_dpipe_value
*value
)
2116 if (nla_put(skb
, DEVLINK_ATTR_DPIPE_VALUE
,
2117 value
->value_size
, value
->value
))
2120 if (nla_put(skb
, DEVLINK_ATTR_DPIPE_VALUE_MASK
,
2121 value
->value_size
, value
->mask
))
2123 if (value
->mapping_valid
)
2124 if (nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_VALUE_MAPPING
,
2125 value
->mapping_value
))
2130 static int devlink_dpipe_action_value_put(struct sk_buff
*skb
,
2131 struct devlink_dpipe_value
*value
)
2135 if (devlink_dpipe_action_put(skb
, value
->action
))
2137 if (devlink_dpipe_value_put(skb
, value
))
2142 static int devlink_dpipe_action_values_put(struct sk_buff
*skb
,
2143 struct devlink_dpipe_value
*values
,
2144 unsigned int values_count
)
2146 struct nlattr
*action_attr
;
2150 for (i
= 0; i
< values_count
; i
++) {
2151 action_attr
= nla_nest_start_noflag(skb
,
2152 DEVLINK_ATTR_DPIPE_ACTION_VALUE
);
2155 err
= devlink_dpipe_action_value_put(skb
, &values
[i
]);
2157 goto err_action_value_put
;
2158 nla_nest_end(skb
, action_attr
);
2162 err_action_value_put
:
2163 nla_nest_cancel(skb
, action_attr
);
2167 static int devlink_dpipe_match_value_put(struct sk_buff
*skb
,
2168 struct devlink_dpipe_value
*value
)
2172 if (devlink_dpipe_match_put(skb
, value
->match
))
2174 if (devlink_dpipe_value_put(skb
, value
))
2179 static int devlink_dpipe_match_values_put(struct sk_buff
*skb
,
2180 struct devlink_dpipe_value
*values
,
2181 unsigned int values_count
)
2183 struct nlattr
*match_attr
;
2187 for (i
= 0; i
< values_count
; i
++) {
2188 match_attr
= nla_nest_start_noflag(skb
,
2189 DEVLINK_ATTR_DPIPE_MATCH_VALUE
);
2192 err
= devlink_dpipe_match_value_put(skb
, &values
[i
]);
2194 goto err_match_value_put
;
2195 nla_nest_end(skb
, match_attr
);
2199 err_match_value_put
:
2200 nla_nest_cancel(skb
, match_attr
);
2204 static int devlink_dpipe_entry_put(struct sk_buff
*skb
,
2205 struct devlink_dpipe_entry
*entry
)
2207 struct nlattr
*entry_attr
, *matches_attr
, *actions_attr
;
2210 entry_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_ENTRY
);
2214 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_ENTRY_INDEX
, entry
->index
,
2216 goto nla_put_failure
;
2217 if (entry
->counter_valid
)
2218 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER
,
2219 entry
->counter
, DEVLINK_ATTR_PAD
))
2220 goto nla_put_failure
;
2222 matches_attr
= nla_nest_start_noflag(skb
,
2223 DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES
);
2225 goto nla_put_failure
;
2227 err
= devlink_dpipe_match_values_put(skb
, entry
->match_values
,
2228 entry
->match_values_count
);
2230 nla_nest_cancel(skb
, matches_attr
);
2231 goto err_match_values_put
;
2233 nla_nest_end(skb
, matches_attr
);
2235 actions_attr
= nla_nest_start_noflag(skb
,
2236 DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES
);
2238 goto nla_put_failure
;
2240 err
= devlink_dpipe_action_values_put(skb
, entry
->action_values
,
2241 entry
->action_values_count
);
2243 nla_nest_cancel(skb
, actions_attr
);
2244 goto err_action_values_put
;
2246 nla_nest_end(skb
, actions_attr
);
2248 nla_nest_end(skb
, entry_attr
);
2253 err_match_values_put
:
2254 err_action_values_put
:
2255 nla_nest_cancel(skb
, entry_attr
);
2259 static struct devlink_dpipe_table
*
2260 devlink_dpipe_table_find(struct list_head
*dpipe_tables
,
2261 const char *table_name
, struct devlink
*devlink
)
2263 struct devlink_dpipe_table
*table
;
2264 list_for_each_entry_rcu(table
, dpipe_tables
, list
,
2265 lockdep_is_held(&devlink
->lock
)) {
2266 if (!strcmp(table
->name
, table_name
))
2272 int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx
*dump_ctx
)
2274 struct devlink
*devlink
;
2277 err
= devlink_dpipe_send_and_alloc_skb(&dump_ctx
->skb
,
2282 dump_ctx
->hdr
= genlmsg_put(dump_ctx
->skb
,
2283 dump_ctx
->info
->snd_portid
,
2284 dump_ctx
->info
->snd_seq
,
2285 &devlink_nl_family
, NLM_F_MULTI
,
2288 goto nla_put_failure
;
2290 devlink
= dump_ctx
->info
->user_ptr
[0];
2291 if (devlink_nl_put_handle(dump_ctx
->skb
, devlink
))
2292 goto nla_put_failure
;
2293 dump_ctx
->nest
= nla_nest_start_noflag(dump_ctx
->skb
,
2294 DEVLINK_ATTR_DPIPE_ENTRIES
);
2295 if (!dump_ctx
->nest
)
2296 goto nla_put_failure
;
2300 nlmsg_free(dump_ctx
->skb
);
2303 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare
);
2305 int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx
*dump_ctx
,
2306 struct devlink_dpipe_entry
*entry
)
2308 return devlink_dpipe_entry_put(dump_ctx
->skb
, entry
);
2310 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append
);
2312 int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx
*dump_ctx
)
2314 nla_nest_end(dump_ctx
->skb
, dump_ctx
->nest
);
2315 genlmsg_end(dump_ctx
->skb
, dump_ctx
->hdr
);
2318 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close
);
2320 void devlink_dpipe_entry_clear(struct devlink_dpipe_entry
*entry
)
2323 unsigned int value_count
, value_index
;
2324 struct devlink_dpipe_value
*value
;
2326 value
= entry
->action_values
;
2327 value_count
= entry
->action_values_count
;
2328 for (value_index
= 0; value_index
< value_count
; value_index
++) {
2329 kfree(value
[value_index
].value
);
2330 kfree(value
[value_index
].mask
);
2333 value
= entry
->match_values
;
2334 value_count
= entry
->match_values_count
;
2335 for (value_index
= 0; value_index
< value_count
; value_index
++) {
2336 kfree(value
[value_index
].value
);
2337 kfree(value
[value_index
].mask
);
2340 EXPORT_SYMBOL(devlink_dpipe_entry_clear
);
2342 static int devlink_dpipe_entries_fill(struct genl_info
*info
,
2343 enum devlink_command cmd
, int flags
,
2344 struct devlink_dpipe_table
*table
)
2346 struct devlink_dpipe_dump_ctx dump_ctx
;
2347 struct nlmsghdr
*nlh
;
2350 dump_ctx
.skb
= NULL
;
2352 dump_ctx
.info
= info
;
2354 err
= table
->table_ops
->entries_dump(table
->priv
,
2355 table
->counters_enabled
,
2361 nlh
= nlmsg_put(dump_ctx
.skb
, info
->snd_portid
, info
->snd_seq
,
2362 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
2364 err
= devlink_dpipe_send_and_alloc_skb(&dump_ctx
.skb
, info
);
2369 return genlmsg_reply(dump_ctx
.skb
, info
);
2372 static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff
*skb
,
2373 struct genl_info
*info
)
2375 struct devlink
*devlink
= info
->user_ptr
[0];
2376 struct devlink_dpipe_table
*table
;
2377 const char *table_name
;
2379 if (!info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
])
2382 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
2383 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
2384 table_name
, devlink
);
2388 if (!table
->table_ops
->entries_dump
)
2391 return devlink_dpipe_entries_fill(info
, DEVLINK_CMD_DPIPE_ENTRIES_GET
,
2395 static int devlink_dpipe_fields_put(struct sk_buff
*skb
,
2396 const struct devlink_dpipe_header
*header
)
2398 struct devlink_dpipe_field
*field
;
2399 struct nlattr
*field_attr
;
2402 for (i
= 0; i
< header
->fields_count
; i
++) {
2403 field
= &header
->fields
[i
];
2404 field_attr
= nla_nest_start_noflag(skb
,
2405 DEVLINK_ATTR_DPIPE_FIELD
);
2408 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_FIELD_NAME
, field
->name
) ||
2409 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_ID
, field
->id
) ||
2410 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH
, field
->bitwidth
) ||
2411 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE
, field
->mapping_type
))
2412 goto nla_put_failure
;
2413 nla_nest_end(skb
, field_attr
);
2418 nla_nest_cancel(skb
, field_attr
);
2422 static int devlink_dpipe_header_put(struct sk_buff
*skb
,
2423 struct devlink_dpipe_header
*header
)
2425 struct nlattr
*fields_attr
, *header_attr
;
2428 header_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_HEADER
);
2432 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_HEADER_NAME
, header
->name
) ||
2433 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_ID
, header
->id
) ||
2434 nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL
, header
->global
))
2435 goto nla_put_failure
;
2437 fields_attr
= nla_nest_start_noflag(skb
,
2438 DEVLINK_ATTR_DPIPE_HEADER_FIELDS
);
2440 goto nla_put_failure
;
2442 err
= devlink_dpipe_fields_put(skb
, header
);
2444 nla_nest_cancel(skb
, fields_attr
);
2445 goto nla_put_failure
;
2447 nla_nest_end(skb
, fields_attr
);
2448 nla_nest_end(skb
, header_attr
);
2453 nla_nest_cancel(skb
, header_attr
);
2457 static int devlink_dpipe_headers_fill(struct genl_info
*info
,
2458 enum devlink_command cmd
, int flags
,
2459 struct devlink_dpipe_headers
*
2462 struct devlink
*devlink
= info
->user_ptr
[0];
2463 struct nlattr
*headers_attr
;
2464 struct sk_buff
*skb
= NULL
;
2465 struct nlmsghdr
*nlh
;
2472 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2476 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2477 &devlink_nl_family
, NLM_F_MULTI
, cmd
);
2483 if (devlink_nl_put_handle(skb
, devlink
))
2484 goto nla_put_failure
;
2485 headers_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_DPIPE_HEADERS
);
2487 goto nla_put_failure
;
2490 for (; i
< dpipe_headers
->headers_count
; i
++) {
2491 err
= devlink_dpipe_header_put(skb
, dpipe_headers
->headers
[i
]);
2499 nla_nest_end(skb
, headers_attr
);
2500 genlmsg_end(skb
, hdr
);
2501 if (i
!= dpipe_headers
->headers_count
)
2505 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2506 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
2508 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2513 return genlmsg_reply(skb
, info
);
2522 static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff
*skb
,
2523 struct genl_info
*info
)
2525 struct devlink
*devlink
= info
->user_ptr
[0];
2527 if (!devlink
->dpipe_headers
)
2529 return devlink_dpipe_headers_fill(info
, DEVLINK_CMD_DPIPE_HEADERS_GET
,
2530 0, devlink
->dpipe_headers
);
2533 static int devlink_dpipe_table_counters_set(struct devlink
*devlink
,
2534 const char *table_name
,
2537 struct devlink_dpipe_table
*table
;
2539 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
2540 table_name
, devlink
);
2544 if (table
->counter_control_extern
)
2547 if (!(table
->counters_enabled
^ enable
))
2550 table
->counters_enabled
= enable
;
2551 if (table
->table_ops
->counters_set_update
)
2552 table
->table_ops
->counters_set_update(table
->priv
, enable
);
2556 static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff
*skb
,
2557 struct genl_info
*info
)
2559 struct devlink
*devlink
= info
->user_ptr
[0];
2560 const char *table_name
;
2561 bool counters_enable
;
2563 if (!info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
] ||
2564 !info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
])
2567 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
2568 counters_enable
= !!nla_get_u8(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
]);
2570 return devlink_dpipe_table_counters_set(devlink
, table_name
,
2574 static struct devlink_resource
*
2575 devlink_resource_find(struct devlink
*devlink
,
2576 struct devlink_resource
*resource
, u64 resource_id
)
2578 struct list_head
*resource_list
;
2581 resource_list
= &resource
->resource_list
;
2583 resource_list
= &devlink
->resource_list
;
2585 list_for_each_entry(resource
, resource_list
, list
) {
2586 struct devlink_resource
*child_resource
;
2588 if (resource
->id
== resource_id
)
2591 child_resource
= devlink_resource_find(devlink
, resource
,
2594 return child_resource
;
2600 devlink_resource_validate_children(struct devlink_resource
*resource
)
2602 struct devlink_resource
*child_resource
;
2603 bool size_valid
= true;
2606 if (list_empty(&resource
->resource_list
))
2609 list_for_each_entry(child_resource
, &resource
->resource_list
, list
)
2610 parts_size
+= child_resource
->size_new
;
2612 if (parts_size
> resource
->size_new
)
2615 resource
->size_valid
= size_valid
;
2619 devlink_resource_validate_size(struct devlink_resource
*resource
, u64 size
,
2620 struct netlink_ext_ack
*extack
)
2625 if (size
> resource
->size_params
.size_max
) {
2626 NL_SET_ERR_MSG_MOD(extack
, "Size larger than maximum");
2630 if (size
< resource
->size_params
.size_min
) {
2631 NL_SET_ERR_MSG_MOD(extack
, "Size smaller than minimum");
2635 div64_u64_rem(size
, resource
->size_params
.size_granularity
, &reminder
);
2637 NL_SET_ERR_MSG_MOD(extack
, "Wrong granularity");
2644 static int devlink_nl_cmd_resource_set(struct sk_buff
*skb
,
2645 struct genl_info
*info
)
2647 struct devlink
*devlink
= info
->user_ptr
[0];
2648 struct devlink_resource
*resource
;
2653 if (!info
->attrs
[DEVLINK_ATTR_RESOURCE_ID
] ||
2654 !info
->attrs
[DEVLINK_ATTR_RESOURCE_SIZE
])
2656 resource_id
= nla_get_u64(info
->attrs
[DEVLINK_ATTR_RESOURCE_ID
]);
2658 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
2662 size
= nla_get_u64(info
->attrs
[DEVLINK_ATTR_RESOURCE_SIZE
]);
2663 err
= devlink_resource_validate_size(resource
, size
, info
->extack
);
2667 resource
->size_new
= size
;
2668 devlink_resource_validate_children(resource
);
2669 if (resource
->parent
)
2670 devlink_resource_validate_children(resource
->parent
);
2675 devlink_resource_size_params_put(struct devlink_resource
*resource
,
2676 struct sk_buff
*skb
)
2678 struct devlink_resource_size_params
*size_params
;
2680 size_params
= &resource
->size_params
;
2681 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_GRAN
,
2682 size_params
->size_granularity
, DEVLINK_ATTR_PAD
) ||
2683 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_MAX
,
2684 size_params
->size_max
, DEVLINK_ATTR_PAD
) ||
2685 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_MIN
,
2686 size_params
->size_min
, DEVLINK_ATTR_PAD
) ||
2687 nla_put_u8(skb
, DEVLINK_ATTR_RESOURCE_UNIT
, size_params
->unit
))
2692 static int devlink_resource_occ_put(struct devlink_resource
*resource
,
2693 struct sk_buff
*skb
)
2695 if (!resource
->occ_get
)
2697 return nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_OCC
,
2698 resource
->occ_get(resource
->occ_get_priv
),
2702 static int devlink_resource_put(struct devlink
*devlink
, struct sk_buff
*skb
,
2703 struct devlink_resource
*resource
)
2705 struct devlink_resource
*child_resource
;
2706 struct nlattr
*child_resource_attr
;
2707 struct nlattr
*resource_attr
;
2709 resource_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_RESOURCE
);
2713 if (nla_put_string(skb
, DEVLINK_ATTR_RESOURCE_NAME
, resource
->name
) ||
2714 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE
, resource
->size
,
2715 DEVLINK_ATTR_PAD
) ||
2716 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_ID
, resource
->id
,
2718 goto nla_put_failure
;
2719 if (resource
->size
!= resource
->size_new
)
2720 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_NEW
,
2721 resource
->size_new
, DEVLINK_ATTR_PAD
);
2722 if (devlink_resource_occ_put(resource
, skb
))
2723 goto nla_put_failure
;
2724 if (devlink_resource_size_params_put(resource
, skb
))
2725 goto nla_put_failure
;
2726 if (list_empty(&resource
->resource_list
))
2729 if (nla_put_u8(skb
, DEVLINK_ATTR_RESOURCE_SIZE_VALID
,
2730 resource
->size_valid
))
2731 goto nla_put_failure
;
2733 child_resource_attr
= nla_nest_start_noflag(skb
,
2734 DEVLINK_ATTR_RESOURCE_LIST
);
2735 if (!child_resource_attr
)
2736 goto nla_put_failure
;
2738 list_for_each_entry(child_resource
, &resource
->resource_list
, list
) {
2739 if (devlink_resource_put(devlink
, skb
, child_resource
))
2740 goto resource_put_failure
;
2743 nla_nest_end(skb
, child_resource_attr
);
2745 nla_nest_end(skb
, resource_attr
);
2748 resource_put_failure
:
2749 nla_nest_cancel(skb
, child_resource_attr
);
2751 nla_nest_cancel(skb
, resource_attr
);
2755 static int devlink_resource_fill(struct genl_info
*info
,
2756 enum devlink_command cmd
, int flags
)
2758 struct devlink
*devlink
= info
->user_ptr
[0];
2759 struct devlink_resource
*resource
;
2760 struct nlattr
*resources_attr
;
2761 struct sk_buff
*skb
= NULL
;
2762 struct nlmsghdr
*nlh
;
2768 resource
= list_first_entry(&devlink
->resource_list
,
2769 struct devlink_resource
, list
);
2771 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2775 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2776 &devlink_nl_family
, NLM_F_MULTI
, cmd
);
2782 if (devlink_nl_put_handle(skb
, devlink
))
2783 goto nla_put_failure
;
2785 resources_attr
= nla_nest_start_noflag(skb
,
2786 DEVLINK_ATTR_RESOURCE_LIST
);
2787 if (!resources_attr
)
2788 goto nla_put_failure
;
2792 list_for_each_entry_from(resource
, &devlink
->resource_list
, list
) {
2793 err
= devlink_resource_put(devlink
, skb
, resource
);
2796 goto err_resource_put
;
2802 nla_nest_end(skb
, resources_attr
);
2803 genlmsg_end(skb
, hdr
);
2807 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2808 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
2810 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2815 return genlmsg_reply(skb
, info
);
2824 static int devlink_nl_cmd_resource_dump(struct sk_buff
*skb
,
2825 struct genl_info
*info
)
2827 struct devlink
*devlink
= info
->user_ptr
[0];
2829 if (list_empty(&devlink
->resource_list
))
2832 return devlink_resource_fill(info
, DEVLINK_CMD_RESOURCE_DUMP
, 0);
2836 devlink_resources_validate(struct devlink
*devlink
,
2837 struct devlink_resource
*resource
,
2838 struct genl_info
*info
)
2840 struct list_head
*resource_list
;
2844 resource_list
= &resource
->resource_list
;
2846 resource_list
= &devlink
->resource_list
;
2848 list_for_each_entry(resource
, resource_list
, list
) {
2849 if (!resource
->size_valid
)
2851 err
= devlink_resources_validate(devlink
, resource
, info
);
2858 static struct net
*devlink_netns_get(struct sk_buff
*skb
,
2859 struct genl_info
*info
)
2861 struct nlattr
*netns_pid_attr
= info
->attrs
[DEVLINK_ATTR_NETNS_PID
];
2862 struct nlattr
*netns_fd_attr
= info
->attrs
[DEVLINK_ATTR_NETNS_FD
];
2863 struct nlattr
*netns_id_attr
= info
->attrs
[DEVLINK_ATTR_NETNS_ID
];
2866 if (!!netns_pid_attr
+ !!netns_fd_attr
+ !!netns_id_attr
> 1) {
2867 NL_SET_ERR_MSG_MOD(info
->extack
, "multiple netns identifying attributes specified");
2868 return ERR_PTR(-EINVAL
);
2871 if (netns_pid_attr
) {
2872 net
= get_net_ns_by_pid(nla_get_u32(netns_pid_attr
));
2873 } else if (netns_fd_attr
) {
2874 net
= get_net_ns_by_fd(nla_get_u32(netns_fd_attr
));
2875 } else if (netns_id_attr
) {
2876 net
= get_net_ns_by_id(sock_net(skb
->sk
),
2877 nla_get_u32(netns_id_attr
));
2879 net
= ERR_PTR(-EINVAL
);
2882 net
= ERR_PTR(-EINVAL
);
2885 NL_SET_ERR_MSG_MOD(info
->extack
, "Unknown network namespace");
2886 return ERR_PTR(-EINVAL
);
2888 if (!netlink_ns_capable(skb
, net
->user_ns
, CAP_NET_ADMIN
)) {
2890 return ERR_PTR(-EPERM
);
2895 static void devlink_param_notify(struct devlink
*devlink
,
2896 unsigned int port_index
,
2897 struct devlink_param_item
*param_item
,
2898 enum devlink_command cmd
);
2900 static void devlink_reload_netns_change(struct devlink
*devlink
,
2901 struct net
*dest_net
)
2903 struct devlink_param_item
*param_item
;
2905 /* Userspace needs to be notified about devlink objects
2906 * removed from original and entering new network namespace.
2907 * The rest of the devlink objects are re-created during
2908 * reload process so the notifications are generated separatelly.
2911 list_for_each_entry(param_item
, &devlink
->param_list
, list
)
2912 devlink_param_notify(devlink
, 0, param_item
,
2913 DEVLINK_CMD_PARAM_DEL
);
2914 devlink_notify(devlink
, DEVLINK_CMD_DEL
);
2916 __devlink_net_set(devlink
, dest_net
);
2918 devlink_notify(devlink
, DEVLINK_CMD_NEW
);
2919 list_for_each_entry(param_item
, &devlink
->param_list
, list
)
2920 devlink_param_notify(devlink
, 0, param_item
,
2921 DEVLINK_CMD_PARAM_NEW
);
2924 static bool devlink_reload_supported(struct devlink
*devlink
)
2926 return devlink
->ops
->reload_down
&& devlink
->ops
->reload_up
;
2929 static void devlink_reload_failed_set(struct devlink
*devlink
,
2932 if (devlink
->reload_failed
== reload_failed
)
2934 devlink
->reload_failed
= reload_failed
;
2935 devlink_notify(devlink
, DEVLINK_CMD_NEW
);
2938 bool devlink_is_reload_failed(const struct devlink
*devlink
)
2940 return devlink
->reload_failed
;
2942 EXPORT_SYMBOL_GPL(devlink_is_reload_failed
);
2944 static int devlink_reload(struct devlink
*devlink
, struct net
*dest_net
,
2945 struct netlink_ext_ack
*extack
)
2949 if (!devlink
->reload_enabled
)
2952 err
= devlink
->ops
->reload_down(devlink
, !!dest_net
, extack
);
2956 if (dest_net
&& !net_eq(dest_net
, devlink_net(devlink
)))
2957 devlink_reload_netns_change(devlink
, dest_net
);
2959 err
= devlink
->ops
->reload_up(devlink
, extack
);
2960 devlink_reload_failed_set(devlink
, !!err
);
2964 static int devlink_nl_cmd_reload(struct sk_buff
*skb
, struct genl_info
*info
)
2966 struct devlink
*devlink
= info
->user_ptr
[0];
2967 struct net
*dest_net
= NULL
;
2970 if (!devlink_reload_supported(devlink
) || !devlink
->reload_enabled
)
2973 err
= devlink_resources_validate(devlink
, NULL
, info
);
2975 NL_SET_ERR_MSG_MOD(info
->extack
, "resources size validation failed");
2979 if (info
->attrs
[DEVLINK_ATTR_NETNS_PID
] ||
2980 info
->attrs
[DEVLINK_ATTR_NETNS_FD
] ||
2981 info
->attrs
[DEVLINK_ATTR_NETNS_ID
]) {
2982 dest_net
= devlink_netns_get(skb
, info
);
2983 if (IS_ERR(dest_net
))
2984 return PTR_ERR(dest_net
);
2987 err
= devlink_reload(devlink
, dest_net
, info
->extack
);
2995 static int devlink_nl_flash_update_fill(struct sk_buff
*msg
,
2996 struct devlink
*devlink
,
2997 enum devlink_command cmd
,
2998 const char *status_msg
,
2999 const char *component
,
3000 unsigned long done
, unsigned long total
)
3004 hdr
= genlmsg_put(msg
, 0, 0, &devlink_nl_family
, 0, cmd
);
3008 if (devlink_nl_put_handle(msg
, devlink
))
3009 goto nla_put_failure
;
3011 if (cmd
!= DEVLINK_CMD_FLASH_UPDATE_STATUS
)
3015 nla_put_string(msg
, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG
,
3017 goto nla_put_failure
;
3019 nla_put_string(msg
, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT
,
3021 goto nla_put_failure
;
3022 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE
,
3023 done
, DEVLINK_ATTR_PAD
))
3024 goto nla_put_failure
;
3025 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL
,
3026 total
, DEVLINK_ATTR_PAD
))
3027 goto nla_put_failure
;
3030 genlmsg_end(msg
, hdr
);
3034 genlmsg_cancel(msg
, hdr
);
3038 static void __devlink_flash_update_notify(struct devlink
*devlink
,
3039 enum devlink_command cmd
,
3040 const char *status_msg
,
3041 const char *component
,
3043 unsigned long total
)
3045 struct sk_buff
*msg
;
3048 WARN_ON(cmd
!= DEVLINK_CMD_FLASH_UPDATE
&&
3049 cmd
!= DEVLINK_CMD_FLASH_UPDATE_END
&&
3050 cmd
!= DEVLINK_CMD_FLASH_UPDATE_STATUS
);
3052 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
3056 err
= devlink_nl_flash_update_fill(msg
, devlink
, cmd
, status_msg
,
3057 component
, done
, total
);
3061 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
3062 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
3069 void devlink_flash_update_begin_notify(struct devlink
*devlink
)
3071 __devlink_flash_update_notify(devlink
,
3072 DEVLINK_CMD_FLASH_UPDATE
,
3075 EXPORT_SYMBOL_GPL(devlink_flash_update_begin_notify
);
3077 void devlink_flash_update_end_notify(struct devlink
*devlink
)
3079 __devlink_flash_update_notify(devlink
,
3080 DEVLINK_CMD_FLASH_UPDATE_END
,
3083 EXPORT_SYMBOL_GPL(devlink_flash_update_end_notify
);
3085 void devlink_flash_update_status_notify(struct devlink
*devlink
,
3086 const char *status_msg
,
3087 const char *component
,
3089 unsigned long total
)
3091 __devlink_flash_update_notify(devlink
,
3092 DEVLINK_CMD_FLASH_UPDATE_STATUS
,
3093 status_msg
, component
, done
, total
);
3095 EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify
);
3097 static int devlink_nl_cmd_flash_update(struct sk_buff
*skb
,
3098 struct genl_info
*info
)
3100 struct devlink
*devlink
= info
->user_ptr
[0];
3101 const char *file_name
, *component
;
3102 struct nlattr
*nla_component
;
3104 if (!devlink
->ops
->flash_update
)
3107 if (!info
->attrs
[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME
])
3109 file_name
= nla_data(info
->attrs
[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME
]);
3111 nla_component
= info
->attrs
[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT
];
3112 component
= nla_component
? nla_data(nla_component
) : NULL
;
3114 return devlink
->ops
->flash_update(devlink
, file_name
, component
,
3118 static const struct devlink_param devlink_param_generic
[] = {
3120 .id
= DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET
,
3121 .name
= DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME
,
3122 .type
= DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE
,
3125 .id
= DEVLINK_PARAM_GENERIC_ID_MAX_MACS
,
3126 .name
= DEVLINK_PARAM_GENERIC_MAX_MACS_NAME
,
3127 .type
= DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE
,
3130 .id
= DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV
,
3131 .name
= DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME
,
3132 .type
= DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE
,
3135 .id
= DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT
,
3136 .name
= DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME
,
3137 .type
= DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE
,
3140 .id
= DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI
,
3141 .name
= DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME
,
3142 .type
= DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE
,
3145 .id
= DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX
,
3146 .name
= DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME
,
3147 .type
= DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE
,
3150 .id
= DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN
,
3151 .name
= DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME
,
3152 .type
= DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE
,
3155 .id
= DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY
,
3156 .name
= DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME
,
3157 .type
= DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE
,
3160 .id
= DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE
,
3161 .name
= DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME
,
3162 .type
= DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE
,
3165 .id
= DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE
,
3166 .name
= DEVLINK_PARAM_GENERIC_ENABLE_ROCE_NAME
,
3167 .type
= DEVLINK_PARAM_GENERIC_ENABLE_ROCE_TYPE
,
3171 static int devlink_param_generic_verify(const struct devlink_param
*param
)
3173 /* verify it match generic parameter by id and name */
3174 if (param
->id
> DEVLINK_PARAM_GENERIC_ID_MAX
)
3176 if (strcmp(param
->name
, devlink_param_generic
[param
->id
].name
))
3179 WARN_ON(param
->type
!= devlink_param_generic
[param
->id
].type
);
3184 static int devlink_param_driver_verify(const struct devlink_param
*param
)
3188 if (param
->id
<= DEVLINK_PARAM_GENERIC_ID_MAX
)
3190 /* verify no such name in generic params */
3191 for (i
= 0; i
<= DEVLINK_PARAM_GENERIC_ID_MAX
; i
++)
3192 if (!strcmp(param
->name
, devlink_param_generic
[i
].name
))
3198 static struct devlink_param_item
*
3199 devlink_param_find_by_name(struct list_head
*param_list
,
3200 const char *param_name
)
3202 struct devlink_param_item
*param_item
;
3204 list_for_each_entry(param_item
, param_list
, list
)
3205 if (!strcmp(param_item
->param
->name
, param_name
))
3210 static struct devlink_param_item
*
3211 devlink_param_find_by_id(struct list_head
*param_list
, u32 param_id
)
3213 struct devlink_param_item
*param_item
;
3215 list_for_each_entry(param_item
, param_list
, list
)
3216 if (param_item
->param
->id
== param_id
)
3222 devlink_param_cmode_is_supported(const struct devlink_param
*param
,
3223 enum devlink_param_cmode cmode
)
3225 return test_bit(cmode
, ¶m
->supported_cmodes
);
3228 static int devlink_param_get(struct devlink
*devlink
,
3229 const struct devlink_param
*param
,
3230 struct devlink_param_gset_ctx
*ctx
)
3234 return param
->get(devlink
, param
->id
, ctx
);
3237 static int devlink_param_set(struct devlink
*devlink
,
3238 const struct devlink_param
*param
,
3239 struct devlink_param_gset_ctx
*ctx
)
3243 return param
->set(devlink
, param
->id
, ctx
);
3247 devlink_param_type_to_nla_type(enum devlink_param_type param_type
)
3249 switch (param_type
) {
3250 case DEVLINK_PARAM_TYPE_U8
:
3252 case DEVLINK_PARAM_TYPE_U16
:
3254 case DEVLINK_PARAM_TYPE_U32
:
3256 case DEVLINK_PARAM_TYPE_STRING
:
3258 case DEVLINK_PARAM_TYPE_BOOL
:
3266 devlink_nl_param_value_fill_one(struct sk_buff
*msg
,
3267 enum devlink_param_type type
,
3268 enum devlink_param_cmode cmode
,
3269 union devlink_param_value val
)
3271 struct nlattr
*param_value_attr
;
3273 param_value_attr
= nla_nest_start_noflag(msg
,
3274 DEVLINK_ATTR_PARAM_VALUE
);
3275 if (!param_value_attr
)
3276 goto nla_put_failure
;
3278 if (nla_put_u8(msg
, DEVLINK_ATTR_PARAM_VALUE_CMODE
, cmode
))
3279 goto value_nest_cancel
;
3282 case DEVLINK_PARAM_TYPE_U8
:
3283 if (nla_put_u8(msg
, DEVLINK_ATTR_PARAM_VALUE_DATA
, val
.vu8
))
3284 goto value_nest_cancel
;
3286 case DEVLINK_PARAM_TYPE_U16
:
3287 if (nla_put_u16(msg
, DEVLINK_ATTR_PARAM_VALUE_DATA
, val
.vu16
))
3288 goto value_nest_cancel
;
3290 case DEVLINK_PARAM_TYPE_U32
:
3291 if (nla_put_u32(msg
, DEVLINK_ATTR_PARAM_VALUE_DATA
, val
.vu32
))
3292 goto value_nest_cancel
;
3294 case DEVLINK_PARAM_TYPE_STRING
:
3295 if (nla_put_string(msg
, DEVLINK_ATTR_PARAM_VALUE_DATA
,
3297 goto value_nest_cancel
;
3299 case DEVLINK_PARAM_TYPE_BOOL
:
3301 nla_put_flag(msg
, DEVLINK_ATTR_PARAM_VALUE_DATA
))
3302 goto value_nest_cancel
;
3306 nla_nest_end(msg
, param_value_attr
);
3310 nla_nest_cancel(msg
, param_value_attr
);
3315 static int devlink_nl_param_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
3316 unsigned int port_index
,
3317 struct devlink_param_item
*param_item
,
3318 enum devlink_command cmd
,
3319 u32 portid
, u32 seq
, int flags
)
3321 union devlink_param_value param_value
[DEVLINK_PARAM_CMODE_MAX
+ 1];
3322 bool param_value_set
[DEVLINK_PARAM_CMODE_MAX
+ 1] = {};
3323 const struct devlink_param
*param
= param_item
->param
;
3324 struct devlink_param_gset_ctx ctx
;
3325 struct nlattr
*param_values_list
;
3326 struct nlattr
*param_attr
;
3332 /* Get value from driver part to driverinit configuration mode */
3333 for (i
= 0; i
<= DEVLINK_PARAM_CMODE_MAX
; i
++) {
3334 if (!devlink_param_cmode_is_supported(param
, i
))
3336 if (i
== DEVLINK_PARAM_CMODE_DRIVERINIT
) {
3337 if (!param_item
->driverinit_value_valid
)
3339 param_value
[i
] = param_item
->driverinit_value
;
3341 if (!param_item
->published
)
3344 err
= devlink_param_get(devlink
, param
, &ctx
);
3347 param_value
[i
] = ctx
.val
;
3349 param_value_set
[i
] = true;
3352 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
3356 if (devlink_nl_put_handle(msg
, devlink
))
3357 goto genlmsg_cancel
;
3359 if (cmd
== DEVLINK_CMD_PORT_PARAM_GET
||
3360 cmd
== DEVLINK_CMD_PORT_PARAM_NEW
||
3361 cmd
== DEVLINK_CMD_PORT_PARAM_DEL
)
3362 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, port_index
))
3363 goto genlmsg_cancel
;
3365 param_attr
= nla_nest_start_noflag(msg
, DEVLINK_ATTR_PARAM
);
3367 goto genlmsg_cancel
;
3368 if (nla_put_string(msg
, DEVLINK_ATTR_PARAM_NAME
, param
->name
))
3369 goto param_nest_cancel
;
3370 if (param
->generic
&& nla_put_flag(msg
, DEVLINK_ATTR_PARAM_GENERIC
))
3371 goto param_nest_cancel
;
3373 nla_type
= devlink_param_type_to_nla_type(param
->type
);
3375 goto param_nest_cancel
;
3376 if (nla_put_u8(msg
, DEVLINK_ATTR_PARAM_TYPE
, nla_type
))
3377 goto param_nest_cancel
;
3379 param_values_list
= nla_nest_start_noflag(msg
,
3380 DEVLINK_ATTR_PARAM_VALUES_LIST
);
3381 if (!param_values_list
)
3382 goto param_nest_cancel
;
3384 for (i
= 0; i
<= DEVLINK_PARAM_CMODE_MAX
; i
++) {
3385 if (!param_value_set
[i
])
3387 err
= devlink_nl_param_value_fill_one(msg
, param
->type
,
3390 goto values_list_nest_cancel
;
3393 nla_nest_end(msg
, param_values_list
);
3394 nla_nest_end(msg
, param_attr
);
3395 genlmsg_end(msg
, hdr
);
3398 values_list_nest_cancel
:
3399 nla_nest_end(msg
, param_values_list
);
3401 nla_nest_cancel(msg
, param_attr
);
3403 genlmsg_cancel(msg
, hdr
);
3407 static void devlink_param_notify(struct devlink
*devlink
,
3408 unsigned int port_index
,
3409 struct devlink_param_item
*param_item
,
3410 enum devlink_command cmd
)
3412 struct sk_buff
*msg
;
3415 WARN_ON(cmd
!= DEVLINK_CMD_PARAM_NEW
&& cmd
!= DEVLINK_CMD_PARAM_DEL
&&
3416 cmd
!= DEVLINK_CMD_PORT_PARAM_NEW
&&
3417 cmd
!= DEVLINK_CMD_PORT_PARAM_DEL
);
3419 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
3422 err
= devlink_nl_param_fill(msg
, devlink
, port_index
, param_item
, cmd
,
3429 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
3430 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
3433 static int devlink_nl_cmd_param_get_dumpit(struct sk_buff
*msg
,
3434 struct netlink_callback
*cb
)
3436 struct devlink_param_item
*param_item
;
3437 struct devlink
*devlink
;
3438 int start
= cb
->args
[0];
3442 mutex_lock(&devlink_mutex
);
3443 list_for_each_entry(devlink
, &devlink_list
, list
) {
3444 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
3446 mutex_lock(&devlink
->lock
);
3447 list_for_each_entry(param_item
, &devlink
->param_list
, list
) {
3452 err
= devlink_nl_param_fill(msg
, devlink
, 0, param_item
,
3453 DEVLINK_CMD_PARAM_GET
,
3454 NETLINK_CB(cb
->skb
).portid
,
3457 if (err
&& err
!= -EOPNOTSUPP
) {
3458 mutex_unlock(&devlink
->lock
);
3463 mutex_unlock(&devlink
->lock
);
3466 mutex_unlock(&devlink_mutex
);
3468 if (err
!= -EMSGSIZE
)
3476 devlink_param_type_get_from_info(struct genl_info
*info
,
3477 enum devlink_param_type
*param_type
)
3479 if (!info
->attrs
[DEVLINK_ATTR_PARAM_TYPE
])
3482 switch (nla_get_u8(info
->attrs
[DEVLINK_ATTR_PARAM_TYPE
])) {
3484 *param_type
= DEVLINK_PARAM_TYPE_U8
;
3487 *param_type
= DEVLINK_PARAM_TYPE_U16
;
3490 *param_type
= DEVLINK_PARAM_TYPE_U32
;
3493 *param_type
= DEVLINK_PARAM_TYPE_STRING
;
3496 *param_type
= DEVLINK_PARAM_TYPE_BOOL
;
3506 devlink_param_value_get_from_info(const struct devlink_param
*param
,
3507 struct genl_info
*info
,
3508 union devlink_param_value
*value
)
3510 struct nlattr
*param_data
;
3513 param_data
= info
->attrs
[DEVLINK_ATTR_PARAM_VALUE_DATA
];
3515 if (param
->type
!= DEVLINK_PARAM_TYPE_BOOL
&& !param_data
)
3518 switch (param
->type
) {
3519 case DEVLINK_PARAM_TYPE_U8
:
3520 if (nla_len(param_data
) != sizeof(u8
))
3522 value
->vu8
= nla_get_u8(param_data
);
3524 case DEVLINK_PARAM_TYPE_U16
:
3525 if (nla_len(param_data
) != sizeof(u16
))
3527 value
->vu16
= nla_get_u16(param_data
);
3529 case DEVLINK_PARAM_TYPE_U32
:
3530 if (nla_len(param_data
) != sizeof(u32
))
3532 value
->vu32
= nla_get_u32(param_data
);
3534 case DEVLINK_PARAM_TYPE_STRING
:
3535 len
= strnlen(nla_data(param_data
), nla_len(param_data
));
3536 if (len
== nla_len(param_data
) ||
3537 len
>= __DEVLINK_PARAM_MAX_STRING_VALUE
)
3539 strcpy(value
->vstr
, nla_data(param_data
));
3541 case DEVLINK_PARAM_TYPE_BOOL
:
3542 if (param_data
&& nla_len(param_data
))
3544 value
->vbool
= nla_get_flag(param_data
);
3550 static struct devlink_param_item
*
3551 devlink_param_get_from_info(struct list_head
*param_list
,
3552 struct genl_info
*info
)
3556 if (!info
->attrs
[DEVLINK_ATTR_PARAM_NAME
])
3559 param_name
= nla_data(info
->attrs
[DEVLINK_ATTR_PARAM_NAME
]);
3560 return devlink_param_find_by_name(param_list
, param_name
);
3563 static int devlink_nl_cmd_param_get_doit(struct sk_buff
*skb
,
3564 struct genl_info
*info
)
3566 struct devlink
*devlink
= info
->user_ptr
[0];
3567 struct devlink_param_item
*param_item
;
3568 struct sk_buff
*msg
;
3571 param_item
= devlink_param_get_from_info(&devlink
->param_list
, info
);
3575 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
3579 err
= devlink_nl_param_fill(msg
, devlink
, 0, param_item
,
3580 DEVLINK_CMD_PARAM_GET
,
3581 info
->snd_portid
, info
->snd_seq
, 0);
3587 return genlmsg_reply(msg
, info
);
3590 static int __devlink_nl_cmd_param_set_doit(struct devlink
*devlink
,
3591 unsigned int port_index
,
3592 struct list_head
*param_list
,
3593 struct genl_info
*info
,
3594 enum devlink_command cmd
)
3596 enum devlink_param_type param_type
;
3597 struct devlink_param_gset_ctx ctx
;
3598 enum devlink_param_cmode cmode
;
3599 struct devlink_param_item
*param_item
;
3600 const struct devlink_param
*param
;
3601 union devlink_param_value value
;
3604 param_item
= devlink_param_get_from_info(param_list
, info
);
3607 param
= param_item
->param
;
3608 err
= devlink_param_type_get_from_info(info
, ¶m_type
);
3611 if (param_type
!= param
->type
)
3613 err
= devlink_param_value_get_from_info(param
, info
, &value
);
3616 if (param
->validate
) {
3617 err
= param
->validate(devlink
, param
->id
, value
, info
->extack
);
3622 if (!info
->attrs
[DEVLINK_ATTR_PARAM_VALUE_CMODE
])
3624 cmode
= nla_get_u8(info
->attrs
[DEVLINK_ATTR_PARAM_VALUE_CMODE
]);
3625 if (!devlink_param_cmode_is_supported(param
, cmode
))
3628 if (cmode
== DEVLINK_PARAM_CMODE_DRIVERINIT
) {
3629 if (param
->type
== DEVLINK_PARAM_TYPE_STRING
)
3630 strcpy(param_item
->driverinit_value
.vstr
, value
.vstr
);
3632 param_item
->driverinit_value
= value
;
3633 param_item
->driverinit_value_valid
= true;
3639 err
= devlink_param_set(devlink
, param
, &ctx
);
3644 devlink_param_notify(devlink
, port_index
, param_item
, cmd
);
3648 static int devlink_nl_cmd_param_set_doit(struct sk_buff
*skb
,
3649 struct genl_info
*info
)
3651 struct devlink
*devlink
= info
->user_ptr
[0];
3653 return __devlink_nl_cmd_param_set_doit(devlink
, 0, &devlink
->param_list
,
3654 info
, DEVLINK_CMD_PARAM_NEW
);
3657 static int devlink_param_register_one(struct devlink
*devlink
,
3658 unsigned int port_index
,
3659 struct list_head
*param_list
,
3660 const struct devlink_param
*param
,
3661 enum devlink_command cmd
)
3663 struct devlink_param_item
*param_item
;
3665 if (devlink_param_find_by_name(param_list
, param
->name
))
3668 if (param
->supported_cmodes
== BIT(DEVLINK_PARAM_CMODE_DRIVERINIT
))
3669 WARN_ON(param
->get
|| param
->set
);
3671 WARN_ON(!param
->get
|| !param
->set
);
3673 param_item
= kzalloc(sizeof(*param_item
), GFP_KERNEL
);
3676 param_item
->param
= param
;
3678 list_add_tail(¶m_item
->list
, param_list
);
3679 devlink_param_notify(devlink
, port_index
, param_item
, cmd
);
3683 static void devlink_param_unregister_one(struct devlink
*devlink
,
3684 unsigned int port_index
,
3685 struct list_head
*param_list
,
3686 const struct devlink_param
*param
,
3687 enum devlink_command cmd
)
3689 struct devlink_param_item
*param_item
;
3691 param_item
= devlink_param_find_by_name(param_list
, param
->name
);
3692 WARN_ON(!param_item
);
3693 devlink_param_notify(devlink
, port_index
, param_item
, cmd
);
3694 list_del(¶m_item
->list
);
3698 static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff
*msg
,
3699 struct netlink_callback
*cb
)
3701 struct devlink_param_item
*param_item
;
3702 struct devlink_port
*devlink_port
;
3703 struct devlink
*devlink
;
3704 int start
= cb
->args
[0];
3708 mutex_lock(&devlink_mutex
);
3709 list_for_each_entry(devlink
, &devlink_list
, list
) {
3710 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
3712 mutex_lock(&devlink
->lock
);
3713 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
3714 list_for_each_entry(param_item
,
3715 &devlink_port
->param_list
, list
) {
3720 err
= devlink_nl_param_fill(msg
,
3721 devlink_port
->devlink
,
3722 devlink_port
->index
, param_item
,
3723 DEVLINK_CMD_PORT_PARAM_GET
,
3724 NETLINK_CB(cb
->skb
).portid
,
3727 if (err
&& err
!= -EOPNOTSUPP
) {
3728 mutex_unlock(&devlink
->lock
);
3734 mutex_unlock(&devlink
->lock
);
3737 mutex_unlock(&devlink_mutex
);
3739 if (err
!= -EMSGSIZE
)
3746 static int devlink_nl_cmd_port_param_get_doit(struct sk_buff
*skb
,
3747 struct genl_info
*info
)
3749 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
3750 struct devlink_param_item
*param_item
;
3751 struct sk_buff
*msg
;
3754 param_item
= devlink_param_get_from_info(&devlink_port
->param_list
,
3759 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
3763 err
= devlink_nl_param_fill(msg
, devlink_port
->devlink
,
3764 devlink_port
->index
, param_item
,
3765 DEVLINK_CMD_PORT_PARAM_GET
,
3766 info
->snd_portid
, info
->snd_seq
, 0);
3772 return genlmsg_reply(msg
, info
);
3775 static int devlink_nl_cmd_port_param_set_doit(struct sk_buff
*skb
,
3776 struct genl_info
*info
)
3778 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
3780 return __devlink_nl_cmd_param_set_doit(devlink_port
->devlink
,
3781 devlink_port
->index
,
3782 &devlink_port
->param_list
, info
,
3783 DEVLINK_CMD_PORT_PARAM_NEW
);
3786 static int devlink_nl_region_snapshot_id_put(struct sk_buff
*msg
,
3787 struct devlink
*devlink
,
3788 struct devlink_snapshot
*snapshot
)
3790 struct nlattr
*snap_attr
;
3793 snap_attr
= nla_nest_start_noflag(msg
, DEVLINK_ATTR_REGION_SNAPSHOT
);
3797 err
= nla_put_u32(msg
, DEVLINK_ATTR_REGION_SNAPSHOT_ID
, snapshot
->id
);
3799 goto nla_put_failure
;
3801 nla_nest_end(msg
, snap_attr
);
3805 nla_nest_cancel(msg
, snap_attr
);
3809 static int devlink_nl_region_snapshots_id_put(struct sk_buff
*msg
,
3810 struct devlink
*devlink
,
3811 struct devlink_region
*region
)
3813 struct devlink_snapshot
*snapshot
;
3814 struct nlattr
*snapshots_attr
;
3817 snapshots_attr
= nla_nest_start_noflag(msg
,
3818 DEVLINK_ATTR_REGION_SNAPSHOTS
);
3819 if (!snapshots_attr
)
3822 list_for_each_entry(snapshot
, ®ion
->snapshot_list
, list
) {
3823 err
= devlink_nl_region_snapshot_id_put(msg
, devlink
, snapshot
);
3825 goto nla_put_failure
;
3828 nla_nest_end(msg
, snapshots_attr
);
3832 nla_nest_cancel(msg
, snapshots_attr
);
3836 static int devlink_nl_region_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
3837 enum devlink_command cmd
, u32 portid
,
3839 struct devlink_region
*region
)
3844 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
3848 err
= devlink_nl_put_handle(msg
, devlink
);
3850 goto nla_put_failure
;
3852 err
= nla_put_string(msg
, DEVLINK_ATTR_REGION_NAME
, region
->ops
->name
);
3854 goto nla_put_failure
;
3856 err
= nla_put_u64_64bit(msg
, DEVLINK_ATTR_REGION_SIZE
,
3860 goto nla_put_failure
;
3862 err
= devlink_nl_region_snapshots_id_put(msg
, devlink
, region
);
3864 goto nla_put_failure
;
3866 genlmsg_end(msg
, hdr
);
3870 genlmsg_cancel(msg
, hdr
);
3874 static struct sk_buff
*
3875 devlink_nl_region_notify_build(struct devlink_region
*region
,
3876 struct devlink_snapshot
*snapshot
,
3877 enum devlink_command cmd
, u32 portid
, u32 seq
)
3879 struct devlink
*devlink
= region
->devlink
;
3880 struct sk_buff
*msg
;
3885 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
3887 return ERR_PTR(-ENOMEM
);
3889 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, 0, cmd
);
3895 err
= devlink_nl_put_handle(msg
, devlink
);
3897 goto out_cancel_msg
;
3899 err
= nla_put_string(msg
, DEVLINK_ATTR_REGION_NAME
,
3902 goto out_cancel_msg
;
3905 err
= nla_put_u32(msg
, DEVLINK_ATTR_REGION_SNAPSHOT_ID
,
3908 goto out_cancel_msg
;
3910 err
= nla_put_u64_64bit(msg
, DEVLINK_ATTR_REGION_SIZE
,
3911 region
->size
, DEVLINK_ATTR_PAD
);
3913 goto out_cancel_msg
;
3915 genlmsg_end(msg
, hdr
);
3920 genlmsg_cancel(msg
, hdr
);
3923 return ERR_PTR(err
);
3926 static void devlink_nl_region_notify(struct devlink_region
*region
,
3927 struct devlink_snapshot
*snapshot
,
3928 enum devlink_command cmd
)
3930 struct devlink
*devlink
= region
->devlink
;
3931 struct sk_buff
*msg
;
3933 WARN_ON(cmd
!= DEVLINK_CMD_REGION_NEW
&& cmd
!= DEVLINK_CMD_REGION_DEL
);
3935 msg
= devlink_nl_region_notify_build(region
, snapshot
, cmd
, 0, 0);
3939 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
3940 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
3944 * __devlink_snapshot_id_increment - Increment number of snapshots using an id
3945 * @devlink: devlink instance
3946 * @id: the snapshot id
3948 * Track when a new snapshot begins using an id. Load the count for the
3949 * given id from the snapshot xarray, increment it, and store it back.
3951 * Called when a new snapshot is created with the given id.
3953 * The id *must* have been previously allocated by
3954 * devlink_region_snapshot_id_get().
3956 * Returns 0 on success, or an error on failure.
3958 static int __devlink_snapshot_id_increment(struct devlink
*devlink
, u32 id
)
3960 unsigned long count
;
3963 lockdep_assert_held(&devlink
->lock
);
3965 p
= xa_load(&devlink
->snapshot_ids
, id
);
3969 if (WARN_ON(!xa_is_value(p
)))
3972 count
= xa_to_value(p
);
3975 return xa_err(xa_store(&devlink
->snapshot_ids
, id
, xa_mk_value(count
),
3980 * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id
3981 * @devlink: devlink instance
3982 * @id: the snapshot id
3984 * Track when a snapshot is deleted and stops using an id. Load the count
3985 * for the given id from the snapshot xarray, decrement it, and store it
3988 * If the count reaches zero, erase this id from the xarray, freeing it
3989 * up for future re-use by devlink_region_snapshot_id_get().
3991 * Called when a snapshot using the given id is deleted, and when the
3992 * initial allocator of the id is finished using it.
3994 static void __devlink_snapshot_id_decrement(struct devlink
*devlink
, u32 id
)
3996 unsigned long count
;
3999 lockdep_assert_held(&devlink
->lock
);
4001 p
= xa_load(&devlink
->snapshot_ids
, id
);
4005 if (WARN_ON(!xa_is_value(p
)))
4008 count
= xa_to_value(p
);
4012 xa_store(&devlink
->snapshot_ids
, id
, xa_mk_value(count
),
4015 /* If this was the last user, we can erase this id */
4016 xa_erase(&devlink
->snapshot_ids
, id
);
4021 * __devlink_snapshot_id_insert - Insert a specific snapshot ID
4022 * @devlink: devlink instance
4023 * @id: the snapshot id
4025 * Mark the given snapshot id as used by inserting a zero value into the
4028 * This must be called while holding the devlink instance lock. Unlike
4029 * devlink_snapshot_id_get, the initial reference count is zero, not one.
4030 * It is expected that the id will immediately be used before
4031 * releasing the devlink instance lock.
4033 * Returns zero on success, or an error code if the snapshot id could not
4036 static int __devlink_snapshot_id_insert(struct devlink
*devlink
, u32 id
)
4038 lockdep_assert_held(&devlink
->lock
);
4040 if (WARN_ON(xa_load(&devlink
->snapshot_ids
, id
)))
4043 return xa_err(xa_store(&devlink
->snapshot_ids
, id
, xa_mk_value(0),
4048 * __devlink_region_snapshot_id_get - get snapshot ID
4049 * @devlink: devlink instance
4050 * @id: storage to return snapshot id
4052 * Allocates a new snapshot id. Returns zero on success, or a negative
4053 * error on failure. Must be called while holding the devlink instance
4056 * Snapshot IDs are tracked using an xarray which stores the number of
4057 * users of the snapshot id.
4059 * Note that the caller of this function counts as a 'user', in order to
4060 * avoid race conditions. The caller must release its hold on the
4061 * snapshot by using devlink_region_snapshot_id_put.
4063 static int __devlink_region_snapshot_id_get(struct devlink
*devlink
, u32
*id
)
4065 lockdep_assert_held(&devlink
->lock
);
4067 return xa_alloc(&devlink
->snapshot_ids
, id
, xa_mk_value(1),
4068 xa_limit_32b
, GFP_KERNEL
);
4072 * __devlink_region_snapshot_create - create a new snapshot
4073 * This will add a new snapshot of a region. The snapshot
4074 * will be stored on the region struct and can be accessed
4075 * from devlink. This is useful for future analyses of snapshots.
4076 * Multiple snapshots can be created on a region.
4077 * The @snapshot_id should be obtained using the getter function.
4079 * Must be called only while holding the devlink instance lock.
4081 * @region: devlink region of the snapshot
4082 * @data: snapshot data
4083 * @snapshot_id: snapshot id to be created
4086 __devlink_region_snapshot_create(struct devlink_region
*region
,
4087 u8
*data
, u32 snapshot_id
)
4089 struct devlink
*devlink
= region
->devlink
;
4090 struct devlink_snapshot
*snapshot
;
4093 lockdep_assert_held(&devlink
->lock
);
4095 /* check if region can hold one more snapshot */
4096 if (region
->cur_snapshots
== region
->max_snapshots
)
4099 if (devlink_region_snapshot_get_by_id(region
, snapshot_id
))
4102 snapshot
= kzalloc(sizeof(*snapshot
), GFP_KERNEL
);
4106 err
= __devlink_snapshot_id_increment(devlink
, snapshot_id
);
4108 goto err_snapshot_id_increment
;
4110 snapshot
->id
= snapshot_id
;
4111 snapshot
->region
= region
;
4112 snapshot
->data
= data
;
4114 list_add_tail(&snapshot
->list
, ®ion
->snapshot_list
);
4116 region
->cur_snapshots
++;
4118 devlink_nl_region_notify(region
, snapshot
, DEVLINK_CMD_REGION_NEW
);
4121 err_snapshot_id_increment
:
4126 static void devlink_region_snapshot_del(struct devlink_region
*region
,
4127 struct devlink_snapshot
*snapshot
)
4129 struct devlink
*devlink
= region
->devlink
;
4131 lockdep_assert_held(&devlink
->lock
);
4133 devlink_nl_region_notify(region
, snapshot
, DEVLINK_CMD_REGION_DEL
);
4134 region
->cur_snapshots
--;
4135 list_del(&snapshot
->list
);
4136 region
->ops
->destructor(snapshot
->data
);
4137 __devlink_snapshot_id_decrement(devlink
, snapshot
->id
);
4141 static int devlink_nl_cmd_region_get_doit(struct sk_buff
*skb
,
4142 struct genl_info
*info
)
4144 struct devlink
*devlink
= info
->user_ptr
[0];
4145 struct devlink_region
*region
;
4146 const char *region_name
;
4147 struct sk_buff
*msg
;
4150 if (!info
->attrs
[DEVLINK_ATTR_REGION_NAME
])
4153 region_name
= nla_data(info
->attrs
[DEVLINK_ATTR_REGION_NAME
]);
4154 region
= devlink_region_get_by_name(devlink
, region_name
);
4158 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
4162 err
= devlink_nl_region_fill(msg
, devlink
, DEVLINK_CMD_REGION_GET
,
4163 info
->snd_portid
, info
->snd_seq
, 0,
4170 return genlmsg_reply(msg
, info
);
4173 static int devlink_nl_cmd_region_get_dumpit(struct sk_buff
*msg
,
4174 struct netlink_callback
*cb
)
4176 struct devlink_region
*region
;
4177 struct devlink
*devlink
;
4178 int start
= cb
->args
[0];
4182 mutex_lock(&devlink_mutex
);
4183 list_for_each_entry(devlink
, &devlink_list
, list
) {
4184 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
4187 mutex_lock(&devlink
->lock
);
4188 list_for_each_entry(region
, &devlink
->region_list
, list
) {
4193 err
= devlink_nl_region_fill(msg
, devlink
,
4194 DEVLINK_CMD_REGION_GET
,
4195 NETLINK_CB(cb
->skb
).portid
,
4197 NLM_F_MULTI
, region
);
4199 mutex_unlock(&devlink
->lock
);
4204 mutex_unlock(&devlink
->lock
);
4207 mutex_unlock(&devlink_mutex
);
4212 static int devlink_nl_cmd_region_del(struct sk_buff
*skb
,
4213 struct genl_info
*info
)
4215 struct devlink
*devlink
= info
->user_ptr
[0];
4216 struct devlink_snapshot
*snapshot
;
4217 struct devlink_region
*region
;
4218 const char *region_name
;
4221 if (!info
->attrs
[DEVLINK_ATTR_REGION_NAME
] ||
4222 !info
->attrs
[DEVLINK_ATTR_REGION_SNAPSHOT_ID
])
4225 region_name
= nla_data(info
->attrs
[DEVLINK_ATTR_REGION_NAME
]);
4226 snapshot_id
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_REGION_SNAPSHOT_ID
]);
4228 region
= devlink_region_get_by_name(devlink
, region_name
);
4232 snapshot
= devlink_region_snapshot_get_by_id(region
, snapshot_id
);
4236 devlink_region_snapshot_del(region
, snapshot
);
4241 devlink_nl_cmd_region_new(struct sk_buff
*skb
, struct genl_info
*info
)
4243 struct devlink
*devlink
= info
->user_ptr
[0];
4244 struct devlink_snapshot
*snapshot
;
4245 struct nlattr
*snapshot_id_attr
;
4246 struct devlink_region
*region
;
4247 const char *region_name
;
4252 if (!info
->attrs
[DEVLINK_ATTR_REGION_NAME
]) {
4253 NL_SET_ERR_MSG_MOD(info
->extack
, "No region name provided");
4257 region_name
= nla_data(info
->attrs
[DEVLINK_ATTR_REGION_NAME
]);
4258 region
= devlink_region_get_by_name(devlink
, region_name
);
4260 NL_SET_ERR_MSG_MOD(info
->extack
, "The requested region does not exist");
4264 if (!region
->ops
->snapshot
) {
4265 NL_SET_ERR_MSG_MOD(info
->extack
, "The requested region does not support taking an immediate snapshot");
4269 if (region
->cur_snapshots
== region
->max_snapshots
) {
4270 NL_SET_ERR_MSG_MOD(info
->extack
, "The region has reached the maximum number of stored snapshots");
4274 snapshot_id_attr
= info
->attrs
[DEVLINK_ATTR_REGION_SNAPSHOT_ID
];
4275 if (snapshot_id_attr
) {
4276 snapshot_id
= nla_get_u32(snapshot_id_attr
);
4278 if (devlink_region_snapshot_get_by_id(region
, snapshot_id
)) {
4279 NL_SET_ERR_MSG_MOD(info
->extack
, "The requested snapshot id is already in use");
4283 err
= __devlink_snapshot_id_insert(devlink
, snapshot_id
);
4287 err
= __devlink_region_snapshot_id_get(devlink
, &snapshot_id
);
4289 NL_SET_ERR_MSG_MOD(info
->extack
, "Failed to allocate a new snapshot id");
4294 err
= region
->ops
->snapshot(devlink
, info
->extack
, &data
);
4296 goto err_snapshot_capture
;
4298 err
= __devlink_region_snapshot_create(region
, data
, snapshot_id
);
4300 goto err_snapshot_create
;
4302 if (!snapshot_id_attr
) {
4303 struct sk_buff
*msg
;
4305 snapshot
= devlink_region_snapshot_get_by_id(region
,
4307 if (WARN_ON(!snapshot
))
4310 msg
= devlink_nl_region_notify_build(region
, snapshot
,
4311 DEVLINK_CMD_REGION_NEW
,
4314 err
= PTR_ERR_OR_ZERO(msg
);
4318 err
= genlmsg_reply(msg
, info
);
4325 err_snapshot_create
:
4326 region
->ops
->destructor(data
);
4327 err_snapshot_capture
:
4328 __devlink_snapshot_id_decrement(devlink
, snapshot_id
);
4332 devlink_region_snapshot_del(region
, snapshot
);
4336 static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff
*msg
,
4337 struct devlink
*devlink
,
4338 u8
*chunk
, u32 chunk_size
,
4341 struct nlattr
*chunk_attr
;
4344 chunk_attr
= nla_nest_start_noflag(msg
, DEVLINK_ATTR_REGION_CHUNK
);
4348 err
= nla_put(msg
, DEVLINK_ATTR_REGION_CHUNK_DATA
, chunk_size
, chunk
);
4350 goto nla_put_failure
;
4352 err
= nla_put_u64_64bit(msg
, DEVLINK_ATTR_REGION_CHUNK_ADDR
, addr
,
4355 goto nla_put_failure
;
4357 nla_nest_end(msg
, chunk_attr
);
4361 nla_nest_cancel(msg
, chunk_attr
);
4365 #define DEVLINK_REGION_READ_CHUNK_SIZE 256
4367 static int devlink_nl_region_read_snapshot_fill(struct sk_buff
*skb
,
4368 struct devlink
*devlink
,
4369 struct devlink_region
*region
,
4370 struct nlattr
**attrs
,
4375 struct devlink_snapshot
*snapshot
;
4376 u64 curr_offset
= start_offset
;
4380 *new_offset
= start_offset
;
4382 snapshot_id
= nla_get_u32(attrs
[DEVLINK_ATTR_REGION_SNAPSHOT_ID
]);
4383 snapshot
= devlink_region_snapshot_get_by_id(region
, snapshot_id
);
4387 while (curr_offset
< end_offset
) {
4391 if (end_offset
- curr_offset
< DEVLINK_REGION_READ_CHUNK_SIZE
)
4392 data_size
= end_offset
- curr_offset
;
4394 data_size
= DEVLINK_REGION_READ_CHUNK_SIZE
;
4396 data
= &snapshot
->data
[curr_offset
];
4397 err
= devlink_nl_cmd_region_read_chunk_fill(skb
, devlink
,
4403 curr_offset
+= data_size
;
4405 *new_offset
= curr_offset
;
4410 static int devlink_nl_cmd_region_read_dumpit(struct sk_buff
*skb
,
4411 struct netlink_callback
*cb
)
4413 const struct genl_dumpit_info
*info
= genl_dumpit_info(cb
);
4414 u64 ret_offset
, start_offset
, end_offset
= U64_MAX
;
4415 struct nlattr
**attrs
= info
->attrs
;
4416 struct devlink_region
*region
;
4417 struct nlattr
*chunks_attr
;
4418 const char *region_name
;
4419 struct devlink
*devlink
;
4423 start_offset
= *((u64
*)&cb
->args
[0]);
4425 mutex_lock(&devlink_mutex
);
4426 devlink
= devlink_get_from_attrs(sock_net(cb
->skb
->sk
), attrs
);
4427 if (IS_ERR(devlink
)) {
4428 err
= PTR_ERR(devlink
);
4432 mutex_lock(&devlink
->lock
);
4434 if (!attrs
[DEVLINK_ATTR_REGION_NAME
] ||
4435 !attrs
[DEVLINK_ATTR_REGION_SNAPSHOT_ID
]) {
4440 region_name
= nla_data(attrs
[DEVLINK_ATTR_REGION_NAME
]);
4441 region
= devlink_region_get_by_name(devlink
, region_name
);
4447 if (attrs
[DEVLINK_ATTR_REGION_CHUNK_ADDR
] &&
4448 attrs
[DEVLINK_ATTR_REGION_CHUNK_LEN
]) {
4451 nla_get_u64(attrs
[DEVLINK_ATTR_REGION_CHUNK_ADDR
]);
4453 end_offset
= nla_get_u64(attrs
[DEVLINK_ATTR_REGION_CHUNK_ADDR
]);
4454 end_offset
+= nla_get_u64(attrs
[DEVLINK_ATTR_REGION_CHUNK_LEN
]);
4457 if (end_offset
> region
->size
)
4458 end_offset
= region
->size
;
4460 /* return 0 if there is no further data to read */
4461 if (start_offset
== end_offset
) {
4466 hdr
= genlmsg_put(skb
, NETLINK_CB(cb
->skb
).portid
, cb
->nlh
->nlmsg_seq
,
4467 &devlink_nl_family
, NLM_F_ACK
| NLM_F_MULTI
,
4468 DEVLINK_CMD_REGION_READ
);
4474 err
= devlink_nl_put_handle(skb
, devlink
);
4476 goto nla_put_failure
;
4478 err
= nla_put_string(skb
, DEVLINK_ATTR_REGION_NAME
, region_name
);
4480 goto nla_put_failure
;
4482 chunks_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_REGION_CHUNKS
);
4485 goto nla_put_failure
;
4488 err
= devlink_nl_region_read_snapshot_fill(skb
, devlink
,
4491 end_offset
, &ret_offset
);
4493 if (err
&& err
!= -EMSGSIZE
)
4494 goto nla_put_failure
;
4496 /* Check if there was any progress done to prevent infinite loop */
4497 if (ret_offset
== start_offset
) {
4499 goto nla_put_failure
;
4502 *((u64
*)&cb
->args
[0]) = ret_offset
;
4504 nla_nest_end(skb
, chunks_attr
);
4505 genlmsg_end(skb
, hdr
);
4506 mutex_unlock(&devlink
->lock
);
4507 mutex_unlock(&devlink_mutex
);
4512 genlmsg_cancel(skb
, hdr
);
4514 mutex_unlock(&devlink
->lock
);
4516 mutex_unlock(&devlink_mutex
);
4520 struct devlink_info_req
{
4521 struct sk_buff
*msg
;
4524 int devlink_info_driver_name_put(struct devlink_info_req
*req
, const char *name
)
4526 return nla_put_string(req
->msg
, DEVLINK_ATTR_INFO_DRIVER_NAME
, name
);
4528 EXPORT_SYMBOL_GPL(devlink_info_driver_name_put
);
4530 int devlink_info_serial_number_put(struct devlink_info_req
*req
, const char *sn
)
4532 return nla_put_string(req
->msg
, DEVLINK_ATTR_INFO_SERIAL_NUMBER
, sn
);
4534 EXPORT_SYMBOL_GPL(devlink_info_serial_number_put
);
4536 int devlink_info_board_serial_number_put(struct devlink_info_req
*req
,
4539 return nla_put_string(req
->msg
, DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER
,
4542 EXPORT_SYMBOL_GPL(devlink_info_board_serial_number_put
);
4544 static int devlink_info_version_put(struct devlink_info_req
*req
, int attr
,
4545 const char *version_name
,
4546 const char *version_value
)
4548 struct nlattr
*nest
;
4551 nest
= nla_nest_start_noflag(req
->msg
, attr
);
4555 err
= nla_put_string(req
->msg
, DEVLINK_ATTR_INFO_VERSION_NAME
,
4558 goto nla_put_failure
;
4560 err
= nla_put_string(req
->msg
, DEVLINK_ATTR_INFO_VERSION_VALUE
,
4563 goto nla_put_failure
;
4565 nla_nest_end(req
->msg
, nest
);
4570 nla_nest_cancel(req
->msg
, nest
);
4574 int devlink_info_version_fixed_put(struct devlink_info_req
*req
,
4575 const char *version_name
,
4576 const char *version_value
)
4578 return devlink_info_version_put(req
, DEVLINK_ATTR_INFO_VERSION_FIXED
,
4579 version_name
, version_value
);
4581 EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put
);
4583 int devlink_info_version_stored_put(struct devlink_info_req
*req
,
4584 const char *version_name
,
4585 const char *version_value
)
4587 return devlink_info_version_put(req
, DEVLINK_ATTR_INFO_VERSION_STORED
,
4588 version_name
, version_value
);
4590 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put
);
4592 int devlink_info_version_running_put(struct devlink_info_req
*req
,
4593 const char *version_name
,
4594 const char *version_value
)
4596 return devlink_info_version_put(req
, DEVLINK_ATTR_INFO_VERSION_RUNNING
,
4597 version_name
, version_value
);
4599 EXPORT_SYMBOL_GPL(devlink_info_version_running_put
);
4602 devlink_nl_info_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
4603 enum devlink_command cmd
, u32 portid
,
4604 u32 seq
, int flags
, struct netlink_ext_ack
*extack
)
4606 struct devlink_info_req req
;
4610 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
4615 if (devlink_nl_put_handle(msg
, devlink
))
4616 goto err_cancel_msg
;
4619 err
= devlink
->ops
->info_get(devlink
, &req
, extack
);
4621 goto err_cancel_msg
;
4623 genlmsg_end(msg
, hdr
);
4627 genlmsg_cancel(msg
, hdr
);
4631 static int devlink_nl_cmd_info_get_doit(struct sk_buff
*skb
,
4632 struct genl_info
*info
)
4634 struct devlink
*devlink
= info
->user_ptr
[0];
4635 struct sk_buff
*msg
;
4638 if (!devlink
->ops
->info_get
)
4641 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
4645 err
= devlink_nl_info_fill(msg
, devlink
, DEVLINK_CMD_INFO_GET
,
4646 info
->snd_portid
, info
->snd_seq
, 0,
4653 return genlmsg_reply(msg
, info
);
4656 static int devlink_nl_cmd_info_get_dumpit(struct sk_buff
*msg
,
4657 struct netlink_callback
*cb
)
4659 struct devlink
*devlink
;
4660 int start
= cb
->args
[0];
4664 mutex_lock(&devlink_mutex
);
4665 list_for_each_entry(devlink
, &devlink_list
, list
) {
4666 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
4673 if (!devlink
->ops
->info_get
) {
4678 mutex_lock(&devlink
->lock
);
4679 err
= devlink_nl_info_fill(msg
, devlink
, DEVLINK_CMD_INFO_GET
,
4680 NETLINK_CB(cb
->skb
).portid
,
4681 cb
->nlh
->nlmsg_seq
, NLM_F_MULTI
,
4683 mutex_unlock(&devlink
->lock
);
4684 if (err
&& err
!= -EOPNOTSUPP
)
4688 mutex_unlock(&devlink_mutex
);
4690 if (err
!= -EMSGSIZE
)
4697 struct devlink_fmsg_item
{
4698 struct list_head list
;
4705 struct devlink_fmsg
{
4706 struct list_head item_list
;
4707 bool putting_binary
; /* This flag forces enclosing of binary data
4708 * in an array brackets. It forces using
4709 * of designated API:
4710 * devlink_fmsg_binary_pair_nest_start()
4711 * devlink_fmsg_binary_pair_nest_end()
4715 static struct devlink_fmsg
*devlink_fmsg_alloc(void)
4717 struct devlink_fmsg
*fmsg
;
4719 fmsg
= kzalloc(sizeof(*fmsg
), GFP_KERNEL
);
4723 INIT_LIST_HEAD(&fmsg
->item_list
);
4728 static void devlink_fmsg_free(struct devlink_fmsg
*fmsg
)
4730 struct devlink_fmsg_item
*item
, *tmp
;
4732 list_for_each_entry_safe(item
, tmp
, &fmsg
->item_list
, list
) {
4733 list_del(&item
->list
);
4739 static int devlink_fmsg_nest_common(struct devlink_fmsg
*fmsg
,
4742 struct devlink_fmsg_item
*item
;
4744 item
= kzalloc(sizeof(*item
), GFP_KERNEL
);
4748 item
->attrtype
= attrtype
;
4749 list_add_tail(&item
->list
, &fmsg
->item_list
);
4754 int devlink_fmsg_obj_nest_start(struct devlink_fmsg
*fmsg
)
4756 if (fmsg
->putting_binary
)
4759 return devlink_fmsg_nest_common(fmsg
, DEVLINK_ATTR_FMSG_OBJ_NEST_START
);
4761 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start
);
4763 static int devlink_fmsg_nest_end(struct devlink_fmsg
*fmsg
)
4765 if (fmsg
->putting_binary
)
4768 return devlink_fmsg_nest_common(fmsg
, DEVLINK_ATTR_FMSG_NEST_END
);
4771 int devlink_fmsg_obj_nest_end(struct devlink_fmsg
*fmsg
)
4773 if (fmsg
->putting_binary
)
4776 return devlink_fmsg_nest_end(fmsg
);
4778 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end
);
4780 #define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN)
4782 static int devlink_fmsg_put_name(struct devlink_fmsg
*fmsg
, const char *name
)
4784 struct devlink_fmsg_item
*item
;
4786 if (fmsg
->putting_binary
)
4789 if (strlen(name
) + 1 > DEVLINK_FMSG_MAX_SIZE
)
4792 item
= kzalloc(sizeof(*item
) + strlen(name
) + 1, GFP_KERNEL
);
4796 item
->nla_type
= NLA_NUL_STRING
;
4797 item
->len
= strlen(name
) + 1;
4798 item
->attrtype
= DEVLINK_ATTR_FMSG_OBJ_NAME
;
4799 memcpy(&item
->value
, name
, item
->len
);
4800 list_add_tail(&item
->list
, &fmsg
->item_list
);
4805 int devlink_fmsg_pair_nest_start(struct devlink_fmsg
*fmsg
, const char *name
)
4809 if (fmsg
->putting_binary
)
4812 err
= devlink_fmsg_nest_common(fmsg
, DEVLINK_ATTR_FMSG_PAIR_NEST_START
);
4816 err
= devlink_fmsg_put_name(fmsg
, name
);
4822 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start
);
4824 int devlink_fmsg_pair_nest_end(struct devlink_fmsg
*fmsg
)
4826 if (fmsg
->putting_binary
)
4829 return devlink_fmsg_nest_end(fmsg
);
4831 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end
);
4833 int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg
*fmsg
,
4838 if (fmsg
->putting_binary
)
4841 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
4845 err
= devlink_fmsg_nest_common(fmsg
, DEVLINK_ATTR_FMSG_ARR_NEST_START
);
4851 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start
);
4853 int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg
*fmsg
)
4857 if (fmsg
->putting_binary
)
4860 err
= devlink_fmsg_nest_end(fmsg
);
4864 err
= devlink_fmsg_nest_end(fmsg
);
4870 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end
);
4872 int devlink_fmsg_binary_pair_nest_start(struct devlink_fmsg
*fmsg
,
4877 err
= devlink_fmsg_arr_pair_nest_start(fmsg
, name
);
4881 fmsg
->putting_binary
= true;
4884 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_start
);
4886 int devlink_fmsg_binary_pair_nest_end(struct devlink_fmsg
*fmsg
)
4888 if (!fmsg
->putting_binary
)
4891 fmsg
->putting_binary
= false;
4892 return devlink_fmsg_arr_pair_nest_end(fmsg
);
4894 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_end
);
4896 static int devlink_fmsg_put_value(struct devlink_fmsg
*fmsg
,
4897 const void *value
, u16 value_len
,
4900 struct devlink_fmsg_item
*item
;
4902 if (value_len
> DEVLINK_FMSG_MAX_SIZE
)
4905 item
= kzalloc(sizeof(*item
) + value_len
, GFP_KERNEL
);
4909 item
->nla_type
= value_nla_type
;
4910 item
->len
= value_len
;
4911 item
->attrtype
= DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA
;
4912 memcpy(&item
->value
, value
, item
->len
);
4913 list_add_tail(&item
->list
, &fmsg
->item_list
);
4918 int devlink_fmsg_bool_put(struct devlink_fmsg
*fmsg
, bool value
)
4920 if (fmsg
->putting_binary
)
4923 return devlink_fmsg_put_value(fmsg
, &value
, sizeof(value
), NLA_FLAG
);
4925 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_put
);
4927 int devlink_fmsg_u8_put(struct devlink_fmsg
*fmsg
, u8 value
)
4929 if (fmsg
->putting_binary
)
4932 return devlink_fmsg_put_value(fmsg
, &value
, sizeof(value
), NLA_U8
);
4934 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_put
);
4936 int devlink_fmsg_u32_put(struct devlink_fmsg
*fmsg
, u32 value
)
4938 if (fmsg
->putting_binary
)
4941 return devlink_fmsg_put_value(fmsg
, &value
, sizeof(value
), NLA_U32
);
4943 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put
);
4945 int devlink_fmsg_u64_put(struct devlink_fmsg
*fmsg
, u64 value
)
4947 if (fmsg
->putting_binary
)
4950 return devlink_fmsg_put_value(fmsg
, &value
, sizeof(value
), NLA_U64
);
4952 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_put
);
4954 int devlink_fmsg_string_put(struct devlink_fmsg
*fmsg
, const char *value
)
4956 if (fmsg
->putting_binary
)
4959 return devlink_fmsg_put_value(fmsg
, value
, strlen(value
) + 1,
4962 EXPORT_SYMBOL_GPL(devlink_fmsg_string_put
);
4964 int devlink_fmsg_binary_put(struct devlink_fmsg
*fmsg
, const void *value
,
4967 if (!fmsg
->putting_binary
)
4970 return devlink_fmsg_put_value(fmsg
, value
, value_len
, NLA_BINARY
);
4972 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put
);
4974 int devlink_fmsg_bool_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
4979 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
4983 err
= devlink_fmsg_bool_put(fmsg
, value
);
4987 err
= devlink_fmsg_pair_nest_end(fmsg
);
4993 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put
);
4995 int devlink_fmsg_u8_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
5000 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
5004 err
= devlink_fmsg_u8_put(fmsg
, value
);
5008 err
= devlink_fmsg_pair_nest_end(fmsg
);
5014 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put
);
5016 int devlink_fmsg_u32_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
5021 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
5025 err
= devlink_fmsg_u32_put(fmsg
, value
);
5029 err
= devlink_fmsg_pair_nest_end(fmsg
);
5035 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put
);
5037 int devlink_fmsg_u64_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
5042 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
5046 err
= devlink_fmsg_u64_put(fmsg
, value
);
5050 err
= devlink_fmsg_pair_nest_end(fmsg
);
5056 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put
);
5058 int devlink_fmsg_string_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
5063 err
= devlink_fmsg_pair_nest_start(fmsg
, name
);
5067 err
= devlink_fmsg_string_put(fmsg
, value
);
5071 err
= devlink_fmsg_pair_nest_end(fmsg
);
5077 EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put
);
5079 int devlink_fmsg_binary_pair_put(struct devlink_fmsg
*fmsg
, const char *name
,
5080 const void *value
, u32 value_len
)
5087 err
= devlink_fmsg_binary_pair_nest_start(fmsg
, name
);
5091 for (offset
= 0; offset
< value_len
; offset
+= data_size
) {
5092 data_size
= value_len
- offset
;
5093 if (data_size
> DEVLINK_FMSG_MAX_SIZE
)
5094 data_size
= DEVLINK_FMSG_MAX_SIZE
;
5095 err
= devlink_fmsg_binary_put(fmsg
, value
+ offset
, data_size
);
5098 /* Exit from loop with a break (instead of
5099 * return) to make sure putting_binary is turned off in
5100 * devlink_fmsg_binary_pair_nest_end
5104 end_err
= devlink_fmsg_binary_pair_nest_end(fmsg
);
5110 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put
);
5113 devlink_fmsg_item_fill_type(struct devlink_fmsg_item
*msg
, struct sk_buff
*skb
)
5115 switch (msg
->nla_type
) {
5120 case NLA_NUL_STRING
:
5122 return nla_put_u8(skb
, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE
,
5130 devlink_fmsg_item_fill_data(struct devlink_fmsg_item
*msg
, struct sk_buff
*skb
)
5132 int attrtype
= DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA
;
5135 switch (msg
->nla_type
) {
5137 /* Always provide flag data, regardless of its value */
5138 tmp
= *(bool *) msg
->value
;
5140 return nla_put_u8(skb
, attrtype
, tmp
);
5142 return nla_put_u8(skb
, attrtype
, *(u8
*) msg
->value
);
5144 return nla_put_u32(skb
, attrtype
, *(u32
*) msg
->value
);
5146 return nla_put_u64_64bit(skb
, attrtype
, *(u64
*) msg
->value
,
5148 case NLA_NUL_STRING
:
5149 return nla_put_string(skb
, attrtype
, (char *) &msg
->value
);
5151 return nla_put(skb
, attrtype
, msg
->len
, (void *) &msg
->value
);
5158 devlink_fmsg_prepare_skb(struct devlink_fmsg
*fmsg
, struct sk_buff
*skb
,
5161 struct devlink_fmsg_item
*item
;
5162 struct nlattr
*fmsg_nlattr
;
5166 fmsg_nlattr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_FMSG
);
5170 list_for_each_entry(item
, &fmsg
->item_list
, list
) {
5176 switch (item
->attrtype
) {
5177 case DEVLINK_ATTR_FMSG_OBJ_NEST_START
:
5178 case DEVLINK_ATTR_FMSG_PAIR_NEST_START
:
5179 case DEVLINK_ATTR_FMSG_ARR_NEST_START
:
5180 case DEVLINK_ATTR_FMSG_NEST_END
:
5181 err
= nla_put_flag(skb
, item
->attrtype
);
5183 case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA
:
5184 err
= devlink_fmsg_item_fill_type(item
, skb
);
5187 err
= devlink_fmsg_item_fill_data(item
, skb
);
5189 case DEVLINK_ATTR_FMSG_OBJ_NAME
:
5190 err
= nla_put_string(skb
, item
->attrtype
,
5191 (char *) &item
->value
);
5203 nla_nest_end(skb
, fmsg_nlattr
);
5207 static int devlink_fmsg_snd(struct devlink_fmsg
*fmsg
,
5208 struct genl_info
*info
,
5209 enum devlink_command cmd
, int flags
)
5211 struct nlmsghdr
*nlh
;
5212 struct sk_buff
*skb
;
5219 int tmp_index
= index
;
5221 skb
= genlmsg_new(GENLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
5225 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
5226 &devlink_nl_family
, flags
| NLM_F_MULTI
, cmd
);
5229 goto nla_put_failure
;
5232 err
= devlink_fmsg_prepare_skb(fmsg
, skb
, &index
);
5235 else if (err
!= -EMSGSIZE
|| tmp_index
== index
)
5236 goto nla_put_failure
;
5238 genlmsg_end(skb
, hdr
);
5239 err
= genlmsg_reply(skb
, info
);
5244 skb
= genlmsg_new(GENLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
5247 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
5248 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
5251 goto nla_put_failure
;
5254 return genlmsg_reply(skb
, info
);
5261 static int devlink_fmsg_dumpit(struct devlink_fmsg
*fmsg
, struct sk_buff
*skb
,
5262 struct netlink_callback
*cb
,
5263 enum devlink_command cmd
)
5265 int index
= cb
->args
[0];
5266 int tmp_index
= index
;
5270 hdr
= genlmsg_put(skb
, NETLINK_CB(cb
->skb
).portid
, cb
->nlh
->nlmsg_seq
,
5271 &devlink_nl_family
, NLM_F_ACK
| NLM_F_MULTI
, cmd
);
5274 goto nla_put_failure
;
5277 err
= devlink_fmsg_prepare_skb(fmsg
, skb
, &index
);
5278 if ((err
&& err
!= -EMSGSIZE
) || tmp_index
== index
)
5279 goto nla_put_failure
;
5281 cb
->args
[0] = index
;
5282 genlmsg_end(skb
, hdr
);
5286 genlmsg_cancel(skb
, hdr
);
5290 struct devlink_health_reporter
{
5291 struct list_head list
;
5293 const struct devlink_health_reporter_ops
*ops
;
5294 struct devlink
*devlink
;
5295 struct devlink_port
*devlink_port
;
5296 struct devlink_fmsg
*dump_fmsg
;
5297 struct mutex dump_lock
; /* lock parallel read/write from dump buffers */
5298 u64 graceful_period
;
5306 u64 last_recovery_ts
;
5307 refcount_t refcount
;
5311 devlink_health_reporter_priv(struct devlink_health_reporter
*reporter
)
5313 return reporter
->priv
;
5315 EXPORT_SYMBOL_GPL(devlink_health_reporter_priv
);
5317 static struct devlink_health_reporter
*
5318 __devlink_health_reporter_find_by_name(struct list_head
*reporter_list
,
5319 struct mutex
*list_lock
,
5320 const char *reporter_name
)
5322 struct devlink_health_reporter
*reporter
;
5324 lockdep_assert_held(list_lock
);
5325 list_for_each_entry(reporter
, reporter_list
, list
)
5326 if (!strcmp(reporter
->ops
->name
, reporter_name
))
5331 static struct devlink_health_reporter
*
5332 devlink_health_reporter_find_by_name(struct devlink
*devlink
,
5333 const char *reporter_name
)
5335 return __devlink_health_reporter_find_by_name(&devlink
->reporter_list
,
5336 &devlink
->reporters_lock
,
5340 static struct devlink_health_reporter
*
5341 devlink_port_health_reporter_find_by_name(struct devlink_port
*devlink_port
,
5342 const char *reporter_name
)
5344 return __devlink_health_reporter_find_by_name(&devlink_port
->reporter_list
,
5345 &devlink_port
->reporters_lock
,
5349 static struct devlink_health_reporter
*
5350 __devlink_health_reporter_create(struct devlink
*devlink
,
5351 const struct devlink_health_reporter_ops
*ops
,
5352 u64 graceful_period
, void *priv
)
5354 struct devlink_health_reporter
*reporter
;
5356 if (WARN_ON(graceful_period
&& !ops
->recover
))
5357 return ERR_PTR(-EINVAL
);
5359 reporter
= kzalloc(sizeof(*reporter
), GFP_KERNEL
);
5361 return ERR_PTR(-ENOMEM
);
5363 reporter
->priv
= priv
;
5364 reporter
->ops
= ops
;
5365 reporter
->devlink
= devlink
;
5366 reporter
->graceful_period
= graceful_period
;
5367 reporter
->auto_recover
= !!ops
->recover
;
5368 reporter
->auto_dump
= !!ops
->dump
;
5369 mutex_init(&reporter
->dump_lock
);
5370 refcount_set(&reporter
->refcount
, 1);
5375 * devlink_port_health_reporter_create - create devlink health reporter for
5376 * specified port instance
5378 * @port: devlink_port which should contain the new reporter
5380 * @graceful_period: to avoid recovery loops, in msecs
5383 struct devlink_health_reporter
*
5384 devlink_port_health_reporter_create(struct devlink_port
*port
,
5385 const struct devlink_health_reporter_ops
*ops
,
5386 u64 graceful_period
, void *priv
)
5388 struct devlink_health_reporter
*reporter
;
5390 mutex_lock(&port
->reporters_lock
);
5391 if (__devlink_health_reporter_find_by_name(&port
->reporter_list
,
5392 &port
->reporters_lock
, ops
->name
)) {
5393 reporter
= ERR_PTR(-EEXIST
);
5397 reporter
= __devlink_health_reporter_create(port
->devlink
, ops
,
5398 graceful_period
, priv
);
5399 if (IS_ERR(reporter
))
5402 reporter
->devlink_port
= port
;
5403 list_add_tail(&reporter
->list
, &port
->reporter_list
);
5405 mutex_unlock(&port
->reporters_lock
);
5408 EXPORT_SYMBOL_GPL(devlink_port_health_reporter_create
);
5411 * devlink_health_reporter_create - create devlink health reporter
5415 * @graceful_period: to avoid recovery loops, in msecs
5418 struct devlink_health_reporter
*
5419 devlink_health_reporter_create(struct devlink
*devlink
,
5420 const struct devlink_health_reporter_ops
*ops
,
5421 u64 graceful_period
, void *priv
)
5423 struct devlink_health_reporter
*reporter
;
5425 mutex_lock(&devlink
->reporters_lock
);
5426 if (devlink_health_reporter_find_by_name(devlink
, ops
->name
)) {
5427 reporter
= ERR_PTR(-EEXIST
);
5431 reporter
= __devlink_health_reporter_create(devlink
, ops
,
5432 graceful_period
, priv
);
5433 if (IS_ERR(reporter
))
5436 list_add_tail(&reporter
->list
, &devlink
->reporter_list
);
5438 mutex_unlock(&devlink
->reporters_lock
);
5441 EXPORT_SYMBOL_GPL(devlink_health_reporter_create
);
5444 devlink_health_reporter_free(struct devlink_health_reporter
*reporter
)
5446 mutex_destroy(&reporter
->dump_lock
);
5447 if (reporter
->dump_fmsg
)
5448 devlink_fmsg_free(reporter
->dump_fmsg
);
5453 devlink_health_reporter_put(struct devlink_health_reporter
*reporter
)
5455 if (refcount_dec_and_test(&reporter
->refcount
))
5456 devlink_health_reporter_free(reporter
);
5460 __devlink_health_reporter_destroy(struct devlink_health_reporter
*reporter
)
5462 list_del(&reporter
->list
);
5463 devlink_health_reporter_put(reporter
);
5467 * devlink_health_reporter_destroy - destroy devlink health reporter
5469 * @reporter: devlink health reporter to destroy
5472 devlink_health_reporter_destroy(struct devlink_health_reporter
*reporter
)
5474 struct mutex
*lock
= &reporter
->devlink
->reporters_lock
;
5477 __devlink_health_reporter_destroy(reporter
);
5480 EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy
);
5483 * devlink_port_health_reporter_destroy - destroy devlink port health reporter
5485 * @reporter: devlink health reporter to destroy
5488 devlink_port_health_reporter_destroy(struct devlink_health_reporter
*reporter
)
5490 struct mutex
*lock
= &reporter
->devlink_port
->reporters_lock
;
5493 __devlink_health_reporter_destroy(reporter
);
5496 EXPORT_SYMBOL_GPL(devlink_port_health_reporter_destroy
);
5499 devlink_nl_health_reporter_fill(struct sk_buff
*msg
,
5500 struct devlink
*devlink
,
5501 struct devlink_health_reporter
*reporter
,
5502 enum devlink_command cmd
, u32 portid
,
5505 struct nlattr
*reporter_attr
;
5508 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
5512 if (devlink_nl_put_handle(msg
, devlink
))
5513 goto genlmsg_cancel
;
5515 if (reporter
->devlink_port
) {
5516 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, reporter
->devlink_port
->index
))
5517 goto genlmsg_cancel
;
5519 reporter_attr
= nla_nest_start_noflag(msg
,
5520 DEVLINK_ATTR_HEALTH_REPORTER
);
5522 goto genlmsg_cancel
;
5523 if (nla_put_string(msg
, DEVLINK_ATTR_HEALTH_REPORTER_NAME
,
5524 reporter
->ops
->name
))
5525 goto reporter_nest_cancel
;
5526 if (nla_put_u8(msg
, DEVLINK_ATTR_HEALTH_REPORTER_STATE
,
5527 reporter
->health_state
))
5528 goto reporter_nest_cancel
;
5529 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT
,
5530 reporter
->error_count
, DEVLINK_ATTR_PAD
))
5531 goto reporter_nest_cancel
;
5532 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT
,
5533 reporter
->recovery_count
, DEVLINK_ATTR_PAD
))
5534 goto reporter_nest_cancel
;
5535 if (reporter
->ops
->recover
&&
5536 nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
,
5537 reporter
->graceful_period
,
5539 goto reporter_nest_cancel
;
5540 if (reporter
->ops
->recover
&&
5541 nla_put_u8(msg
, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
,
5542 reporter
->auto_recover
))
5543 goto reporter_nest_cancel
;
5544 if (reporter
->dump_fmsg
&&
5545 nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS
,
5546 jiffies_to_msecs(reporter
->dump_ts
),
5548 goto reporter_nest_cancel
;
5549 if (reporter
->dump_fmsg
&&
5550 nla_put_u64_64bit(msg
, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS
,
5551 reporter
->dump_real_ts
, DEVLINK_ATTR_PAD
))
5552 goto reporter_nest_cancel
;
5553 if (reporter
->ops
->dump
&&
5554 nla_put_u8(msg
, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP
,
5555 reporter
->auto_dump
))
5556 goto reporter_nest_cancel
;
5558 nla_nest_end(msg
, reporter_attr
);
5559 genlmsg_end(msg
, hdr
);
5562 reporter_nest_cancel
:
5563 nla_nest_end(msg
, reporter_attr
);
5565 genlmsg_cancel(msg
, hdr
);
5569 static void devlink_recover_notify(struct devlink_health_reporter
*reporter
,
5570 enum devlink_command cmd
)
5572 struct sk_buff
*msg
;
5575 WARN_ON(cmd
!= DEVLINK_CMD_HEALTH_REPORTER_RECOVER
);
5577 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
5581 err
= devlink_nl_health_reporter_fill(msg
, reporter
->devlink
,
5582 reporter
, cmd
, 0, 0, 0);
5588 genlmsg_multicast_netns(&devlink_nl_family
,
5589 devlink_net(reporter
->devlink
),
5590 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
5594 devlink_health_reporter_recovery_done(struct devlink_health_reporter
*reporter
)
5596 reporter
->recovery_count
++;
5597 reporter
->last_recovery_ts
= jiffies
;
5599 EXPORT_SYMBOL_GPL(devlink_health_reporter_recovery_done
);
5602 devlink_health_reporter_recover(struct devlink_health_reporter
*reporter
,
5603 void *priv_ctx
, struct netlink_ext_ack
*extack
)
5607 if (reporter
->health_state
== DEVLINK_HEALTH_REPORTER_STATE_HEALTHY
)
5610 if (!reporter
->ops
->recover
)
5613 err
= reporter
->ops
->recover(reporter
, priv_ctx
, extack
);
5617 devlink_health_reporter_recovery_done(reporter
);
5618 reporter
->health_state
= DEVLINK_HEALTH_REPORTER_STATE_HEALTHY
;
5619 devlink_recover_notify(reporter
, DEVLINK_CMD_HEALTH_REPORTER_RECOVER
);
5625 devlink_health_dump_clear(struct devlink_health_reporter
*reporter
)
5627 if (!reporter
->dump_fmsg
)
5629 devlink_fmsg_free(reporter
->dump_fmsg
);
5630 reporter
->dump_fmsg
= NULL
;
5633 static int devlink_health_do_dump(struct devlink_health_reporter
*reporter
,
5635 struct netlink_ext_ack
*extack
)
5639 if (!reporter
->ops
->dump
)
5642 if (reporter
->dump_fmsg
)
5645 reporter
->dump_fmsg
= devlink_fmsg_alloc();
5646 if (!reporter
->dump_fmsg
) {
5651 err
= devlink_fmsg_obj_nest_start(reporter
->dump_fmsg
);
5655 err
= reporter
->ops
->dump(reporter
, reporter
->dump_fmsg
,
5660 err
= devlink_fmsg_obj_nest_end(reporter
->dump_fmsg
);
5664 reporter
->dump_ts
= jiffies
;
5665 reporter
->dump_real_ts
= ktime_get_real_ns();
5670 devlink_health_dump_clear(reporter
);
5674 int devlink_health_report(struct devlink_health_reporter
*reporter
,
5675 const char *msg
, void *priv_ctx
)
5677 enum devlink_health_reporter_state prev_health_state
;
5678 struct devlink
*devlink
= reporter
->devlink
;
5679 unsigned long recover_ts_threshold
;
5681 /* write a log message of the current error */
5683 trace_devlink_health_report(devlink
, reporter
->ops
->name
, msg
);
5684 reporter
->error_count
++;
5685 prev_health_state
= reporter
->health_state
;
5686 reporter
->health_state
= DEVLINK_HEALTH_REPORTER_STATE_ERROR
;
5687 devlink_recover_notify(reporter
, DEVLINK_CMD_HEALTH_REPORTER_RECOVER
);
5689 /* abort if the previous error wasn't recovered */
5690 recover_ts_threshold
= reporter
->last_recovery_ts
+
5691 msecs_to_jiffies(reporter
->graceful_period
);
5692 if (reporter
->auto_recover
&&
5693 (prev_health_state
!= DEVLINK_HEALTH_REPORTER_STATE_HEALTHY
||
5694 (reporter
->last_recovery_ts
&& reporter
->recovery_count
&&
5695 time_is_after_jiffies(recover_ts_threshold
)))) {
5696 trace_devlink_health_recover_aborted(devlink
,
5697 reporter
->ops
->name
,
5698 reporter
->health_state
,
5700 reporter
->last_recovery_ts
);
5704 reporter
->health_state
= DEVLINK_HEALTH_REPORTER_STATE_ERROR
;
5706 if (reporter
->auto_dump
) {
5707 mutex_lock(&reporter
->dump_lock
);
5708 /* store current dump of current error, for later analysis */
5709 devlink_health_do_dump(reporter
, priv_ctx
, NULL
);
5710 mutex_unlock(&reporter
->dump_lock
);
5713 if (reporter
->auto_recover
)
5714 return devlink_health_reporter_recover(reporter
,
5719 EXPORT_SYMBOL_GPL(devlink_health_report
);
5721 static struct devlink_health_reporter
*
5722 devlink_health_reporter_get_from_attrs(struct devlink
*devlink
,
5723 struct nlattr
**attrs
)
5725 struct devlink_health_reporter
*reporter
;
5726 struct devlink_port
*devlink_port
;
5727 char *reporter_name
;
5729 if (!attrs
[DEVLINK_ATTR_HEALTH_REPORTER_NAME
])
5732 reporter_name
= nla_data(attrs
[DEVLINK_ATTR_HEALTH_REPORTER_NAME
]);
5733 devlink_port
= devlink_port_get_from_attrs(devlink
, attrs
);
5734 if (IS_ERR(devlink_port
)) {
5735 mutex_lock(&devlink
->reporters_lock
);
5736 reporter
= devlink_health_reporter_find_by_name(devlink
, reporter_name
);
5738 refcount_inc(&reporter
->refcount
);
5739 mutex_unlock(&devlink
->reporters_lock
);
5741 mutex_lock(&devlink_port
->reporters_lock
);
5742 reporter
= devlink_port_health_reporter_find_by_name(devlink_port
, reporter_name
);
5744 refcount_inc(&reporter
->refcount
);
5745 mutex_unlock(&devlink_port
->reporters_lock
);
5751 static struct devlink_health_reporter
*
5752 devlink_health_reporter_get_from_info(struct devlink
*devlink
,
5753 struct genl_info
*info
)
5755 return devlink_health_reporter_get_from_attrs(devlink
, info
->attrs
);
5758 static struct devlink_health_reporter
*
5759 devlink_health_reporter_get_from_cb(struct netlink_callback
*cb
)
5761 const struct genl_dumpit_info
*info
= genl_dumpit_info(cb
);
5762 struct devlink_health_reporter
*reporter
;
5763 struct nlattr
**attrs
= info
->attrs
;
5764 struct devlink
*devlink
;
5766 mutex_lock(&devlink_mutex
);
5767 devlink
= devlink_get_from_attrs(sock_net(cb
->skb
->sk
), attrs
);
5768 if (IS_ERR(devlink
))
5771 reporter
= devlink_health_reporter_get_from_attrs(devlink
, attrs
);
5772 mutex_unlock(&devlink_mutex
);
5775 mutex_unlock(&devlink_mutex
);
5780 devlink_health_reporter_state_update(struct devlink_health_reporter
*reporter
,
5781 enum devlink_health_reporter_state state
)
5783 if (WARN_ON(state
!= DEVLINK_HEALTH_REPORTER_STATE_HEALTHY
&&
5784 state
!= DEVLINK_HEALTH_REPORTER_STATE_ERROR
))
5787 if (reporter
->health_state
== state
)
5790 reporter
->health_state
= state
;
5791 trace_devlink_health_reporter_state_update(reporter
->devlink
,
5792 reporter
->ops
->name
, state
);
5793 devlink_recover_notify(reporter
, DEVLINK_CMD_HEALTH_REPORTER_RECOVER
);
5795 EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update
);
5797 static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff
*skb
,
5798 struct genl_info
*info
)
5800 struct devlink
*devlink
= info
->user_ptr
[0];
5801 struct devlink_health_reporter
*reporter
;
5802 struct sk_buff
*msg
;
5805 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5809 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
5815 err
= devlink_nl_health_reporter_fill(msg
, devlink
, reporter
,
5816 DEVLINK_CMD_HEALTH_REPORTER_GET
,
5817 info
->snd_portid
, info
->snd_seq
,
5824 err
= genlmsg_reply(msg
, info
);
5826 devlink_health_reporter_put(reporter
);
5831 devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff
*msg
,
5832 struct netlink_callback
*cb
)
5834 struct devlink_health_reporter
*reporter
;
5835 struct devlink_port
*port
;
5836 struct devlink
*devlink
;
5837 int start
= cb
->args
[0];
5841 mutex_lock(&devlink_mutex
);
5842 list_for_each_entry(devlink
, &devlink_list
, list
) {
5843 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
5845 mutex_lock(&devlink
->reporters_lock
);
5846 list_for_each_entry(reporter
, &devlink
->reporter_list
,
5852 err
= devlink_nl_health_reporter_fill(msg
, devlink
,
5854 DEVLINK_CMD_HEALTH_REPORTER_GET
,
5855 NETLINK_CB(cb
->skb
).portid
,
5859 mutex_unlock(&devlink
->reporters_lock
);
5864 mutex_unlock(&devlink
->reporters_lock
);
5867 list_for_each_entry(devlink
, &devlink_list
, list
) {
5868 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
5870 list_for_each_entry(port
, &devlink
->port_list
, list
) {
5871 mutex_lock(&port
->reporters_lock
);
5872 list_for_each_entry(reporter
, &port
->reporter_list
, list
) {
5877 err
= devlink_nl_health_reporter_fill(msg
, devlink
, reporter
,
5878 DEVLINK_CMD_HEALTH_REPORTER_GET
,
5879 NETLINK_CB(cb
->skb
).portid
,
5883 mutex_unlock(&port
->reporters_lock
);
5888 mutex_unlock(&port
->reporters_lock
);
5892 mutex_unlock(&devlink_mutex
);
5899 devlink_nl_cmd_health_reporter_set_doit(struct sk_buff
*skb
,
5900 struct genl_info
*info
)
5902 struct devlink
*devlink
= info
->user_ptr
[0];
5903 struct devlink_health_reporter
*reporter
;
5906 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5910 if (!reporter
->ops
->recover
&&
5911 (info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
] ||
5912 info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
])) {
5916 if (!reporter
->ops
->dump
&&
5917 info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP
]) {
5922 if (info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
])
5923 reporter
->graceful_period
=
5924 nla_get_u64(info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
]);
5926 if (info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
])
5927 reporter
->auto_recover
=
5928 nla_get_u8(info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
]);
5930 if (info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP
])
5931 reporter
->auto_dump
=
5932 nla_get_u8(info
->attrs
[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP
]);
5934 devlink_health_reporter_put(reporter
);
5937 devlink_health_reporter_put(reporter
);
5941 static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff
*skb
,
5942 struct genl_info
*info
)
5944 struct devlink
*devlink
= info
->user_ptr
[0];
5945 struct devlink_health_reporter
*reporter
;
5948 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5952 err
= devlink_health_reporter_recover(reporter
, NULL
, info
->extack
);
5954 devlink_health_reporter_put(reporter
);
5958 static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff
*skb
,
5959 struct genl_info
*info
)
5961 struct devlink
*devlink
= info
->user_ptr
[0];
5962 struct devlink_health_reporter
*reporter
;
5963 struct devlink_fmsg
*fmsg
;
5966 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
5970 if (!reporter
->ops
->diagnose
) {
5971 devlink_health_reporter_put(reporter
);
5975 fmsg
= devlink_fmsg_alloc();
5977 devlink_health_reporter_put(reporter
);
5981 err
= devlink_fmsg_obj_nest_start(fmsg
);
5985 err
= reporter
->ops
->diagnose(reporter
, fmsg
, info
->extack
);
5989 err
= devlink_fmsg_obj_nest_end(fmsg
);
5993 err
= devlink_fmsg_snd(fmsg
, info
,
5994 DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE
, 0);
5997 devlink_fmsg_free(fmsg
);
5998 devlink_health_reporter_put(reporter
);
6003 devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff
*skb
,
6004 struct netlink_callback
*cb
)
6006 struct devlink_health_reporter
*reporter
;
6007 u64 start
= cb
->args
[0];
6010 reporter
= devlink_health_reporter_get_from_cb(cb
);
6014 if (!reporter
->ops
->dump
) {
6018 mutex_lock(&reporter
->dump_lock
);
6020 err
= devlink_health_do_dump(reporter
, NULL
, cb
->extack
);
6023 cb
->args
[1] = reporter
->dump_ts
;
6025 if (!reporter
->dump_fmsg
|| cb
->args
[1] != reporter
->dump_ts
) {
6026 NL_SET_ERR_MSG_MOD(cb
->extack
, "Dump trampled, please retry");
6031 err
= devlink_fmsg_dumpit(reporter
->dump_fmsg
, skb
, cb
,
6032 DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET
);
6034 mutex_unlock(&reporter
->dump_lock
);
6036 devlink_health_reporter_put(reporter
);
6041 devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff
*skb
,
6042 struct genl_info
*info
)
6044 struct devlink
*devlink
= info
->user_ptr
[0];
6045 struct devlink_health_reporter
*reporter
;
6047 reporter
= devlink_health_reporter_get_from_info(devlink
, info
);
6051 if (!reporter
->ops
->dump
) {
6052 devlink_health_reporter_put(reporter
);
6056 mutex_lock(&reporter
->dump_lock
);
6057 devlink_health_dump_clear(reporter
);
6058 mutex_unlock(&reporter
->dump_lock
);
6059 devlink_health_reporter_put(reporter
);
6063 struct devlink_stats
{
6066 struct u64_stats_sync syncp
;
6070 * struct devlink_trap_policer_item - Packet trap policer attributes.
6071 * @policer: Immutable packet trap policer attributes.
6072 * @rate: Rate in packets / sec.
6073 * @burst: Burst size in packets.
6074 * @list: trap_policer_list member.
6076 * Describes packet trap policer attributes. Created by devlink during trap
6077 * policer registration.
6079 struct devlink_trap_policer_item
{
6080 const struct devlink_trap_policer
*policer
;
6083 struct list_head list
;
6087 * struct devlink_trap_group_item - Packet trap group attributes.
6088 * @group: Immutable packet trap group attributes.
6089 * @policer_item: Associated policer item. Can be NULL.
6090 * @list: trap_group_list member.
6091 * @stats: Trap group statistics.
6093 * Describes packet trap group attributes. Created by devlink during trap
6094 * group registration.
6096 struct devlink_trap_group_item
{
6097 const struct devlink_trap_group
*group
;
6098 struct devlink_trap_policer_item
*policer_item
;
6099 struct list_head list
;
6100 struct devlink_stats __percpu
*stats
;
6104 * struct devlink_trap_item - Packet trap attributes.
6105 * @trap: Immutable packet trap attributes.
6106 * @group_item: Associated group item.
6107 * @list: trap_list member.
6108 * @action: Trap action.
6109 * @stats: Trap statistics.
6110 * @priv: Driver private information.
6112 * Describes both mutable and immutable packet trap attributes. Created by
6113 * devlink during trap registration and used for all trap related operations.
6115 struct devlink_trap_item
{
6116 const struct devlink_trap
*trap
;
6117 struct devlink_trap_group_item
*group_item
;
6118 struct list_head list
;
6119 enum devlink_trap_action action
;
6120 struct devlink_stats __percpu
*stats
;
6124 static struct devlink_trap_policer_item
*
6125 devlink_trap_policer_item_lookup(struct devlink
*devlink
, u32 id
)
6127 struct devlink_trap_policer_item
*policer_item
;
6129 list_for_each_entry(policer_item
, &devlink
->trap_policer_list
, list
) {
6130 if (policer_item
->policer
->id
== id
)
6131 return policer_item
;
6137 static struct devlink_trap_item
*
6138 devlink_trap_item_lookup(struct devlink
*devlink
, const char *name
)
6140 struct devlink_trap_item
*trap_item
;
6142 list_for_each_entry(trap_item
, &devlink
->trap_list
, list
) {
6143 if (!strcmp(trap_item
->trap
->name
, name
))
6150 static struct devlink_trap_item
*
6151 devlink_trap_item_get_from_info(struct devlink
*devlink
,
6152 struct genl_info
*info
)
6154 struct nlattr
*attr
;
6156 if (!info
->attrs
[DEVLINK_ATTR_TRAP_NAME
])
6158 attr
= info
->attrs
[DEVLINK_ATTR_TRAP_NAME
];
6160 return devlink_trap_item_lookup(devlink
, nla_data(attr
));
6164 devlink_trap_action_get_from_info(struct genl_info
*info
,
6165 enum devlink_trap_action
*p_trap_action
)
6169 val
= nla_get_u8(info
->attrs
[DEVLINK_ATTR_TRAP_ACTION
]);
6171 case DEVLINK_TRAP_ACTION_DROP
: /* fall-through */
6172 case DEVLINK_TRAP_ACTION_TRAP
: /* fall-through */
6173 case DEVLINK_TRAP_ACTION_MIRROR
:
6174 *p_trap_action
= val
;
6183 static int devlink_trap_metadata_put(struct sk_buff
*msg
,
6184 const struct devlink_trap
*trap
)
6186 struct nlattr
*attr
;
6188 attr
= nla_nest_start(msg
, DEVLINK_ATTR_TRAP_METADATA
);
6192 if ((trap
->metadata_cap
& DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT
) &&
6193 nla_put_flag(msg
, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT
))
6194 goto nla_put_failure
;
6195 if ((trap
->metadata_cap
& DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE
) &&
6196 nla_put_flag(msg
, DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE
))
6197 goto nla_put_failure
;
6199 nla_nest_end(msg
, attr
);
6204 nla_nest_cancel(msg
, attr
);
6208 static void devlink_trap_stats_read(struct devlink_stats __percpu
*trap_stats
,
6209 struct devlink_stats
*stats
)
6213 memset(stats
, 0, sizeof(*stats
));
6214 for_each_possible_cpu(i
) {
6215 struct devlink_stats
*cpu_stats
;
6216 u64 rx_packets
, rx_bytes
;
6219 cpu_stats
= per_cpu_ptr(trap_stats
, i
);
6221 start
= u64_stats_fetch_begin_irq(&cpu_stats
->syncp
);
6222 rx_packets
= cpu_stats
->rx_packets
;
6223 rx_bytes
= cpu_stats
->rx_bytes
;
6224 } while (u64_stats_fetch_retry_irq(&cpu_stats
->syncp
, start
));
6226 stats
->rx_packets
+= rx_packets
;
6227 stats
->rx_bytes
+= rx_bytes
;
6231 static int devlink_trap_stats_put(struct sk_buff
*msg
,
6232 struct devlink_stats __percpu
*trap_stats
)
6234 struct devlink_stats stats
;
6235 struct nlattr
*attr
;
6237 devlink_trap_stats_read(trap_stats
, &stats
);
6239 attr
= nla_nest_start(msg
, DEVLINK_ATTR_STATS
);
6243 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_STATS_RX_PACKETS
,
6244 stats
.rx_packets
, DEVLINK_ATTR_PAD
))
6245 goto nla_put_failure
;
6247 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_STATS_RX_BYTES
,
6248 stats
.rx_bytes
, DEVLINK_ATTR_PAD
))
6249 goto nla_put_failure
;
6251 nla_nest_end(msg
, attr
);
6256 nla_nest_cancel(msg
, attr
);
6260 static int devlink_nl_trap_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
6261 const struct devlink_trap_item
*trap_item
,
6262 enum devlink_command cmd
, u32 portid
, u32 seq
,
6265 struct devlink_trap_group_item
*group_item
= trap_item
->group_item
;
6269 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
6273 if (devlink_nl_put_handle(msg
, devlink
))
6274 goto nla_put_failure
;
6276 if (nla_put_string(msg
, DEVLINK_ATTR_TRAP_GROUP_NAME
,
6277 group_item
->group
->name
))
6278 goto nla_put_failure
;
6280 if (nla_put_string(msg
, DEVLINK_ATTR_TRAP_NAME
, trap_item
->trap
->name
))
6281 goto nla_put_failure
;
6283 if (nla_put_u8(msg
, DEVLINK_ATTR_TRAP_TYPE
, trap_item
->trap
->type
))
6284 goto nla_put_failure
;
6286 if (trap_item
->trap
->generic
&&
6287 nla_put_flag(msg
, DEVLINK_ATTR_TRAP_GENERIC
))
6288 goto nla_put_failure
;
6290 if (nla_put_u8(msg
, DEVLINK_ATTR_TRAP_ACTION
, trap_item
->action
))
6291 goto nla_put_failure
;
6293 err
= devlink_trap_metadata_put(msg
, trap_item
->trap
);
6295 goto nla_put_failure
;
6297 err
= devlink_trap_stats_put(msg
, trap_item
->stats
);
6299 goto nla_put_failure
;
6301 genlmsg_end(msg
, hdr
);
6306 genlmsg_cancel(msg
, hdr
);
6310 static int devlink_nl_cmd_trap_get_doit(struct sk_buff
*skb
,
6311 struct genl_info
*info
)
6313 struct netlink_ext_ack
*extack
= info
->extack
;
6314 struct devlink
*devlink
= info
->user_ptr
[0];
6315 struct devlink_trap_item
*trap_item
;
6316 struct sk_buff
*msg
;
6319 if (list_empty(&devlink
->trap_list
))
6322 trap_item
= devlink_trap_item_get_from_info(devlink
, info
);
6324 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap");
6328 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
6332 err
= devlink_nl_trap_fill(msg
, devlink
, trap_item
,
6333 DEVLINK_CMD_TRAP_NEW
, info
->snd_portid
,
6338 return genlmsg_reply(msg
, info
);
6345 static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff
*msg
,
6346 struct netlink_callback
*cb
)
6348 struct devlink_trap_item
*trap_item
;
6349 struct devlink
*devlink
;
6350 int start
= cb
->args
[0];
6354 mutex_lock(&devlink_mutex
);
6355 list_for_each_entry(devlink
, &devlink_list
, list
) {
6356 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
6358 mutex_lock(&devlink
->lock
);
6359 list_for_each_entry(trap_item
, &devlink
->trap_list
, list
) {
6364 err
= devlink_nl_trap_fill(msg
, devlink
, trap_item
,
6365 DEVLINK_CMD_TRAP_NEW
,
6366 NETLINK_CB(cb
->skb
).portid
,
6370 mutex_unlock(&devlink
->lock
);
6375 mutex_unlock(&devlink
->lock
);
6378 mutex_unlock(&devlink_mutex
);
6384 static int __devlink_trap_action_set(struct devlink
*devlink
,
6385 struct devlink_trap_item
*trap_item
,
6386 enum devlink_trap_action trap_action
,
6387 struct netlink_ext_ack
*extack
)
6391 if (trap_item
->action
!= trap_action
&&
6392 trap_item
->trap
->type
!= DEVLINK_TRAP_TYPE_DROP
) {
6393 NL_SET_ERR_MSG_MOD(extack
, "Cannot change action of non-drop traps. Skipping");
6397 err
= devlink
->ops
->trap_action_set(devlink
, trap_item
->trap
,
6402 trap_item
->action
= trap_action
;
6407 static int devlink_trap_action_set(struct devlink
*devlink
,
6408 struct devlink_trap_item
*trap_item
,
6409 struct genl_info
*info
)
6411 enum devlink_trap_action trap_action
;
6414 if (!info
->attrs
[DEVLINK_ATTR_TRAP_ACTION
])
6417 err
= devlink_trap_action_get_from_info(info
, &trap_action
);
6419 NL_SET_ERR_MSG_MOD(info
->extack
, "Invalid trap action");
6423 return __devlink_trap_action_set(devlink
, trap_item
, trap_action
,
6427 static int devlink_nl_cmd_trap_set_doit(struct sk_buff
*skb
,
6428 struct genl_info
*info
)
6430 struct netlink_ext_ack
*extack
= info
->extack
;
6431 struct devlink
*devlink
= info
->user_ptr
[0];
6432 struct devlink_trap_item
*trap_item
;
6435 if (list_empty(&devlink
->trap_list
))
6438 trap_item
= devlink_trap_item_get_from_info(devlink
, info
);
6440 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap");
6444 err
= devlink_trap_action_set(devlink
, trap_item
, info
);
6451 static struct devlink_trap_group_item
*
6452 devlink_trap_group_item_lookup(struct devlink
*devlink
, const char *name
)
6454 struct devlink_trap_group_item
*group_item
;
6456 list_for_each_entry(group_item
, &devlink
->trap_group_list
, list
) {
6457 if (!strcmp(group_item
->group
->name
, name
))
6464 static struct devlink_trap_group_item
*
6465 devlink_trap_group_item_lookup_by_id(struct devlink
*devlink
, u16 id
)
6467 struct devlink_trap_group_item
*group_item
;
6469 list_for_each_entry(group_item
, &devlink
->trap_group_list
, list
) {
6470 if (group_item
->group
->id
== id
)
6477 static struct devlink_trap_group_item
*
6478 devlink_trap_group_item_get_from_info(struct devlink
*devlink
,
6479 struct genl_info
*info
)
6483 if (!info
->attrs
[DEVLINK_ATTR_TRAP_GROUP_NAME
])
6485 name
= nla_data(info
->attrs
[DEVLINK_ATTR_TRAP_GROUP_NAME
]);
6487 return devlink_trap_group_item_lookup(devlink
, name
);
6491 devlink_nl_trap_group_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
6492 const struct devlink_trap_group_item
*group_item
,
6493 enum devlink_command cmd
, u32 portid
, u32 seq
,
6499 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
6503 if (devlink_nl_put_handle(msg
, devlink
))
6504 goto nla_put_failure
;
6506 if (nla_put_string(msg
, DEVLINK_ATTR_TRAP_GROUP_NAME
,
6507 group_item
->group
->name
))
6508 goto nla_put_failure
;
6510 if (group_item
->group
->generic
&&
6511 nla_put_flag(msg
, DEVLINK_ATTR_TRAP_GENERIC
))
6512 goto nla_put_failure
;
6514 if (group_item
->policer_item
&&
6515 nla_put_u32(msg
, DEVLINK_ATTR_TRAP_POLICER_ID
,
6516 group_item
->policer_item
->policer
->id
))
6517 goto nla_put_failure
;
6519 err
= devlink_trap_stats_put(msg
, group_item
->stats
);
6521 goto nla_put_failure
;
6523 genlmsg_end(msg
, hdr
);
6528 genlmsg_cancel(msg
, hdr
);
6532 static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff
*skb
,
6533 struct genl_info
*info
)
6535 struct netlink_ext_ack
*extack
= info
->extack
;
6536 struct devlink
*devlink
= info
->user_ptr
[0];
6537 struct devlink_trap_group_item
*group_item
;
6538 struct sk_buff
*msg
;
6541 if (list_empty(&devlink
->trap_group_list
))
6544 group_item
= devlink_trap_group_item_get_from_info(devlink
, info
);
6546 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap group");
6550 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
6554 err
= devlink_nl_trap_group_fill(msg
, devlink
, group_item
,
6555 DEVLINK_CMD_TRAP_GROUP_NEW
,
6556 info
->snd_portid
, info
->snd_seq
, 0);
6558 goto err_trap_group_fill
;
6560 return genlmsg_reply(msg
, info
);
6562 err_trap_group_fill
:
6567 static int devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff
*msg
,
6568 struct netlink_callback
*cb
)
6570 enum devlink_command cmd
= DEVLINK_CMD_TRAP_GROUP_NEW
;
6571 struct devlink_trap_group_item
*group_item
;
6572 u32 portid
= NETLINK_CB(cb
->skb
).portid
;
6573 struct devlink
*devlink
;
6574 int start
= cb
->args
[0];
6578 mutex_lock(&devlink_mutex
);
6579 list_for_each_entry(devlink
, &devlink_list
, list
) {
6580 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
6582 mutex_lock(&devlink
->lock
);
6583 list_for_each_entry(group_item
, &devlink
->trap_group_list
,
6589 err
= devlink_nl_trap_group_fill(msg
, devlink
,
6595 mutex_unlock(&devlink
->lock
);
6600 mutex_unlock(&devlink
->lock
);
6603 mutex_unlock(&devlink_mutex
);
6610 __devlink_trap_group_action_set(struct devlink
*devlink
,
6611 struct devlink_trap_group_item
*group_item
,
6612 enum devlink_trap_action trap_action
,
6613 struct netlink_ext_ack
*extack
)
6615 const char *group_name
= group_item
->group
->name
;
6616 struct devlink_trap_item
*trap_item
;
6619 list_for_each_entry(trap_item
, &devlink
->trap_list
, list
) {
6620 if (strcmp(trap_item
->group_item
->group
->name
, group_name
))
6622 err
= __devlink_trap_action_set(devlink
, trap_item
,
6623 trap_action
, extack
);
6632 devlink_trap_group_action_set(struct devlink
*devlink
,
6633 struct devlink_trap_group_item
*group_item
,
6634 struct genl_info
*info
, bool *p_modified
)
6636 enum devlink_trap_action trap_action
;
6639 if (!info
->attrs
[DEVLINK_ATTR_TRAP_ACTION
])
6642 err
= devlink_trap_action_get_from_info(info
, &trap_action
);
6644 NL_SET_ERR_MSG_MOD(info
->extack
, "Invalid trap action");
6648 err
= __devlink_trap_group_action_set(devlink
, group_item
, trap_action
,
6658 static int devlink_trap_group_set(struct devlink
*devlink
,
6659 struct devlink_trap_group_item
*group_item
,
6660 struct genl_info
*info
)
6662 struct devlink_trap_policer_item
*policer_item
;
6663 struct netlink_ext_ack
*extack
= info
->extack
;
6664 const struct devlink_trap_policer
*policer
;
6665 struct nlattr
**attrs
= info
->attrs
;
6668 if (!attrs
[DEVLINK_ATTR_TRAP_POLICER_ID
])
6671 if (!devlink
->ops
->trap_group_set
)
6674 policer_item
= group_item
->policer_item
;
6675 if (attrs
[DEVLINK_ATTR_TRAP_POLICER_ID
]) {
6678 policer_id
= nla_get_u32(attrs
[DEVLINK_ATTR_TRAP_POLICER_ID
]);
6679 policer_item
= devlink_trap_policer_item_lookup(devlink
,
6681 if (policer_id
&& !policer_item
) {
6682 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap policer");
6686 policer
= policer_item
? policer_item
->policer
: NULL
;
6688 err
= devlink
->ops
->trap_group_set(devlink
, group_item
->group
, policer
);
6692 group_item
->policer_item
= policer_item
;
6697 static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff
*skb
,
6698 struct genl_info
*info
)
6700 struct netlink_ext_ack
*extack
= info
->extack
;
6701 struct devlink
*devlink
= info
->user_ptr
[0];
6702 struct devlink_trap_group_item
*group_item
;
6703 bool modified
= false;
6706 if (list_empty(&devlink
->trap_group_list
))
6709 group_item
= devlink_trap_group_item_get_from_info(devlink
, info
);
6711 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap group");
6715 err
= devlink_trap_group_action_set(devlink
, group_item
, info
,
6720 err
= devlink_trap_group_set(devlink
, group_item
, info
);
6722 goto err_trap_group_set
;
6728 NL_SET_ERR_MSG_MOD(extack
, "Trap group set failed, but some changes were committed already");
6732 static struct devlink_trap_policer_item
*
6733 devlink_trap_policer_item_get_from_info(struct devlink
*devlink
,
6734 struct genl_info
*info
)
6738 if (!info
->attrs
[DEVLINK_ATTR_TRAP_POLICER_ID
])
6740 id
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_TRAP_POLICER_ID
]);
6742 return devlink_trap_policer_item_lookup(devlink
, id
);
6746 devlink_trap_policer_stats_put(struct sk_buff
*msg
, struct devlink
*devlink
,
6747 const struct devlink_trap_policer
*policer
)
6749 struct nlattr
*attr
;
6753 if (!devlink
->ops
->trap_policer_counter_get
)
6756 err
= devlink
->ops
->trap_policer_counter_get(devlink
, policer
, &drops
);
6760 attr
= nla_nest_start(msg
, DEVLINK_ATTR_STATS
);
6764 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_STATS_RX_DROPPED
, drops
,
6766 goto nla_put_failure
;
6768 nla_nest_end(msg
, attr
);
6773 nla_nest_cancel(msg
, attr
);
6778 devlink_nl_trap_policer_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
6779 const struct devlink_trap_policer_item
*policer_item
,
6780 enum devlink_command cmd
, u32 portid
, u32 seq
,
6786 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
6790 if (devlink_nl_put_handle(msg
, devlink
))
6791 goto nla_put_failure
;
6793 if (nla_put_u32(msg
, DEVLINK_ATTR_TRAP_POLICER_ID
,
6794 policer_item
->policer
->id
))
6795 goto nla_put_failure
;
6797 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_TRAP_POLICER_RATE
,
6798 policer_item
->rate
, DEVLINK_ATTR_PAD
))
6799 goto nla_put_failure
;
6801 if (nla_put_u64_64bit(msg
, DEVLINK_ATTR_TRAP_POLICER_BURST
,
6802 policer_item
->burst
, DEVLINK_ATTR_PAD
))
6803 goto nla_put_failure
;
6805 err
= devlink_trap_policer_stats_put(msg
, devlink
,
6806 policer_item
->policer
);
6808 goto nla_put_failure
;
6810 genlmsg_end(msg
, hdr
);
6815 genlmsg_cancel(msg
, hdr
);
6819 static int devlink_nl_cmd_trap_policer_get_doit(struct sk_buff
*skb
,
6820 struct genl_info
*info
)
6822 struct devlink_trap_policer_item
*policer_item
;
6823 struct netlink_ext_ack
*extack
= info
->extack
;
6824 struct devlink
*devlink
= info
->user_ptr
[0];
6825 struct sk_buff
*msg
;
6828 if (list_empty(&devlink
->trap_policer_list
))
6831 policer_item
= devlink_trap_policer_item_get_from_info(devlink
, info
);
6832 if (!policer_item
) {
6833 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap policer");
6837 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
6841 err
= devlink_nl_trap_policer_fill(msg
, devlink
, policer_item
,
6842 DEVLINK_CMD_TRAP_POLICER_NEW
,
6843 info
->snd_portid
, info
->snd_seq
, 0);
6845 goto err_trap_policer_fill
;
6847 return genlmsg_reply(msg
, info
);
6849 err_trap_policer_fill
:
6854 static int devlink_nl_cmd_trap_policer_get_dumpit(struct sk_buff
*msg
,
6855 struct netlink_callback
*cb
)
6857 enum devlink_command cmd
= DEVLINK_CMD_TRAP_POLICER_NEW
;
6858 struct devlink_trap_policer_item
*policer_item
;
6859 u32 portid
= NETLINK_CB(cb
->skb
).portid
;
6860 struct devlink
*devlink
;
6861 int start
= cb
->args
[0];
6865 mutex_lock(&devlink_mutex
);
6866 list_for_each_entry(devlink
, &devlink_list
, list
) {
6867 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
6869 mutex_lock(&devlink
->lock
);
6870 list_for_each_entry(policer_item
, &devlink
->trap_policer_list
,
6876 err
= devlink_nl_trap_policer_fill(msg
, devlink
,
6882 mutex_unlock(&devlink
->lock
);
6887 mutex_unlock(&devlink
->lock
);
6890 mutex_unlock(&devlink_mutex
);
6897 devlink_trap_policer_set(struct devlink
*devlink
,
6898 struct devlink_trap_policer_item
*policer_item
,
6899 struct genl_info
*info
)
6901 struct netlink_ext_ack
*extack
= info
->extack
;
6902 struct nlattr
**attrs
= info
->attrs
;
6906 rate
= policer_item
->rate
;
6907 burst
= policer_item
->burst
;
6909 if (attrs
[DEVLINK_ATTR_TRAP_POLICER_RATE
])
6910 rate
= nla_get_u64(attrs
[DEVLINK_ATTR_TRAP_POLICER_RATE
]);
6912 if (attrs
[DEVLINK_ATTR_TRAP_POLICER_BURST
])
6913 burst
= nla_get_u64(attrs
[DEVLINK_ATTR_TRAP_POLICER_BURST
]);
6915 if (rate
< policer_item
->policer
->min_rate
) {
6916 NL_SET_ERR_MSG_MOD(extack
, "Policer rate lower than limit");
6920 if (rate
> policer_item
->policer
->max_rate
) {
6921 NL_SET_ERR_MSG_MOD(extack
, "Policer rate higher than limit");
6925 if (burst
< policer_item
->policer
->min_burst
) {
6926 NL_SET_ERR_MSG_MOD(extack
, "Policer burst size lower than limit");
6930 if (burst
> policer_item
->policer
->max_burst
) {
6931 NL_SET_ERR_MSG_MOD(extack
, "Policer burst size higher than limit");
6935 err
= devlink
->ops
->trap_policer_set(devlink
, policer_item
->policer
,
6936 rate
, burst
, info
->extack
);
6940 policer_item
->rate
= rate
;
6941 policer_item
->burst
= burst
;
6946 static int devlink_nl_cmd_trap_policer_set_doit(struct sk_buff
*skb
,
6947 struct genl_info
*info
)
6949 struct devlink_trap_policer_item
*policer_item
;
6950 struct netlink_ext_ack
*extack
= info
->extack
;
6951 struct devlink
*devlink
= info
->user_ptr
[0];
6953 if (list_empty(&devlink
->trap_policer_list
))
6956 if (!devlink
->ops
->trap_policer_set
)
6959 policer_item
= devlink_trap_policer_item_get_from_info(devlink
, info
);
6960 if (!policer_item
) {
6961 NL_SET_ERR_MSG_MOD(extack
, "Device did not register this trap policer");
6965 return devlink_trap_policer_set(devlink
, policer_item
, info
);
6968 static const struct nla_policy devlink_nl_policy
[DEVLINK_ATTR_MAX
+ 1] = {
6969 [DEVLINK_ATTR_UNSPEC
] = { .strict_start_type
=
6970 DEVLINK_ATTR_TRAP_POLICER_ID
},
6971 [DEVLINK_ATTR_BUS_NAME
] = { .type
= NLA_NUL_STRING
},
6972 [DEVLINK_ATTR_DEV_NAME
] = { .type
= NLA_NUL_STRING
},
6973 [DEVLINK_ATTR_PORT_INDEX
] = { .type
= NLA_U32
},
6974 [DEVLINK_ATTR_PORT_TYPE
] = { .type
= NLA_U16
},
6975 [DEVLINK_ATTR_PORT_SPLIT_COUNT
] = { .type
= NLA_U32
},
6976 [DEVLINK_ATTR_SB_INDEX
] = { .type
= NLA_U32
},
6977 [DEVLINK_ATTR_SB_POOL_INDEX
] = { .type
= NLA_U16
},
6978 [DEVLINK_ATTR_SB_POOL_TYPE
] = { .type
= NLA_U8
},
6979 [DEVLINK_ATTR_SB_POOL_SIZE
] = { .type
= NLA_U32
},
6980 [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
] = { .type
= NLA_U8
},
6981 [DEVLINK_ATTR_SB_THRESHOLD
] = { .type
= NLA_U32
},
6982 [DEVLINK_ATTR_SB_TC_INDEX
] = { .type
= NLA_U16
},
6983 [DEVLINK_ATTR_ESWITCH_MODE
] = { .type
= NLA_U16
},
6984 [DEVLINK_ATTR_ESWITCH_INLINE_MODE
] = { .type
= NLA_U8
},
6985 [DEVLINK_ATTR_ESWITCH_ENCAP_MODE
] = { .type
= NLA_U8
},
6986 [DEVLINK_ATTR_DPIPE_TABLE_NAME
] = { .type
= NLA_NUL_STRING
},
6987 [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
] = { .type
= NLA_U8
},
6988 [DEVLINK_ATTR_RESOURCE_ID
] = { .type
= NLA_U64
},
6989 [DEVLINK_ATTR_RESOURCE_SIZE
] = { .type
= NLA_U64
},
6990 [DEVLINK_ATTR_PARAM_NAME
] = { .type
= NLA_NUL_STRING
},
6991 [DEVLINK_ATTR_PARAM_TYPE
] = { .type
= NLA_U8
},
6992 [DEVLINK_ATTR_PARAM_VALUE_CMODE
] = { .type
= NLA_U8
},
6993 [DEVLINK_ATTR_REGION_NAME
] = { .type
= NLA_NUL_STRING
},
6994 [DEVLINK_ATTR_REGION_SNAPSHOT_ID
] = { .type
= NLA_U32
},
6995 [DEVLINK_ATTR_REGION_CHUNK_ADDR
] = { .type
= NLA_U64
},
6996 [DEVLINK_ATTR_REGION_CHUNK_LEN
] = { .type
= NLA_U64
},
6997 [DEVLINK_ATTR_HEALTH_REPORTER_NAME
] = { .type
= NLA_NUL_STRING
},
6998 [DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD
] = { .type
= NLA_U64
},
6999 [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER
] = { .type
= NLA_U8
},
7000 [DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME
] = { .type
= NLA_NUL_STRING
},
7001 [DEVLINK_ATTR_FLASH_UPDATE_COMPONENT
] = { .type
= NLA_NUL_STRING
},
7002 [DEVLINK_ATTR_TRAP_NAME
] = { .type
= NLA_NUL_STRING
},
7003 [DEVLINK_ATTR_TRAP_ACTION
] = { .type
= NLA_U8
},
7004 [DEVLINK_ATTR_TRAP_GROUP_NAME
] = { .type
= NLA_NUL_STRING
},
7005 [DEVLINK_ATTR_NETNS_PID
] = { .type
= NLA_U32
},
7006 [DEVLINK_ATTR_NETNS_FD
] = { .type
= NLA_U32
},
7007 [DEVLINK_ATTR_NETNS_ID
] = { .type
= NLA_U32
},
7008 [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP
] = { .type
= NLA_U8
},
7009 [DEVLINK_ATTR_TRAP_POLICER_ID
] = { .type
= NLA_U32
},
7010 [DEVLINK_ATTR_TRAP_POLICER_RATE
] = { .type
= NLA_U64
},
7011 [DEVLINK_ATTR_TRAP_POLICER_BURST
] = { .type
= NLA_U64
},
7012 [DEVLINK_ATTR_PORT_FUNCTION
] = { .type
= NLA_NESTED
},
7015 static const struct genl_ops devlink_nl_ops
[] = {
7017 .cmd
= DEVLINK_CMD_GET
,
7018 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7019 .doit
= devlink_nl_cmd_get_doit
,
7020 .dumpit
= devlink_nl_cmd_get_dumpit
,
7021 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7022 /* can be retrieved by unprivileged users */
7025 .cmd
= DEVLINK_CMD_PORT_GET
,
7026 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7027 .doit
= devlink_nl_cmd_port_get_doit
,
7028 .dumpit
= devlink_nl_cmd_port_get_dumpit
,
7029 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
7030 /* can be retrieved by unprivileged users */
7033 .cmd
= DEVLINK_CMD_PORT_SET
,
7034 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7035 .doit
= devlink_nl_cmd_port_set_doit
,
7036 .flags
= GENL_ADMIN_PERM
,
7037 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
7040 .cmd
= DEVLINK_CMD_PORT_SPLIT
,
7041 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7042 .doit
= devlink_nl_cmd_port_split_doit
,
7043 .flags
= GENL_ADMIN_PERM
,
7044 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
7045 DEVLINK_NL_FLAG_NO_LOCK
,
7048 .cmd
= DEVLINK_CMD_PORT_UNSPLIT
,
7049 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7050 .doit
= devlink_nl_cmd_port_unsplit_doit
,
7051 .flags
= GENL_ADMIN_PERM
,
7052 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
7053 DEVLINK_NL_FLAG_NO_LOCK
,
7056 .cmd
= DEVLINK_CMD_SB_GET
,
7057 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7058 .doit
= devlink_nl_cmd_sb_get_doit
,
7059 .dumpit
= devlink_nl_cmd_sb_get_dumpit
,
7060 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
7061 DEVLINK_NL_FLAG_NEED_SB
,
7062 /* can be retrieved by unprivileged users */
7065 .cmd
= DEVLINK_CMD_SB_POOL_GET
,
7066 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7067 .doit
= devlink_nl_cmd_sb_pool_get_doit
,
7068 .dumpit
= devlink_nl_cmd_sb_pool_get_dumpit
,
7069 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
7070 DEVLINK_NL_FLAG_NEED_SB
,
7071 /* can be retrieved by unprivileged users */
7074 .cmd
= DEVLINK_CMD_SB_POOL_SET
,
7075 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7076 .doit
= devlink_nl_cmd_sb_pool_set_doit
,
7077 .flags
= GENL_ADMIN_PERM
,
7078 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
7079 DEVLINK_NL_FLAG_NEED_SB
,
7082 .cmd
= DEVLINK_CMD_SB_PORT_POOL_GET
,
7083 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7084 .doit
= devlink_nl_cmd_sb_port_pool_get_doit
,
7085 .dumpit
= devlink_nl_cmd_sb_port_pool_get_dumpit
,
7086 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
7087 DEVLINK_NL_FLAG_NEED_SB
,
7088 /* can be retrieved by unprivileged users */
7091 .cmd
= DEVLINK_CMD_SB_PORT_POOL_SET
,
7092 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7093 .doit
= devlink_nl_cmd_sb_port_pool_set_doit
,
7094 .flags
= GENL_ADMIN_PERM
,
7095 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
7096 DEVLINK_NL_FLAG_NEED_SB
,
7099 .cmd
= DEVLINK_CMD_SB_TC_POOL_BIND_GET
,
7100 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7101 .doit
= devlink_nl_cmd_sb_tc_pool_bind_get_doit
,
7102 .dumpit
= devlink_nl_cmd_sb_tc_pool_bind_get_dumpit
,
7103 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
7104 DEVLINK_NL_FLAG_NEED_SB
,
7105 /* can be retrieved by unprivileged users */
7108 .cmd
= DEVLINK_CMD_SB_TC_POOL_BIND_SET
,
7109 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7110 .doit
= devlink_nl_cmd_sb_tc_pool_bind_set_doit
,
7111 .flags
= GENL_ADMIN_PERM
,
7112 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
7113 DEVLINK_NL_FLAG_NEED_SB
,
7116 .cmd
= DEVLINK_CMD_SB_OCC_SNAPSHOT
,
7117 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7118 .doit
= devlink_nl_cmd_sb_occ_snapshot_doit
,
7119 .flags
= GENL_ADMIN_PERM
,
7120 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
7121 DEVLINK_NL_FLAG_NEED_SB
,
7124 .cmd
= DEVLINK_CMD_SB_OCC_MAX_CLEAR
,
7125 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7126 .doit
= devlink_nl_cmd_sb_occ_max_clear_doit
,
7127 .flags
= GENL_ADMIN_PERM
,
7128 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
7129 DEVLINK_NL_FLAG_NEED_SB
,
7132 .cmd
= DEVLINK_CMD_ESWITCH_GET
,
7133 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7134 .doit
= devlink_nl_cmd_eswitch_get_doit
,
7135 .flags
= GENL_ADMIN_PERM
,
7136 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
7137 DEVLINK_NL_FLAG_NO_LOCK
,
7140 .cmd
= DEVLINK_CMD_ESWITCH_SET
,
7141 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7142 .doit
= devlink_nl_cmd_eswitch_set_doit
,
7143 .flags
= GENL_ADMIN_PERM
,
7144 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
7145 DEVLINK_NL_FLAG_NO_LOCK
,
7148 .cmd
= DEVLINK_CMD_DPIPE_TABLE_GET
,
7149 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7150 .doit
= devlink_nl_cmd_dpipe_table_get
,
7151 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7152 /* can be retrieved by unprivileged users */
7155 .cmd
= DEVLINK_CMD_DPIPE_ENTRIES_GET
,
7156 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7157 .doit
= devlink_nl_cmd_dpipe_entries_get
,
7158 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7159 /* can be retrieved by unprivileged users */
7162 .cmd
= DEVLINK_CMD_DPIPE_HEADERS_GET
,
7163 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7164 .doit
= devlink_nl_cmd_dpipe_headers_get
,
7165 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7166 /* can be retrieved by unprivileged users */
7169 .cmd
= DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET
,
7170 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7171 .doit
= devlink_nl_cmd_dpipe_table_counters_set
,
7172 .flags
= GENL_ADMIN_PERM
,
7173 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7176 .cmd
= DEVLINK_CMD_RESOURCE_SET
,
7177 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7178 .doit
= devlink_nl_cmd_resource_set
,
7179 .flags
= GENL_ADMIN_PERM
,
7180 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7183 .cmd
= DEVLINK_CMD_RESOURCE_DUMP
,
7184 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7185 .doit
= devlink_nl_cmd_resource_dump
,
7186 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7187 /* can be retrieved by unprivileged users */
7190 .cmd
= DEVLINK_CMD_RELOAD
,
7191 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7192 .doit
= devlink_nl_cmd_reload
,
7193 .flags
= GENL_ADMIN_PERM
,
7194 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
7195 DEVLINK_NL_FLAG_NO_LOCK
,
7198 .cmd
= DEVLINK_CMD_PARAM_GET
,
7199 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7200 .doit
= devlink_nl_cmd_param_get_doit
,
7201 .dumpit
= devlink_nl_cmd_param_get_dumpit
,
7202 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7203 /* can be retrieved by unprivileged users */
7206 .cmd
= DEVLINK_CMD_PARAM_SET
,
7207 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7208 .doit
= devlink_nl_cmd_param_set_doit
,
7209 .flags
= GENL_ADMIN_PERM
,
7210 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7213 .cmd
= DEVLINK_CMD_PORT_PARAM_GET
,
7214 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7215 .doit
= devlink_nl_cmd_port_param_get_doit
,
7216 .dumpit
= devlink_nl_cmd_port_param_get_dumpit
,
7217 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
7218 /* can be retrieved by unprivileged users */
7221 .cmd
= DEVLINK_CMD_PORT_PARAM_SET
,
7222 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7223 .doit
= devlink_nl_cmd_port_param_set_doit
,
7224 .flags
= GENL_ADMIN_PERM
,
7225 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
7228 .cmd
= DEVLINK_CMD_REGION_GET
,
7229 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7230 .doit
= devlink_nl_cmd_region_get_doit
,
7231 .dumpit
= devlink_nl_cmd_region_get_dumpit
,
7232 .flags
= GENL_ADMIN_PERM
,
7233 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7236 .cmd
= DEVLINK_CMD_REGION_NEW
,
7237 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7238 .doit
= devlink_nl_cmd_region_new
,
7239 .flags
= GENL_ADMIN_PERM
,
7240 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7243 .cmd
= DEVLINK_CMD_REGION_DEL
,
7244 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7245 .doit
= devlink_nl_cmd_region_del
,
7246 .flags
= GENL_ADMIN_PERM
,
7247 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7250 .cmd
= DEVLINK_CMD_REGION_READ
,
7251 .validate
= GENL_DONT_VALIDATE_STRICT
|
7252 GENL_DONT_VALIDATE_DUMP_STRICT
,
7253 .dumpit
= devlink_nl_cmd_region_read_dumpit
,
7254 .flags
= GENL_ADMIN_PERM
,
7255 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7258 .cmd
= DEVLINK_CMD_INFO_GET
,
7259 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7260 .doit
= devlink_nl_cmd_info_get_doit
,
7261 .dumpit
= devlink_nl_cmd_info_get_dumpit
,
7262 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7263 /* can be retrieved by unprivileged users */
7266 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_GET
,
7267 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7268 .doit
= devlink_nl_cmd_health_reporter_get_doit
,
7269 .dumpit
= devlink_nl_cmd_health_reporter_get_dumpit
,
7270 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT
|
7271 DEVLINK_NL_FLAG_NO_LOCK
,
7272 /* can be retrieved by unprivileged users */
7275 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_SET
,
7276 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7277 .doit
= devlink_nl_cmd_health_reporter_set_doit
,
7278 .flags
= GENL_ADMIN_PERM
,
7279 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT
|
7280 DEVLINK_NL_FLAG_NO_LOCK
,
7283 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_RECOVER
,
7284 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7285 .doit
= devlink_nl_cmd_health_reporter_recover_doit
,
7286 .flags
= GENL_ADMIN_PERM
,
7287 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT
|
7288 DEVLINK_NL_FLAG_NO_LOCK
,
7291 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE
,
7292 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7293 .doit
= devlink_nl_cmd_health_reporter_diagnose_doit
,
7294 .flags
= GENL_ADMIN_PERM
,
7295 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT
|
7296 DEVLINK_NL_FLAG_NO_LOCK
,
7299 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET
,
7300 .validate
= GENL_DONT_VALIDATE_STRICT
|
7301 GENL_DONT_VALIDATE_DUMP_STRICT
,
7302 .dumpit
= devlink_nl_cmd_health_reporter_dump_get_dumpit
,
7303 .flags
= GENL_ADMIN_PERM
,
7304 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT
|
7305 DEVLINK_NL_FLAG_NO_LOCK
,
7308 .cmd
= DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR
,
7309 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7310 .doit
= devlink_nl_cmd_health_reporter_dump_clear_doit
,
7311 .flags
= GENL_ADMIN_PERM
,
7312 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT
|
7313 DEVLINK_NL_FLAG_NO_LOCK
,
7316 .cmd
= DEVLINK_CMD_FLASH_UPDATE
,
7317 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
7318 .doit
= devlink_nl_cmd_flash_update
,
7319 .flags
= GENL_ADMIN_PERM
,
7320 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7323 .cmd
= DEVLINK_CMD_TRAP_GET
,
7324 .doit
= devlink_nl_cmd_trap_get_doit
,
7325 .dumpit
= devlink_nl_cmd_trap_get_dumpit
,
7326 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7327 /* can be retrieved by unprivileged users */
7330 .cmd
= DEVLINK_CMD_TRAP_SET
,
7331 .doit
= devlink_nl_cmd_trap_set_doit
,
7332 .flags
= GENL_ADMIN_PERM
,
7333 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7336 .cmd
= DEVLINK_CMD_TRAP_GROUP_GET
,
7337 .doit
= devlink_nl_cmd_trap_group_get_doit
,
7338 .dumpit
= devlink_nl_cmd_trap_group_get_dumpit
,
7339 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7340 /* can be retrieved by unprivileged users */
7343 .cmd
= DEVLINK_CMD_TRAP_GROUP_SET
,
7344 .doit
= devlink_nl_cmd_trap_group_set_doit
,
7345 .flags
= GENL_ADMIN_PERM
,
7346 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7349 .cmd
= DEVLINK_CMD_TRAP_POLICER_GET
,
7350 .doit
= devlink_nl_cmd_trap_policer_get_doit
,
7351 .dumpit
= devlink_nl_cmd_trap_policer_get_dumpit
,
7352 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7353 /* can be retrieved by unprivileged users */
7356 .cmd
= DEVLINK_CMD_TRAP_POLICER_SET
,
7357 .doit
= devlink_nl_cmd_trap_policer_set_doit
,
7358 .flags
= GENL_ADMIN_PERM
,
7359 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
7363 static struct genl_family devlink_nl_family __ro_after_init
= {
7364 .name
= DEVLINK_GENL_NAME
,
7365 .version
= DEVLINK_GENL_VERSION
,
7366 .maxattr
= DEVLINK_ATTR_MAX
,
7367 .policy
= devlink_nl_policy
,
7369 .pre_doit
= devlink_nl_pre_doit
,
7370 .post_doit
= devlink_nl_post_doit
,
7371 .module
= THIS_MODULE
,
7372 .ops
= devlink_nl_ops
,
7373 .n_ops
= ARRAY_SIZE(devlink_nl_ops
),
7374 .mcgrps
= devlink_nl_mcgrps
,
7375 .n_mcgrps
= ARRAY_SIZE(devlink_nl_mcgrps
),
7379 * devlink_alloc - Allocate new devlink instance resources
7382 * @priv_size: size of user private data
7384 * Allocate new devlink instance resources, including devlink index
7387 struct devlink
*devlink_alloc(const struct devlink_ops
*ops
, size_t priv_size
)
7389 struct devlink
*devlink
;
7394 devlink
= kzalloc(sizeof(*devlink
) + priv_size
, GFP_KERNEL
);
7398 xa_init_flags(&devlink
->snapshot_ids
, XA_FLAGS_ALLOC
);
7399 __devlink_net_set(devlink
, &init_net
);
7400 INIT_LIST_HEAD(&devlink
->port_list
);
7401 INIT_LIST_HEAD(&devlink
->sb_list
);
7402 INIT_LIST_HEAD_RCU(&devlink
->dpipe_table_list
);
7403 INIT_LIST_HEAD(&devlink
->resource_list
);
7404 INIT_LIST_HEAD(&devlink
->param_list
);
7405 INIT_LIST_HEAD(&devlink
->region_list
);
7406 INIT_LIST_HEAD(&devlink
->reporter_list
);
7407 INIT_LIST_HEAD(&devlink
->trap_list
);
7408 INIT_LIST_HEAD(&devlink
->trap_group_list
);
7409 INIT_LIST_HEAD(&devlink
->trap_policer_list
);
7410 mutex_init(&devlink
->lock
);
7411 mutex_init(&devlink
->reporters_lock
);
7414 EXPORT_SYMBOL_GPL(devlink_alloc
);
7417 * devlink_register - Register devlink instance
7420 * @dev: parent device
7422 int devlink_register(struct devlink
*devlink
, struct device
*dev
)
7425 devlink
->registered
= true;
7426 mutex_lock(&devlink_mutex
);
7427 list_add_tail(&devlink
->list
, &devlink_list
);
7428 devlink_notify(devlink
, DEVLINK_CMD_NEW
);
7429 mutex_unlock(&devlink_mutex
);
7432 EXPORT_SYMBOL_GPL(devlink_register
);
7435 * devlink_unregister - Unregister devlink instance
7439 void devlink_unregister(struct devlink
*devlink
)
7441 mutex_lock(&devlink_mutex
);
7442 WARN_ON(devlink_reload_supported(devlink
) &&
7443 devlink
->reload_enabled
);
7444 devlink_notify(devlink
, DEVLINK_CMD_DEL
);
7445 list_del(&devlink
->list
);
7446 mutex_unlock(&devlink_mutex
);
7448 EXPORT_SYMBOL_GPL(devlink_unregister
);
7451 * devlink_reload_enable - Enable reload of devlink instance
7455 * Should be called at end of device initialization
7456 * process when reload operation is supported.
7458 void devlink_reload_enable(struct devlink
*devlink
)
7460 mutex_lock(&devlink_mutex
);
7461 devlink
->reload_enabled
= true;
7462 mutex_unlock(&devlink_mutex
);
7464 EXPORT_SYMBOL_GPL(devlink_reload_enable
);
7467 * devlink_reload_disable - Disable reload of devlink instance
7471 * Should be called at the beginning of device cleanup
7472 * process when reload operation is supported.
7474 void devlink_reload_disable(struct devlink
*devlink
)
7476 mutex_lock(&devlink_mutex
);
7477 /* Mutex is taken which ensures that no reload operation is in
7478 * progress while setting up forbidded flag.
7480 devlink
->reload_enabled
= false;
7481 mutex_unlock(&devlink_mutex
);
7483 EXPORT_SYMBOL_GPL(devlink_reload_disable
);
7486 * devlink_free - Free devlink instance resources
7490 void devlink_free(struct devlink
*devlink
)
7492 mutex_destroy(&devlink
->reporters_lock
);
7493 mutex_destroy(&devlink
->lock
);
7494 WARN_ON(!list_empty(&devlink
->trap_policer_list
));
7495 WARN_ON(!list_empty(&devlink
->trap_group_list
));
7496 WARN_ON(!list_empty(&devlink
->trap_list
));
7497 WARN_ON(!list_empty(&devlink
->reporter_list
));
7498 WARN_ON(!list_empty(&devlink
->region_list
));
7499 WARN_ON(!list_empty(&devlink
->param_list
));
7500 WARN_ON(!list_empty(&devlink
->resource_list
));
7501 WARN_ON(!list_empty(&devlink
->dpipe_table_list
));
7502 WARN_ON(!list_empty(&devlink
->sb_list
));
7503 WARN_ON(!list_empty(&devlink
->port_list
));
7505 xa_destroy(&devlink
->snapshot_ids
);
7509 EXPORT_SYMBOL_GPL(devlink_free
);
7511 static void devlink_port_type_warn(struct work_struct
*work
)
7513 WARN(true, "Type was not set for devlink port.");
7516 static bool devlink_port_type_should_warn(struct devlink_port
*devlink_port
)
7518 /* Ignore CPU and DSA flavours. */
7519 return devlink_port
->attrs
.flavour
!= DEVLINK_PORT_FLAVOUR_CPU
&&
7520 devlink_port
->attrs
.flavour
!= DEVLINK_PORT_FLAVOUR_DSA
;
7523 #define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 3600)
7525 static void devlink_port_type_warn_schedule(struct devlink_port
*devlink_port
)
7527 if (!devlink_port_type_should_warn(devlink_port
))
7529 /* Schedule a work to WARN in case driver does not set port
7530 * type within timeout.
7532 schedule_delayed_work(&devlink_port
->type_warn_dw
,
7533 DEVLINK_PORT_TYPE_WARN_TIMEOUT
);
7536 static void devlink_port_type_warn_cancel(struct devlink_port
*devlink_port
)
7538 if (!devlink_port_type_should_warn(devlink_port
))
7540 cancel_delayed_work_sync(&devlink_port
->type_warn_dw
);
7544 * devlink_port_register - Register devlink port
7547 * @devlink_port: devlink port
7548 * @port_index: driver-specific numerical identifier of the port
7550 * Register devlink port with provided port index. User can use
7551 * any indexing, even hw-related one. devlink_port structure
7552 * is convenient to be embedded inside user driver private structure.
7553 * Note that the caller should take care of zeroing the devlink_port
7556 int devlink_port_register(struct devlink
*devlink
,
7557 struct devlink_port
*devlink_port
,
7558 unsigned int port_index
)
7560 mutex_lock(&devlink
->lock
);
7561 if (devlink_port_index_exists(devlink
, port_index
)) {
7562 mutex_unlock(&devlink
->lock
);
7565 devlink_port
->devlink
= devlink
;
7566 devlink_port
->index
= port_index
;
7567 devlink_port
->registered
= true;
7568 spin_lock_init(&devlink_port
->type_lock
);
7569 list_add_tail(&devlink_port
->list
, &devlink
->port_list
);
7570 INIT_LIST_HEAD(&devlink_port
->param_list
);
7571 mutex_unlock(&devlink
->lock
);
7572 INIT_LIST_HEAD(&devlink_port
->reporter_list
);
7573 mutex_init(&devlink_port
->reporters_lock
);
7574 INIT_DELAYED_WORK(&devlink_port
->type_warn_dw
, &devlink_port_type_warn
);
7575 devlink_port_type_warn_schedule(devlink_port
);
7576 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
7579 EXPORT_SYMBOL_GPL(devlink_port_register
);
7582 * devlink_port_unregister - Unregister devlink port
7584 * @devlink_port: devlink port
7586 void devlink_port_unregister(struct devlink_port
*devlink_port
)
7588 struct devlink
*devlink
= devlink_port
->devlink
;
7590 WARN_ON(!list_empty(&devlink_port
->reporter_list
));
7591 mutex_destroy(&devlink_port
->reporters_lock
);
7592 devlink_port_type_warn_cancel(devlink_port
);
7593 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_DEL
);
7594 mutex_lock(&devlink
->lock
);
7595 list_del(&devlink_port
->list
);
7596 mutex_unlock(&devlink
->lock
);
7598 EXPORT_SYMBOL_GPL(devlink_port_unregister
);
7600 static void __devlink_port_type_set(struct devlink_port
*devlink_port
,
7601 enum devlink_port_type type
,
7604 if (WARN_ON(!devlink_port
->registered
))
7606 devlink_port_type_warn_cancel(devlink_port
);
7607 spin_lock_bh(&devlink_port
->type_lock
);
7608 devlink_port
->type
= type
;
7609 devlink_port
->type_dev
= type_dev
;
7610 spin_unlock_bh(&devlink_port
->type_lock
);
7611 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
7615 * devlink_port_type_eth_set - Set port type to Ethernet
7617 * @devlink_port: devlink port
7618 * @netdev: related netdevice
7620 void devlink_port_type_eth_set(struct devlink_port
*devlink_port
,
7621 struct net_device
*netdev
)
7623 const struct net_device_ops
*ops
= netdev
->netdev_ops
;
7625 /* If driver registers devlink port, it should set devlink port
7626 * attributes accordingly so the compat functions are called
7627 * and the original ops are not used.
7629 if (ops
->ndo_get_phys_port_name
) {
7630 /* Some drivers use the same set of ndos for netdevs
7631 * that have devlink_port registered and also for
7632 * those who don't. Make sure that ndo_get_phys_port_name
7633 * returns -EOPNOTSUPP here in case it is defined.
7636 char name
[IFNAMSIZ
];
7639 err
= ops
->ndo_get_phys_port_name(netdev
, name
, sizeof(name
));
7640 WARN_ON(err
!= -EOPNOTSUPP
);
7642 if (ops
->ndo_get_port_parent_id
) {
7643 /* Some drivers use the same set of ndos for netdevs
7644 * that have devlink_port registered and also for
7645 * those who don't. Make sure that ndo_get_port_parent_id
7646 * returns -EOPNOTSUPP here in case it is defined.
7649 struct netdev_phys_item_id ppid
;
7652 err
= ops
->ndo_get_port_parent_id(netdev
, &ppid
);
7653 WARN_ON(err
!= -EOPNOTSUPP
);
7655 __devlink_port_type_set(devlink_port
, DEVLINK_PORT_TYPE_ETH
, netdev
);
7657 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set
);
7660 * devlink_port_type_ib_set - Set port type to InfiniBand
7662 * @devlink_port: devlink port
7663 * @ibdev: related IB device
7665 void devlink_port_type_ib_set(struct devlink_port
*devlink_port
,
7666 struct ib_device
*ibdev
)
7668 __devlink_port_type_set(devlink_port
, DEVLINK_PORT_TYPE_IB
, ibdev
);
7670 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set
);
7673 * devlink_port_type_clear - Clear port type
7675 * @devlink_port: devlink port
7677 void devlink_port_type_clear(struct devlink_port
*devlink_port
)
7679 __devlink_port_type_set(devlink_port
, DEVLINK_PORT_TYPE_NOTSET
, NULL
);
7680 devlink_port_type_warn_schedule(devlink_port
);
7682 EXPORT_SYMBOL_GPL(devlink_port_type_clear
);
7684 static int __devlink_port_attrs_set(struct devlink_port
*devlink_port
,
7685 enum devlink_port_flavour flavour
)
7687 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
7689 if (WARN_ON(devlink_port
->registered
))
7691 devlink_port
->attrs_set
= true;
7692 attrs
->flavour
= flavour
;
7693 if (attrs
->switch_id
.id_len
) {
7694 devlink_port
->switch_port
= true;
7695 if (WARN_ON(attrs
->switch_id
.id_len
> MAX_PHYS_ITEM_ID_LEN
))
7696 attrs
->switch_id
.id_len
= MAX_PHYS_ITEM_ID_LEN
;
7698 devlink_port
->switch_port
= false;
7704 * devlink_port_attrs_set - Set port attributes
7706 * @devlink_port: devlink port
7707 * @attrs: devlink port attrs
7709 void devlink_port_attrs_set(struct devlink_port
*devlink_port
,
7710 struct devlink_port_attrs
*attrs
)
7714 devlink_port
->attrs
= *attrs
;
7715 ret
= __devlink_port_attrs_set(devlink_port
, attrs
->flavour
);
7718 WARN_ON(attrs
->splittable
&& attrs
->split
);
7720 EXPORT_SYMBOL_GPL(devlink_port_attrs_set
);
7723 * devlink_port_attrs_pci_pf_set - Set PCI PF port attributes
7725 * @devlink_port: devlink port
7726 * @pf: associated PF for the devlink port instance
7728 void devlink_port_attrs_pci_pf_set(struct devlink_port
*devlink_port
, u16 pf
)
7730 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
7733 ret
= __devlink_port_attrs_set(devlink_port
,
7734 DEVLINK_PORT_FLAVOUR_PCI_PF
);
7738 attrs
->pci_pf
.pf
= pf
;
7740 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set
);
7743 * devlink_port_attrs_pci_vf_set - Set PCI VF port attributes
7745 * @devlink_port: devlink port
7746 * @pf: associated PF for the devlink port instance
7747 * @vf: associated VF of a PF for the devlink port instance
7749 void devlink_port_attrs_pci_vf_set(struct devlink_port
*devlink_port
,
7752 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
7755 ret
= __devlink_port_attrs_set(devlink_port
,
7756 DEVLINK_PORT_FLAVOUR_PCI_VF
);
7759 attrs
->pci_vf
.pf
= pf
;
7760 attrs
->pci_vf
.vf
= vf
;
7762 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set
);
7764 static int __devlink_port_phys_port_name_get(struct devlink_port
*devlink_port
,
7765 char *name
, size_t len
)
7767 struct devlink_port_attrs
*attrs
= &devlink_port
->attrs
;
7770 if (!devlink_port
->attrs_set
)
7773 switch (attrs
->flavour
) {
7774 case DEVLINK_PORT_FLAVOUR_PHYSICAL
:
7775 case DEVLINK_PORT_FLAVOUR_VIRTUAL
:
7777 n
= snprintf(name
, len
, "p%u", attrs
->phys
.port_number
);
7779 n
= snprintf(name
, len
, "p%us%u",
7780 attrs
->phys
.port_number
,
7781 attrs
->phys
.split_subport_number
);
7783 case DEVLINK_PORT_FLAVOUR_CPU
:
7784 case DEVLINK_PORT_FLAVOUR_DSA
:
7785 /* As CPU and DSA ports do not have a netdevice associated
7786 * case should not ever happen.
7790 case DEVLINK_PORT_FLAVOUR_PCI_PF
:
7791 n
= snprintf(name
, len
, "pf%u", attrs
->pci_pf
.pf
);
7793 case DEVLINK_PORT_FLAVOUR_PCI_VF
:
7794 n
= snprintf(name
, len
, "pf%uvf%u",
7795 attrs
->pci_vf
.pf
, attrs
->pci_vf
.vf
);
7805 int devlink_sb_register(struct devlink
*devlink
, unsigned int sb_index
,
7806 u32 size
, u16 ingress_pools_count
,
7807 u16 egress_pools_count
, u16 ingress_tc_count
,
7808 u16 egress_tc_count
)
7810 struct devlink_sb
*devlink_sb
;
7813 mutex_lock(&devlink
->lock
);
7814 if (devlink_sb_index_exists(devlink
, sb_index
)) {
7819 devlink_sb
= kzalloc(sizeof(*devlink_sb
), GFP_KERNEL
);
7824 devlink_sb
->index
= sb_index
;
7825 devlink_sb
->size
= size
;
7826 devlink_sb
->ingress_pools_count
= ingress_pools_count
;
7827 devlink_sb
->egress_pools_count
= egress_pools_count
;
7828 devlink_sb
->ingress_tc_count
= ingress_tc_count
;
7829 devlink_sb
->egress_tc_count
= egress_tc_count
;
7830 list_add_tail(&devlink_sb
->list
, &devlink
->sb_list
);
7832 mutex_unlock(&devlink
->lock
);
7835 EXPORT_SYMBOL_GPL(devlink_sb_register
);
7837 void devlink_sb_unregister(struct devlink
*devlink
, unsigned int sb_index
)
7839 struct devlink_sb
*devlink_sb
;
7841 mutex_lock(&devlink
->lock
);
7842 devlink_sb
= devlink_sb_get_by_index(devlink
, sb_index
);
7843 WARN_ON(!devlink_sb
);
7844 list_del(&devlink_sb
->list
);
7845 mutex_unlock(&devlink
->lock
);
7848 EXPORT_SYMBOL_GPL(devlink_sb_unregister
);
7851 * devlink_dpipe_headers_register - register dpipe headers
7854 * @dpipe_headers: dpipe header array
7856 * Register the headers supported by hardware.
7858 int devlink_dpipe_headers_register(struct devlink
*devlink
,
7859 struct devlink_dpipe_headers
*dpipe_headers
)
7861 mutex_lock(&devlink
->lock
);
7862 devlink
->dpipe_headers
= dpipe_headers
;
7863 mutex_unlock(&devlink
->lock
);
7866 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register
);
7869 * devlink_dpipe_headers_unregister - unregister dpipe headers
7873 * Unregister the headers supported by hardware.
7875 void devlink_dpipe_headers_unregister(struct devlink
*devlink
)
7877 mutex_lock(&devlink
->lock
);
7878 devlink
->dpipe_headers
= NULL
;
7879 mutex_unlock(&devlink
->lock
);
7881 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister
);
7884 * devlink_dpipe_table_counter_enabled - check if counter allocation
7887 * @table_name: tables name
7889 * Used by driver to check if counter allocation is required.
7890 * After counter allocation is turned on the table entries
7891 * are updated to include counter statistics.
7893 * After that point on the driver must respect the counter
7894 * state so that each entry added to the table is added
7897 bool devlink_dpipe_table_counter_enabled(struct devlink
*devlink
,
7898 const char *table_name
)
7900 struct devlink_dpipe_table
*table
;
7904 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
7905 table_name
, devlink
);
7908 enabled
= table
->counters_enabled
;
7912 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled
);
7915 * devlink_dpipe_table_register - register dpipe table
7918 * @table_name: table name
7919 * @table_ops: table ops
7921 * @counter_control_extern: external control for counters
7923 int devlink_dpipe_table_register(struct devlink
*devlink
,
7924 const char *table_name
,
7925 struct devlink_dpipe_table_ops
*table_ops
,
7926 void *priv
, bool counter_control_extern
)
7928 struct devlink_dpipe_table
*table
;
7931 if (WARN_ON(!table_ops
->size_get
))
7934 mutex_lock(&devlink
->lock
);
7936 if (devlink_dpipe_table_find(&devlink
->dpipe_table_list
, table_name
,
7942 table
= kzalloc(sizeof(*table
), GFP_KERNEL
);
7948 table
->name
= table_name
;
7949 table
->table_ops
= table_ops
;
7951 table
->counter_control_extern
= counter_control_extern
;
7953 list_add_tail_rcu(&table
->list
, &devlink
->dpipe_table_list
);
7955 mutex_unlock(&devlink
->lock
);
7958 EXPORT_SYMBOL_GPL(devlink_dpipe_table_register
);
7961 * devlink_dpipe_table_unregister - unregister dpipe table
7964 * @table_name: table name
7966 void devlink_dpipe_table_unregister(struct devlink
*devlink
,
7967 const char *table_name
)
7969 struct devlink_dpipe_table
*table
;
7971 mutex_lock(&devlink
->lock
);
7972 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
7973 table_name
, devlink
);
7976 list_del_rcu(&table
->list
);
7977 mutex_unlock(&devlink
->lock
);
7978 kfree_rcu(table
, rcu
);
7981 mutex_unlock(&devlink
->lock
);
7983 EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister
);
7986 * devlink_resource_register - devlink resource register
7989 * @resource_name: resource's name
7990 * @resource_size: resource's size
7991 * @resource_id: resource's id
7992 * @parent_resource_id: resource's parent id
7993 * @size_params: size parameters
7995 int devlink_resource_register(struct devlink
*devlink
,
7996 const char *resource_name
,
7999 u64 parent_resource_id
,
8000 const struct devlink_resource_size_params
*size_params
)
8002 struct devlink_resource
*resource
;
8003 struct list_head
*resource_list
;
8007 top_hierarchy
= parent_resource_id
== DEVLINK_RESOURCE_ID_PARENT_TOP
;
8009 mutex_lock(&devlink
->lock
);
8010 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
8016 resource
= kzalloc(sizeof(*resource
), GFP_KERNEL
);
8022 if (top_hierarchy
) {
8023 resource_list
= &devlink
->resource_list
;
8025 struct devlink_resource
*parent_resource
;
8027 parent_resource
= devlink_resource_find(devlink
, NULL
,
8028 parent_resource_id
);
8029 if (parent_resource
) {
8030 resource_list
= &parent_resource
->resource_list
;
8031 resource
->parent
= parent_resource
;
8039 resource
->name
= resource_name
;
8040 resource
->size
= resource_size
;
8041 resource
->size_new
= resource_size
;
8042 resource
->id
= resource_id
;
8043 resource
->size_valid
= true;
8044 memcpy(&resource
->size_params
, size_params
,
8045 sizeof(resource
->size_params
));
8046 INIT_LIST_HEAD(&resource
->resource_list
);
8047 list_add_tail(&resource
->list
, resource_list
);
8049 mutex_unlock(&devlink
->lock
);
8052 EXPORT_SYMBOL_GPL(devlink_resource_register
);
8055 * devlink_resources_unregister - free all resources
8058 * @resource: resource
8060 void devlink_resources_unregister(struct devlink
*devlink
,
8061 struct devlink_resource
*resource
)
8063 struct devlink_resource
*tmp
, *child_resource
;
8064 struct list_head
*resource_list
;
8067 resource_list
= &resource
->resource_list
;
8069 resource_list
= &devlink
->resource_list
;
8072 mutex_lock(&devlink
->lock
);
8074 list_for_each_entry_safe(child_resource
, tmp
, resource_list
, list
) {
8075 devlink_resources_unregister(devlink
, child_resource
);
8076 list_del(&child_resource
->list
);
8077 kfree(child_resource
);
8081 mutex_unlock(&devlink
->lock
);
8083 EXPORT_SYMBOL_GPL(devlink_resources_unregister
);
8086 * devlink_resource_size_get - get and update size
8089 * @resource_id: the requested resource id
8090 * @p_resource_size: ptr to update
8092 int devlink_resource_size_get(struct devlink
*devlink
,
8094 u64
*p_resource_size
)
8096 struct devlink_resource
*resource
;
8099 mutex_lock(&devlink
->lock
);
8100 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
8105 *p_resource_size
= resource
->size_new
;
8106 resource
->size
= resource
->size_new
;
8108 mutex_unlock(&devlink
->lock
);
8111 EXPORT_SYMBOL_GPL(devlink_resource_size_get
);
8114 * devlink_dpipe_table_resource_set - set the resource id
8117 * @table_name: table name
8118 * @resource_id: resource id
8119 * @resource_units: number of resource's units consumed per table's entry
8121 int devlink_dpipe_table_resource_set(struct devlink
*devlink
,
8122 const char *table_name
, u64 resource_id
,
8125 struct devlink_dpipe_table
*table
;
8128 mutex_lock(&devlink
->lock
);
8129 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
8130 table_name
, devlink
);
8135 table
->resource_id
= resource_id
;
8136 table
->resource_units
= resource_units
;
8137 table
->resource_valid
= true;
8139 mutex_unlock(&devlink
->lock
);
8142 EXPORT_SYMBOL_GPL(devlink_dpipe_table_resource_set
);
8145 * devlink_resource_occ_get_register - register occupancy getter
8148 * @resource_id: resource id
8149 * @occ_get: occupancy getter callback
8150 * @occ_get_priv: occupancy getter callback priv
8152 void devlink_resource_occ_get_register(struct devlink
*devlink
,
8154 devlink_resource_occ_get_t
*occ_get
,
8157 struct devlink_resource
*resource
;
8159 mutex_lock(&devlink
->lock
);
8160 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
8161 if (WARN_ON(!resource
))
8163 WARN_ON(resource
->occ_get
);
8165 resource
->occ_get
= occ_get
;
8166 resource
->occ_get_priv
= occ_get_priv
;
8168 mutex_unlock(&devlink
->lock
);
8170 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register
);
8173 * devlink_resource_occ_get_unregister - unregister occupancy getter
8176 * @resource_id: resource id
8178 void devlink_resource_occ_get_unregister(struct devlink
*devlink
,
8181 struct devlink_resource
*resource
;
8183 mutex_lock(&devlink
->lock
);
8184 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
8185 if (WARN_ON(!resource
))
8187 WARN_ON(!resource
->occ_get
);
8189 resource
->occ_get
= NULL
;
8190 resource
->occ_get_priv
= NULL
;
8192 mutex_unlock(&devlink
->lock
);
8194 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister
);
8196 static int devlink_param_verify(const struct devlink_param
*param
)
8198 if (!param
|| !param
->name
|| !param
->supported_cmodes
)
8201 return devlink_param_generic_verify(param
);
8203 return devlink_param_driver_verify(param
);
8206 static int __devlink_params_register(struct devlink
*devlink
,
8207 unsigned int port_index
,
8208 struct list_head
*param_list
,
8209 const struct devlink_param
*params
,
8210 size_t params_count
,
8211 enum devlink_command reg_cmd
,
8212 enum devlink_command unreg_cmd
)
8214 const struct devlink_param
*param
= params
;
8218 mutex_lock(&devlink
->lock
);
8219 for (i
= 0; i
< params_count
; i
++, param
++) {
8220 err
= devlink_param_verify(param
);
8224 err
= devlink_param_register_one(devlink
, port_index
,
8225 param_list
, param
, reg_cmd
);
8230 mutex_unlock(&devlink
->lock
);
8236 for (param
--; i
> 0; i
--, param
--)
8237 devlink_param_unregister_one(devlink
, port_index
, param_list
,
8240 mutex_unlock(&devlink
->lock
);
8244 static void __devlink_params_unregister(struct devlink
*devlink
,
8245 unsigned int port_index
,
8246 struct list_head
*param_list
,
8247 const struct devlink_param
*params
,
8248 size_t params_count
,
8249 enum devlink_command cmd
)
8251 const struct devlink_param
*param
= params
;
8254 mutex_lock(&devlink
->lock
);
8255 for (i
= 0; i
< params_count
; i
++, param
++)
8256 devlink_param_unregister_one(devlink
, 0, param_list
, param
,
8258 mutex_unlock(&devlink
->lock
);
8262 * devlink_params_register - register configuration parameters
8265 * @params: configuration parameters array
8266 * @params_count: number of parameters provided
8268 * Register the configuration parameters supported by the driver.
8270 int devlink_params_register(struct devlink
*devlink
,
8271 const struct devlink_param
*params
,
8272 size_t params_count
)
8274 return __devlink_params_register(devlink
, 0, &devlink
->param_list
,
8275 params
, params_count
,
8276 DEVLINK_CMD_PARAM_NEW
,
8277 DEVLINK_CMD_PARAM_DEL
);
8279 EXPORT_SYMBOL_GPL(devlink_params_register
);
8282 * devlink_params_unregister - unregister configuration parameters
8284 * @params: configuration parameters to unregister
8285 * @params_count: number of parameters provided
8287 void devlink_params_unregister(struct devlink
*devlink
,
8288 const struct devlink_param
*params
,
8289 size_t params_count
)
8291 return __devlink_params_unregister(devlink
, 0, &devlink
->param_list
,
8292 params
, params_count
,
8293 DEVLINK_CMD_PARAM_DEL
);
8295 EXPORT_SYMBOL_GPL(devlink_params_unregister
);
8298 * devlink_params_publish - publish configuration parameters
8302 * Publish previously registered configuration parameters.
8304 void devlink_params_publish(struct devlink
*devlink
)
8306 struct devlink_param_item
*param_item
;
8308 list_for_each_entry(param_item
, &devlink
->param_list
, list
) {
8309 if (param_item
->published
)
8311 param_item
->published
= true;
8312 devlink_param_notify(devlink
, 0, param_item
,
8313 DEVLINK_CMD_PARAM_NEW
);
8316 EXPORT_SYMBOL_GPL(devlink_params_publish
);
8319 * devlink_params_unpublish - unpublish configuration parameters
8323 * Unpublish previously registered configuration parameters.
8325 void devlink_params_unpublish(struct devlink
*devlink
)
8327 struct devlink_param_item
*param_item
;
8329 list_for_each_entry(param_item
, &devlink
->param_list
, list
) {
8330 if (!param_item
->published
)
8332 param_item
->published
= false;
8333 devlink_param_notify(devlink
, 0, param_item
,
8334 DEVLINK_CMD_PARAM_DEL
);
8337 EXPORT_SYMBOL_GPL(devlink_params_unpublish
);
8340 * devlink_port_params_register - register port configuration parameters
8342 * @devlink_port: devlink port
8343 * @params: configuration parameters array
8344 * @params_count: number of parameters provided
8346 * Register the configuration parameters supported by the port.
8348 int devlink_port_params_register(struct devlink_port
*devlink_port
,
8349 const struct devlink_param
*params
,
8350 size_t params_count
)
8352 return __devlink_params_register(devlink_port
->devlink
,
8353 devlink_port
->index
,
8354 &devlink_port
->param_list
, params
,
8356 DEVLINK_CMD_PORT_PARAM_NEW
,
8357 DEVLINK_CMD_PORT_PARAM_DEL
);
8359 EXPORT_SYMBOL_GPL(devlink_port_params_register
);
8362 * devlink_port_params_unregister - unregister port configuration
8365 * @devlink_port: devlink port
8366 * @params: configuration parameters array
8367 * @params_count: number of parameters provided
8369 void devlink_port_params_unregister(struct devlink_port
*devlink_port
,
8370 const struct devlink_param
*params
,
8371 size_t params_count
)
8373 return __devlink_params_unregister(devlink_port
->devlink
,
8374 devlink_port
->index
,
8375 &devlink_port
->param_list
,
8376 params
, params_count
,
8377 DEVLINK_CMD_PORT_PARAM_DEL
);
8379 EXPORT_SYMBOL_GPL(devlink_port_params_unregister
);
8382 __devlink_param_driverinit_value_get(struct list_head
*param_list
, u32 param_id
,
8383 union devlink_param_value
*init_val
)
8385 struct devlink_param_item
*param_item
;
8387 param_item
= devlink_param_find_by_id(param_list
, param_id
);
8391 if (!param_item
->driverinit_value_valid
||
8392 !devlink_param_cmode_is_supported(param_item
->param
,
8393 DEVLINK_PARAM_CMODE_DRIVERINIT
))
8396 if (param_item
->param
->type
== DEVLINK_PARAM_TYPE_STRING
)
8397 strcpy(init_val
->vstr
, param_item
->driverinit_value
.vstr
);
8399 *init_val
= param_item
->driverinit_value
;
8405 __devlink_param_driverinit_value_set(struct devlink
*devlink
,
8406 unsigned int port_index
,
8407 struct list_head
*param_list
, u32 param_id
,
8408 union devlink_param_value init_val
,
8409 enum devlink_command cmd
)
8411 struct devlink_param_item
*param_item
;
8413 param_item
= devlink_param_find_by_id(param_list
, param_id
);
8417 if (!devlink_param_cmode_is_supported(param_item
->param
,
8418 DEVLINK_PARAM_CMODE_DRIVERINIT
))
8421 if (param_item
->param
->type
== DEVLINK_PARAM_TYPE_STRING
)
8422 strcpy(param_item
->driverinit_value
.vstr
, init_val
.vstr
);
8424 param_item
->driverinit_value
= init_val
;
8425 param_item
->driverinit_value_valid
= true;
8427 devlink_param_notify(devlink
, port_index
, param_item
, cmd
);
8432 * devlink_param_driverinit_value_get - get configuration parameter
8433 * value for driver initializing
8436 * @param_id: parameter ID
8437 * @init_val: value of parameter in driverinit configuration mode
8439 * This function should be used by the driver to get driverinit
8440 * configuration for initialization after reload command.
8442 int devlink_param_driverinit_value_get(struct devlink
*devlink
, u32 param_id
,
8443 union devlink_param_value
*init_val
)
8445 if (!devlink_reload_supported(devlink
))
8448 return __devlink_param_driverinit_value_get(&devlink
->param_list
,
8449 param_id
, init_val
);
8451 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_get
);
8454 * devlink_param_driverinit_value_set - set value of configuration
8455 * parameter for driverinit
8456 * configuration mode
8459 * @param_id: parameter ID
8460 * @init_val: value of parameter to set for driverinit configuration mode
8462 * This function should be used by the driver to set driverinit
8463 * configuration mode default value.
8465 int devlink_param_driverinit_value_set(struct devlink
*devlink
, u32 param_id
,
8466 union devlink_param_value init_val
)
8468 return __devlink_param_driverinit_value_set(devlink
, 0,
8469 &devlink
->param_list
,
8471 DEVLINK_CMD_PARAM_NEW
);
8473 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set
);
8476 * devlink_port_param_driverinit_value_get - get configuration parameter
8477 * value for driver initializing
8479 * @devlink_port: devlink_port
8480 * @param_id: parameter ID
8481 * @init_val: value of parameter in driverinit configuration mode
8483 * This function should be used by the driver to get driverinit
8484 * configuration for initialization after reload command.
8486 int devlink_port_param_driverinit_value_get(struct devlink_port
*devlink_port
,
8488 union devlink_param_value
*init_val
)
8490 struct devlink
*devlink
= devlink_port
->devlink
;
8492 if (!devlink_reload_supported(devlink
))
8495 return __devlink_param_driverinit_value_get(&devlink_port
->param_list
,
8496 param_id
, init_val
);
8498 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_get
);
8501 * devlink_port_param_driverinit_value_set - set value of configuration
8502 * parameter for driverinit
8503 * configuration mode
8505 * @devlink_port: devlink_port
8506 * @param_id: parameter ID
8507 * @init_val: value of parameter to set for driverinit configuration mode
8509 * This function should be used by the driver to set driverinit
8510 * configuration mode default value.
8512 int devlink_port_param_driverinit_value_set(struct devlink_port
*devlink_port
,
8514 union devlink_param_value init_val
)
8516 return __devlink_param_driverinit_value_set(devlink_port
->devlink
,
8517 devlink_port
->index
,
8518 &devlink_port
->param_list
,
8520 DEVLINK_CMD_PORT_PARAM_NEW
);
8522 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_set
);
8525 * devlink_param_value_changed - notify devlink on a parameter's value
8526 * change. Should be called by the driver
8527 * right after the change.
8530 * @param_id: parameter ID
8532 * This function should be used by the driver to notify devlink on value
8533 * change, excluding driverinit configuration mode.
8534 * For driverinit configuration mode driver should use the function
8536 void devlink_param_value_changed(struct devlink
*devlink
, u32 param_id
)
8538 struct devlink_param_item
*param_item
;
8540 param_item
= devlink_param_find_by_id(&devlink
->param_list
, param_id
);
8541 WARN_ON(!param_item
);
8543 devlink_param_notify(devlink
, 0, param_item
, DEVLINK_CMD_PARAM_NEW
);
8545 EXPORT_SYMBOL_GPL(devlink_param_value_changed
);
8548 * devlink_port_param_value_changed - notify devlink on a parameter's value
8549 * change. Should be called by the driver
8550 * right after the change.
8552 * @devlink_port: devlink_port
8553 * @param_id: parameter ID
8555 * This function should be used by the driver to notify devlink on value
8556 * change, excluding driverinit configuration mode.
8557 * For driverinit configuration mode driver should use the function
8558 * devlink_port_param_driverinit_value_set() instead.
8560 void devlink_port_param_value_changed(struct devlink_port
*devlink_port
,
8563 struct devlink_param_item
*param_item
;
8565 param_item
= devlink_param_find_by_id(&devlink_port
->param_list
,
8567 WARN_ON(!param_item
);
8569 devlink_param_notify(devlink_port
->devlink
, devlink_port
->index
,
8570 param_item
, DEVLINK_CMD_PORT_PARAM_NEW
);
8572 EXPORT_SYMBOL_GPL(devlink_port_param_value_changed
);
8575 * devlink_param_value_str_fill - Safely fill-up the string preventing
8576 * from overflow of the preallocated buffer
8578 * @dst_val: destination devlink_param_value
8579 * @src: source buffer
8581 void devlink_param_value_str_fill(union devlink_param_value
*dst_val
,
8586 len
= strlcpy(dst_val
->vstr
, src
, __DEVLINK_PARAM_MAX_STRING_VALUE
);
8587 WARN_ON(len
>= __DEVLINK_PARAM_MAX_STRING_VALUE
);
8589 EXPORT_SYMBOL_GPL(devlink_param_value_str_fill
);
8592 * devlink_region_create - create a new address region
8595 * @ops: region operations and name
8596 * @region_max_snapshots: Maximum supported number of snapshots for region
8597 * @region_size: size of region
8599 struct devlink_region
*
8600 devlink_region_create(struct devlink
*devlink
,
8601 const struct devlink_region_ops
*ops
,
8602 u32 region_max_snapshots
, u64 region_size
)
8604 struct devlink_region
*region
;
8607 if (WARN_ON(!ops
) || WARN_ON(!ops
->destructor
))
8608 return ERR_PTR(-EINVAL
);
8610 mutex_lock(&devlink
->lock
);
8612 if (devlink_region_get_by_name(devlink
, ops
->name
)) {
8617 region
= kzalloc(sizeof(*region
), GFP_KERNEL
);
8623 region
->devlink
= devlink
;
8624 region
->max_snapshots
= region_max_snapshots
;
8626 region
->size
= region_size
;
8627 INIT_LIST_HEAD(®ion
->snapshot_list
);
8628 list_add_tail(®ion
->list
, &devlink
->region_list
);
8629 devlink_nl_region_notify(region
, NULL
, DEVLINK_CMD_REGION_NEW
);
8631 mutex_unlock(&devlink
->lock
);
8635 mutex_unlock(&devlink
->lock
);
8636 return ERR_PTR(err
);
8638 EXPORT_SYMBOL_GPL(devlink_region_create
);
8641 * devlink_region_destroy - destroy address region
8643 * @region: devlink region to destroy
8645 void devlink_region_destroy(struct devlink_region
*region
)
8647 struct devlink
*devlink
= region
->devlink
;
8648 struct devlink_snapshot
*snapshot
, *ts
;
8650 mutex_lock(&devlink
->lock
);
8652 /* Free all snapshots of region */
8653 list_for_each_entry_safe(snapshot
, ts
, ®ion
->snapshot_list
, list
)
8654 devlink_region_snapshot_del(region
, snapshot
);
8656 list_del(®ion
->list
);
8658 devlink_nl_region_notify(region
, NULL
, DEVLINK_CMD_REGION_DEL
);
8659 mutex_unlock(&devlink
->lock
);
8662 EXPORT_SYMBOL_GPL(devlink_region_destroy
);
8665 * devlink_region_snapshot_id_get - get snapshot ID
8667 * This callback should be called when adding a new snapshot,
8668 * Driver should use the same id for multiple snapshots taken
8669 * on multiple regions at the same time/by the same trigger.
8671 * The caller of this function must use devlink_region_snapshot_id_put
8672 * when finished creating regions using this id.
8674 * Returns zero on success, or a negative error code on failure.
8677 * @id: storage to return id
8679 int devlink_region_snapshot_id_get(struct devlink
*devlink
, u32
*id
)
8683 mutex_lock(&devlink
->lock
);
8684 err
= __devlink_region_snapshot_id_get(devlink
, id
);
8685 mutex_unlock(&devlink
->lock
);
8689 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get
);
8692 * devlink_region_snapshot_id_put - put snapshot ID reference
8694 * This should be called by a driver after finishing creating snapshots
8695 * with an id. Doing so ensures that the ID can later be released in the
8696 * event that all snapshots using it have been destroyed.
8699 * @id: id to release reference on
8701 void devlink_region_snapshot_id_put(struct devlink
*devlink
, u32 id
)
8703 mutex_lock(&devlink
->lock
);
8704 __devlink_snapshot_id_decrement(devlink
, id
);
8705 mutex_unlock(&devlink
->lock
);
8707 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put
);
8710 * devlink_region_snapshot_create - create a new snapshot
8711 * This will add a new snapshot of a region. The snapshot
8712 * will be stored on the region struct and can be accessed
8713 * from devlink. This is useful for future analyses of snapshots.
8714 * Multiple snapshots can be created on a region.
8715 * The @snapshot_id should be obtained using the getter function.
8717 * @region: devlink region of the snapshot
8718 * @data: snapshot data
8719 * @snapshot_id: snapshot id to be created
8721 int devlink_region_snapshot_create(struct devlink_region
*region
,
8722 u8
*data
, u32 snapshot_id
)
8724 struct devlink
*devlink
= region
->devlink
;
8727 mutex_lock(&devlink
->lock
);
8728 err
= __devlink_region_snapshot_create(region
, data
, snapshot_id
);
8729 mutex_unlock(&devlink
->lock
);
8733 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create
);
8735 #define DEVLINK_TRAP(_id, _type) \
8737 .type = DEVLINK_TRAP_TYPE_##_type, \
8738 .id = DEVLINK_TRAP_GENERIC_ID_##_id, \
8739 .name = DEVLINK_TRAP_GENERIC_NAME_##_id, \
8742 static const struct devlink_trap devlink_trap_generic
[] = {
8743 DEVLINK_TRAP(SMAC_MC
, DROP
),
8744 DEVLINK_TRAP(VLAN_TAG_MISMATCH
, DROP
),
8745 DEVLINK_TRAP(INGRESS_VLAN_FILTER
, DROP
),
8746 DEVLINK_TRAP(INGRESS_STP_FILTER
, DROP
),
8747 DEVLINK_TRAP(EMPTY_TX_LIST
, DROP
),
8748 DEVLINK_TRAP(PORT_LOOPBACK_FILTER
, DROP
),
8749 DEVLINK_TRAP(BLACKHOLE_ROUTE
, DROP
),
8750 DEVLINK_TRAP(TTL_ERROR
, EXCEPTION
),
8751 DEVLINK_TRAP(TAIL_DROP
, DROP
),
8752 DEVLINK_TRAP(NON_IP_PACKET
, DROP
),
8753 DEVLINK_TRAP(UC_DIP_MC_DMAC
, DROP
),
8754 DEVLINK_TRAP(DIP_LB
, DROP
),
8755 DEVLINK_TRAP(SIP_MC
, DROP
),
8756 DEVLINK_TRAP(SIP_LB
, DROP
),
8757 DEVLINK_TRAP(CORRUPTED_IP_HDR
, DROP
),
8758 DEVLINK_TRAP(IPV4_SIP_BC
, DROP
),
8759 DEVLINK_TRAP(IPV6_MC_DIP_RESERVED_SCOPE
, DROP
),
8760 DEVLINK_TRAP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE
, DROP
),
8761 DEVLINK_TRAP(MTU_ERROR
, EXCEPTION
),
8762 DEVLINK_TRAP(UNRESOLVED_NEIGH
, EXCEPTION
),
8763 DEVLINK_TRAP(RPF
, EXCEPTION
),
8764 DEVLINK_TRAP(REJECT_ROUTE
, EXCEPTION
),
8765 DEVLINK_TRAP(IPV4_LPM_UNICAST_MISS
, EXCEPTION
),
8766 DEVLINK_TRAP(IPV6_LPM_UNICAST_MISS
, EXCEPTION
),
8767 DEVLINK_TRAP(NON_ROUTABLE
, DROP
),
8768 DEVLINK_TRAP(DECAP_ERROR
, EXCEPTION
),
8769 DEVLINK_TRAP(OVERLAY_SMAC_MC
, DROP
),
8770 DEVLINK_TRAP(INGRESS_FLOW_ACTION_DROP
, DROP
),
8771 DEVLINK_TRAP(EGRESS_FLOW_ACTION_DROP
, DROP
),
8772 DEVLINK_TRAP(STP
, CONTROL
),
8773 DEVLINK_TRAP(LACP
, CONTROL
),
8774 DEVLINK_TRAP(LLDP
, CONTROL
),
8775 DEVLINK_TRAP(IGMP_QUERY
, CONTROL
),
8776 DEVLINK_TRAP(IGMP_V1_REPORT
, CONTROL
),
8777 DEVLINK_TRAP(IGMP_V2_REPORT
, CONTROL
),
8778 DEVLINK_TRAP(IGMP_V3_REPORT
, CONTROL
),
8779 DEVLINK_TRAP(IGMP_V2_LEAVE
, CONTROL
),
8780 DEVLINK_TRAP(MLD_QUERY
, CONTROL
),
8781 DEVLINK_TRAP(MLD_V1_REPORT
, CONTROL
),
8782 DEVLINK_TRAP(MLD_V2_REPORT
, CONTROL
),
8783 DEVLINK_TRAP(MLD_V1_DONE
, CONTROL
),
8784 DEVLINK_TRAP(IPV4_DHCP
, CONTROL
),
8785 DEVLINK_TRAP(IPV6_DHCP
, CONTROL
),
8786 DEVLINK_TRAP(ARP_REQUEST
, CONTROL
),
8787 DEVLINK_TRAP(ARP_RESPONSE
, CONTROL
),
8788 DEVLINK_TRAP(ARP_OVERLAY
, CONTROL
),
8789 DEVLINK_TRAP(IPV6_NEIGH_SOLICIT
, CONTROL
),
8790 DEVLINK_TRAP(IPV6_NEIGH_ADVERT
, CONTROL
),
8791 DEVLINK_TRAP(IPV4_BFD
, CONTROL
),
8792 DEVLINK_TRAP(IPV6_BFD
, CONTROL
),
8793 DEVLINK_TRAP(IPV4_OSPF
, CONTROL
),
8794 DEVLINK_TRAP(IPV6_OSPF
, CONTROL
),
8795 DEVLINK_TRAP(IPV4_BGP
, CONTROL
),
8796 DEVLINK_TRAP(IPV6_BGP
, CONTROL
),
8797 DEVLINK_TRAP(IPV4_VRRP
, CONTROL
),
8798 DEVLINK_TRAP(IPV6_VRRP
, CONTROL
),
8799 DEVLINK_TRAP(IPV4_PIM
, CONTROL
),
8800 DEVLINK_TRAP(IPV6_PIM
, CONTROL
),
8801 DEVLINK_TRAP(UC_LB
, CONTROL
),
8802 DEVLINK_TRAP(LOCAL_ROUTE
, CONTROL
),
8803 DEVLINK_TRAP(EXTERNAL_ROUTE
, CONTROL
),
8804 DEVLINK_TRAP(IPV6_UC_DIP_LINK_LOCAL_SCOPE
, CONTROL
),
8805 DEVLINK_TRAP(IPV6_DIP_ALL_NODES
, CONTROL
),
8806 DEVLINK_TRAP(IPV6_DIP_ALL_ROUTERS
, CONTROL
),
8807 DEVLINK_TRAP(IPV6_ROUTER_SOLICIT
, CONTROL
),
8808 DEVLINK_TRAP(IPV6_ROUTER_ADVERT
, CONTROL
),
8809 DEVLINK_TRAP(IPV6_REDIRECT
, CONTROL
),
8810 DEVLINK_TRAP(IPV4_ROUTER_ALERT
, CONTROL
),
8811 DEVLINK_TRAP(IPV6_ROUTER_ALERT
, CONTROL
),
8812 DEVLINK_TRAP(PTP_EVENT
, CONTROL
),
8813 DEVLINK_TRAP(PTP_GENERAL
, CONTROL
),
8814 DEVLINK_TRAP(FLOW_ACTION_SAMPLE
, CONTROL
),
8815 DEVLINK_TRAP(FLOW_ACTION_TRAP
, CONTROL
),
8818 #define DEVLINK_TRAP_GROUP(_id) \
8820 .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \
8821 .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \
8824 static const struct devlink_trap_group devlink_trap_group_generic
[] = {
8825 DEVLINK_TRAP_GROUP(L2_DROPS
),
8826 DEVLINK_TRAP_GROUP(L3_DROPS
),
8827 DEVLINK_TRAP_GROUP(L3_EXCEPTIONS
),
8828 DEVLINK_TRAP_GROUP(BUFFER_DROPS
),
8829 DEVLINK_TRAP_GROUP(TUNNEL_DROPS
),
8830 DEVLINK_TRAP_GROUP(ACL_DROPS
),
8831 DEVLINK_TRAP_GROUP(STP
),
8832 DEVLINK_TRAP_GROUP(LACP
),
8833 DEVLINK_TRAP_GROUP(LLDP
),
8834 DEVLINK_TRAP_GROUP(MC_SNOOPING
),
8835 DEVLINK_TRAP_GROUP(DHCP
),
8836 DEVLINK_TRAP_GROUP(NEIGH_DISCOVERY
),
8837 DEVLINK_TRAP_GROUP(BFD
),
8838 DEVLINK_TRAP_GROUP(OSPF
),
8839 DEVLINK_TRAP_GROUP(BGP
),
8840 DEVLINK_TRAP_GROUP(VRRP
),
8841 DEVLINK_TRAP_GROUP(PIM
),
8842 DEVLINK_TRAP_GROUP(UC_LB
),
8843 DEVLINK_TRAP_GROUP(LOCAL_DELIVERY
),
8844 DEVLINK_TRAP_GROUP(IPV6
),
8845 DEVLINK_TRAP_GROUP(PTP_EVENT
),
8846 DEVLINK_TRAP_GROUP(PTP_GENERAL
),
8847 DEVLINK_TRAP_GROUP(ACL_SAMPLE
),
8848 DEVLINK_TRAP_GROUP(ACL_TRAP
),
8851 static int devlink_trap_generic_verify(const struct devlink_trap
*trap
)
8853 if (trap
->id
> DEVLINK_TRAP_GENERIC_ID_MAX
)
8856 if (strcmp(trap
->name
, devlink_trap_generic
[trap
->id
].name
))
8859 if (trap
->type
!= devlink_trap_generic
[trap
->id
].type
)
8865 static int devlink_trap_driver_verify(const struct devlink_trap
*trap
)
8869 if (trap
->id
<= DEVLINK_TRAP_GENERIC_ID_MAX
)
8872 for (i
= 0; i
< ARRAY_SIZE(devlink_trap_generic
); i
++) {
8873 if (!strcmp(trap
->name
, devlink_trap_generic
[i
].name
))
8880 static int devlink_trap_verify(const struct devlink_trap
*trap
)
8882 if (!trap
|| !trap
->name
)
8886 return devlink_trap_generic_verify(trap
);
8888 return devlink_trap_driver_verify(trap
);
8892 devlink_trap_group_generic_verify(const struct devlink_trap_group
*group
)
8894 if (group
->id
> DEVLINK_TRAP_GROUP_GENERIC_ID_MAX
)
8897 if (strcmp(group
->name
, devlink_trap_group_generic
[group
->id
].name
))
8904 devlink_trap_group_driver_verify(const struct devlink_trap_group
*group
)
8908 if (group
->id
<= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX
)
8911 for (i
= 0; i
< ARRAY_SIZE(devlink_trap_group_generic
); i
++) {
8912 if (!strcmp(group
->name
, devlink_trap_group_generic
[i
].name
))
8919 static int devlink_trap_group_verify(const struct devlink_trap_group
*group
)
8922 return devlink_trap_group_generic_verify(group
);
8924 return devlink_trap_group_driver_verify(group
);
8928 devlink_trap_group_notify(struct devlink
*devlink
,
8929 const struct devlink_trap_group_item
*group_item
,
8930 enum devlink_command cmd
)
8932 struct sk_buff
*msg
;
8935 WARN_ON_ONCE(cmd
!= DEVLINK_CMD_TRAP_GROUP_NEW
&&
8936 cmd
!= DEVLINK_CMD_TRAP_GROUP_DEL
);
8938 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
8942 err
= devlink_nl_trap_group_fill(msg
, devlink
, group_item
, cmd
, 0, 0,
8949 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
8950 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
8954 devlink_trap_item_group_link(struct devlink
*devlink
,
8955 struct devlink_trap_item
*trap_item
)
8957 u16 group_id
= trap_item
->trap
->init_group_id
;
8958 struct devlink_trap_group_item
*group_item
;
8960 group_item
= devlink_trap_group_item_lookup_by_id(devlink
, group_id
);
8961 if (WARN_ON_ONCE(!group_item
))
8964 trap_item
->group_item
= group_item
;
8969 static void devlink_trap_notify(struct devlink
*devlink
,
8970 const struct devlink_trap_item
*trap_item
,
8971 enum devlink_command cmd
)
8973 struct sk_buff
*msg
;
8976 WARN_ON_ONCE(cmd
!= DEVLINK_CMD_TRAP_NEW
&&
8977 cmd
!= DEVLINK_CMD_TRAP_DEL
);
8979 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
8983 err
= devlink_nl_trap_fill(msg
, devlink
, trap_item
, cmd
, 0, 0, 0);
8989 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
8990 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
8994 devlink_trap_register(struct devlink
*devlink
,
8995 const struct devlink_trap
*trap
, void *priv
)
8997 struct devlink_trap_item
*trap_item
;
9000 if (devlink_trap_item_lookup(devlink
, trap
->name
))
9003 trap_item
= kzalloc(sizeof(*trap_item
), GFP_KERNEL
);
9007 trap_item
->stats
= netdev_alloc_pcpu_stats(struct devlink_stats
);
9008 if (!trap_item
->stats
) {
9010 goto err_stats_alloc
;
9013 trap_item
->trap
= trap
;
9014 trap_item
->action
= trap
->init_action
;
9015 trap_item
->priv
= priv
;
9017 err
= devlink_trap_item_group_link(devlink
, trap_item
);
9019 goto err_group_link
;
9021 err
= devlink
->ops
->trap_init(devlink
, trap
, trap_item
);
9025 list_add_tail(&trap_item
->list
, &devlink
->trap_list
);
9026 devlink_trap_notify(devlink
, trap_item
, DEVLINK_CMD_TRAP_NEW
);
9032 free_percpu(trap_item
->stats
);
9038 static void devlink_trap_unregister(struct devlink
*devlink
,
9039 const struct devlink_trap
*trap
)
9041 struct devlink_trap_item
*trap_item
;
9043 trap_item
= devlink_trap_item_lookup(devlink
, trap
->name
);
9044 if (WARN_ON_ONCE(!trap_item
))
9047 devlink_trap_notify(devlink
, trap_item
, DEVLINK_CMD_TRAP_DEL
);
9048 list_del(&trap_item
->list
);
9049 if (devlink
->ops
->trap_fini
)
9050 devlink
->ops
->trap_fini(devlink
, trap
, trap_item
);
9051 free_percpu(trap_item
->stats
);
9055 static void devlink_trap_disable(struct devlink
*devlink
,
9056 const struct devlink_trap
*trap
)
9058 struct devlink_trap_item
*trap_item
;
9060 trap_item
= devlink_trap_item_lookup(devlink
, trap
->name
);
9061 if (WARN_ON_ONCE(!trap_item
))
9064 devlink
->ops
->trap_action_set(devlink
, trap
, DEVLINK_TRAP_ACTION_DROP
);
9065 trap_item
->action
= DEVLINK_TRAP_ACTION_DROP
;
9069 * devlink_traps_register - Register packet traps with devlink.
9070 * @devlink: devlink.
9071 * @traps: Packet traps.
9072 * @traps_count: Count of provided packet traps.
9073 * @priv: Driver private information.
9075 * Return: Non-zero value on failure.
9077 int devlink_traps_register(struct devlink
*devlink
,
9078 const struct devlink_trap
*traps
,
9079 size_t traps_count
, void *priv
)
9083 if (!devlink
->ops
->trap_init
|| !devlink
->ops
->trap_action_set
)
9086 mutex_lock(&devlink
->lock
);
9087 for (i
= 0; i
< traps_count
; i
++) {
9088 const struct devlink_trap
*trap
= &traps
[i
];
9090 err
= devlink_trap_verify(trap
);
9092 goto err_trap_verify
;
9094 err
= devlink_trap_register(devlink
, trap
, priv
);
9096 goto err_trap_register
;
9098 mutex_unlock(&devlink
->lock
);
9104 for (i
--; i
>= 0; i
--)
9105 devlink_trap_unregister(devlink
, &traps
[i
]);
9106 mutex_unlock(&devlink
->lock
);
9109 EXPORT_SYMBOL_GPL(devlink_traps_register
);
9112 * devlink_traps_unregister - Unregister packet traps from devlink.
9113 * @devlink: devlink.
9114 * @traps: Packet traps.
9115 * @traps_count: Count of provided packet traps.
9117 void devlink_traps_unregister(struct devlink
*devlink
,
9118 const struct devlink_trap
*traps
,
9123 mutex_lock(&devlink
->lock
);
9124 /* Make sure we do not have any packets in-flight while unregistering
9125 * traps by disabling all of them and waiting for a grace period.
9127 for (i
= traps_count
- 1; i
>= 0; i
--)
9128 devlink_trap_disable(devlink
, &traps
[i
]);
9130 for (i
= traps_count
- 1; i
>= 0; i
--)
9131 devlink_trap_unregister(devlink
, &traps
[i
]);
9132 mutex_unlock(&devlink
->lock
);
9134 EXPORT_SYMBOL_GPL(devlink_traps_unregister
);
9137 devlink_trap_stats_update(struct devlink_stats __percpu
*trap_stats
,
9140 struct devlink_stats
*stats
;
9142 stats
= this_cpu_ptr(trap_stats
);
9143 u64_stats_update_begin(&stats
->syncp
);
9144 stats
->rx_bytes
+= skb_len
;
9145 stats
->rx_packets
++;
9146 u64_stats_update_end(&stats
->syncp
);
9150 devlink_trap_report_metadata_fill(struct net_dm_hw_metadata
*hw_metadata
,
9151 const struct devlink_trap_item
*trap_item
,
9152 struct devlink_port
*in_devlink_port
,
9153 const struct flow_action_cookie
*fa_cookie
)
9155 struct devlink_trap_group_item
*group_item
= trap_item
->group_item
;
9157 hw_metadata
->trap_group_name
= group_item
->group
->name
;
9158 hw_metadata
->trap_name
= trap_item
->trap
->name
;
9159 hw_metadata
->fa_cookie
= fa_cookie
;
9161 spin_lock(&in_devlink_port
->type_lock
);
9162 if (in_devlink_port
->type
== DEVLINK_PORT_TYPE_ETH
)
9163 hw_metadata
->input_dev
= in_devlink_port
->type_dev
;
9164 spin_unlock(&in_devlink_port
->type_lock
);
9168 * devlink_trap_report - Report trapped packet to drop monitor.
9169 * @devlink: devlink.
9170 * @skb: Trapped packet.
9171 * @trap_ctx: Trap context.
9172 * @in_devlink_port: Input devlink port.
9173 * @fa_cookie: Flow action cookie. Could be NULL.
9175 void devlink_trap_report(struct devlink
*devlink
, struct sk_buff
*skb
,
9176 void *trap_ctx
, struct devlink_port
*in_devlink_port
,
9177 const struct flow_action_cookie
*fa_cookie
)
9180 struct devlink_trap_item
*trap_item
= trap_ctx
;
9181 struct net_dm_hw_metadata hw_metadata
= {};
9183 devlink_trap_stats_update(trap_item
->stats
, skb
->len
);
9184 devlink_trap_stats_update(trap_item
->group_item
->stats
, skb
->len
);
9186 /* Control packets were not dropped by the device or encountered an
9187 * exception during forwarding and therefore should not be reported to
9188 * the kernel's drop monitor.
9190 if (trap_item
->trap
->type
== DEVLINK_TRAP_TYPE_CONTROL
)
9193 devlink_trap_report_metadata_fill(&hw_metadata
, trap_item
,
9194 in_devlink_port
, fa_cookie
);
9195 net_dm_hw_report(skb
, &hw_metadata
);
9197 EXPORT_SYMBOL_GPL(devlink_trap_report
);
9200 * devlink_trap_ctx_priv - Trap context to driver private information.
9201 * @trap_ctx: Trap context.
9203 * Return: Driver private information passed during registration.
9205 void *devlink_trap_ctx_priv(void *trap_ctx
)
9207 struct devlink_trap_item
*trap_item
= trap_ctx
;
9209 return trap_item
->priv
;
9211 EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv
);
9214 devlink_trap_group_item_policer_link(struct devlink
*devlink
,
9215 struct devlink_trap_group_item
*group_item
)
9217 u32 policer_id
= group_item
->group
->init_policer_id
;
9218 struct devlink_trap_policer_item
*policer_item
;
9220 if (policer_id
== 0)
9223 policer_item
= devlink_trap_policer_item_lookup(devlink
, policer_id
);
9224 if (WARN_ON_ONCE(!policer_item
))
9227 group_item
->policer_item
= policer_item
;
9233 devlink_trap_group_register(struct devlink
*devlink
,
9234 const struct devlink_trap_group
*group
)
9236 struct devlink_trap_group_item
*group_item
;
9239 if (devlink_trap_group_item_lookup(devlink
, group
->name
))
9242 group_item
= kzalloc(sizeof(*group_item
), GFP_KERNEL
);
9246 group_item
->stats
= netdev_alloc_pcpu_stats(struct devlink_stats
);
9247 if (!group_item
->stats
) {
9249 goto err_stats_alloc
;
9252 group_item
->group
= group
;
9254 err
= devlink_trap_group_item_policer_link(devlink
, group_item
);
9256 goto err_policer_link
;
9258 if (devlink
->ops
->trap_group_init
) {
9259 err
= devlink
->ops
->trap_group_init(devlink
, group
);
9261 goto err_group_init
;
9264 list_add_tail(&group_item
->list
, &devlink
->trap_group_list
);
9265 devlink_trap_group_notify(devlink
, group_item
,
9266 DEVLINK_CMD_TRAP_GROUP_NEW
);
9272 free_percpu(group_item
->stats
);
9279 devlink_trap_group_unregister(struct devlink
*devlink
,
9280 const struct devlink_trap_group
*group
)
9282 struct devlink_trap_group_item
*group_item
;
9284 group_item
= devlink_trap_group_item_lookup(devlink
, group
->name
);
9285 if (WARN_ON_ONCE(!group_item
))
9288 devlink_trap_group_notify(devlink
, group_item
,
9289 DEVLINK_CMD_TRAP_GROUP_DEL
);
9290 list_del(&group_item
->list
);
9291 free_percpu(group_item
->stats
);
9296 * devlink_trap_groups_register - Register packet trap groups with devlink.
9297 * @devlink: devlink.
9298 * @groups: Packet trap groups.
9299 * @groups_count: Count of provided packet trap groups.
9301 * Return: Non-zero value on failure.
9303 int devlink_trap_groups_register(struct devlink
*devlink
,
9304 const struct devlink_trap_group
*groups
,
9305 size_t groups_count
)
9309 mutex_lock(&devlink
->lock
);
9310 for (i
= 0; i
< groups_count
; i
++) {
9311 const struct devlink_trap_group
*group
= &groups
[i
];
9313 err
= devlink_trap_group_verify(group
);
9315 goto err_trap_group_verify
;
9317 err
= devlink_trap_group_register(devlink
, group
);
9319 goto err_trap_group_register
;
9321 mutex_unlock(&devlink
->lock
);
9325 err_trap_group_register
:
9326 err_trap_group_verify
:
9327 for (i
--; i
>= 0; i
--)
9328 devlink_trap_group_unregister(devlink
, &groups
[i
]);
9329 mutex_unlock(&devlink
->lock
);
9332 EXPORT_SYMBOL_GPL(devlink_trap_groups_register
);
9335 * devlink_trap_groups_unregister - Unregister packet trap groups from devlink.
9336 * @devlink: devlink.
9337 * @groups: Packet trap groups.
9338 * @groups_count: Count of provided packet trap groups.
9340 void devlink_trap_groups_unregister(struct devlink
*devlink
,
9341 const struct devlink_trap_group
*groups
,
9342 size_t groups_count
)
9346 mutex_lock(&devlink
->lock
);
9347 for (i
= groups_count
- 1; i
>= 0; i
--)
9348 devlink_trap_group_unregister(devlink
, &groups
[i
]);
9349 mutex_unlock(&devlink
->lock
);
9351 EXPORT_SYMBOL_GPL(devlink_trap_groups_unregister
);
9354 devlink_trap_policer_notify(struct devlink
*devlink
,
9355 const struct devlink_trap_policer_item
*policer_item
,
9356 enum devlink_command cmd
)
9358 struct sk_buff
*msg
;
9361 WARN_ON_ONCE(cmd
!= DEVLINK_CMD_TRAP_POLICER_NEW
&&
9362 cmd
!= DEVLINK_CMD_TRAP_POLICER_DEL
);
9364 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
9368 err
= devlink_nl_trap_policer_fill(msg
, devlink
, policer_item
, cmd
, 0,
9375 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
9376 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
9380 devlink_trap_policer_register(struct devlink
*devlink
,
9381 const struct devlink_trap_policer
*policer
)
9383 struct devlink_trap_policer_item
*policer_item
;
9386 if (devlink_trap_policer_item_lookup(devlink
, policer
->id
))
9389 policer_item
= kzalloc(sizeof(*policer_item
), GFP_KERNEL
);
9393 policer_item
->policer
= policer
;
9394 policer_item
->rate
= policer
->init_rate
;
9395 policer_item
->burst
= policer
->init_burst
;
9397 if (devlink
->ops
->trap_policer_init
) {
9398 err
= devlink
->ops
->trap_policer_init(devlink
, policer
);
9400 goto err_policer_init
;
9403 list_add_tail(&policer_item
->list
, &devlink
->trap_policer_list
);
9404 devlink_trap_policer_notify(devlink
, policer_item
,
9405 DEVLINK_CMD_TRAP_POLICER_NEW
);
9410 kfree(policer_item
);
9415 devlink_trap_policer_unregister(struct devlink
*devlink
,
9416 const struct devlink_trap_policer
*policer
)
9418 struct devlink_trap_policer_item
*policer_item
;
9420 policer_item
= devlink_trap_policer_item_lookup(devlink
, policer
->id
);
9421 if (WARN_ON_ONCE(!policer_item
))
9424 devlink_trap_policer_notify(devlink
, policer_item
,
9425 DEVLINK_CMD_TRAP_POLICER_DEL
);
9426 list_del(&policer_item
->list
);
9427 if (devlink
->ops
->trap_policer_fini
)
9428 devlink
->ops
->trap_policer_fini(devlink
, policer
);
9429 kfree(policer_item
);
9433 * devlink_trap_policers_register - Register packet trap policers with devlink.
9434 * @devlink: devlink.
9435 * @policers: Packet trap policers.
9436 * @policers_count: Count of provided packet trap policers.
9438 * Return: Non-zero value on failure.
9441 devlink_trap_policers_register(struct devlink
*devlink
,
9442 const struct devlink_trap_policer
*policers
,
9443 size_t policers_count
)
9447 mutex_lock(&devlink
->lock
);
9448 for (i
= 0; i
< policers_count
; i
++) {
9449 const struct devlink_trap_policer
*policer
= &policers
[i
];
9451 if (WARN_ON(policer
->id
== 0 ||
9452 policer
->max_rate
< policer
->min_rate
||
9453 policer
->max_burst
< policer
->min_burst
)) {
9455 goto err_trap_policer_verify
;
9458 err
= devlink_trap_policer_register(devlink
, policer
);
9460 goto err_trap_policer_register
;
9462 mutex_unlock(&devlink
->lock
);
9466 err_trap_policer_register
:
9467 err_trap_policer_verify
:
9468 for (i
--; i
>= 0; i
--)
9469 devlink_trap_policer_unregister(devlink
, &policers
[i
]);
9470 mutex_unlock(&devlink
->lock
);
9473 EXPORT_SYMBOL_GPL(devlink_trap_policers_register
);
9476 * devlink_trap_policers_unregister - Unregister packet trap policers from devlink.
9477 * @devlink: devlink.
9478 * @policers: Packet trap policers.
9479 * @policers_count: Count of provided packet trap policers.
9482 devlink_trap_policers_unregister(struct devlink
*devlink
,
9483 const struct devlink_trap_policer
*policers
,
9484 size_t policers_count
)
9488 mutex_lock(&devlink
->lock
);
9489 for (i
= policers_count
- 1; i
>= 0; i
--)
9490 devlink_trap_policer_unregister(devlink
, &policers
[i
]);
9491 mutex_unlock(&devlink
->lock
);
9493 EXPORT_SYMBOL_GPL(devlink_trap_policers_unregister
);
9495 static void __devlink_compat_running_version(struct devlink
*devlink
,
9496 char *buf
, size_t len
)
9498 const struct nlattr
*nlattr
;
9499 struct devlink_info_req req
;
9500 struct sk_buff
*msg
;
9503 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
9508 err
= devlink
->ops
->info_get(devlink
, &req
, NULL
);
9512 nla_for_each_attr(nlattr
, (void *)msg
->data
, msg
->len
, rem
) {
9513 const struct nlattr
*kv
;
9516 if (nla_type(nlattr
) != DEVLINK_ATTR_INFO_VERSION_RUNNING
)
9519 nla_for_each_nested(kv
, nlattr
, rem_kv
) {
9520 if (nla_type(kv
) != DEVLINK_ATTR_INFO_VERSION_VALUE
)
9523 strlcat(buf
, nla_data(kv
), len
);
9524 strlcat(buf
, " ", len
);
9531 void devlink_compat_running_version(struct net_device
*dev
,
9532 char *buf
, size_t len
)
9534 struct devlink
*devlink
;
9539 devlink
= netdev_to_devlink(dev
);
9540 if (!devlink
|| !devlink
->ops
->info_get
)
9543 mutex_lock(&devlink
->lock
);
9544 __devlink_compat_running_version(devlink
, buf
, len
);
9545 mutex_unlock(&devlink
->lock
);
9552 int devlink_compat_flash_update(struct net_device
*dev
, const char *file_name
)
9554 struct devlink
*devlink
;
9560 devlink
= netdev_to_devlink(dev
);
9561 if (!devlink
|| !devlink
->ops
->flash_update
) {
9566 mutex_lock(&devlink
->lock
);
9567 ret
= devlink
->ops
->flash_update(devlink
, file_name
, NULL
, NULL
);
9568 mutex_unlock(&devlink
->lock
);
9577 int devlink_compat_phys_port_name_get(struct net_device
*dev
,
9578 char *name
, size_t len
)
9580 struct devlink_port
*devlink_port
;
9582 /* RTNL mutex is held here which ensures that devlink_port
9583 * instance cannot disappear in the middle. No need to take
9584 * any devlink lock as only permanent values are accessed.
9588 devlink_port
= netdev_to_devlink_port(dev
);
9592 return __devlink_port_phys_port_name_get(devlink_port
, name
, len
);
9595 int devlink_compat_switch_id_get(struct net_device
*dev
,
9596 struct netdev_phys_item_id
*ppid
)
9598 struct devlink_port
*devlink_port
;
9600 /* Caller must hold RTNL mutex or reference to dev, which ensures that
9601 * devlink_port instance cannot disappear in the middle. No need to take
9602 * any devlink lock as only permanent values are accessed.
9604 devlink_port
= netdev_to_devlink_port(dev
);
9605 if (!devlink_port
|| !devlink_port
->switch_port
)
9608 memcpy(ppid
, &devlink_port
->attrs
.switch_id
, sizeof(*ppid
));
9613 static void __net_exit
devlink_pernet_pre_exit(struct net
*net
)
9615 struct devlink
*devlink
;
9618 /* In case network namespace is getting destroyed, reload
9619 * all devlink instances from this namespace into init_net.
9621 mutex_lock(&devlink_mutex
);
9622 list_for_each_entry(devlink
, &devlink_list
, list
) {
9623 if (net_eq(devlink_net(devlink
), net
)) {
9624 if (WARN_ON(!devlink_reload_supported(devlink
)))
9626 err
= devlink_reload(devlink
, &init_net
, NULL
);
9627 if (err
&& err
!= -EOPNOTSUPP
)
9628 pr_warn("Failed to reload devlink instance into init_net\n");
9631 mutex_unlock(&devlink_mutex
);
9634 static struct pernet_operations devlink_pernet_ops __net_initdata
= {
9635 .pre_exit
= devlink_pernet_pre_exit
,
9638 static int __init
devlink_init(void)
9642 err
= genl_register_family(&devlink_nl_family
);
9645 err
= register_pernet_subsys(&devlink_pernet_ops
);
9652 subsys_initcall(devlink_init
);