1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * net/core/devlink.c - Network physical/parent device Netlink interface
5 * Heavily inspired by net/wireless/
6 * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
7 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/types.h>
13 #include <linux/slab.h>
14 #include <linux/gfp.h>
15 #include <linux/device.h>
16 #include <linux/list.h>
17 #include <linux/netdevice.h>
18 #include <linux/spinlock.h>
19 #include <linux/refcount.h>
20 #include <linux/workqueue.h>
21 #include <linux/u64_stats_sync.h>
22 #include <linux/timekeeping.h>
23 #include <rdma/ib_verbs.h>
24 #include <net/netlink.h>
25 #include <net/genetlink.h>
26 #include <net/rtnetlink.h>
27 #include <net/net_namespace.h>
29 #include <net/devlink.h>
30 #include <net/drop_monitor.h>
31 #define CREATE_TRACE_POINTS
32 #include <trace/events/devlink.h>
34 static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = {
36 .name = "destination mac",
37 .id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
42 struct devlink_dpipe_header devlink_dpipe_header_ethernet = {
44 .id = DEVLINK_DPIPE_HEADER_ETHERNET,
45 .fields = devlink_dpipe_fields_ethernet,
46 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet),
49 EXPORT_SYMBOL(devlink_dpipe_header_ethernet);
51 static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = {
53 .name = "destination ip",
54 .id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP,
59 struct devlink_dpipe_header devlink_dpipe_header_ipv4 = {
61 .id = DEVLINK_DPIPE_HEADER_IPV4,
62 .fields = devlink_dpipe_fields_ipv4,
63 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4),
66 EXPORT_SYMBOL(devlink_dpipe_header_ipv4);
68 static struct devlink_dpipe_field devlink_dpipe_fields_ipv6[] = {
70 .name = "destination ip",
71 .id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP,
76 struct devlink_dpipe_header devlink_dpipe_header_ipv6 = {
78 .id = DEVLINK_DPIPE_HEADER_IPV6,
79 .fields = devlink_dpipe_fields_ipv6,
80 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv6),
83 EXPORT_SYMBOL(devlink_dpipe_header_ipv6);
85 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg);
86 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwerr);
88 static LIST_HEAD(devlink_list);
92 * An overall lock guarding every operation coming from userspace.
93 * It also guards devlink devices list and it is taken when
94 * driver registers/unregisters it.
96 static DEFINE_MUTEX(devlink_mutex);
98 static struct net *devlink_net(const struct devlink *devlink)
100 return read_pnet(&devlink->_net);
103 static void devlink_net_set(struct devlink *devlink, struct net *net)
105 write_pnet(&devlink->_net, net);
108 static struct devlink *devlink_get_from_attrs(struct net *net,
109 struct nlattr **attrs)
111 struct devlink *devlink;
115 if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME])
116 return ERR_PTR(-EINVAL);
118 busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]);
119 devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
121 lockdep_assert_held(&devlink_mutex);
123 list_for_each_entry(devlink, &devlink_list, list) {
124 if (strcmp(devlink->dev->bus->name, busname) == 0 &&
125 strcmp(dev_name(devlink->dev), devname) == 0 &&
126 net_eq(devlink_net(devlink), net))
130 return ERR_PTR(-ENODEV);
133 static struct devlink *devlink_get_from_info(struct genl_info *info)
135 return devlink_get_from_attrs(genl_info_net(info), info->attrs);
138 static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
139 unsigned int port_index)
141 struct devlink_port *devlink_port;
143 list_for_each_entry(devlink_port, &devlink->port_list, list) {
144 if (devlink_port->index == port_index)
150 static bool devlink_port_index_exists(struct devlink *devlink,
151 unsigned int port_index)
153 return devlink_port_get_by_index(devlink, port_index);
156 static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
157 struct nlattr **attrs)
159 if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
160 u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
161 struct devlink_port *devlink_port;
163 devlink_port = devlink_port_get_by_index(devlink, port_index);
165 return ERR_PTR(-ENODEV);
168 return ERR_PTR(-EINVAL);
171 static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
172 struct genl_info *info)
174 return devlink_port_get_from_attrs(devlink, info->attrs);
178 struct list_head list;
181 u16 ingress_pools_count;
182 u16 egress_pools_count;
183 u16 ingress_tc_count;
187 static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb)
189 return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count;
192 static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink,
193 unsigned int sb_index)
195 struct devlink_sb *devlink_sb;
197 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
198 if (devlink_sb->index == sb_index)
204 static bool devlink_sb_index_exists(struct devlink *devlink,
205 unsigned int sb_index)
207 return devlink_sb_get_by_index(devlink, sb_index);
210 static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink,
211 struct nlattr **attrs)
213 if (attrs[DEVLINK_ATTR_SB_INDEX]) {
214 u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]);
215 struct devlink_sb *devlink_sb;
217 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
219 return ERR_PTR(-ENODEV);
222 return ERR_PTR(-EINVAL);
225 static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink,
226 struct genl_info *info)
228 return devlink_sb_get_from_attrs(devlink, info->attrs);
231 static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb,
232 struct nlattr **attrs,
237 if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX])
240 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]);
241 if (val >= devlink_sb_pool_count(devlink_sb))
247 static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb,
248 struct genl_info *info,
251 return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs,
256 devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs,
257 enum devlink_sb_pool_type *p_pool_type)
261 if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE])
264 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]);
265 if (val != DEVLINK_SB_POOL_TYPE_INGRESS &&
266 val != DEVLINK_SB_POOL_TYPE_EGRESS)
273 devlink_sb_pool_type_get_from_info(struct genl_info *info,
274 enum devlink_sb_pool_type *p_pool_type)
276 return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type);
280 devlink_sb_th_type_get_from_attrs(struct nlattr **attrs,
281 enum devlink_sb_threshold_type *p_th_type)
285 if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])
288 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]);
289 if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC &&
290 val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC)
297 devlink_sb_th_type_get_from_info(struct genl_info *info,
298 enum devlink_sb_threshold_type *p_th_type)
300 return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type);
304 devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb,
305 struct nlattr **attrs,
306 enum devlink_sb_pool_type pool_type,
311 if (!attrs[DEVLINK_ATTR_SB_TC_INDEX])
314 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]);
315 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS &&
316 val >= devlink_sb->ingress_tc_count)
318 if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS &&
319 val >= devlink_sb->egress_tc_count)
326 devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
327 struct genl_info *info,
328 enum devlink_sb_pool_type pool_type,
331 return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs,
332 pool_type, p_tc_index);
335 struct devlink_region {
336 struct devlink *devlink;
337 struct list_head list;
339 struct list_head snapshot_list;
345 struct devlink_snapshot {
346 struct list_head list;
347 struct devlink_region *region;
348 devlink_snapshot_data_dest_t *data_destructor;
353 static struct devlink_region *
354 devlink_region_get_by_name(struct devlink *devlink, const char *region_name)
356 struct devlink_region *region;
358 list_for_each_entry(region, &devlink->region_list, list)
359 if (!strcmp(region->name, region_name))
365 static struct devlink_snapshot *
366 devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id)
368 struct devlink_snapshot *snapshot;
370 list_for_each_entry(snapshot, ®ion->snapshot_list, list)
371 if (snapshot->id == id)
377 #define DEVLINK_NL_FLAG_NEED_DEVLINK BIT(0)
378 #define DEVLINK_NL_FLAG_NEED_PORT BIT(1)
379 #define DEVLINK_NL_FLAG_NEED_SB BIT(2)
381 /* The per devlink instance lock is taken by default in the pre-doit
382 * operation, yet several commands do not require this. The global
383 * devlink lock is taken and protects from disruption by user-calls.
385 #define DEVLINK_NL_FLAG_NO_LOCK BIT(3)
387 static int devlink_nl_pre_doit(const struct genl_ops *ops,
388 struct sk_buff *skb, struct genl_info *info)
390 struct devlink *devlink;
393 mutex_lock(&devlink_mutex);
394 devlink = devlink_get_from_info(info);
395 if (IS_ERR(devlink)) {
396 mutex_unlock(&devlink_mutex);
397 return PTR_ERR(devlink);
399 if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
400 mutex_lock(&devlink->lock);
401 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK) {
402 info->user_ptr[0] = devlink;
403 } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) {
404 struct devlink_port *devlink_port;
406 devlink_port = devlink_port_get_from_info(devlink, info);
407 if (IS_ERR(devlink_port)) {
408 err = PTR_ERR(devlink_port);
411 info->user_ptr[0] = devlink_port;
413 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_SB) {
414 struct devlink_sb *devlink_sb;
416 devlink_sb = devlink_sb_get_from_info(devlink, info);
417 if (IS_ERR(devlink_sb)) {
418 err = PTR_ERR(devlink_sb);
421 info->user_ptr[1] = devlink_sb;
426 if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
427 mutex_unlock(&devlink->lock);
428 mutex_unlock(&devlink_mutex);
432 static void devlink_nl_post_doit(const struct genl_ops *ops,
433 struct sk_buff *skb, struct genl_info *info)
435 struct devlink *devlink;
437 devlink = devlink_get_from_info(info);
438 if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
439 mutex_unlock(&devlink->lock);
440 mutex_unlock(&devlink_mutex);
443 static struct genl_family devlink_nl_family;
445 enum devlink_multicast_groups {
446 DEVLINK_MCGRP_CONFIG,
449 static const struct genl_multicast_group devlink_nl_mcgrps[] = {
450 [DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME },
453 static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
455 if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name))
457 if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev)))
462 static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
463 enum devlink_command cmd, u32 portid,
468 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
472 if (devlink_nl_put_handle(msg, devlink))
473 goto nla_put_failure;
474 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_FAILED, devlink->reload_failed))
475 goto nla_put_failure;
477 genlmsg_end(msg, hdr);
481 genlmsg_cancel(msg, hdr);
485 static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
490 WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
492 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
496 err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0);
502 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
503 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
506 static int devlink_nl_port_attrs_put(struct sk_buff *msg,
507 struct devlink_port *devlink_port)
509 struct devlink_port_attrs *attrs = &devlink_port->attrs;
513 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour))
515 switch (devlink_port->attrs.flavour) {
516 case DEVLINK_PORT_FLAVOUR_PCI_PF:
517 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER,
521 case DEVLINK_PORT_FLAVOUR_PCI_VF:
522 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER,
524 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_VF_NUMBER,
528 case DEVLINK_PORT_FLAVOUR_PHYSICAL:
529 case DEVLINK_PORT_FLAVOUR_CPU:
530 case DEVLINK_PORT_FLAVOUR_DSA:
531 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER,
532 attrs->phys.port_number))
536 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
537 attrs->phys.port_number))
539 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER,
540 attrs->phys.split_subport_number))
549 static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
550 struct devlink_port *devlink_port,
551 enum devlink_command cmd, u32 portid,
556 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
560 if (devlink_nl_put_handle(msg, devlink))
561 goto nla_put_failure;
562 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
563 goto nla_put_failure;
565 spin_lock_bh(&devlink_port->type_lock);
566 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
567 goto nla_put_failure_type_locked;
568 if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
569 nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
570 devlink_port->desired_type))
571 goto nla_put_failure_type_locked;
572 if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
573 struct net_device *netdev = devlink_port->type_dev;
576 (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
578 nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
580 goto nla_put_failure_type_locked;
582 if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
583 struct ib_device *ibdev = devlink_port->type_dev;
586 nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
588 goto nla_put_failure_type_locked;
590 spin_unlock_bh(&devlink_port->type_lock);
591 if (devlink_nl_port_attrs_put(msg, devlink_port))
592 goto nla_put_failure;
594 genlmsg_end(msg, hdr);
597 nla_put_failure_type_locked:
598 spin_unlock_bh(&devlink_port->type_lock);
600 genlmsg_cancel(msg, hdr);
604 static void devlink_port_notify(struct devlink_port *devlink_port,
605 enum devlink_command cmd)
607 struct devlink *devlink = devlink_port->devlink;
611 if (!devlink_port->registered)
614 WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
616 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
620 err = devlink_nl_port_fill(msg, devlink, devlink_port, cmd, 0, 0, 0);
626 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
627 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
630 static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
632 struct devlink *devlink = info->user_ptr[0];
636 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
640 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
641 info->snd_portid, info->snd_seq, 0);
647 return genlmsg_reply(msg, info);
650 static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
651 struct netlink_callback *cb)
653 struct devlink *devlink;
654 int start = cb->args[0];
658 mutex_lock(&devlink_mutex);
659 list_for_each_entry(devlink, &devlink_list, list) {
660 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
666 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
667 NETLINK_CB(cb->skb).portid,
668 cb->nlh->nlmsg_seq, NLM_F_MULTI);
674 mutex_unlock(&devlink_mutex);
680 static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
681 struct genl_info *info)
683 struct devlink_port *devlink_port = info->user_ptr[0];
684 struct devlink *devlink = devlink_port->devlink;
688 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
692 err = devlink_nl_port_fill(msg, devlink, devlink_port,
693 DEVLINK_CMD_PORT_NEW,
694 info->snd_portid, info->snd_seq, 0);
700 return genlmsg_reply(msg, info);
703 static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
704 struct netlink_callback *cb)
706 struct devlink *devlink;
707 struct devlink_port *devlink_port;
708 int start = cb->args[0];
712 mutex_lock(&devlink_mutex);
713 list_for_each_entry(devlink, &devlink_list, list) {
714 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
716 mutex_lock(&devlink->lock);
717 list_for_each_entry(devlink_port, &devlink->port_list, list) {
722 err = devlink_nl_port_fill(msg, devlink, devlink_port,
724 NETLINK_CB(cb->skb).portid,
728 mutex_unlock(&devlink->lock);
733 mutex_unlock(&devlink->lock);
736 mutex_unlock(&devlink_mutex);
742 static int devlink_port_type_set(struct devlink *devlink,
743 struct devlink_port *devlink_port,
744 enum devlink_port_type port_type)
749 if (devlink->ops->port_type_set) {
750 if (port_type == DEVLINK_PORT_TYPE_NOTSET)
752 if (port_type == devlink_port->type)
754 err = devlink->ops->port_type_set(devlink_port, port_type);
757 devlink_port->desired_type = port_type;
758 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
764 static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
765 struct genl_info *info)
767 struct devlink_port *devlink_port = info->user_ptr[0];
768 struct devlink *devlink = devlink_port->devlink;
771 if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
772 enum devlink_port_type port_type;
774 port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
775 err = devlink_port_type_set(devlink, devlink_port, port_type);
782 static int devlink_port_split(struct devlink *devlink, u32 port_index,
783 u32 count, struct netlink_ext_ack *extack)
786 if (devlink->ops->port_split)
787 return devlink->ops->port_split(devlink, port_index, count,
792 static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
793 struct genl_info *info)
795 struct devlink *devlink = info->user_ptr[0];
799 if (!info->attrs[DEVLINK_ATTR_PORT_INDEX] ||
800 !info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT])
803 port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
804 count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
805 return devlink_port_split(devlink, port_index, count, info->extack);
808 static int devlink_port_unsplit(struct devlink *devlink, u32 port_index,
809 struct netlink_ext_ack *extack)
812 if (devlink->ops->port_unsplit)
813 return devlink->ops->port_unsplit(devlink, port_index, extack);
817 static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
818 struct genl_info *info)
820 struct devlink *devlink = info->user_ptr[0];
823 if (!info->attrs[DEVLINK_ATTR_PORT_INDEX])
826 port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
827 return devlink_port_unsplit(devlink, port_index, info->extack);
830 static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
831 struct devlink_sb *devlink_sb,
832 enum devlink_command cmd, u32 portid,
837 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
841 if (devlink_nl_put_handle(msg, devlink))
842 goto nla_put_failure;
843 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
844 goto nla_put_failure;
845 if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size))
846 goto nla_put_failure;
847 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT,
848 devlink_sb->ingress_pools_count))
849 goto nla_put_failure;
850 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT,
851 devlink_sb->egress_pools_count))
852 goto nla_put_failure;
853 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT,
854 devlink_sb->ingress_tc_count))
855 goto nla_put_failure;
856 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT,
857 devlink_sb->egress_tc_count))
858 goto nla_put_failure;
860 genlmsg_end(msg, hdr);
864 genlmsg_cancel(msg, hdr);
868 static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb,
869 struct genl_info *info)
871 struct devlink *devlink = info->user_ptr[0];
872 struct devlink_sb *devlink_sb = info->user_ptr[1];
876 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
880 err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
882 info->snd_portid, info->snd_seq, 0);
888 return genlmsg_reply(msg, info);
891 static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg,
892 struct netlink_callback *cb)
894 struct devlink *devlink;
895 struct devlink_sb *devlink_sb;
896 int start = cb->args[0];
900 mutex_lock(&devlink_mutex);
901 list_for_each_entry(devlink, &devlink_list, list) {
902 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
904 mutex_lock(&devlink->lock);
905 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
910 err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
912 NETLINK_CB(cb->skb).portid,
916 mutex_unlock(&devlink->lock);
921 mutex_unlock(&devlink->lock);
924 mutex_unlock(&devlink_mutex);
930 static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink,
931 struct devlink_sb *devlink_sb,
932 u16 pool_index, enum devlink_command cmd,
933 u32 portid, u32 seq, int flags)
935 struct devlink_sb_pool_info pool_info;
939 err = devlink->ops->sb_pool_get(devlink, devlink_sb->index,
940 pool_index, &pool_info);
944 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
948 if (devlink_nl_put_handle(msg, devlink))
949 goto nla_put_failure;
950 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
951 goto nla_put_failure;
952 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
953 goto nla_put_failure;
954 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type))
955 goto nla_put_failure;
956 if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size))
957 goto nla_put_failure;
958 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE,
959 pool_info.threshold_type))
960 goto nla_put_failure;
961 if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_CELL_SIZE,
962 pool_info.cell_size))
963 goto nla_put_failure;
965 genlmsg_end(msg, hdr);
969 genlmsg_cancel(msg, hdr);
973 static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb,
974 struct genl_info *info)
976 struct devlink *devlink = info->user_ptr[0];
977 struct devlink_sb *devlink_sb = info->user_ptr[1];
982 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
987 if (!devlink->ops->sb_pool_get)
990 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
994 err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index,
995 DEVLINK_CMD_SB_POOL_NEW,
996 info->snd_portid, info->snd_seq, 0);
1002 return genlmsg_reply(msg, info);
1005 static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
1006 struct devlink *devlink,
1007 struct devlink_sb *devlink_sb,
1008 u32 portid, u32 seq)
1010 u16 pool_count = devlink_sb_pool_count(devlink_sb);
1014 for (pool_index = 0; pool_index < pool_count; pool_index++) {
1015 if (*p_idx < start) {
1019 err = devlink_nl_sb_pool_fill(msg, devlink,
1022 DEVLINK_CMD_SB_POOL_NEW,
1023 portid, seq, NLM_F_MULTI);
1031 static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg,
1032 struct netlink_callback *cb)
1034 struct devlink *devlink;
1035 struct devlink_sb *devlink_sb;
1036 int start = cb->args[0];
1040 mutex_lock(&devlink_mutex);
1041 list_for_each_entry(devlink, &devlink_list, list) {
1042 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1043 !devlink->ops->sb_pool_get)
1045 mutex_lock(&devlink->lock);
1046 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1047 err = __sb_pool_get_dumpit(msg, start, &idx, devlink,
1049 NETLINK_CB(cb->skb).portid,
1050 cb->nlh->nlmsg_seq);
1051 if (err && err != -EOPNOTSUPP) {
1052 mutex_unlock(&devlink->lock);
1056 mutex_unlock(&devlink->lock);
1059 mutex_unlock(&devlink_mutex);
1065 static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
1066 u16 pool_index, u32 size,
1067 enum devlink_sb_threshold_type threshold_type,
1068 struct netlink_ext_ack *extack)
1071 const struct devlink_ops *ops = devlink->ops;
1073 if (ops->sb_pool_set)
1074 return ops->sb_pool_set(devlink, sb_index, pool_index,
1075 size, threshold_type, extack);
1079 static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb,
1080 struct genl_info *info)
1082 struct devlink *devlink = info->user_ptr[0];
1083 struct devlink_sb *devlink_sb = info->user_ptr[1];
1084 enum devlink_sb_threshold_type threshold_type;
1089 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1094 err = devlink_sb_th_type_get_from_info(info, &threshold_type);
1098 if (!info->attrs[DEVLINK_ATTR_SB_POOL_SIZE])
1101 size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]);
1102 return devlink_sb_pool_set(devlink, devlink_sb->index,
1103 pool_index, size, threshold_type,
1107 static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg,
1108 struct devlink *devlink,
1109 struct devlink_port *devlink_port,
1110 struct devlink_sb *devlink_sb,
1112 enum devlink_command cmd,
1113 u32 portid, u32 seq, int flags)
1115 const struct devlink_ops *ops = devlink->ops;
1120 err = ops->sb_port_pool_get(devlink_port, devlink_sb->index,
1121 pool_index, &threshold);
1125 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1129 if (devlink_nl_put_handle(msg, devlink))
1130 goto nla_put_failure;
1131 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1132 goto nla_put_failure;
1133 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1134 goto nla_put_failure;
1135 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
1136 goto nla_put_failure;
1137 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
1138 goto nla_put_failure;
1140 if (ops->sb_occ_port_pool_get) {
1144 err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index,
1145 pool_index, &cur, &max);
1146 if (err && err != -EOPNOTSUPP)
1149 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
1150 goto nla_put_failure;
1151 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
1152 goto nla_put_failure;
1156 genlmsg_end(msg, hdr);
1160 genlmsg_cancel(msg, hdr);
1164 static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,
1165 struct genl_info *info)
1167 struct devlink_port *devlink_port = info->user_ptr[0];
1168 struct devlink *devlink = devlink_port->devlink;
1169 struct devlink_sb *devlink_sb = info->user_ptr[1];
1170 struct sk_buff *msg;
1174 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1179 if (!devlink->ops->sb_port_pool_get)
1182 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1186 err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port,
1187 devlink_sb, pool_index,
1188 DEVLINK_CMD_SB_PORT_POOL_NEW,
1189 info->snd_portid, info->snd_seq, 0);
1195 return genlmsg_reply(msg, info);
1198 static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
1199 struct devlink *devlink,
1200 struct devlink_sb *devlink_sb,
1201 u32 portid, u32 seq)
1203 struct devlink_port *devlink_port;
1204 u16 pool_count = devlink_sb_pool_count(devlink_sb);
1208 list_for_each_entry(devlink_port, &devlink->port_list, list) {
1209 for (pool_index = 0; pool_index < pool_count; pool_index++) {
1210 if (*p_idx < start) {
1214 err = devlink_nl_sb_port_pool_fill(msg, devlink,
1218 DEVLINK_CMD_SB_PORT_POOL_NEW,
1229 static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg,
1230 struct netlink_callback *cb)
1232 struct devlink *devlink;
1233 struct devlink_sb *devlink_sb;
1234 int start = cb->args[0];
1238 mutex_lock(&devlink_mutex);
1239 list_for_each_entry(devlink, &devlink_list, list) {
1240 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1241 !devlink->ops->sb_port_pool_get)
1243 mutex_lock(&devlink->lock);
1244 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1245 err = __sb_port_pool_get_dumpit(msg, start, &idx,
1246 devlink, devlink_sb,
1247 NETLINK_CB(cb->skb).portid,
1248 cb->nlh->nlmsg_seq);
1249 if (err && err != -EOPNOTSUPP) {
1250 mutex_unlock(&devlink->lock);
1254 mutex_unlock(&devlink->lock);
1257 mutex_unlock(&devlink_mutex);
1263 static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
1264 unsigned int sb_index, u16 pool_index,
1266 struct netlink_ext_ack *extack)
1269 const struct devlink_ops *ops = devlink_port->devlink->ops;
1271 if (ops->sb_port_pool_set)
1272 return ops->sb_port_pool_set(devlink_port, sb_index,
1273 pool_index, threshold, extack);
1277 static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb,
1278 struct genl_info *info)
1280 struct devlink_port *devlink_port = info->user_ptr[0];
1281 struct devlink_sb *devlink_sb = info->user_ptr[1];
1286 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1291 if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1294 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1295 return devlink_sb_port_pool_set(devlink_port, devlink_sb->index,
1296 pool_index, threshold, info->extack);
1300 devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink,
1301 struct devlink_port *devlink_port,
1302 struct devlink_sb *devlink_sb, u16 tc_index,
1303 enum devlink_sb_pool_type pool_type,
1304 enum devlink_command cmd,
1305 u32 portid, u32 seq, int flags)
1307 const struct devlink_ops *ops = devlink->ops;
1313 err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index,
1314 tc_index, pool_type,
1315 &pool_index, &threshold);
1319 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1323 if (devlink_nl_put_handle(msg, devlink))
1324 goto nla_put_failure;
1325 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1326 goto nla_put_failure;
1327 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1328 goto nla_put_failure;
1329 if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index))
1330 goto nla_put_failure;
1331 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type))
1332 goto nla_put_failure;
1333 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
1334 goto nla_put_failure;
1335 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
1336 goto nla_put_failure;
1338 if (ops->sb_occ_tc_port_bind_get) {
1342 err = ops->sb_occ_tc_port_bind_get(devlink_port,
1344 tc_index, pool_type,
1346 if (err && err != -EOPNOTSUPP)
1349 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
1350 goto nla_put_failure;
1351 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
1352 goto nla_put_failure;
1356 genlmsg_end(msg, hdr);
1360 genlmsg_cancel(msg, hdr);
1364 static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,
1365 struct genl_info *info)
1367 struct devlink_port *devlink_port = info->user_ptr[0];
1368 struct devlink *devlink = devlink_port->devlink;
1369 struct devlink_sb *devlink_sb = info->user_ptr[1];
1370 struct sk_buff *msg;
1371 enum devlink_sb_pool_type pool_type;
1375 err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1379 err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1380 pool_type, &tc_index);
1384 if (!devlink->ops->sb_tc_pool_bind_get)
1387 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1391 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port,
1392 devlink_sb, tc_index, pool_type,
1393 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1401 return genlmsg_reply(msg, info);
1404 static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1405 int start, int *p_idx,
1406 struct devlink *devlink,
1407 struct devlink_sb *devlink_sb,
1408 u32 portid, u32 seq)
1410 struct devlink_port *devlink_port;
1414 list_for_each_entry(devlink_port, &devlink->port_list, list) {
1416 tc_index < devlink_sb->ingress_tc_count; tc_index++) {
1417 if (*p_idx < start) {
1421 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1425 DEVLINK_SB_POOL_TYPE_INGRESS,
1426 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1434 tc_index < devlink_sb->egress_tc_count; tc_index++) {
1435 if (*p_idx < start) {
1439 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1443 DEVLINK_SB_POOL_TYPE_EGRESS,
1444 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1456 devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1457 struct netlink_callback *cb)
1459 struct devlink *devlink;
1460 struct devlink_sb *devlink_sb;
1461 int start = cb->args[0];
1465 mutex_lock(&devlink_mutex);
1466 list_for_each_entry(devlink, &devlink_list, list) {
1467 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1468 !devlink->ops->sb_tc_pool_bind_get)
1471 mutex_lock(&devlink->lock);
1472 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1473 err = __sb_tc_pool_bind_get_dumpit(msg, start, &idx,
1476 NETLINK_CB(cb->skb).portid,
1477 cb->nlh->nlmsg_seq);
1478 if (err && err != -EOPNOTSUPP) {
1479 mutex_unlock(&devlink->lock);
1483 mutex_unlock(&devlink->lock);
1486 mutex_unlock(&devlink_mutex);
1492 static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port,
1493 unsigned int sb_index, u16 tc_index,
1494 enum devlink_sb_pool_type pool_type,
1495 u16 pool_index, u32 threshold,
1496 struct netlink_ext_ack *extack)
1499 const struct devlink_ops *ops = devlink_port->devlink->ops;
1501 if (ops->sb_tc_pool_bind_set)
1502 return ops->sb_tc_pool_bind_set(devlink_port, sb_index,
1503 tc_index, pool_type,
1504 pool_index, threshold, extack);
1508 static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb,
1509 struct genl_info *info)
1511 struct devlink_port *devlink_port = info->user_ptr[0];
1512 struct devlink_sb *devlink_sb = info->user_ptr[1];
1513 enum devlink_sb_pool_type pool_type;
1519 err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1523 err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1524 pool_type, &tc_index);
1528 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1533 if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1536 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1537 return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index,
1538 tc_index, pool_type,
1539 pool_index, threshold, info->extack);
1542 static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
1543 struct genl_info *info)
1545 struct devlink *devlink = info->user_ptr[0];
1546 struct devlink_sb *devlink_sb = info->user_ptr[1];
1547 const struct devlink_ops *ops = devlink->ops;
1549 if (ops->sb_occ_snapshot)
1550 return ops->sb_occ_snapshot(devlink, devlink_sb->index);
1554 static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
1555 struct genl_info *info)
1557 struct devlink *devlink = info->user_ptr[0];
1558 struct devlink_sb *devlink_sb = info->user_ptr[1];
1559 const struct devlink_ops *ops = devlink->ops;
1561 if (ops->sb_occ_max_clear)
1562 return ops->sb_occ_max_clear(devlink, devlink_sb->index);
1566 static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
1567 enum devlink_command cmd, u32 portid,
1570 const struct devlink_ops *ops = devlink->ops;
1571 enum devlink_eswitch_encap_mode encap_mode;
1577 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1581 err = devlink_nl_put_handle(msg, devlink);
1583 goto nla_put_failure;
1585 if (ops->eswitch_mode_get) {
1586 err = ops->eswitch_mode_get(devlink, &mode);
1588 goto nla_put_failure;
1589 err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode);
1591 goto nla_put_failure;
1594 if (ops->eswitch_inline_mode_get) {
1595 err = ops->eswitch_inline_mode_get(devlink, &inline_mode);
1597 goto nla_put_failure;
1598 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE,
1601 goto nla_put_failure;
1604 if (ops->eswitch_encap_mode_get) {
1605 err = ops->eswitch_encap_mode_get(devlink, &encap_mode);
1607 goto nla_put_failure;
1608 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode);
1610 goto nla_put_failure;
1613 genlmsg_end(msg, hdr);
1617 genlmsg_cancel(msg, hdr);
1621 static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb,
1622 struct genl_info *info)
1624 struct devlink *devlink = info->user_ptr[0];
1625 struct sk_buff *msg;
1628 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1632 err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET,
1633 info->snd_portid, info->snd_seq, 0);
1640 return genlmsg_reply(msg, info);
1643 static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb,
1644 struct genl_info *info)
1646 struct devlink *devlink = info->user_ptr[0];
1647 const struct devlink_ops *ops = devlink->ops;
1648 enum devlink_eswitch_encap_mode encap_mode;
1653 if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) {
1654 if (!ops->eswitch_mode_set)
1656 mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
1657 err = ops->eswitch_mode_set(devlink, mode, info->extack);
1662 if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) {
1663 if (!ops->eswitch_inline_mode_set)
1665 inline_mode = nla_get_u8(
1666 info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]);
1667 err = ops->eswitch_inline_mode_set(devlink, inline_mode,
1673 if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) {
1674 if (!ops->eswitch_encap_mode_set)
1676 encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]);
1677 err = ops->eswitch_encap_mode_set(devlink, encap_mode,
1686 int devlink_dpipe_match_put(struct sk_buff *skb,
1687 struct devlink_dpipe_match *match)
1689 struct devlink_dpipe_header *header = match->header;
1690 struct devlink_dpipe_field *field = &header->fields[match->field_id];
1691 struct nlattr *match_attr;
1693 match_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_MATCH);
1697 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) ||
1698 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) ||
1699 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
1700 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
1701 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
1702 goto nla_put_failure;
1704 nla_nest_end(skb, match_attr);
1708 nla_nest_cancel(skb, match_attr);
1711 EXPORT_SYMBOL_GPL(devlink_dpipe_match_put);
1713 static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table,
1714 struct sk_buff *skb)
1716 struct nlattr *matches_attr;
1718 matches_attr = nla_nest_start_noflag(skb,
1719 DEVLINK_ATTR_DPIPE_TABLE_MATCHES);
1723 if (table->table_ops->matches_dump(table->priv, skb))
1724 goto nla_put_failure;
1726 nla_nest_end(skb, matches_attr);
1730 nla_nest_cancel(skb, matches_attr);
1734 int devlink_dpipe_action_put(struct sk_buff *skb,
1735 struct devlink_dpipe_action *action)
1737 struct devlink_dpipe_header *header = action->header;
1738 struct devlink_dpipe_field *field = &header->fields[action->field_id];
1739 struct nlattr *action_attr;
1741 action_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ACTION);
1745 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) ||
1746 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) ||
1747 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
1748 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
1749 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
1750 goto nla_put_failure;
1752 nla_nest_end(skb, action_attr);
1756 nla_nest_cancel(skb, action_attr);
1759 EXPORT_SYMBOL_GPL(devlink_dpipe_action_put);
1761 static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table,
1762 struct sk_buff *skb)
1764 struct nlattr *actions_attr;
1766 actions_attr = nla_nest_start_noflag(skb,
1767 DEVLINK_ATTR_DPIPE_TABLE_ACTIONS);
1771 if (table->table_ops->actions_dump(table->priv, skb))
1772 goto nla_put_failure;
1774 nla_nest_end(skb, actions_attr);
1778 nla_nest_cancel(skb, actions_attr);
1782 static int devlink_dpipe_table_put(struct sk_buff *skb,
1783 struct devlink_dpipe_table *table)
1785 struct nlattr *table_attr;
1788 table_size = table->table_ops->size_get(table->priv);
1789 table_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLE);
1793 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) ||
1794 nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size,
1796 goto nla_put_failure;
1797 if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
1798 table->counters_enabled))
1799 goto nla_put_failure;
1801 if (table->resource_valid) {
1802 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID,
1803 table->resource_id, DEVLINK_ATTR_PAD) ||
1804 nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS,
1805 table->resource_units, DEVLINK_ATTR_PAD))
1806 goto nla_put_failure;
1808 if (devlink_dpipe_matches_put(table, skb))
1809 goto nla_put_failure;
1811 if (devlink_dpipe_actions_put(table, skb))
1812 goto nla_put_failure;
1814 nla_nest_end(skb, table_attr);
1818 nla_nest_cancel(skb, table_attr);
1822 static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb,
1823 struct genl_info *info)
1828 err = genlmsg_reply(*pskb, info);
1832 *pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
1838 static int devlink_dpipe_tables_fill(struct genl_info *info,
1839 enum devlink_command cmd, int flags,
1840 struct list_head *dpipe_tables,
1841 const char *table_name)
1843 struct devlink *devlink = info->user_ptr[0];
1844 struct devlink_dpipe_table *table;
1845 struct nlattr *tables_attr;
1846 struct sk_buff *skb = NULL;
1847 struct nlmsghdr *nlh;
1853 table = list_first_entry(dpipe_tables,
1854 struct devlink_dpipe_table, list);
1856 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
1860 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
1861 &devlink_nl_family, NLM_F_MULTI, cmd);
1867 if (devlink_nl_put_handle(skb, devlink))
1868 goto nla_put_failure;
1869 tables_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLES);
1871 goto nla_put_failure;
1875 list_for_each_entry_from(table, dpipe_tables, list) {
1877 err = devlink_dpipe_table_put(skb, table);
1885 if (!strcmp(table->name, table_name)) {
1886 err = devlink_dpipe_table_put(skb, table);
1894 nla_nest_end(skb, tables_attr);
1895 genlmsg_end(skb, hdr);
1900 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
1901 NLMSG_DONE, 0, flags | NLM_F_MULTI);
1903 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
1909 return genlmsg_reply(skb, info);
1918 static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb,
1919 struct genl_info *info)
1921 struct devlink *devlink = info->user_ptr[0];
1922 const char *table_name = NULL;
1924 if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
1925 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
1927 return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0,
1928 &devlink->dpipe_table_list,
1932 static int devlink_dpipe_value_put(struct sk_buff *skb,
1933 struct devlink_dpipe_value *value)
1935 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE,
1936 value->value_size, value->value))
1939 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK,
1940 value->value_size, value->mask))
1942 if (value->mapping_valid)
1943 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING,
1944 value->mapping_value))
1949 static int devlink_dpipe_action_value_put(struct sk_buff *skb,
1950 struct devlink_dpipe_value *value)
1954 if (devlink_dpipe_action_put(skb, value->action))
1956 if (devlink_dpipe_value_put(skb, value))
1961 static int devlink_dpipe_action_values_put(struct sk_buff *skb,
1962 struct devlink_dpipe_value *values,
1963 unsigned int values_count)
1965 struct nlattr *action_attr;
1969 for (i = 0; i < values_count; i++) {
1970 action_attr = nla_nest_start_noflag(skb,
1971 DEVLINK_ATTR_DPIPE_ACTION_VALUE);
1974 err = devlink_dpipe_action_value_put(skb, &values[i]);
1976 goto err_action_value_put;
1977 nla_nest_end(skb, action_attr);
1981 err_action_value_put:
1982 nla_nest_cancel(skb, action_attr);
1986 static int devlink_dpipe_match_value_put(struct sk_buff *skb,
1987 struct devlink_dpipe_value *value)
1991 if (devlink_dpipe_match_put(skb, value->match))
1993 if (devlink_dpipe_value_put(skb, value))
1998 static int devlink_dpipe_match_values_put(struct sk_buff *skb,
1999 struct devlink_dpipe_value *values,
2000 unsigned int values_count)
2002 struct nlattr *match_attr;
2006 for (i = 0; i < values_count; i++) {
2007 match_attr = nla_nest_start_noflag(skb,
2008 DEVLINK_ATTR_DPIPE_MATCH_VALUE);
2011 err = devlink_dpipe_match_value_put(skb, &values[i]);
2013 goto err_match_value_put;
2014 nla_nest_end(skb, match_attr);
2018 err_match_value_put:
2019 nla_nest_cancel(skb, match_attr);
2023 static int devlink_dpipe_entry_put(struct sk_buff *skb,
2024 struct devlink_dpipe_entry *entry)
2026 struct nlattr *entry_attr, *matches_attr, *actions_attr;
2029 entry_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ENTRY);
2033 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index,
2035 goto nla_put_failure;
2036 if (entry->counter_valid)
2037 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER,
2038 entry->counter, DEVLINK_ATTR_PAD))
2039 goto nla_put_failure;
2041 matches_attr = nla_nest_start_noflag(skb,
2042 DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES);
2044 goto nla_put_failure;
2046 err = devlink_dpipe_match_values_put(skb, entry->match_values,
2047 entry->match_values_count);
2049 nla_nest_cancel(skb, matches_attr);
2050 goto err_match_values_put;
2052 nla_nest_end(skb, matches_attr);
2054 actions_attr = nla_nest_start_noflag(skb,
2055 DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES);
2057 goto nla_put_failure;
2059 err = devlink_dpipe_action_values_put(skb, entry->action_values,
2060 entry->action_values_count);
2062 nla_nest_cancel(skb, actions_attr);
2063 goto err_action_values_put;
2065 nla_nest_end(skb, actions_attr);
2067 nla_nest_end(skb, entry_attr);
2072 err_match_values_put:
2073 err_action_values_put:
2074 nla_nest_cancel(skb, entry_attr);
2078 static struct devlink_dpipe_table *
2079 devlink_dpipe_table_find(struct list_head *dpipe_tables,
2080 const char *table_name)
2082 struct devlink_dpipe_table *table;
2084 list_for_each_entry_rcu(table, dpipe_tables, list) {
2085 if (!strcmp(table->name, table_name))
2091 int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx)
2093 struct devlink *devlink;
2096 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb,
2101 dump_ctx->hdr = genlmsg_put(dump_ctx->skb,
2102 dump_ctx->info->snd_portid,
2103 dump_ctx->info->snd_seq,
2104 &devlink_nl_family, NLM_F_MULTI,
2107 goto nla_put_failure;
2109 devlink = dump_ctx->info->user_ptr[0];
2110 if (devlink_nl_put_handle(dump_ctx->skb, devlink))
2111 goto nla_put_failure;
2112 dump_ctx->nest = nla_nest_start_noflag(dump_ctx->skb,
2113 DEVLINK_ATTR_DPIPE_ENTRIES);
2114 if (!dump_ctx->nest)
2115 goto nla_put_failure;
2119 nlmsg_free(dump_ctx->skb);
2122 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare);
2124 int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx,
2125 struct devlink_dpipe_entry *entry)
2127 return devlink_dpipe_entry_put(dump_ctx->skb, entry);
2129 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append);
2131 int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx)
2133 nla_nest_end(dump_ctx->skb, dump_ctx->nest);
2134 genlmsg_end(dump_ctx->skb, dump_ctx->hdr);
2137 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close);
2139 void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry)
2142 unsigned int value_count, value_index;
2143 struct devlink_dpipe_value *value;
2145 value = entry->action_values;
2146 value_count = entry->action_values_count;
2147 for (value_index = 0; value_index < value_count; value_index++) {
2148 kfree(value[value_index].value);
2149 kfree(value[value_index].mask);
2152 value = entry->match_values;
2153 value_count = entry->match_values_count;
2154 for (value_index = 0; value_index < value_count; value_index++) {
2155 kfree(value[value_index].value);
2156 kfree(value[value_index].mask);
2159 EXPORT_SYMBOL(devlink_dpipe_entry_clear);
2161 static int devlink_dpipe_entries_fill(struct genl_info *info,
2162 enum devlink_command cmd, int flags,
2163 struct devlink_dpipe_table *table)
2165 struct devlink_dpipe_dump_ctx dump_ctx;
2166 struct nlmsghdr *nlh;
2169 dump_ctx.skb = NULL;
2171 dump_ctx.info = info;
2173 err = table->table_ops->entries_dump(table->priv,
2174 table->counters_enabled,
2180 nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq,
2181 NLMSG_DONE, 0, flags | NLM_F_MULTI);
2183 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info);
2188 return genlmsg_reply(dump_ctx.skb, info);
2191 static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
2192 struct genl_info *info)
2194 struct devlink *devlink = info->user_ptr[0];
2195 struct devlink_dpipe_table *table;
2196 const char *table_name;
2198 if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
2201 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
2202 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2207 if (!table->table_ops->entries_dump)
2210 return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET,
2214 static int devlink_dpipe_fields_put(struct sk_buff *skb,
2215 const struct devlink_dpipe_header *header)
2217 struct devlink_dpipe_field *field;
2218 struct nlattr *field_attr;
2221 for (i = 0; i < header->fields_count; i++) {
2222 field = &header->fields[i];
2223 field_attr = nla_nest_start_noflag(skb,
2224 DEVLINK_ATTR_DPIPE_FIELD);
2227 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) ||
2228 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
2229 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) ||
2230 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type))
2231 goto nla_put_failure;
2232 nla_nest_end(skb, field_attr);
2237 nla_nest_cancel(skb, field_attr);
2241 static int devlink_dpipe_header_put(struct sk_buff *skb,
2242 struct devlink_dpipe_header *header)
2244 struct nlattr *fields_attr, *header_attr;
2247 header_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADER);
2251 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) ||
2252 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
2253 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
2254 goto nla_put_failure;
2256 fields_attr = nla_nest_start_noflag(skb,
2257 DEVLINK_ATTR_DPIPE_HEADER_FIELDS);
2259 goto nla_put_failure;
2261 err = devlink_dpipe_fields_put(skb, header);
2263 nla_nest_cancel(skb, fields_attr);
2264 goto nla_put_failure;
2266 nla_nest_end(skb, fields_attr);
2267 nla_nest_end(skb, header_attr);
2272 nla_nest_cancel(skb, header_attr);
2276 static int devlink_dpipe_headers_fill(struct genl_info *info,
2277 enum devlink_command cmd, int flags,
2278 struct devlink_dpipe_headers *
2281 struct devlink *devlink = info->user_ptr[0];
2282 struct nlattr *headers_attr;
2283 struct sk_buff *skb = NULL;
2284 struct nlmsghdr *nlh;
2291 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2295 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
2296 &devlink_nl_family, NLM_F_MULTI, cmd);
2302 if (devlink_nl_put_handle(skb, devlink))
2303 goto nla_put_failure;
2304 headers_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADERS);
2306 goto nla_put_failure;
2309 for (; i < dpipe_headers->headers_count; i++) {
2310 err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]);
2318 nla_nest_end(skb, headers_attr);
2319 genlmsg_end(skb, hdr);
2320 if (i != dpipe_headers->headers_count)
2324 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
2325 NLMSG_DONE, 0, flags | NLM_F_MULTI);
2327 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2332 return genlmsg_reply(skb, info);
2341 static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb,
2342 struct genl_info *info)
2344 struct devlink *devlink = info->user_ptr[0];
2346 if (!devlink->dpipe_headers)
2348 return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET,
2349 0, devlink->dpipe_headers);
2352 static int devlink_dpipe_table_counters_set(struct devlink *devlink,
2353 const char *table_name,
2356 struct devlink_dpipe_table *table;
2358 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2363 if (table->counter_control_extern)
2366 if (!(table->counters_enabled ^ enable))
2369 table->counters_enabled = enable;
2370 if (table->table_ops->counters_set_update)
2371 table->table_ops->counters_set_update(table->priv, enable);
2375 static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb,
2376 struct genl_info *info)
2378 struct devlink *devlink = info->user_ptr[0];
2379 const char *table_name;
2380 bool counters_enable;
2382 if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME] ||
2383 !info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED])
2386 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
2387 counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]);
2389 return devlink_dpipe_table_counters_set(devlink, table_name,
2393 static struct devlink_resource *
2394 devlink_resource_find(struct devlink *devlink,
2395 struct devlink_resource *resource, u64 resource_id)
2397 struct list_head *resource_list;
2400 resource_list = &resource->resource_list;
2402 resource_list = &devlink->resource_list;
2404 list_for_each_entry(resource, resource_list, list) {
2405 struct devlink_resource *child_resource;
2407 if (resource->id == resource_id)
2410 child_resource = devlink_resource_find(devlink, resource,
2413 return child_resource;
2419 devlink_resource_validate_children(struct devlink_resource *resource)
2421 struct devlink_resource *child_resource;
2422 bool size_valid = true;
2425 if (list_empty(&resource->resource_list))
2428 list_for_each_entry(child_resource, &resource->resource_list, list)
2429 parts_size += child_resource->size_new;
2431 if (parts_size > resource->size_new)
2434 resource->size_valid = size_valid;
2438 devlink_resource_validate_size(struct devlink_resource *resource, u64 size,
2439 struct netlink_ext_ack *extack)
2444 if (size > resource->size_params.size_max) {
2445 NL_SET_ERR_MSG_MOD(extack, "Size larger than maximum");
2449 if (size < resource->size_params.size_min) {
2450 NL_SET_ERR_MSG_MOD(extack, "Size smaller than minimum");
2454 div64_u64_rem(size, resource->size_params.size_granularity, &reminder);
2456 NL_SET_ERR_MSG_MOD(extack, "Wrong granularity");
2463 static int devlink_nl_cmd_resource_set(struct sk_buff *skb,
2464 struct genl_info *info)
2466 struct devlink *devlink = info->user_ptr[0];
2467 struct devlink_resource *resource;
2472 if (!info->attrs[DEVLINK_ATTR_RESOURCE_ID] ||
2473 !info->attrs[DEVLINK_ATTR_RESOURCE_SIZE])
2475 resource_id = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_ID]);
2477 resource = devlink_resource_find(devlink, NULL, resource_id);
2481 size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]);
2482 err = devlink_resource_validate_size(resource, size, info->extack);
2486 resource->size_new = size;
2487 devlink_resource_validate_children(resource);
2488 if (resource->parent)
2489 devlink_resource_validate_children(resource->parent);
2494 devlink_resource_size_params_put(struct devlink_resource *resource,
2495 struct sk_buff *skb)
2497 struct devlink_resource_size_params *size_params;
2499 size_params = &resource->size_params;
2500 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_GRAN,
2501 size_params->size_granularity, DEVLINK_ATTR_PAD) ||
2502 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MAX,
2503 size_params->size_max, DEVLINK_ATTR_PAD) ||
2504 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MIN,
2505 size_params->size_min, DEVLINK_ATTR_PAD) ||
2506 nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_UNIT, size_params->unit))
2511 static int devlink_resource_occ_put(struct devlink_resource *resource,
2512 struct sk_buff *skb)
2514 if (!resource->occ_get)
2516 return nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_OCC,
2517 resource->occ_get(resource->occ_get_priv),
2521 static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb,
2522 struct devlink_resource *resource)
2524 struct devlink_resource *child_resource;
2525 struct nlattr *child_resource_attr;
2526 struct nlattr *resource_attr;
2528 resource_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_RESOURCE);
2532 if (nla_put_string(skb, DEVLINK_ATTR_RESOURCE_NAME, resource->name) ||
2533 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE, resource->size,
2534 DEVLINK_ATTR_PAD) ||
2535 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_ID, resource->id,
2537 goto nla_put_failure;
2538 if (resource->size != resource->size_new)
2539 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_NEW,
2540 resource->size_new, DEVLINK_ATTR_PAD);
2541 if (devlink_resource_occ_put(resource, skb))
2542 goto nla_put_failure;
2543 if (devlink_resource_size_params_put(resource, skb))
2544 goto nla_put_failure;
2545 if (list_empty(&resource->resource_list))
2548 if (nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_SIZE_VALID,
2549 resource->size_valid))
2550 goto nla_put_failure;
2552 child_resource_attr = nla_nest_start_noflag(skb,
2553 DEVLINK_ATTR_RESOURCE_LIST);
2554 if (!child_resource_attr)
2555 goto nla_put_failure;
2557 list_for_each_entry(child_resource, &resource->resource_list, list) {
2558 if (devlink_resource_put(devlink, skb, child_resource))
2559 goto resource_put_failure;
2562 nla_nest_end(skb, child_resource_attr);
2564 nla_nest_end(skb, resource_attr);
2567 resource_put_failure:
2568 nla_nest_cancel(skb, child_resource_attr);
2570 nla_nest_cancel(skb, resource_attr);
2574 static int devlink_resource_fill(struct genl_info *info,
2575 enum devlink_command cmd, int flags)
2577 struct devlink *devlink = info->user_ptr[0];
2578 struct devlink_resource *resource;
2579 struct nlattr *resources_attr;
2580 struct sk_buff *skb = NULL;
2581 struct nlmsghdr *nlh;
2587 resource = list_first_entry(&devlink->resource_list,
2588 struct devlink_resource, list);
2590 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2594 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
2595 &devlink_nl_family, NLM_F_MULTI, cmd);
2601 if (devlink_nl_put_handle(skb, devlink))
2602 goto nla_put_failure;
2604 resources_attr = nla_nest_start_noflag(skb,
2605 DEVLINK_ATTR_RESOURCE_LIST);
2606 if (!resources_attr)
2607 goto nla_put_failure;
2611 list_for_each_entry_from(resource, &devlink->resource_list, list) {
2612 err = devlink_resource_put(devlink, skb, resource);
2615 goto err_resource_put;
2621 nla_nest_end(skb, resources_attr);
2622 genlmsg_end(skb, hdr);
2626 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
2627 NLMSG_DONE, 0, flags | NLM_F_MULTI);
2629 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2634 return genlmsg_reply(skb, info);
2643 static int devlink_nl_cmd_resource_dump(struct sk_buff *skb,
2644 struct genl_info *info)
2646 struct devlink *devlink = info->user_ptr[0];
2648 if (list_empty(&devlink->resource_list))
2651 return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0);
2655 devlink_resources_validate(struct devlink *devlink,
2656 struct devlink_resource *resource,
2657 struct genl_info *info)
2659 struct list_head *resource_list;
2663 resource_list = &resource->resource_list;
2665 resource_list = &devlink->resource_list;
2667 list_for_each_entry(resource, resource_list, list) {
2668 if (!resource->size_valid)
2670 err = devlink_resources_validate(devlink, resource, info);
2677 static bool devlink_reload_supported(struct devlink *devlink)
2679 return devlink->ops->reload_down && devlink->ops->reload_up;
2682 static void devlink_reload_failed_set(struct devlink *devlink,
2685 if (devlink->reload_failed == reload_failed)
2687 devlink->reload_failed = reload_failed;
2688 devlink_notify(devlink, DEVLINK_CMD_NEW);
2691 bool devlink_is_reload_failed(const struct devlink *devlink)
2693 return devlink->reload_failed;
2695 EXPORT_SYMBOL_GPL(devlink_is_reload_failed);
2697 static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
2699 struct devlink *devlink = info->user_ptr[0];
2702 if (!devlink_reload_supported(devlink))
2705 err = devlink_resources_validate(devlink, NULL, info);
2707 NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed");
2710 err = devlink->ops->reload_down(devlink, info->extack);
2713 err = devlink->ops->reload_up(devlink, info->extack);
2714 devlink_reload_failed_set(devlink, !!err);
2718 static int devlink_nl_flash_update_fill(struct sk_buff *msg,
2719 struct devlink *devlink,
2720 enum devlink_command cmd,
2721 const char *status_msg,
2722 const char *component,
2723 unsigned long done, unsigned long total)
2727 hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd);
2731 if (devlink_nl_put_handle(msg, devlink))
2732 goto nla_put_failure;
2734 if (cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS)
2738 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG,
2740 goto nla_put_failure;
2742 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT,
2744 goto nla_put_failure;
2745 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE,
2746 done, DEVLINK_ATTR_PAD))
2747 goto nla_put_failure;
2748 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL,
2749 total, DEVLINK_ATTR_PAD))
2750 goto nla_put_failure;
2753 genlmsg_end(msg, hdr);
2757 genlmsg_cancel(msg, hdr);
2761 static void __devlink_flash_update_notify(struct devlink *devlink,
2762 enum devlink_command cmd,
2763 const char *status_msg,
2764 const char *component,
2766 unsigned long total)
2768 struct sk_buff *msg;
2771 WARN_ON(cmd != DEVLINK_CMD_FLASH_UPDATE &&
2772 cmd != DEVLINK_CMD_FLASH_UPDATE_END &&
2773 cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS);
2775 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2779 err = devlink_nl_flash_update_fill(msg, devlink, cmd, status_msg,
2780 component, done, total);
2784 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
2785 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
2792 void devlink_flash_update_begin_notify(struct devlink *devlink)
2794 __devlink_flash_update_notify(devlink,
2795 DEVLINK_CMD_FLASH_UPDATE,
2798 EXPORT_SYMBOL_GPL(devlink_flash_update_begin_notify);
2800 void devlink_flash_update_end_notify(struct devlink *devlink)
2802 __devlink_flash_update_notify(devlink,
2803 DEVLINK_CMD_FLASH_UPDATE_END,
2806 EXPORT_SYMBOL_GPL(devlink_flash_update_end_notify);
2808 void devlink_flash_update_status_notify(struct devlink *devlink,
2809 const char *status_msg,
2810 const char *component,
2812 unsigned long total)
2814 __devlink_flash_update_notify(devlink,
2815 DEVLINK_CMD_FLASH_UPDATE_STATUS,
2816 status_msg, component, done, total);
2818 EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify);
2820 static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
2821 struct genl_info *info)
2823 struct devlink *devlink = info->user_ptr[0];
2824 const char *file_name, *component;
2825 struct nlattr *nla_component;
2827 if (!devlink->ops->flash_update)
2830 if (!info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME])
2832 file_name = nla_data(info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]);
2834 nla_component = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT];
2835 component = nla_component ? nla_data(nla_component) : NULL;
2837 return devlink->ops->flash_update(devlink, file_name, component,
2841 static const struct devlink_param devlink_param_generic[] = {
2843 .id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET,
2844 .name = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME,
2845 .type = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE,
2848 .id = DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
2849 .name = DEVLINK_PARAM_GENERIC_MAX_MACS_NAME,
2850 .type = DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE,
2853 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV,
2854 .name = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME,
2855 .type = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE,
2858 .id = DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT,
2859 .name = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME,
2860 .type = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE,
2863 .id = DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI,
2864 .name = DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME,
2865 .type = DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE,
2868 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX,
2869 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME,
2870 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE,
2873 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN,
2874 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME,
2875 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE,
2878 .id = DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY,
2879 .name = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME,
2880 .type = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE,
2883 .id = DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE,
2884 .name = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME,
2885 .type = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE,
2889 static int devlink_param_generic_verify(const struct devlink_param *param)
2891 /* verify it match generic parameter by id and name */
2892 if (param->id > DEVLINK_PARAM_GENERIC_ID_MAX)
2894 if (strcmp(param->name, devlink_param_generic[param->id].name))
2897 WARN_ON(param->type != devlink_param_generic[param->id].type);
2902 static int devlink_param_driver_verify(const struct devlink_param *param)
2906 if (param->id <= DEVLINK_PARAM_GENERIC_ID_MAX)
2908 /* verify no such name in generic params */
2909 for (i = 0; i <= DEVLINK_PARAM_GENERIC_ID_MAX; i++)
2910 if (!strcmp(param->name, devlink_param_generic[i].name))
2916 static struct devlink_param_item *
2917 devlink_param_find_by_name(struct list_head *param_list,
2918 const char *param_name)
2920 struct devlink_param_item *param_item;
2922 list_for_each_entry(param_item, param_list, list)
2923 if (!strcmp(param_item->param->name, param_name))
2928 static struct devlink_param_item *
2929 devlink_param_find_by_id(struct list_head *param_list, u32 param_id)
2931 struct devlink_param_item *param_item;
2933 list_for_each_entry(param_item, param_list, list)
2934 if (param_item->param->id == param_id)
2940 devlink_param_cmode_is_supported(const struct devlink_param *param,
2941 enum devlink_param_cmode cmode)
2943 return test_bit(cmode, ¶m->supported_cmodes);
2946 static int devlink_param_get(struct devlink *devlink,
2947 const struct devlink_param *param,
2948 struct devlink_param_gset_ctx *ctx)
2952 return param->get(devlink, param->id, ctx);
2955 static int devlink_param_set(struct devlink *devlink,
2956 const struct devlink_param *param,
2957 struct devlink_param_gset_ctx *ctx)
2961 return param->set(devlink, param->id, ctx);
2965 devlink_param_type_to_nla_type(enum devlink_param_type param_type)
2967 switch (param_type) {
2968 case DEVLINK_PARAM_TYPE_U8:
2970 case DEVLINK_PARAM_TYPE_U16:
2972 case DEVLINK_PARAM_TYPE_U32:
2974 case DEVLINK_PARAM_TYPE_STRING:
2976 case DEVLINK_PARAM_TYPE_BOOL:
2984 devlink_nl_param_value_fill_one(struct sk_buff *msg,
2985 enum devlink_param_type type,
2986 enum devlink_param_cmode cmode,
2987 union devlink_param_value val)
2989 struct nlattr *param_value_attr;
2991 param_value_attr = nla_nest_start_noflag(msg,
2992 DEVLINK_ATTR_PARAM_VALUE);
2993 if (!param_value_attr)
2994 goto nla_put_failure;
2996 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode))
2997 goto value_nest_cancel;
3000 case DEVLINK_PARAM_TYPE_U8:
3001 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu8))
3002 goto value_nest_cancel;
3004 case DEVLINK_PARAM_TYPE_U16:
3005 if (nla_put_u16(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu16))
3006 goto value_nest_cancel;
3008 case DEVLINK_PARAM_TYPE_U32:
3009 if (nla_put_u32(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu32))
3010 goto value_nest_cancel;
3012 case DEVLINK_PARAM_TYPE_STRING:
3013 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_VALUE_DATA,
3015 goto value_nest_cancel;
3017 case DEVLINK_PARAM_TYPE_BOOL:
3019 nla_put_flag(msg, DEVLINK_ATTR_PARAM_VALUE_DATA))
3020 goto value_nest_cancel;
3024 nla_nest_end(msg, param_value_attr);
3028 nla_nest_cancel(msg, param_value_attr);
3033 static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
3034 unsigned int port_index,
3035 struct devlink_param_item *param_item,
3036 enum devlink_command cmd,
3037 u32 portid, u32 seq, int flags)
3039 union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1];
3040 bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {};
3041 const struct devlink_param *param = param_item->param;
3042 struct devlink_param_gset_ctx ctx;
3043 struct nlattr *param_values_list;
3044 struct nlattr *param_attr;
3050 /* Get value from driver part to driverinit configuration mode */
3051 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
3052 if (!devlink_param_cmode_is_supported(param, i))
3054 if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) {
3055 if (!param_item->driverinit_value_valid)
3057 param_value[i] = param_item->driverinit_value;
3059 if (!param_item->published)
3062 err = devlink_param_get(devlink, param, &ctx);
3065 param_value[i] = ctx.val;
3067 param_value_set[i] = true;
3070 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
3074 if (devlink_nl_put_handle(msg, devlink))
3075 goto genlmsg_cancel;
3077 if (cmd == DEVLINK_CMD_PORT_PARAM_GET ||
3078 cmd == DEVLINK_CMD_PORT_PARAM_NEW ||
3079 cmd == DEVLINK_CMD_PORT_PARAM_DEL)
3080 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index))
3081 goto genlmsg_cancel;
3083 param_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PARAM);
3085 goto genlmsg_cancel;
3086 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_NAME, param->name))
3087 goto param_nest_cancel;
3088 if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC))
3089 goto param_nest_cancel;
3091 nla_type = devlink_param_type_to_nla_type(param->type);
3093 goto param_nest_cancel;
3094 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, nla_type))
3095 goto param_nest_cancel;
3097 param_values_list = nla_nest_start_noflag(msg,
3098 DEVLINK_ATTR_PARAM_VALUES_LIST);
3099 if (!param_values_list)
3100 goto param_nest_cancel;
3102 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
3103 if (!param_value_set[i])
3105 err = devlink_nl_param_value_fill_one(msg, param->type,
3108 goto values_list_nest_cancel;
3111 nla_nest_end(msg, param_values_list);
3112 nla_nest_end(msg, param_attr);
3113 genlmsg_end(msg, hdr);
3116 values_list_nest_cancel:
3117 nla_nest_end(msg, param_values_list);
3119 nla_nest_cancel(msg, param_attr);
3121 genlmsg_cancel(msg, hdr);
3125 static void devlink_param_notify(struct devlink *devlink,
3126 unsigned int port_index,
3127 struct devlink_param_item *param_item,
3128 enum devlink_command cmd)
3130 struct sk_buff *msg;
3133 WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL &&
3134 cmd != DEVLINK_CMD_PORT_PARAM_NEW &&
3135 cmd != DEVLINK_CMD_PORT_PARAM_DEL);
3137 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3140 err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd,
3147 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
3148 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
3151 static int devlink_nl_cmd_param_get_dumpit(struct sk_buff *msg,
3152 struct netlink_callback *cb)
3154 struct devlink_param_item *param_item;
3155 struct devlink *devlink;
3156 int start = cb->args[0];
3160 mutex_lock(&devlink_mutex);
3161 list_for_each_entry(devlink, &devlink_list, list) {
3162 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
3164 mutex_lock(&devlink->lock);
3165 list_for_each_entry(param_item, &devlink->param_list, list) {
3170 err = devlink_nl_param_fill(msg, devlink, 0, param_item,
3171 DEVLINK_CMD_PARAM_GET,
3172 NETLINK_CB(cb->skb).portid,
3176 mutex_unlock(&devlink->lock);
3181 mutex_unlock(&devlink->lock);
3184 mutex_unlock(&devlink_mutex);
3191 devlink_param_type_get_from_info(struct genl_info *info,
3192 enum devlink_param_type *param_type)
3194 if (!info->attrs[DEVLINK_ATTR_PARAM_TYPE])
3197 switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) {
3199 *param_type = DEVLINK_PARAM_TYPE_U8;
3202 *param_type = DEVLINK_PARAM_TYPE_U16;
3205 *param_type = DEVLINK_PARAM_TYPE_U32;
3208 *param_type = DEVLINK_PARAM_TYPE_STRING;
3211 *param_type = DEVLINK_PARAM_TYPE_BOOL;
3221 devlink_param_value_get_from_info(const struct devlink_param *param,
3222 struct genl_info *info,
3223 union devlink_param_value *value)
3227 if (param->type != DEVLINK_PARAM_TYPE_BOOL &&
3228 !info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA])
3231 switch (param->type) {
3232 case DEVLINK_PARAM_TYPE_U8:
3233 value->vu8 = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]);
3235 case DEVLINK_PARAM_TYPE_U16:
3236 value->vu16 = nla_get_u16(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]);
3238 case DEVLINK_PARAM_TYPE_U32:
3239 value->vu32 = nla_get_u32(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]);
3241 case DEVLINK_PARAM_TYPE_STRING:
3242 len = strnlen(nla_data(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]),
3243 nla_len(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]));
3244 if (len == nla_len(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]) ||
3245 len >= __DEVLINK_PARAM_MAX_STRING_VALUE)
3248 nla_data(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]));
3250 case DEVLINK_PARAM_TYPE_BOOL:
3251 value->vbool = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA] ?
3258 static struct devlink_param_item *
3259 devlink_param_get_from_info(struct list_head *param_list,
3260 struct genl_info *info)
3264 if (!info->attrs[DEVLINK_ATTR_PARAM_NAME])
3267 param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]);
3268 return devlink_param_find_by_name(param_list, param_name);
3271 static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb,
3272 struct genl_info *info)
3274 struct devlink *devlink = info->user_ptr[0];
3275 struct devlink_param_item *param_item;
3276 struct sk_buff *msg;
3279 param_item = devlink_param_get_from_info(&devlink->param_list, info);
3283 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3287 err = devlink_nl_param_fill(msg, devlink, 0, param_item,
3288 DEVLINK_CMD_PARAM_GET,
3289 info->snd_portid, info->snd_seq, 0);
3295 return genlmsg_reply(msg, info);
3298 static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink,
3299 unsigned int port_index,
3300 struct list_head *param_list,
3301 struct genl_info *info,
3302 enum devlink_command cmd)
3304 enum devlink_param_type param_type;
3305 struct devlink_param_gset_ctx ctx;
3306 enum devlink_param_cmode cmode;
3307 struct devlink_param_item *param_item;
3308 const struct devlink_param *param;
3309 union devlink_param_value value;
3312 param_item = devlink_param_get_from_info(param_list, info);
3315 param = param_item->param;
3316 err = devlink_param_type_get_from_info(info, ¶m_type);
3319 if (param_type != param->type)
3321 err = devlink_param_value_get_from_info(param, info, &value);
3324 if (param->validate) {
3325 err = param->validate(devlink, param->id, value, info->extack);
3330 if (!info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE])
3332 cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]);
3333 if (!devlink_param_cmode_is_supported(param, cmode))
3336 if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) {
3337 if (param->type == DEVLINK_PARAM_TYPE_STRING)
3338 strcpy(param_item->driverinit_value.vstr, value.vstr);
3340 param_item->driverinit_value = value;
3341 param_item->driverinit_value_valid = true;
3347 err = devlink_param_set(devlink, param, &ctx);
3352 devlink_param_notify(devlink, port_index, param_item, cmd);
3356 static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb,
3357 struct genl_info *info)
3359 struct devlink *devlink = info->user_ptr[0];
3361 return __devlink_nl_cmd_param_set_doit(devlink, 0, &devlink->param_list,
3362 info, DEVLINK_CMD_PARAM_NEW);
3365 static int devlink_param_register_one(struct devlink *devlink,
3366 unsigned int port_index,
3367 struct list_head *param_list,
3368 const struct devlink_param *param,
3369 enum devlink_command cmd)
3371 struct devlink_param_item *param_item;
3373 if (devlink_param_find_by_name(param_list, param->name))
3376 if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT))
3377 WARN_ON(param->get || param->set);
3379 WARN_ON(!param->get || !param->set);
3381 param_item = kzalloc(sizeof(*param_item), GFP_KERNEL);
3384 param_item->param = param;
3386 list_add_tail(¶m_item->list, param_list);
3387 devlink_param_notify(devlink, port_index, param_item, cmd);
3391 static void devlink_param_unregister_one(struct devlink *devlink,
3392 unsigned int port_index,
3393 struct list_head *param_list,
3394 const struct devlink_param *param,
3395 enum devlink_command cmd)
3397 struct devlink_param_item *param_item;
3399 param_item = devlink_param_find_by_name(param_list, param->name);
3400 WARN_ON(!param_item);
3401 devlink_param_notify(devlink, port_index, param_item, cmd);
3402 list_del(¶m_item->list);
3406 static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg,
3407 struct netlink_callback *cb)
3409 struct devlink_param_item *param_item;
3410 struct devlink_port *devlink_port;
3411 struct devlink *devlink;
3412 int start = cb->args[0];
3416 mutex_lock(&devlink_mutex);
3417 list_for_each_entry(devlink, &devlink_list, list) {
3418 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
3420 mutex_lock(&devlink->lock);
3421 list_for_each_entry(devlink_port, &devlink->port_list, list) {
3422 list_for_each_entry(param_item,
3423 &devlink_port->param_list, list) {
3428 err = devlink_nl_param_fill(msg,
3429 devlink_port->devlink,
3430 devlink_port->index, param_item,
3431 DEVLINK_CMD_PORT_PARAM_GET,
3432 NETLINK_CB(cb->skb).portid,
3436 mutex_unlock(&devlink->lock);
3442 mutex_unlock(&devlink->lock);
3445 mutex_unlock(&devlink_mutex);
3451 static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb,
3452 struct genl_info *info)
3454 struct devlink_port *devlink_port = info->user_ptr[0];
3455 struct devlink_param_item *param_item;
3456 struct sk_buff *msg;
3459 param_item = devlink_param_get_from_info(&devlink_port->param_list,
3464 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3468 err = devlink_nl_param_fill(msg, devlink_port->devlink,
3469 devlink_port->index, param_item,
3470 DEVLINK_CMD_PORT_PARAM_GET,
3471 info->snd_portid, info->snd_seq, 0);
3477 return genlmsg_reply(msg, info);
3480 static int devlink_nl_cmd_port_param_set_doit(struct sk_buff *skb,
3481 struct genl_info *info)
3483 struct devlink_port *devlink_port = info->user_ptr[0];
3485 return __devlink_nl_cmd_param_set_doit(devlink_port->devlink,
3486 devlink_port->index,
3487 &devlink_port->param_list, info,
3488 DEVLINK_CMD_PORT_PARAM_NEW);
3491 static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg,
3492 struct devlink *devlink,
3493 struct devlink_snapshot *snapshot)
3495 struct nlattr *snap_attr;
3498 snap_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_SNAPSHOT);
3502 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, snapshot->id);
3504 goto nla_put_failure;
3506 nla_nest_end(msg, snap_attr);
3510 nla_nest_cancel(msg, snap_attr);
3514 static int devlink_nl_region_snapshots_id_put(struct sk_buff *msg,
3515 struct devlink *devlink,
3516 struct devlink_region *region)
3518 struct devlink_snapshot *snapshot;
3519 struct nlattr *snapshots_attr;
3522 snapshots_attr = nla_nest_start_noflag(msg,
3523 DEVLINK_ATTR_REGION_SNAPSHOTS);
3524 if (!snapshots_attr)
3527 list_for_each_entry(snapshot, ®ion->snapshot_list, list) {
3528 err = devlink_nl_region_snapshot_id_put(msg, devlink, snapshot);
3530 goto nla_put_failure;
3533 nla_nest_end(msg, snapshots_attr);
3537 nla_nest_cancel(msg, snapshots_attr);
3541 static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink,
3542 enum devlink_command cmd, u32 portid,
3544 struct devlink_region *region)
3549 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
3553 err = devlink_nl_put_handle(msg, devlink);
3555 goto nla_put_failure;
3557 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->name);
3559 goto nla_put_failure;
3561 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
3565 goto nla_put_failure;
3567 err = devlink_nl_region_snapshots_id_put(msg, devlink, region);
3569 goto nla_put_failure;
3571 genlmsg_end(msg, hdr);
3575 genlmsg_cancel(msg, hdr);
3579 static void devlink_nl_region_notify(struct devlink_region *region,
3580 struct devlink_snapshot *snapshot,
3581 enum devlink_command cmd)
3583 struct devlink *devlink = region->devlink;
3584 struct sk_buff *msg;
3588 WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL);
3590 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3594 hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd);
3598 err = devlink_nl_put_handle(msg, devlink);
3600 goto out_cancel_msg;
3602 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME,
3605 goto out_cancel_msg;
3608 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID,
3611 goto out_cancel_msg;
3613 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
3614 region->size, DEVLINK_ATTR_PAD);
3616 goto out_cancel_msg;
3618 genlmsg_end(msg, hdr);
3620 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
3621 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
3626 genlmsg_cancel(msg, hdr);
3631 static void devlink_region_snapshot_del(struct devlink_region *region,
3632 struct devlink_snapshot *snapshot)
3634 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL);
3635 region->cur_snapshots--;
3636 list_del(&snapshot->list);
3637 (*snapshot->data_destructor)(snapshot->data);
3641 static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb,
3642 struct genl_info *info)
3644 struct devlink *devlink = info->user_ptr[0];
3645 struct devlink_region *region;
3646 const char *region_name;
3647 struct sk_buff *msg;
3650 if (!info->attrs[DEVLINK_ATTR_REGION_NAME])
3653 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
3654 region = devlink_region_get_by_name(devlink, region_name);
3658 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3662 err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET,
3663 info->snd_portid, info->snd_seq, 0,
3670 return genlmsg_reply(msg, info);
3673 static int devlink_nl_cmd_region_get_dumpit(struct sk_buff *msg,
3674 struct netlink_callback *cb)
3676 struct devlink_region *region;
3677 struct devlink *devlink;
3678 int start = cb->args[0];
3682 mutex_lock(&devlink_mutex);
3683 list_for_each_entry(devlink, &devlink_list, list) {
3684 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
3687 mutex_lock(&devlink->lock);
3688 list_for_each_entry(region, &devlink->region_list, list) {
3693 err = devlink_nl_region_fill(msg, devlink,
3694 DEVLINK_CMD_REGION_GET,
3695 NETLINK_CB(cb->skb).portid,
3697 NLM_F_MULTI, region);
3699 mutex_unlock(&devlink->lock);
3704 mutex_unlock(&devlink->lock);
3707 mutex_unlock(&devlink_mutex);
3712 static int devlink_nl_cmd_region_del(struct sk_buff *skb,
3713 struct genl_info *info)
3715 struct devlink *devlink = info->user_ptr[0];
3716 struct devlink_snapshot *snapshot;
3717 struct devlink_region *region;
3718 const char *region_name;
3721 if (!info->attrs[DEVLINK_ATTR_REGION_NAME] ||
3722 !info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID])
3725 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
3726 snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
3728 region = devlink_region_get_by_name(devlink, region_name);
3732 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
3736 devlink_region_snapshot_del(region, snapshot);
3740 static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg,
3741 struct devlink *devlink,
3742 u8 *chunk, u32 chunk_size,
3745 struct nlattr *chunk_attr;
3748 chunk_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_CHUNK);
3752 err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk);
3754 goto nla_put_failure;
3756 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr,
3759 goto nla_put_failure;
3761 nla_nest_end(msg, chunk_attr);
3765 nla_nest_cancel(msg, chunk_attr);
3769 #define DEVLINK_REGION_READ_CHUNK_SIZE 256
3771 static int devlink_nl_region_read_snapshot_fill(struct sk_buff *skb,
3772 struct devlink *devlink,
3773 struct devlink_region *region,
3774 struct nlattr **attrs,
3780 struct devlink_snapshot *snapshot;
3781 u64 curr_offset = start_offset;
3785 *new_offset = start_offset;
3787 snapshot_id = nla_get_u32(attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
3788 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
3792 if (end_offset > region->size || dump)
3793 end_offset = region->size;
3795 while (curr_offset < end_offset) {
3799 if (end_offset - curr_offset < DEVLINK_REGION_READ_CHUNK_SIZE)
3800 data_size = end_offset - curr_offset;
3802 data_size = DEVLINK_REGION_READ_CHUNK_SIZE;
3804 data = &snapshot->data[curr_offset];
3805 err = devlink_nl_cmd_region_read_chunk_fill(skb, devlink,
3811 curr_offset += data_size;
3813 *new_offset = curr_offset;
3818 static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
3819 struct netlink_callback *cb)
3821 u64 ret_offset, start_offset, end_offset = 0;
3822 struct devlink_region *region;
3823 struct nlattr *chunks_attr;
3824 const char *region_name;
3825 struct devlink *devlink;
3826 struct nlattr **attrs;
3831 start_offset = *((u64 *)&cb->args[0]);
3833 attrs = kmalloc_array(DEVLINK_ATTR_MAX + 1, sizeof(*attrs), GFP_KERNEL);
3837 err = nlmsg_parse_deprecated(cb->nlh,
3838 GENL_HDRLEN + devlink_nl_family.hdrsize,
3839 attrs, DEVLINK_ATTR_MAX,
3840 devlink_nl_family.policy, cb->extack);
3844 mutex_lock(&devlink_mutex);
3845 devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs);
3846 if (IS_ERR(devlink)) {
3847 err = PTR_ERR(devlink);
3851 mutex_lock(&devlink->lock);
3853 if (!attrs[DEVLINK_ATTR_REGION_NAME] ||
3854 !attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]) {
3859 region_name = nla_data(attrs[DEVLINK_ATTR_REGION_NAME]);
3860 region = devlink_region_get_by_name(devlink, region_name);
3866 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
3867 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI,
3868 DEVLINK_CMD_REGION_READ);
3874 err = devlink_nl_put_handle(skb, devlink);
3876 goto nla_put_failure;
3878 err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name);
3880 goto nla_put_failure;
3882 chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS);
3885 goto nla_put_failure;
3888 if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] &&
3889 attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) {
3892 nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
3894 end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
3895 end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]);
3899 err = devlink_nl_region_read_snapshot_fill(skb, devlink,
3905 if (err && err != -EMSGSIZE)
3906 goto nla_put_failure;
3908 /* Check if there was any progress done to prevent infinite loop */
3909 if (ret_offset == start_offset) {
3911 goto nla_put_failure;
3914 *((u64 *)&cb->args[0]) = ret_offset;
3916 nla_nest_end(skb, chunks_attr);
3917 genlmsg_end(skb, hdr);
3918 mutex_unlock(&devlink->lock);
3919 mutex_unlock(&devlink_mutex);
3925 genlmsg_cancel(skb, hdr);
3927 mutex_unlock(&devlink->lock);
3929 mutex_unlock(&devlink_mutex);
3935 struct devlink_info_req {
3936 struct sk_buff *msg;
3939 int devlink_info_driver_name_put(struct devlink_info_req *req, const char *name)
3941 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME, name);
3943 EXPORT_SYMBOL_GPL(devlink_info_driver_name_put);
3945 int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn)
3947 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn);
3949 EXPORT_SYMBOL_GPL(devlink_info_serial_number_put);
3951 static int devlink_info_version_put(struct devlink_info_req *req, int attr,
3952 const char *version_name,
3953 const char *version_value)
3955 struct nlattr *nest;
3958 nest = nla_nest_start_noflag(req->msg, attr);
3962 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME,
3965 goto nla_put_failure;
3967 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE,
3970 goto nla_put_failure;
3972 nla_nest_end(req->msg, nest);
3977 nla_nest_cancel(req->msg, nest);
3981 int devlink_info_version_fixed_put(struct devlink_info_req *req,
3982 const char *version_name,
3983 const char *version_value)
3985 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED,
3986 version_name, version_value);
3988 EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put);
3990 int devlink_info_version_stored_put(struct devlink_info_req *req,
3991 const char *version_name,
3992 const char *version_value)
3994 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED,
3995 version_name, version_value);
3997 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put);
3999 int devlink_info_version_running_put(struct devlink_info_req *req,
4000 const char *version_name,
4001 const char *version_value)
4003 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING,
4004 version_name, version_value);
4006 EXPORT_SYMBOL_GPL(devlink_info_version_running_put);
4009 devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
4010 enum devlink_command cmd, u32 portid,
4011 u32 seq, int flags, struct netlink_ext_ack *extack)
4013 struct devlink_info_req req;
4017 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
4022 if (devlink_nl_put_handle(msg, devlink))
4023 goto err_cancel_msg;
4026 err = devlink->ops->info_get(devlink, &req, extack);
4028 goto err_cancel_msg;
4030 genlmsg_end(msg, hdr);
4034 genlmsg_cancel(msg, hdr);
4038 static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb,
4039 struct genl_info *info)
4041 struct devlink *devlink = info->user_ptr[0];
4042 struct sk_buff *msg;
4045 if (!devlink->ops->info_get)
4048 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4052 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
4053 info->snd_portid, info->snd_seq, 0,
4060 return genlmsg_reply(msg, info);
4063 static int devlink_nl_cmd_info_get_dumpit(struct sk_buff *msg,
4064 struct netlink_callback *cb)
4066 struct devlink *devlink;
4067 int start = cb->args[0];
4071 mutex_lock(&devlink_mutex);
4072 list_for_each_entry(devlink, &devlink_list, list) {
4073 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
4080 if (!devlink->ops->info_get) {
4085 mutex_lock(&devlink->lock);
4086 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
4087 NETLINK_CB(cb->skb).portid,
4088 cb->nlh->nlmsg_seq, NLM_F_MULTI,
4090 mutex_unlock(&devlink->lock);
4095 mutex_unlock(&devlink_mutex);
4101 struct devlink_fmsg_item {
4102 struct list_head list;
4109 struct devlink_fmsg {
4110 struct list_head item_list;
4113 static struct devlink_fmsg *devlink_fmsg_alloc(void)
4115 struct devlink_fmsg *fmsg;
4117 fmsg = kzalloc(sizeof(*fmsg), GFP_KERNEL);
4121 INIT_LIST_HEAD(&fmsg->item_list);
4126 static void devlink_fmsg_free(struct devlink_fmsg *fmsg)
4128 struct devlink_fmsg_item *item, *tmp;
4130 list_for_each_entry_safe(item, tmp, &fmsg->item_list, list) {
4131 list_del(&item->list);
4137 static int devlink_fmsg_nest_common(struct devlink_fmsg *fmsg,
4140 struct devlink_fmsg_item *item;
4142 item = kzalloc(sizeof(*item), GFP_KERNEL);
4146 item->attrtype = attrtype;
4147 list_add_tail(&item->list, &fmsg->item_list);
4152 int devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg)
4154 return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_OBJ_NEST_START);
4156 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start);
4158 static int devlink_fmsg_nest_end(struct devlink_fmsg *fmsg)
4160 return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_NEST_END);
4163 int devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg)
4165 return devlink_fmsg_nest_end(fmsg);
4167 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end);
4169 #define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN)
4171 static int devlink_fmsg_put_name(struct devlink_fmsg *fmsg, const char *name)
4173 struct devlink_fmsg_item *item;
4175 if (strlen(name) + 1 > DEVLINK_FMSG_MAX_SIZE)
4178 item = kzalloc(sizeof(*item) + strlen(name) + 1, GFP_KERNEL);
4182 item->nla_type = NLA_NUL_STRING;
4183 item->len = strlen(name) + 1;
4184 item->attrtype = DEVLINK_ATTR_FMSG_OBJ_NAME;
4185 memcpy(&item->value, name, item->len);
4186 list_add_tail(&item->list, &fmsg->item_list);
4191 int devlink_fmsg_pair_nest_start(struct devlink_fmsg *fmsg, const char *name)
4195 err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_PAIR_NEST_START);
4199 err = devlink_fmsg_put_name(fmsg, name);
4205 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start);
4207 int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg)
4209 return devlink_fmsg_nest_end(fmsg);
4211 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end);
4213 int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg,
4218 err = devlink_fmsg_pair_nest_start(fmsg, name);
4222 err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_ARR_NEST_START);
4228 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start);
4230 int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg)
4234 err = devlink_fmsg_nest_end(fmsg);
4238 err = devlink_fmsg_nest_end(fmsg);
4244 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end);
4246 static int devlink_fmsg_put_value(struct devlink_fmsg *fmsg,
4247 const void *value, u16 value_len,
4250 struct devlink_fmsg_item *item;
4252 if (value_len > DEVLINK_FMSG_MAX_SIZE)
4255 item = kzalloc(sizeof(*item) + value_len, GFP_KERNEL);
4259 item->nla_type = value_nla_type;
4260 item->len = value_len;
4261 item->attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
4262 memcpy(&item->value, value, item->len);
4263 list_add_tail(&item->list, &fmsg->item_list);
4268 int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value)
4270 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_FLAG);
4272 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_put);
4274 int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value)
4276 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U8);
4278 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_put);
4280 int devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value)
4282 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U32);
4284 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put);
4286 int devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value)
4288 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U64);
4290 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_put);
4292 int devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value)
4294 return devlink_fmsg_put_value(fmsg, value, strlen(value) + 1,
4297 EXPORT_SYMBOL_GPL(devlink_fmsg_string_put);
4299 int devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value,
4302 return devlink_fmsg_put_value(fmsg, value, value_len, NLA_BINARY);
4304 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put);
4306 int devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name,
4311 err = devlink_fmsg_pair_nest_start(fmsg, name);
4315 err = devlink_fmsg_bool_put(fmsg, value);
4319 err = devlink_fmsg_pair_nest_end(fmsg);
4325 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put);
4327 int devlink_fmsg_u8_pair_put(struct devlink_fmsg *fmsg, const char *name,
4332 err = devlink_fmsg_pair_nest_start(fmsg, name);
4336 err = devlink_fmsg_u8_put(fmsg, value);
4340 err = devlink_fmsg_pair_nest_end(fmsg);
4346 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put);
4348 int devlink_fmsg_u32_pair_put(struct devlink_fmsg *fmsg, const char *name,
4353 err = devlink_fmsg_pair_nest_start(fmsg, name);
4357 err = devlink_fmsg_u32_put(fmsg, value);
4361 err = devlink_fmsg_pair_nest_end(fmsg);
4367 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put);
4369 int devlink_fmsg_u64_pair_put(struct devlink_fmsg *fmsg, const char *name,
4374 err = devlink_fmsg_pair_nest_start(fmsg, name);
4378 err = devlink_fmsg_u64_put(fmsg, value);
4382 err = devlink_fmsg_pair_nest_end(fmsg);
4388 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put);
4390 int devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name,
4395 err = devlink_fmsg_pair_nest_start(fmsg, name);
4399 err = devlink_fmsg_string_put(fmsg, value);
4403 err = devlink_fmsg_pair_nest_end(fmsg);
4409 EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put);
4411 int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name,
4412 const void *value, u16 value_len)
4416 err = devlink_fmsg_pair_nest_start(fmsg, name);
4420 err = devlink_fmsg_binary_put(fmsg, value, value_len);
4424 err = devlink_fmsg_pair_nest_end(fmsg);
4430 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put);
4433 devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb)
4435 switch (msg->nla_type) {
4440 case NLA_NUL_STRING:
4442 return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE,
4450 devlink_fmsg_item_fill_data(struct devlink_fmsg_item *msg, struct sk_buff *skb)
4452 int attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
4455 switch (msg->nla_type) {
4457 /* Always provide flag data, regardless of its value */
4458 tmp = *(bool *) msg->value;
4460 return nla_put_u8(skb, attrtype, tmp);
4462 return nla_put_u8(skb, attrtype, *(u8 *) msg->value);
4464 return nla_put_u32(skb, attrtype, *(u32 *) msg->value);
4466 return nla_put_u64_64bit(skb, attrtype, *(u64 *) msg->value,
4468 case NLA_NUL_STRING:
4469 return nla_put_string(skb, attrtype, (char *) &msg->value);
4471 return nla_put(skb, attrtype, msg->len, (void *) &msg->value);
4478 devlink_fmsg_prepare_skb(struct devlink_fmsg *fmsg, struct sk_buff *skb,
4481 struct devlink_fmsg_item *item;
4482 struct nlattr *fmsg_nlattr;
4486 fmsg_nlattr = nla_nest_start_noflag(skb, DEVLINK_ATTR_FMSG);
4490 list_for_each_entry(item, &fmsg->item_list, list) {
4496 switch (item->attrtype) {
4497 case DEVLINK_ATTR_FMSG_OBJ_NEST_START:
4498 case DEVLINK_ATTR_FMSG_PAIR_NEST_START:
4499 case DEVLINK_ATTR_FMSG_ARR_NEST_START:
4500 case DEVLINK_ATTR_FMSG_NEST_END:
4501 err = nla_put_flag(skb, item->attrtype);
4503 case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA:
4504 err = devlink_fmsg_item_fill_type(item, skb);
4507 err = devlink_fmsg_item_fill_data(item, skb);
4509 case DEVLINK_ATTR_FMSG_OBJ_NAME:
4510 err = nla_put_string(skb, item->attrtype,
4511 (char *) &item->value);
4523 nla_nest_end(skb, fmsg_nlattr);
4527 static int devlink_fmsg_snd(struct devlink_fmsg *fmsg,
4528 struct genl_info *info,
4529 enum devlink_command cmd, int flags)
4531 struct nlmsghdr *nlh;
4532 struct sk_buff *skb;
4539 int tmp_index = index;
4541 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
4545 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
4546 &devlink_nl_family, flags | NLM_F_MULTI, cmd);
4549 goto nla_put_failure;
4552 err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
4555 else if (err != -EMSGSIZE || tmp_index == index)
4556 goto nla_put_failure;
4558 genlmsg_end(skb, hdr);
4559 err = genlmsg_reply(skb, info);
4564 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
4567 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
4568 NLMSG_DONE, 0, flags | NLM_F_MULTI);
4571 goto nla_put_failure;
4574 return genlmsg_reply(skb, info);
4581 static int devlink_fmsg_dumpit(struct devlink_fmsg *fmsg, struct sk_buff *skb,
4582 struct netlink_callback *cb,
4583 enum devlink_command cmd)
4585 int index = cb->args[0];
4586 int tmp_index = index;
4590 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
4591 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, cmd);
4594 goto nla_put_failure;
4597 err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
4598 if ((err && err != -EMSGSIZE) || tmp_index == index)
4599 goto nla_put_failure;
4601 cb->args[0] = index;
4602 genlmsg_end(skb, hdr);
4606 genlmsg_cancel(skb, hdr);
4610 struct devlink_health_reporter {
4611 struct list_head list;
4613 const struct devlink_health_reporter_ops *ops;
4614 struct devlink *devlink;
4615 struct devlink_fmsg *dump_fmsg;
4616 struct mutex dump_lock; /* lock parallel read/write from dump buffers */
4617 u64 graceful_period;
4623 u64 last_recovery_ts;
4624 refcount_t refcount;
4628 devlink_health_reporter_priv(struct devlink_health_reporter *reporter)
4630 return reporter->priv;
4632 EXPORT_SYMBOL_GPL(devlink_health_reporter_priv);
4634 static struct devlink_health_reporter *
4635 devlink_health_reporter_find_by_name(struct devlink *devlink,
4636 const char *reporter_name)
4638 struct devlink_health_reporter *reporter;
4640 lockdep_assert_held(&devlink->reporters_lock);
4641 list_for_each_entry(reporter, &devlink->reporter_list, list)
4642 if (!strcmp(reporter->ops->name, reporter_name))
4648 * devlink_health_reporter_create - create devlink health reporter
4652 * @graceful_period: to avoid recovery loops, in msecs
4653 * @auto_recover: auto recover when error occurs
4656 struct devlink_health_reporter *
4657 devlink_health_reporter_create(struct devlink *devlink,
4658 const struct devlink_health_reporter_ops *ops,
4659 u64 graceful_period, bool auto_recover,
4662 struct devlink_health_reporter *reporter;
4664 mutex_lock(&devlink->reporters_lock);
4665 if (devlink_health_reporter_find_by_name(devlink, ops->name)) {
4666 reporter = ERR_PTR(-EEXIST);
4670 if (WARN_ON(auto_recover && !ops->recover) ||
4671 WARN_ON(graceful_period && !ops->recover)) {
4672 reporter = ERR_PTR(-EINVAL);
4676 reporter = kzalloc(sizeof(*reporter), GFP_KERNEL);
4678 reporter = ERR_PTR(-ENOMEM);
4682 reporter->priv = priv;
4683 reporter->ops = ops;
4684 reporter->devlink = devlink;
4685 reporter->graceful_period = graceful_period;
4686 reporter->auto_recover = auto_recover;
4687 mutex_init(&reporter->dump_lock);
4688 refcount_set(&reporter->refcount, 1);
4689 list_add_tail(&reporter->list, &devlink->reporter_list);
4691 mutex_unlock(&devlink->reporters_lock);
4694 EXPORT_SYMBOL_GPL(devlink_health_reporter_create);
4697 * devlink_health_reporter_destroy - destroy devlink health reporter
4699 * @reporter: devlink health reporter to destroy
4702 devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
4704 mutex_lock(&reporter->devlink->reporters_lock);
4705 list_del(&reporter->list);
4706 mutex_unlock(&reporter->devlink->reporters_lock);
4707 while (refcount_read(&reporter->refcount) > 1)
4709 mutex_destroy(&reporter->dump_lock);
4710 if (reporter->dump_fmsg)
4711 devlink_fmsg_free(reporter->dump_fmsg);
4714 EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy);
4717 devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
4718 enum devlink_health_reporter_state state)
4720 if (WARN_ON(state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY &&
4721 state != DEVLINK_HEALTH_REPORTER_STATE_ERROR))
4724 if (reporter->health_state == state)
4727 reporter->health_state = state;
4728 trace_devlink_health_reporter_state_update(reporter->devlink,
4729 reporter->ops->name, state);
4731 EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update);
4734 devlink_health_reporter_recover(struct devlink_health_reporter *reporter,
4739 if (!reporter->ops->recover)
4742 err = reporter->ops->recover(reporter, priv_ctx);
4746 reporter->recovery_count++;
4747 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY;
4748 reporter->last_recovery_ts = jiffies;
4754 devlink_health_dump_clear(struct devlink_health_reporter *reporter)
4756 if (!reporter->dump_fmsg)
4758 devlink_fmsg_free(reporter->dump_fmsg);
4759 reporter->dump_fmsg = NULL;
4762 static int devlink_health_do_dump(struct devlink_health_reporter *reporter,
4767 if (!reporter->ops->dump)
4770 if (reporter->dump_fmsg)
4773 reporter->dump_fmsg = devlink_fmsg_alloc();
4774 if (!reporter->dump_fmsg) {
4779 err = devlink_fmsg_obj_nest_start(reporter->dump_fmsg);
4783 err = reporter->ops->dump(reporter, reporter->dump_fmsg,
4788 err = devlink_fmsg_obj_nest_end(reporter->dump_fmsg);
4792 reporter->dump_ts = jiffies;
4797 devlink_health_dump_clear(reporter);
4801 int devlink_health_report(struct devlink_health_reporter *reporter,
4802 const char *msg, void *priv_ctx)
4804 enum devlink_health_reporter_state prev_health_state;
4805 struct devlink *devlink = reporter->devlink;
4807 /* write a log message of the current error */
4809 trace_devlink_health_report(devlink, reporter->ops->name, msg);
4810 reporter->error_count++;
4811 prev_health_state = reporter->health_state;
4812 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
4814 /* abort if the previous error wasn't recovered */
4815 if (reporter->auto_recover &&
4816 (prev_health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY ||
4817 jiffies - reporter->last_recovery_ts <
4818 msecs_to_jiffies(reporter->graceful_period))) {
4819 trace_devlink_health_recover_aborted(devlink,
4820 reporter->ops->name,
4821 reporter->health_state,
4823 reporter->last_recovery_ts);
4827 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
4829 mutex_lock(&reporter->dump_lock);
4830 /* store current dump of current error, for later analysis */
4831 devlink_health_do_dump(reporter, priv_ctx);
4832 mutex_unlock(&reporter->dump_lock);
4834 if (reporter->auto_recover)
4835 return devlink_health_reporter_recover(reporter, priv_ctx);
4839 EXPORT_SYMBOL_GPL(devlink_health_report);
4841 static struct devlink_health_reporter *
4842 devlink_health_reporter_get_from_attrs(struct devlink *devlink,
4843 struct nlattr **attrs)
4845 struct devlink_health_reporter *reporter;
4846 char *reporter_name;
4848 if (!attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME])
4851 reporter_name = nla_data(attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]);
4852 mutex_lock(&devlink->reporters_lock);
4853 reporter = devlink_health_reporter_find_by_name(devlink, reporter_name);
4855 refcount_inc(&reporter->refcount);
4856 mutex_unlock(&devlink->reporters_lock);
4860 static struct devlink_health_reporter *
4861 devlink_health_reporter_get_from_info(struct devlink *devlink,
4862 struct genl_info *info)
4864 return devlink_health_reporter_get_from_attrs(devlink, info->attrs);
4867 static struct devlink_health_reporter *
4868 devlink_health_reporter_get_from_cb(struct netlink_callback *cb)
4870 struct devlink_health_reporter *reporter;
4871 struct devlink *devlink;
4872 struct nlattr **attrs;
4875 attrs = kmalloc_array(DEVLINK_ATTR_MAX + 1, sizeof(*attrs), GFP_KERNEL);
4879 err = nlmsg_parse_deprecated(cb->nlh,
4880 GENL_HDRLEN + devlink_nl_family.hdrsize,
4881 attrs, DEVLINK_ATTR_MAX,
4882 devlink_nl_family.policy, cb->extack);
4886 mutex_lock(&devlink_mutex);
4887 devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs);
4888 if (IS_ERR(devlink))
4891 reporter = devlink_health_reporter_get_from_attrs(devlink, attrs);
4892 mutex_unlock(&devlink_mutex);
4896 mutex_unlock(&devlink_mutex);
4903 devlink_health_reporter_put(struct devlink_health_reporter *reporter)
4905 refcount_dec(&reporter->refcount);
4909 devlink_nl_health_reporter_fill(struct sk_buff *msg,
4910 struct devlink *devlink,
4911 struct devlink_health_reporter *reporter,
4912 enum devlink_command cmd, u32 portid,
4915 struct nlattr *reporter_attr;
4918 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
4922 if (devlink_nl_put_handle(msg, devlink))
4923 goto genlmsg_cancel;
4925 reporter_attr = nla_nest_start_noflag(msg,
4926 DEVLINK_ATTR_HEALTH_REPORTER);
4928 goto genlmsg_cancel;
4929 if (nla_put_string(msg, DEVLINK_ATTR_HEALTH_REPORTER_NAME,
4930 reporter->ops->name))
4931 goto reporter_nest_cancel;
4932 if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_STATE,
4933 reporter->health_state))
4934 goto reporter_nest_cancel;
4935 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT,
4936 reporter->error_count, DEVLINK_ATTR_PAD))
4937 goto reporter_nest_cancel;
4938 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT,
4939 reporter->recovery_count, DEVLINK_ATTR_PAD))
4940 goto reporter_nest_cancel;
4941 if (reporter->ops->recover &&
4942 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD,
4943 reporter->graceful_period,
4945 goto reporter_nest_cancel;
4946 if (reporter->ops->recover &&
4947 nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER,
4948 reporter->auto_recover))
4949 goto reporter_nest_cancel;
4950 if (reporter->dump_fmsg &&
4951 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS,
4952 jiffies_to_msecs(reporter->dump_ts),
4954 goto reporter_nest_cancel;
4956 nla_nest_end(msg, reporter_attr);
4957 genlmsg_end(msg, hdr);
4960 reporter_nest_cancel:
4961 nla_nest_end(msg, reporter_attr);
4963 genlmsg_cancel(msg, hdr);
4967 static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb,
4968 struct genl_info *info)
4970 struct devlink *devlink = info->user_ptr[0];
4971 struct devlink_health_reporter *reporter;
4972 struct sk_buff *msg;
4975 reporter = devlink_health_reporter_get_from_info(devlink, info);
4979 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4985 err = devlink_nl_health_reporter_fill(msg, devlink, reporter,
4986 DEVLINK_CMD_HEALTH_REPORTER_GET,
4987 info->snd_portid, info->snd_seq,
4994 err = genlmsg_reply(msg, info);
4996 devlink_health_reporter_put(reporter);
5001 devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff *msg,
5002 struct netlink_callback *cb)
5004 struct devlink_health_reporter *reporter;
5005 struct devlink *devlink;
5006 int start = cb->args[0];
5010 mutex_lock(&devlink_mutex);
5011 list_for_each_entry(devlink, &devlink_list, list) {
5012 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
5014 mutex_lock(&devlink->reporters_lock);
5015 list_for_each_entry(reporter, &devlink->reporter_list,
5021 err = devlink_nl_health_reporter_fill(msg, devlink,
5023 DEVLINK_CMD_HEALTH_REPORTER_GET,
5024 NETLINK_CB(cb->skb).portid,
5028 mutex_unlock(&devlink->reporters_lock);
5033 mutex_unlock(&devlink->reporters_lock);
5036 mutex_unlock(&devlink_mutex);
5043 devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb,
5044 struct genl_info *info)
5046 struct devlink *devlink = info->user_ptr[0];
5047 struct devlink_health_reporter *reporter;
5050 reporter = devlink_health_reporter_get_from_info(devlink, info);
5054 if (!reporter->ops->recover &&
5055 (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] ||
5056 info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])) {
5061 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD])
5062 reporter->graceful_period =
5063 nla_get_u64(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]);
5065 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])
5066 reporter->auto_recover =
5067 nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]);
5069 devlink_health_reporter_put(reporter);
5072 devlink_health_reporter_put(reporter);
5076 static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb,
5077 struct genl_info *info)
5079 struct devlink *devlink = info->user_ptr[0];
5080 struct devlink_health_reporter *reporter;
5083 reporter = devlink_health_reporter_get_from_info(devlink, info);
5087 err = devlink_health_reporter_recover(reporter, NULL);
5089 devlink_health_reporter_put(reporter);
5093 static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb,
5094 struct genl_info *info)
5096 struct devlink *devlink = info->user_ptr[0];
5097 struct devlink_health_reporter *reporter;
5098 struct devlink_fmsg *fmsg;
5101 reporter = devlink_health_reporter_get_from_info(devlink, info);
5105 if (!reporter->ops->diagnose) {
5106 devlink_health_reporter_put(reporter);
5110 fmsg = devlink_fmsg_alloc();
5112 devlink_health_reporter_put(reporter);
5116 err = devlink_fmsg_obj_nest_start(fmsg);
5120 err = reporter->ops->diagnose(reporter, fmsg);
5124 err = devlink_fmsg_obj_nest_end(fmsg);
5128 err = devlink_fmsg_snd(fmsg, info,
5129 DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 0);
5132 devlink_fmsg_free(fmsg);
5133 devlink_health_reporter_put(reporter);
5138 devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff *skb,
5139 struct netlink_callback *cb)
5141 struct devlink_health_reporter *reporter;
5142 u64 start = cb->args[0];
5145 reporter = devlink_health_reporter_get_from_cb(cb);
5149 if (!reporter->ops->dump) {
5153 mutex_lock(&reporter->dump_lock);
5155 err = devlink_health_do_dump(reporter, NULL);
5158 cb->args[1] = reporter->dump_ts;
5160 if (!reporter->dump_fmsg || cb->args[1] != reporter->dump_ts) {
5161 NL_SET_ERR_MSG_MOD(cb->extack, "Dump trampled, please retry");
5166 err = devlink_fmsg_dumpit(reporter->dump_fmsg, skb, cb,
5167 DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET);
5169 mutex_unlock(&reporter->dump_lock);
5171 devlink_health_reporter_put(reporter);
5176 devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb,
5177 struct genl_info *info)
5179 struct devlink *devlink = info->user_ptr[0];
5180 struct devlink_health_reporter *reporter;
5182 reporter = devlink_health_reporter_get_from_info(devlink, info);
5186 if (!reporter->ops->dump) {
5187 devlink_health_reporter_put(reporter);
5191 mutex_lock(&reporter->dump_lock);
5192 devlink_health_dump_clear(reporter);
5193 mutex_unlock(&reporter->dump_lock);
5194 devlink_health_reporter_put(reporter);
5198 struct devlink_stats {
5201 struct u64_stats_sync syncp;
5205 * struct devlink_trap_group_item - Packet trap group attributes.
5206 * @group: Immutable packet trap group attributes.
5207 * @refcount: Number of trap items using the group.
5208 * @list: trap_group_list member.
5209 * @stats: Trap group statistics.
5211 * Describes packet trap group attributes. Created by devlink during trap
5214 struct devlink_trap_group_item {
5215 const struct devlink_trap_group *group;
5216 refcount_t refcount;
5217 struct list_head list;
5218 struct devlink_stats __percpu *stats;
5222 * struct devlink_trap_item - Packet trap attributes.
5223 * @trap: Immutable packet trap attributes.
5224 * @group_item: Associated group item.
5225 * @list: trap_list member.
5226 * @action: Trap action.
5227 * @stats: Trap statistics.
5228 * @priv: Driver private information.
5230 * Describes both mutable and immutable packet trap attributes. Created by
5231 * devlink during trap registration and used for all trap related operations.
5233 struct devlink_trap_item {
5234 const struct devlink_trap *trap;
5235 struct devlink_trap_group_item *group_item;
5236 struct list_head list;
5237 enum devlink_trap_action action;
5238 struct devlink_stats __percpu *stats;
5242 static struct devlink_trap_item *
5243 devlink_trap_item_lookup(struct devlink *devlink, const char *name)
5245 struct devlink_trap_item *trap_item;
5247 list_for_each_entry(trap_item, &devlink->trap_list, list) {
5248 if (!strcmp(trap_item->trap->name, name))
5255 static struct devlink_trap_item *
5256 devlink_trap_item_get_from_info(struct devlink *devlink,
5257 struct genl_info *info)
5259 struct nlattr *attr;
5261 if (!info->attrs[DEVLINK_ATTR_TRAP_NAME])
5263 attr = info->attrs[DEVLINK_ATTR_TRAP_NAME];
5265 return devlink_trap_item_lookup(devlink, nla_data(attr));
5269 devlink_trap_action_get_from_info(struct genl_info *info,
5270 enum devlink_trap_action *p_trap_action)
5274 val = nla_get_u8(info->attrs[DEVLINK_ATTR_TRAP_ACTION]);
5276 case DEVLINK_TRAP_ACTION_DROP: /* fall-through */
5277 case DEVLINK_TRAP_ACTION_TRAP:
5278 *p_trap_action = val;
5287 static int devlink_trap_metadata_put(struct sk_buff *msg,
5288 const struct devlink_trap *trap)
5290 struct nlattr *attr;
5292 attr = nla_nest_start(msg, DEVLINK_ATTR_TRAP_METADATA);
5296 if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT) &&
5297 nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT))
5298 goto nla_put_failure;
5300 nla_nest_end(msg, attr);
5305 nla_nest_cancel(msg, attr);
5309 static void devlink_trap_stats_read(struct devlink_stats __percpu *trap_stats,
5310 struct devlink_stats *stats)
5314 memset(stats, 0, sizeof(*stats));
5315 for_each_possible_cpu(i) {
5316 struct devlink_stats *cpu_stats;
5317 u64 rx_packets, rx_bytes;
5320 cpu_stats = per_cpu_ptr(trap_stats, i);
5322 start = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
5323 rx_packets = cpu_stats->rx_packets;
5324 rx_bytes = cpu_stats->rx_bytes;
5325 } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start));
5327 stats->rx_packets += rx_packets;
5328 stats->rx_bytes += rx_bytes;
5332 static int devlink_trap_stats_put(struct sk_buff *msg,
5333 struct devlink_stats __percpu *trap_stats)
5335 struct devlink_stats stats;
5336 struct nlattr *attr;
5338 devlink_trap_stats_read(trap_stats, &stats);
5340 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
5344 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS,
5345 stats.rx_packets, DEVLINK_ATTR_PAD))
5346 goto nla_put_failure;
5348 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES,
5349 stats.rx_bytes, DEVLINK_ATTR_PAD))
5350 goto nla_put_failure;
5352 nla_nest_end(msg, attr);
5357 nla_nest_cancel(msg, attr);
5361 static int devlink_nl_trap_fill(struct sk_buff *msg, struct devlink *devlink,
5362 const struct devlink_trap_item *trap_item,
5363 enum devlink_command cmd, u32 portid, u32 seq,
5366 struct devlink_trap_group_item *group_item = trap_item->group_item;
5370 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
5374 if (devlink_nl_put_handle(msg, devlink))
5375 goto nla_put_failure;
5377 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
5378 group_item->group->name))
5379 goto nla_put_failure;
5381 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_NAME, trap_item->trap->name))
5382 goto nla_put_failure;
5384 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_TYPE, trap_item->trap->type))
5385 goto nla_put_failure;
5387 if (trap_item->trap->generic &&
5388 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
5389 goto nla_put_failure;
5391 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_ACTION, trap_item->action))
5392 goto nla_put_failure;
5394 err = devlink_trap_metadata_put(msg, trap_item->trap);
5396 goto nla_put_failure;
5398 err = devlink_trap_stats_put(msg, trap_item->stats);
5400 goto nla_put_failure;
5402 genlmsg_end(msg, hdr);
5407 genlmsg_cancel(msg, hdr);
5411 static int devlink_nl_cmd_trap_get_doit(struct sk_buff *skb,
5412 struct genl_info *info)
5414 struct netlink_ext_ack *extack = info->extack;
5415 struct devlink *devlink = info->user_ptr[0];
5416 struct devlink_trap_item *trap_item;
5417 struct sk_buff *msg;
5420 if (list_empty(&devlink->trap_list))
5423 trap_item = devlink_trap_item_get_from_info(devlink, info);
5425 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
5429 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5433 err = devlink_nl_trap_fill(msg, devlink, trap_item,
5434 DEVLINK_CMD_TRAP_NEW, info->snd_portid,
5439 return genlmsg_reply(msg, info);
5446 static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff *msg,
5447 struct netlink_callback *cb)
5449 struct devlink_trap_item *trap_item;
5450 struct devlink *devlink;
5451 int start = cb->args[0];
5455 mutex_lock(&devlink_mutex);
5456 list_for_each_entry(devlink, &devlink_list, list) {
5457 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
5459 mutex_lock(&devlink->lock);
5460 list_for_each_entry(trap_item, &devlink->trap_list, list) {
5465 err = devlink_nl_trap_fill(msg, devlink, trap_item,
5466 DEVLINK_CMD_TRAP_NEW,
5467 NETLINK_CB(cb->skb).portid,
5471 mutex_unlock(&devlink->lock);
5476 mutex_unlock(&devlink->lock);
5479 mutex_unlock(&devlink_mutex);
5485 static int __devlink_trap_action_set(struct devlink *devlink,
5486 struct devlink_trap_item *trap_item,
5487 enum devlink_trap_action trap_action,
5488 struct netlink_ext_ack *extack)
5492 if (trap_item->action != trap_action &&
5493 trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) {
5494 NL_SET_ERR_MSG_MOD(extack, "Cannot change action of non-drop traps. Skipping");
5498 err = devlink->ops->trap_action_set(devlink, trap_item->trap,
5503 trap_item->action = trap_action;
5508 static int devlink_trap_action_set(struct devlink *devlink,
5509 struct devlink_trap_item *trap_item,
5510 struct genl_info *info)
5512 enum devlink_trap_action trap_action;
5515 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
5518 err = devlink_trap_action_get_from_info(info, &trap_action);
5520 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
5524 return __devlink_trap_action_set(devlink, trap_item, trap_action,
5528 static int devlink_nl_cmd_trap_set_doit(struct sk_buff *skb,
5529 struct genl_info *info)
5531 struct netlink_ext_ack *extack = info->extack;
5532 struct devlink *devlink = info->user_ptr[0];
5533 struct devlink_trap_item *trap_item;
5536 if (list_empty(&devlink->trap_list))
5539 trap_item = devlink_trap_item_get_from_info(devlink, info);
5541 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
5545 err = devlink_trap_action_set(devlink, trap_item, info);
5552 static struct devlink_trap_group_item *
5553 devlink_trap_group_item_lookup(struct devlink *devlink, const char *name)
5555 struct devlink_trap_group_item *group_item;
5557 list_for_each_entry(group_item, &devlink->trap_group_list, list) {
5558 if (!strcmp(group_item->group->name, name))
5565 static struct devlink_trap_group_item *
5566 devlink_trap_group_item_get_from_info(struct devlink *devlink,
5567 struct genl_info *info)
5571 if (!info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME])
5573 name = nla_data(info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]);
5575 return devlink_trap_group_item_lookup(devlink, name);
5579 devlink_nl_trap_group_fill(struct sk_buff *msg, struct devlink *devlink,
5580 const struct devlink_trap_group_item *group_item,
5581 enum devlink_command cmd, u32 portid, u32 seq,
5587 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
5591 if (devlink_nl_put_handle(msg, devlink))
5592 goto nla_put_failure;
5594 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
5595 group_item->group->name))
5596 goto nla_put_failure;
5598 if (group_item->group->generic &&
5599 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
5600 goto nla_put_failure;
5602 err = devlink_trap_stats_put(msg, group_item->stats);
5604 goto nla_put_failure;
5606 genlmsg_end(msg, hdr);
5611 genlmsg_cancel(msg, hdr);
5615 static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff *skb,
5616 struct genl_info *info)
5618 struct netlink_ext_ack *extack = info->extack;
5619 struct devlink *devlink = info->user_ptr[0];
5620 struct devlink_trap_group_item *group_item;
5621 struct sk_buff *msg;
5624 if (list_empty(&devlink->trap_group_list))
5627 group_item = devlink_trap_group_item_get_from_info(devlink, info);
5629 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
5633 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5637 err = devlink_nl_trap_group_fill(msg, devlink, group_item,
5638 DEVLINK_CMD_TRAP_GROUP_NEW,
5639 info->snd_portid, info->snd_seq, 0);
5641 goto err_trap_group_fill;
5643 return genlmsg_reply(msg, info);
5645 err_trap_group_fill:
5650 static int devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff *msg,
5651 struct netlink_callback *cb)
5653 enum devlink_command cmd = DEVLINK_CMD_TRAP_GROUP_NEW;
5654 struct devlink_trap_group_item *group_item;
5655 u32 portid = NETLINK_CB(cb->skb).portid;
5656 struct devlink *devlink;
5657 int start = cb->args[0];
5661 mutex_lock(&devlink_mutex);
5662 list_for_each_entry(devlink, &devlink_list, list) {
5663 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
5665 mutex_lock(&devlink->lock);
5666 list_for_each_entry(group_item, &devlink->trap_group_list,
5672 err = devlink_nl_trap_group_fill(msg, devlink,
5678 mutex_unlock(&devlink->lock);
5683 mutex_unlock(&devlink->lock);
5686 mutex_unlock(&devlink_mutex);
5693 __devlink_trap_group_action_set(struct devlink *devlink,
5694 struct devlink_trap_group_item *group_item,
5695 enum devlink_trap_action trap_action,
5696 struct netlink_ext_ack *extack)
5698 const char *group_name = group_item->group->name;
5699 struct devlink_trap_item *trap_item;
5702 list_for_each_entry(trap_item, &devlink->trap_list, list) {
5703 if (strcmp(trap_item->trap->group.name, group_name))
5705 err = __devlink_trap_action_set(devlink, trap_item,
5706 trap_action, extack);
5715 devlink_trap_group_action_set(struct devlink *devlink,
5716 struct devlink_trap_group_item *group_item,
5717 struct genl_info *info)
5719 enum devlink_trap_action trap_action;
5722 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
5725 err = devlink_trap_action_get_from_info(info, &trap_action);
5727 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
5731 err = __devlink_trap_group_action_set(devlink, group_item, trap_action,
5739 static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff *skb,
5740 struct genl_info *info)
5742 struct netlink_ext_ack *extack = info->extack;
5743 struct devlink *devlink = info->user_ptr[0];
5744 struct devlink_trap_group_item *group_item;
5747 if (list_empty(&devlink->trap_group_list))
5750 group_item = devlink_trap_group_item_get_from_info(devlink, info);
5752 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
5756 err = devlink_trap_group_action_set(devlink, group_item, info);
5763 static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
5764 [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
5765 [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
5766 [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 },
5767 [DEVLINK_ATTR_PORT_TYPE] = { .type = NLA_U16 },
5768 [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 },
5769 [DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 },
5770 [DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 },
5771 [DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 },
5772 [DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 },
5773 [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 },
5774 [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
5775 [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
5776 [DEVLINK_ATTR_ESWITCH_MODE] = { .type = NLA_U16 },
5777 [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 },
5778 [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 },
5779 [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING },
5780 [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 },
5781 [DEVLINK_ATTR_RESOURCE_ID] = { .type = NLA_U64},
5782 [DEVLINK_ATTR_RESOURCE_SIZE] = { .type = NLA_U64},
5783 [DEVLINK_ATTR_PARAM_NAME] = { .type = NLA_NUL_STRING },
5784 [DEVLINK_ATTR_PARAM_TYPE] = { .type = NLA_U8 },
5785 [DEVLINK_ATTR_PARAM_VALUE_CMODE] = { .type = NLA_U8 },
5786 [DEVLINK_ATTR_REGION_NAME] = { .type = NLA_NUL_STRING },
5787 [DEVLINK_ATTR_REGION_SNAPSHOT_ID] = { .type = NLA_U32 },
5788 [DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING },
5789 [DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] = { .type = NLA_U64 },
5790 [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER] = { .type = NLA_U8 },
5791 [DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME] = { .type = NLA_NUL_STRING },
5792 [DEVLINK_ATTR_FLASH_UPDATE_COMPONENT] = { .type = NLA_NUL_STRING },
5793 [DEVLINK_ATTR_TRAP_NAME] = { .type = NLA_NUL_STRING },
5794 [DEVLINK_ATTR_TRAP_ACTION] = { .type = NLA_U8 },
5795 [DEVLINK_ATTR_TRAP_GROUP_NAME] = { .type = NLA_NUL_STRING },
5798 static const struct genl_ops devlink_nl_ops[] = {
5800 .cmd = DEVLINK_CMD_GET,
5801 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5802 .doit = devlink_nl_cmd_get_doit,
5803 .dumpit = devlink_nl_cmd_get_dumpit,
5804 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5805 /* can be retrieved by unprivileged users */
5808 .cmd = DEVLINK_CMD_PORT_GET,
5809 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5810 .doit = devlink_nl_cmd_port_get_doit,
5811 .dumpit = devlink_nl_cmd_port_get_dumpit,
5812 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
5813 /* can be retrieved by unprivileged users */
5816 .cmd = DEVLINK_CMD_PORT_SET,
5817 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5818 .doit = devlink_nl_cmd_port_set_doit,
5819 .flags = GENL_ADMIN_PERM,
5820 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
5823 .cmd = DEVLINK_CMD_PORT_SPLIT,
5824 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5825 .doit = devlink_nl_cmd_port_split_doit,
5826 .flags = GENL_ADMIN_PERM,
5827 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5828 DEVLINK_NL_FLAG_NO_LOCK,
5831 .cmd = DEVLINK_CMD_PORT_UNSPLIT,
5832 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5833 .doit = devlink_nl_cmd_port_unsplit_doit,
5834 .flags = GENL_ADMIN_PERM,
5835 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5836 DEVLINK_NL_FLAG_NO_LOCK,
5839 .cmd = DEVLINK_CMD_SB_GET,
5840 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5841 .doit = devlink_nl_cmd_sb_get_doit,
5842 .dumpit = devlink_nl_cmd_sb_get_dumpit,
5843 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5844 DEVLINK_NL_FLAG_NEED_SB,
5845 /* can be retrieved by unprivileged users */
5848 .cmd = DEVLINK_CMD_SB_POOL_GET,
5849 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5850 .doit = devlink_nl_cmd_sb_pool_get_doit,
5851 .dumpit = devlink_nl_cmd_sb_pool_get_dumpit,
5852 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5853 DEVLINK_NL_FLAG_NEED_SB,
5854 /* can be retrieved by unprivileged users */
5857 .cmd = DEVLINK_CMD_SB_POOL_SET,
5858 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5859 .doit = devlink_nl_cmd_sb_pool_set_doit,
5860 .flags = GENL_ADMIN_PERM,
5861 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5862 DEVLINK_NL_FLAG_NEED_SB,
5865 .cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
5866 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5867 .doit = devlink_nl_cmd_sb_port_pool_get_doit,
5868 .dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit,
5869 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
5870 DEVLINK_NL_FLAG_NEED_SB,
5871 /* can be retrieved by unprivileged users */
5874 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
5875 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5876 .doit = devlink_nl_cmd_sb_port_pool_set_doit,
5877 .flags = GENL_ADMIN_PERM,
5878 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
5879 DEVLINK_NL_FLAG_NEED_SB,
5882 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
5883 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5884 .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
5885 .dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit,
5886 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
5887 DEVLINK_NL_FLAG_NEED_SB,
5888 /* can be retrieved by unprivileged users */
5891 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
5892 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5893 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
5894 .flags = GENL_ADMIN_PERM,
5895 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
5896 DEVLINK_NL_FLAG_NEED_SB,
5899 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
5900 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5901 .doit = devlink_nl_cmd_sb_occ_snapshot_doit,
5902 .flags = GENL_ADMIN_PERM,
5903 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5904 DEVLINK_NL_FLAG_NEED_SB,
5907 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
5908 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5909 .doit = devlink_nl_cmd_sb_occ_max_clear_doit,
5910 .flags = GENL_ADMIN_PERM,
5911 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5912 DEVLINK_NL_FLAG_NEED_SB,
5915 .cmd = DEVLINK_CMD_ESWITCH_GET,
5916 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5917 .doit = devlink_nl_cmd_eswitch_get_doit,
5918 .flags = GENL_ADMIN_PERM,
5919 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5922 .cmd = DEVLINK_CMD_ESWITCH_SET,
5923 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5924 .doit = devlink_nl_cmd_eswitch_set_doit,
5925 .flags = GENL_ADMIN_PERM,
5926 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5927 DEVLINK_NL_FLAG_NO_LOCK,
5930 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET,
5931 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5932 .doit = devlink_nl_cmd_dpipe_table_get,
5933 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5934 /* can be retrieved by unprivileged users */
5937 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET,
5938 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5939 .doit = devlink_nl_cmd_dpipe_entries_get,
5940 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5941 /* can be retrieved by unprivileged users */
5944 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET,
5945 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5946 .doit = devlink_nl_cmd_dpipe_headers_get,
5947 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5948 /* can be retrieved by unprivileged users */
5951 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
5952 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5953 .doit = devlink_nl_cmd_dpipe_table_counters_set,
5954 .flags = GENL_ADMIN_PERM,
5955 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5958 .cmd = DEVLINK_CMD_RESOURCE_SET,
5959 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5960 .doit = devlink_nl_cmd_resource_set,
5961 .flags = GENL_ADMIN_PERM,
5962 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5965 .cmd = DEVLINK_CMD_RESOURCE_DUMP,
5966 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5967 .doit = devlink_nl_cmd_resource_dump,
5968 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5969 /* can be retrieved by unprivileged users */
5972 .cmd = DEVLINK_CMD_RELOAD,
5973 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5974 .doit = devlink_nl_cmd_reload,
5975 .flags = GENL_ADMIN_PERM,
5976 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5977 DEVLINK_NL_FLAG_NO_LOCK,
5980 .cmd = DEVLINK_CMD_PARAM_GET,
5981 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5982 .doit = devlink_nl_cmd_param_get_doit,
5983 .dumpit = devlink_nl_cmd_param_get_dumpit,
5984 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5985 /* can be retrieved by unprivileged users */
5988 .cmd = DEVLINK_CMD_PARAM_SET,
5989 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5990 .doit = devlink_nl_cmd_param_set_doit,
5991 .flags = GENL_ADMIN_PERM,
5992 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5995 .cmd = DEVLINK_CMD_PORT_PARAM_GET,
5996 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5997 .doit = devlink_nl_cmd_port_param_get_doit,
5998 .dumpit = devlink_nl_cmd_port_param_get_dumpit,
5999 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
6000 /* can be retrieved by unprivileged users */
6003 .cmd = DEVLINK_CMD_PORT_PARAM_SET,
6004 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6005 .doit = devlink_nl_cmd_port_param_set_doit,
6006 .flags = GENL_ADMIN_PERM,
6007 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
6010 .cmd = DEVLINK_CMD_REGION_GET,
6011 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6012 .doit = devlink_nl_cmd_region_get_doit,
6013 .dumpit = devlink_nl_cmd_region_get_dumpit,
6014 .flags = GENL_ADMIN_PERM,
6015 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
6018 .cmd = DEVLINK_CMD_REGION_DEL,
6019 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6020 .doit = devlink_nl_cmd_region_del,
6021 .flags = GENL_ADMIN_PERM,
6022 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
6025 .cmd = DEVLINK_CMD_REGION_READ,
6026 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6027 .dumpit = devlink_nl_cmd_region_read_dumpit,
6028 .flags = GENL_ADMIN_PERM,
6029 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
6032 .cmd = DEVLINK_CMD_INFO_GET,
6033 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6034 .doit = devlink_nl_cmd_info_get_doit,
6035 .dumpit = devlink_nl_cmd_info_get_dumpit,
6036 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
6037 /* can be retrieved by unprivileged users */
6040 .cmd = DEVLINK_CMD_HEALTH_REPORTER_GET,
6041 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6042 .doit = devlink_nl_cmd_health_reporter_get_doit,
6043 .dumpit = devlink_nl_cmd_health_reporter_get_dumpit,
6044 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
6045 DEVLINK_NL_FLAG_NO_LOCK,
6046 /* can be retrieved by unprivileged users */
6049 .cmd = DEVLINK_CMD_HEALTH_REPORTER_SET,
6050 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6051 .doit = devlink_nl_cmd_health_reporter_set_doit,
6052 .flags = GENL_ADMIN_PERM,
6053 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
6054 DEVLINK_NL_FLAG_NO_LOCK,
6057 .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER,
6058 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6059 .doit = devlink_nl_cmd_health_reporter_recover_doit,
6060 .flags = GENL_ADMIN_PERM,
6061 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
6062 DEVLINK_NL_FLAG_NO_LOCK,
6065 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE,
6066 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6067 .doit = devlink_nl_cmd_health_reporter_diagnose_doit,
6068 .flags = GENL_ADMIN_PERM,
6069 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
6070 DEVLINK_NL_FLAG_NO_LOCK,
6073 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET,
6074 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6075 .dumpit = devlink_nl_cmd_health_reporter_dump_get_dumpit,
6076 .flags = GENL_ADMIN_PERM,
6077 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
6078 DEVLINK_NL_FLAG_NO_LOCK,
6081 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR,
6082 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6083 .doit = devlink_nl_cmd_health_reporter_dump_clear_doit,
6084 .flags = GENL_ADMIN_PERM,
6085 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
6086 DEVLINK_NL_FLAG_NO_LOCK,
6089 .cmd = DEVLINK_CMD_FLASH_UPDATE,
6090 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6091 .doit = devlink_nl_cmd_flash_update,
6092 .flags = GENL_ADMIN_PERM,
6093 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
6096 .cmd = DEVLINK_CMD_TRAP_GET,
6097 .doit = devlink_nl_cmd_trap_get_doit,
6098 .dumpit = devlink_nl_cmd_trap_get_dumpit,
6099 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
6100 /* can be retrieved by unprivileged users */
6103 .cmd = DEVLINK_CMD_TRAP_SET,
6104 .doit = devlink_nl_cmd_trap_set_doit,
6105 .flags = GENL_ADMIN_PERM,
6106 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
6109 .cmd = DEVLINK_CMD_TRAP_GROUP_GET,
6110 .doit = devlink_nl_cmd_trap_group_get_doit,
6111 .dumpit = devlink_nl_cmd_trap_group_get_dumpit,
6112 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
6113 /* can be retrieved by unprivileged users */
6116 .cmd = DEVLINK_CMD_TRAP_GROUP_SET,
6117 .doit = devlink_nl_cmd_trap_group_set_doit,
6118 .flags = GENL_ADMIN_PERM,
6119 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
6123 static struct genl_family devlink_nl_family __ro_after_init = {
6124 .name = DEVLINK_GENL_NAME,
6125 .version = DEVLINK_GENL_VERSION,
6126 .maxattr = DEVLINK_ATTR_MAX,
6127 .policy = devlink_nl_policy,
6129 .pre_doit = devlink_nl_pre_doit,
6130 .post_doit = devlink_nl_post_doit,
6131 .module = THIS_MODULE,
6132 .ops = devlink_nl_ops,
6133 .n_ops = ARRAY_SIZE(devlink_nl_ops),
6134 .mcgrps = devlink_nl_mcgrps,
6135 .n_mcgrps = ARRAY_SIZE(devlink_nl_mcgrps),
6139 * devlink_alloc - Allocate new devlink instance resources
6142 * @priv_size: size of user private data
6144 * Allocate new devlink instance resources, including devlink index
6147 struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
6149 struct devlink *devlink;
6154 devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
6158 devlink_net_set(devlink, &init_net);
6159 INIT_LIST_HEAD(&devlink->port_list);
6160 INIT_LIST_HEAD(&devlink->sb_list);
6161 INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list);
6162 INIT_LIST_HEAD(&devlink->resource_list);
6163 INIT_LIST_HEAD(&devlink->param_list);
6164 INIT_LIST_HEAD(&devlink->region_list);
6165 INIT_LIST_HEAD(&devlink->reporter_list);
6166 INIT_LIST_HEAD(&devlink->trap_list);
6167 INIT_LIST_HEAD(&devlink->trap_group_list);
6168 mutex_init(&devlink->lock);
6169 mutex_init(&devlink->reporters_lock);
6172 EXPORT_SYMBOL_GPL(devlink_alloc);
6175 * devlink_register - Register devlink instance
6178 * @dev: parent device
6180 int devlink_register(struct devlink *devlink, struct device *dev)
6182 mutex_lock(&devlink_mutex);
6184 list_add_tail(&devlink->list, &devlink_list);
6185 devlink_notify(devlink, DEVLINK_CMD_NEW);
6186 mutex_unlock(&devlink_mutex);
6189 EXPORT_SYMBOL_GPL(devlink_register);
6192 * devlink_unregister - Unregister devlink instance
6196 void devlink_unregister(struct devlink *devlink)
6198 mutex_lock(&devlink_mutex);
6199 devlink_notify(devlink, DEVLINK_CMD_DEL);
6200 list_del(&devlink->list);
6201 mutex_unlock(&devlink_mutex);
6203 EXPORT_SYMBOL_GPL(devlink_unregister);
6206 * devlink_free - Free devlink instance resources
6210 void devlink_free(struct devlink *devlink)
6212 mutex_destroy(&devlink->reporters_lock);
6213 mutex_destroy(&devlink->lock);
6214 WARN_ON(!list_empty(&devlink->trap_group_list));
6215 WARN_ON(!list_empty(&devlink->trap_list));
6216 WARN_ON(!list_empty(&devlink->reporter_list));
6217 WARN_ON(!list_empty(&devlink->region_list));
6218 WARN_ON(!list_empty(&devlink->param_list));
6219 WARN_ON(!list_empty(&devlink->resource_list));
6220 WARN_ON(!list_empty(&devlink->dpipe_table_list));
6221 WARN_ON(!list_empty(&devlink->sb_list));
6222 WARN_ON(!list_empty(&devlink->port_list));
6226 EXPORT_SYMBOL_GPL(devlink_free);
6228 static void devlink_port_type_warn(struct work_struct *work)
6230 WARN(true, "Type was not set for devlink port.");
6233 static bool devlink_port_type_should_warn(struct devlink_port *devlink_port)
6235 /* Ignore CPU and DSA flavours. */
6236 return devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_CPU &&
6237 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_DSA;
6240 #define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 30)
6242 static void devlink_port_type_warn_schedule(struct devlink_port *devlink_port)
6244 if (!devlink_port_type_should_warn(devlink_port))
6246 /* Schedule a work to WARN in case driver does not set port
6247 * type within timeout.
6249 schedule_delayed_work(&devlink_port->type_warn_dw,
6250 DEVLINK_PORT_TYPE_WARN_TIMEOUT);
6253 static void devlink_port_type_warn_cancel(struct devlink_port *devlink_port)
6255 if (!devlink_port_type_should_warn(devlink_port))
6257 cancel_delayed_work_sync(&devlink_port->type_warn_dw);
6261 * devlink_port_register - Register devlink port
6264 * @devlink_port: devlink port
6265 * @port_index: driver-specific numerical identifier of the port
6267 * Register devlink port with provided port index. User can use
6268 * any indexing, even hw-related one. devlink_port structure
6269 * is convenient to be embedded inside user driver private structure.
6270 * Note that the caller should take care of zeroing the devlink_port
6273 int devlink_port_register(struct devlink *devlink,
6274 struct devlink_port *devlink_port,
6275 unsigned int port_index)
6277 mutex_lock(&devlink->lock);
6278 if (devlink_port_index_exists(devlink, port_index)) {
6279 mutex_unlock(&devlink->lock);
6282 devlink_port->devlink = devlink;
6283 devlink_port->index = port_index;
6284 devlink_port->registered = true;
6285 spin_lock_init(&devlink_port->type_lock);
6286 list_add_tail(&devlink_port->list, &devlink->port_list);
6287 INIT_LIST_HEAD(&devlink_port->param_list);
6288 mutex_unlock(&devlink->lock);
6289 INIT_DELAYED_WORK(&devlink_port->type_warn_dw, &devlink_port_type_warn);
6290 devlink_port_type_warn_schedule(devlink_port);
6291 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
6294 EXPORT_SYMBOL_GPL(devlink_port_register);
6297 * devlink_port_unregister - Unregister devlink port
6299 * @devlink_port: devlink port
6301 void devlink_port_unregister(struct devlink_port *devlink_port)
6303 struct devlink *devlink = devlink_port->devlink;
6305 devlink_port_type_warn_cancel(devlink_port);
6306 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
6307 mutex_lock(&devlink->lock);
6308 list_del(&devlink_port->list);
6309 mutex_unlock(&devlink->lock);
6311 EXPORT_SYMBOL_GPL(devlink_port_unregister);
6313 static void __devlink_port_type_set(struct devlink_port *devlink_port,
6314 enum devlink_port_type type,
6317 if (WARN_ON(!devlink_port->registered))
6319 devlink_port_type_warn_cancel(devlink_port);
6320 spin_lock_bh(&devlink_port->type_lock);
6321 devlink_port->type = type;
6322 devlink_port->type_dev = type_dev;
6323 spin_unlock_bh(&devlink_port->type_lock);
6324 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
6328 * devlink_port_type_eth_set - Set port type to Ethernet
6330 * @devlink_port: devlink port
6331 * @netdev: related netdevice
6333 void devlink_port_type_eth_set(struct devlink_port *devlink_port,
6334 struct net_device *netdev)
6336 const struct net_device_ops *ops = netdev->netdev_ops;
6338 /* If driver registers devlink port, it should set devlink port
6339 * attributes accordingly so the compat functions are called
6340 * and the original ops are not used.
6342 if (ops->ndo_get_phys_port_name) {
6343 /* Some drivers use the same set of ndos for netdevs
6344 * that have devlink_port registered and also for
6345 * those who don't. Make sure that ndo_get_phys_port_name
6346 * returns -EOPNOTSUPP here in case it is defined.
6349 char name[IFNAMSIZ];
6352 err = ops->ndo_get_phys_port_name(netdev, name, sizeof(name));
6353 WARN_ON(err != -EOPNOTSUPP);
6355 if (ops->ndo_get_port_parent_id) {
6356 /* Some drivers use the same set of ndos for netdevs
6357 * that have devlink_port registered and also for
6358 * those who don't. Make sure that ndo_get_port_parent_id
6359 * returns -EOPNOTSUPP here in case it is defined.
6362 struct netdev_phys_item_id ppid;
6365 err = ops->ndo_get_port_parent_id(netdev, &ppid);
6366 WARN_ON(err != -EOPNOTSUPP);
6368 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, netdev);
6370 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
6373 * devlink_port_type_ib_set - Set port type to InfiniBand
6375 * @devlink_port: devlink port
6376 * @ibdev: related IB device
6378 void devlink_port_type_ib_set(struct devlink_port *devlink_port,
6379 struct ib_device *ibdev)
6381 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_IB, ibdev);
6383 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
6386 * devlink_port_type_clear - Clear port type
6388 * @devlink_port: devlink port
6390 void devlink_port_type_clear(struct devlink_port *devlink_port)
6392 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, NULL);
6393 devlink_port_type_warn_schedule(devlink_port);
6395 EXPORT_SYMBOL_GPL(devlink_port_type_clear);
6397 static int __devlink_port_attrs_set(struct devlink_port *devlink_port,
6398 enum devlink_port_flavour flavour,
6399 const unsigned char *switch_id,
6400 unsigned char switch_id_len)
6402 struct devlink_port_attrs *attrs = &devlink_port->attrs;
6404 if (WARN_ON(devlink_port->registered))
6407 attrs->flavour = flavour;
6409 attrs->switch_port = true;
6410 if (WARN_ON(switch_id_len > MAX_PHYS_ITEM_ID_LEN))
6411 switch_id_len = MAX_PHYS_ITEM_ID_LEN;
6412 memcpy(attrs->switch_id.id, switch_id, switch_id_len);
6413 attrs->switch_id.id_len = switch_id_len;
6415 attrs->switch_port = false;
6421 * devlink_port_attrs_set - Set port attributes
6423 * @devlink_port: devlink port
6424 * @flavour: flavour of the port
6425 * @port_number: number of the port that is facing user, for example
6426 * the front panel port number
6427 * @split: indicates if this is split port
6428 * @split_subport_number: if the port is split, this is the number
6430 * @switch_id: if the port is part of switch, this is buffer with ID,
6431 * otwerwise this is NULL
6432 * @switch_id_len: length of the switch_id buffer
6434 void devlink_port_attrs_set(struct devlink_port *devlink_port,
6435 enum devlink_port_flavour flavour,
6436 u32 port_number, bool split,
6437 u32 split_subport_number,
6438 const unsigned char *switch_id,
6439 unsigned char switch_id_len)
6441 struct devlink_port_attrs *attrs = &devlink_port->attrs;
6444 ret = __devlink_port_attrs_set(devlink_port, flavour,
6445 switch_id, switch_id_len);
6448 attrs->split = split;
6449 attrs->phys.port_number = port_number;
6450 attrs->phys.split_subport_number = split_subport_number;
6452 EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
6455 * devlink_port_attrs_pci_pf_set - Set PCI PF port attributes
6457 * @devlink_port: devlink port
6458 * @pf: associated PF for the devlink port instance
6459 * @switch_id: if the port is part of switch, this is buffer with ID,
6460 * otherwise this is NULL
6461 * @switch_id_len: length of the switch_id buffer
6463 void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port,
6464 const unsigned char *switch_id,
6465 unsigned char switch_id_len, u16 pf)
6467 struct devlink_port_attrs *attrs = &devlink_port->attrs;
6470 ret = __devlink_port_attrs_set(devlink_port,
6471 DEVLINK_PORT_FLAVOUR_PCI_PF,
6472 switch_id, switch_id_len);
6476 attrs->pci_pf.pf = pf;
6478 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set);
6481 * devlink_port_attrs_pci_vf_set - Set PCI VF port attributes
6483 * @devlink_port: devlink port
6484 * @pf: associated PF for the devlink port instance
6485 * @vf: associated VF of a PF for the devlink port instance
6486 * @switch_id: if the port is part of switch, this is buffer with ID,
6487 * otherwise this is NULL
6488 * @switch_id_len: length of the switch_id buffer
6490 void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port,
6491 const unsigned char *switch_id,
6492 unsigned char switch_id_len,
6495 struct devlink_port_attrs *attrs = &devlink_port->attrs;
6498 ret = __devlink_port_attrs_set(devlink_port,
6499 DEVLINK_PORT_FLAVOUR_PCI_VF,
6500 switch_id, switch_id_len);
6503 attrs->pci_vf.pf = pf;
6504 attrs->pci_vf.vf = vf;
6506 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set);
6508 static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
6509 char *name, size_t len)
6511 struct devlink_port_attrs *attrs = &devlink_port->attrs;
6517 switch (attrs->flavour) {
6518 case DEVLINK_PORT_FLAVOUR_PHYSICAL:
6520 n = snprintf(name, len, "p%u", attrs->phys.port_number);
6522 n = snprintf(name, len, "p%us%u",
6523 attrs->phys.port_number,
6524 attrs->phys.split_subport_number);
6526 case DEVLINK_PORT_FLAVOUR_CPU:
6527 case DEVLINK_PORT_FLAVOUR_DSA:
6528 /* As CPU and DSA ports do not have a netdevice associated
6529 * case should not ever happen.
6533 case DEVLINK_PORT_FLAVOUR_PCI_PF:
6534 n = snprintf(name, len, "pf%u", attrs->pci_pf.pf);
6536 case DEVLINK_PORT_FLAVOUR_PCI_VF:
6537 n = snprintf(name, len, "pf%uvf%u",
6538 attrs->pci_vf.pf, attrs->pci_vf.vf);
6548 int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
6549 u32 size, u16 ingress_pools_count,
6550 u16 egress_pools_count, u16 ingress_tc_count,
6551 u16 egress_tc_count)
6553 struct devlink_sb *devlink_sb;
6556 mutex_lock(&devlink->lock);
6557 if (devlink_sb_index_exists(devlink, sb_index)) {
6562 devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
6567 devlink_sb->index = sb_index;
6568 devlink_sb->size = size;
6569 devlink_sb->ingress_pools_count = ingress_pools_count;
6570 devlink_sb->egress_pools_count = egress_pools_count;
6571 devlink_sb->ingress_tc_count = ingress_tc_count;
6572 devlink_sb->egress_tc_count = egress_tc_count;
6573 list_add_tail(&devlink_sb->list, &devlink->sb_list);
6575 mutex_unlock(&devlink->lock);
6578 EXPORT_SYMBOL_GPL(devlink_sb_register);
6580 void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
6582 struct devlink_sb *devlink_sb;
6584 mutex_lock(&devlink->lock);
6585 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
6586 WARN_ON(!devlink_sb);
6587 list_del(&devlink_sb->list);
6588 mutex_unlock(&devlink->lock);
6591 EXPORT_SYMBOL_GPL(devlink_sb_unregister);
6594 * devlink_dpipe_headers_register - register dpipe headers
6597 * @dpipe_headers: dpipe header array
6599 * Register the headers supported by hardware.
6601 int devlink_dpipe_headers_register(struct devlink *devlink,
6602 struct devlink_dpipe_headers *dpipe_headers)
6604 mutex_lock(&devlink->lock);
6605 devlink->dpipe_headers = dpipe_headers;
6606 mutex_unlock(&devlink->lock);
6609 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register);
6612 * devlink_dpipe_headers_unregister - unregister dpipe headers
6616 * Unregister the headers supported by hardware.
6618 void devlink_dpipe_headers_unregister(struct devlink *devlink)
6620 mutex_lock(&devlink->lock);
6621 devlink->dpipe_headers = NULL;
6622 mutex_unlock(&devlink->lock);
6624 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister);
6627 * devlink_dpipe_table_counter_enabled - check if counter allocation
6630 * @table_name: tables name
6632 * Used by driver to check if counter allocation is required.
6633 * After counter allocation is turned on the table entries
6634 * are updated to include counter statistics.
6636 * After that point on the driver must respect the counter
6637 * state so that each entry added to the table is added
6640 bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
6641 const char *table_name)
6643 struct devlink_dpipe_table *table;
6647 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
6651 enabled = table->counters_enabled;
6655 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled);
6658 * devlink_dpipe_table_register - register dpipe table
6661 * @table_name: table name
6662 * @table_ops: table ops
6664 * @counter_control_extern: external control for counters
6666 int devlink_dpipe_table_register(struct devlink *devlink,
6667 const char *table_name,
6668 struct devlink_dpipe_table_ops *table_ops,
6669 void *priv, bool counter_control_extern)
6671 struct devlink_dpipe_table *table;
6673 if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name))
6676 if (WARN_ON(!table_ops->size_get))
6679 table = kzalloc(sizeof(*table), GFP_KERNEL);
6683 table->name = table_name;
6684 table->table_ops = table_ops;
6686 table->counter_control_extern = counter_control_extern;
6688 mutex_lock(&devlink->lock);
6689 list_add_tail_rcu(&table->list, &devlink->dpipe_table_list);
6690 mutex_unlock(&devlink->lock);
6693 EXPORT_SYMBOL_GPL(devlink_dpipe_table_register);
6696 * devlink_dpipe_table_unregister - unregister dpipe table
6699 * @table_name: table name
6701 void devlink_dpipe_table_unregister(struct devlink *devlink,
6702 const char *table_name)
6704 struct devlink_dpipe_table *table;
6706 mutex_lock(&devlink->lock);
6707 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
6711 list_del_rcu(&table->list);
6712 mutex_unlock(&devlink->lock);
6713 kfree_rcu(table, rcu);
6716 mutex_unlock(&devlink->lock);
6718 EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister);
6721 * devlink_resource_register - devlink resource register
6724 * @resource_name: resource's name
6725 * @resource_size: resource's size
6726 * @resource_id: resource's id
6727 * @parent_resource_id: resource's parent id
6728 * @size_params: size parameters
6730 int devlink_resource_register(struct devlink *devlink,
6731 const char *resource_name,
6734 u64 parent_resource_id,
6735 const struct devlink_resource_size_params *size_params)
6737 struct devlink_resource *resource;
6738 struct list_head *resource_list;
6742 top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
6744 mutex_lock(&devlink->lock);
6745 resource = devlink_resource_find(devlink, NULL, resource_id);
6751 resource = kzalloc(sizeof(*resource), GFP_KERNEL);
6757 if (top_hierarchy) {
6758 resource_list = &devlink->resource_list;
6760 struct devlink_resource *parent_resource;
6762 parent_resource = devlink_resource_find(devlink, NULL,
6763 parent_resource_id);
6764 if (parent_resource) {
6765 resource_list = &parent_resource->resource_list;
6766 resource->parent = parent_resource;
6774 resource->name = resource_name;
6775 resource->size = resource_size;
6776 resource->size_new = resource_size;
6777 resource->id = resource_id;
6778 resource->size_valid = true;
6779 memcpy(&resource->size_params, size_params,
6780 sizeof(resource->size_params));
6781 INIT_LIST_HEAD(&resource->resource_list);
6782 list_add_tail(&resource->list, resource_list);
6784 mutex_unlock(&devlink->lock);
6787 EXPORT_SYMBOL_GPL(devlink_resource_register);
6790 * devlink_resources_unregister - free all resources
6793 * @resource: resource
6795 void devlink_resources_unregister(struct devlink *devlink,
6796 struct devlink_resource *resource)
6798 struct devlink_resource *tmp, *child_resource;
6799 struct list_head *resource_list;
6802 resource_list = &resource->resource_list;
6804 resource_list = &devlink->resource_list;
6807 mutex_lock(&devlink->lock);
6809 list_for_each_entry_safe(child_resource, tmp, resource_list, list) {
6810 devlink_resources_unregister(devlink, child_resource);
6811 list_del(&child_resource->list);
6812 kfree(child_resource);
6816 mutex_unlock(&devlink->lock);
6818 EXPORT_SYMBOL_GPL(devlink_resources_unregister);
6821 * devlink_resource_size_get - get and update size
6824 * @resource_id: the requested resource id
6825 * @p_resource_size: ptr to update
6827 int devlink_resource_size_get(struct devlink *devlink,
6829 u64 *p_resource_size)
6831 struct devlink_resource *resource;
6834 mutex_lock(&devlink->lock);
6835 resource = devlink_resource_find(devlink, NULL, resource_id);
6840 *p_resource_size = resource->size_new;
6841 resource->size = resource->size_new;
6843 mutex_unlock(&devlink->lock);
6846 EXPORT_SYMBOL_GPL(devlink_resource_size_get);
6849 * devlink_dpipe_table_resource_set - set the resource id
6852 * @table_name: table name
6853 * @resource_id: resource id
6854 * @resource_units: number of resource's units consumed per table's entry
6856 int devlink_dpipe_table_resource_set(struct devlink *devlink,
6857 const char *table_name, u64 resource_id,
6860 struct devlink_dpipe_table *table;
6863 mutex_lock(&devlink->lock);
6864 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
6870 table->resource_id = resource_id;
6871 table->resource_units = resource_units;
6872 table->resource_valid = true;
6874 mutex_unlock(&devlink->lock);
6877 EXPORT_SYMBOL_GPL(devlink_dpipe_table_resource_set);
6880 * devlink_resource_occ_get_register - register occupancy getter
6883 * @resource_id: resource id
6884 * @occ_get: occupancy getter callback
6885 * @occ_get_priv: occupancy getter callback priv
6887 void devlink_resource_occ_get_register(struct devlink *devlink,
6889 devlink_resource_occ_get_t *occ_get,
6892 struct devlink_resource *resource;
6894 mutex_lock(&devlink->lock);
6895 resource = devlink_resource_find(devlink, NULL, resource_id);
6896 if (WARN_ON(!resource))
6898 WARN_ON(resource->occ_get);
6900 resource->occ_get = occ_get;
6901 resource->occ_get_priv = occ_get_priv;
6903 mutex_unlock(&devlink->lock);
6905 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register);
6908 * devlink_resource_occ_get_unregister - unregister occupancy getter
6911 * @resource_id: resource id
6913 void devlink_resource_occ_get_unregister(struct devlink *devlink,
6916 struct devlink_resource *resource;
6918 mutex_lock(&devlink->lock);
6919 resource = devlink_resource_find(devlink, NULL, resource_id);
6920 if (WARN_ON(!resource))
6922 WARN_ON(!resource->occ_get);
6924 resource->occ_get = NULL;
6925 resource->occ_get_priv = NULL;
6927 mutex_unlock(&devlink->lock);
6929 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister);
6931 static int devlink_param_verify(const struct devlink_param *param)
6933 if (!param || !param->name || !param->supported_cmodes)
6936 return devlink_param_generic_verify(param);
6938 return devlink_param_driver_verify(param);
6941 static int __devlink_params_register(struct devlink *devlink,
6942 unsigned int port_index,
6943 struct list_head *param_list,
6944 const struct devlink_param *params,
6945 size_t params_count,
6946 enum devlink_command reg_cmd,
6947 enum devlink_command unreg_cmd)
6949 const struct devlink_param *param = params;
6953 mutex_lock(&devlink->lock);
6954 for (i = 0; i < params_count; i++, param++) {
6955 err = devlink_param_verify(param);
6959 err = devlink_param_register_one(devlink, port_index,
6960 param_list, param, reg_cmd);
6965 mutex_unlock(&devlink->lock);
6971 for (param--; i > 0; i--, param--)
6972 devlink_param_unregister_one(devlink, port_index, param_list,
6975 mutex_unlock(&devlink->lock);
6979 static void __devlink_params_unregister(struct devlink *devlink,
6980 unsigned int port_index,
6981 struct list_head *param_list,
6982 const struct devlink_param *params,
6983 size_t params_count,
6984 enum devlink_command cmd)
6986 const struct devlink_param *param = params;
6989 mutex_lock(&devlink->lock);
6990 for (i = 0; i < params_count; i++, param++)
6991 devlink_param_unregister_one(devlink, 0, param_list, param,
6993 mutex_unlock(&devlink->lock);
6997 * devlink_params_register - register configuration parameters
7000 * @params: configuration parameters array
7001 * @params_count: number of parameters provided
7003 * Register the configuration parameters supported by the driver.
7005 int devlink_params_register(struct devlink *devlink,
7006 const struct devlink_param *params,
7007 size_t params_count)
7009 return __devlink_params_register(devlink, 0, &devlink->param_list,
7010 params, params_count,
7011 DEVLINK_CMD_PARAM_NEW,
7012 DEVLINK_CMD_PARAM_DEL);
7014 EXPORT_SYMBOL_GPL(devlink_params_register);
7017 * devlink_params_unregister - unregister configuration parameters
7019 * @params: configuration parameters to unregister
7020 * @params_count: number of parameters provided
7022 void devlink_params_unregister(struct devlink *devlink,
7023 const struct devlink_param *params,
7024 size_t params_count)
7026 return __devlink_params_unregister(devlink, 0, &devlink->param_list,
7027 params, params_count,
7028 DEVLINK_CMD_PARAM_DEL);
7030 EXPORT_SYMBOL_GPL(devlink_params_unregister);
7033 * devlink_params_publish - publish configuration parameters
7037 * Publish previously registered configuration parameters.
7039 void devlink_params_publish(struct devlink *devlink)
7041 struct devlink_param_item *param_item;
7043 list_for_each_entry(param_item, &devlink->param_list, list) {
7044 if (param_item->published)
7046 param_item->published = true;
7047 devlink_param_notify(devlink, 0, param_item,
7048 DEVLINK_CMD_PARAM_NEW);
7051 EXPORT_SYMBOL_GPL(devlink_params_publish);
7054 * devlink_params_unpublish - unpublish configuration parameters
7058 * Unpublish previously registered configuration parameters.
7060 void devlink_params_unpublish(struct devlink *devlink)
7062 struct devlink_param_item *param_item;
7064 list_for_each_entry(param_item, &devlink->param_list, list) {
7065 if (!param_item->published)
7067 param_item->published = false;
7068 devlink_param_notify(devlink, 0, param_item,
7069 DEVLINK_CMD_PARAM_DEL);
7072 EXPORT_SYMBOL_GPL(devlink_params_unpublish);
7075 * devlink_port_params_register - register port configuration parameters
7077 * @devlink_port: devlink port
7078 * @params: configuration parameters array
7079 * @params_count: number of parameters provided
7081 * Register the configuration parameters supported by the port.
7083 int devlink_port_params_register(struct devlink_port *devlink_port,
7084 const struct devlink_param *params,
7085 size_t params_count)
7087 return __devlink_params_register(devlink_port->devlink,
7088 devlink_port->index,
7089 &devlink_port->param_list, params,
7091 DEVLINK_CMD_PORT_PARAM_NEW,
7092 DEVLINK_CMD_PORT_PARAM_DEL);
7094 EXPORT_SYMBOL_GPL(devlink_port_params_register);
7097 * devlink_port_params_unregister - unregister port configuration
7100 * @devlink_port: devlink port
7101 * @params: configuration parameters array
7102 * @params_count: number of parameters provided
7104 void devlink_port_params_unregister(struct devlink_port *devlink_port,
7105 const struct devlink_param *params,
7106 size_t params_count)
7108 return __devlink_params_unregister(devlink_port->devlink,
7109 devlink_port->index,
7110 &devlink_port->param_list,
7111 params, params_count,
7112 DEVLINK_CMD_PORT_PARAM_DEL);
7114 EXPORT_SYMBOL_GPL(devlink_port_params_unregister);
7117 __devlink_param_driverinit_value_get(struct list_head *param_list, u32 param_id,
7118 union devlink_param_value *init_val)
7120 struct devlink_param_item *param_item;
7122 param_item = devlink_param_find_by_id(param_list, param_id);
7126 if (!param_item->driverinit_value_valid ||
7127 !devlink_param_cmode_is_supported(param_item->param,
7128 DEVLINK_PARAM_CMODE_DRIVERINIT))
7131 if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
7132 strcpy(init_val->vstr, param_item->driverinit_value.vstr);
7134 *init_val = param_item->driverinit_value;
7140 __devlink_param_driverinit_value_set(struct devlink *devlink,
7141 unsigned int port_index,
7142 struct list_head *param_list, u32 param_id,
7143 union devlink_param_value init_val,
7144 enum devlink_command cmd)
7146 struct devlink_param_item *param_item;
7148 param_item = devlink_param_find_by_id(param_list, param_id);
7152 if (!devlink_param_cmode_is_supported(param_item->param,
7153 DEVLINK_PARAM_CMODE_DRIVERINIT))
7156 if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
7157 strcpy(param_item->driverinit_value.vstr, init_val.vstr);
7159 param_item->driverinit_value = init_val;
7160 param_item->driverinit_value_valid = true;
7162 devlink_param_notify(devlink, port_index, param_item, cmd);
7167 * devlink_param_driverinit_value_get - get configuration parameter
7168 * value for driver initializing
7171 * @param_id: parameter ID
7172 * @init_val: value of parameter in driverinit configuration mode
7174 * This function should be used by the driver to get driverinit
7175 * configuration for initialization after reload command.
7177 int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
7178 union devlink_param_value *init_val)
7180 if (!devlink_reload_supported(devlink))
7183 return __devlink_param_driverinit_value_get(&devlink->param_list,
7184 param_id, init_val);
7186 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_get);
7189 * devlink_param_driverinit_value_set - set value of configuration
7190 * parameter for driverinit
7191 * configuration mode
7194 * @param_id: parameter ID
7195 * @init_val: value of parameter to set for driverinit configuration mode
7197 * This function should be used by the driver to set driverinit
7198 * configuration mode default value.
7200 int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
7201 union devlink_param_value init_val)
7203 return __devlink_param_driverinit_value_set(devlink, 0,
7204 &devlink->param_list,
7206 DEVLINK_CMD_PARAM_NEW);
7208 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set);
7211 * devlink_port_param_driverinit_value_get - get configuration parameter
7212 * value for driver initializing
7214 * @devlink_port: devlink_port
7215 * @param_id: parameter ID
7216 * @init_val: value of parameter in driverinit configuration mode
7218 * This function should be used by the driver to get driverinit
7219 * configuration for initialization after reload command.
7221 int devlink_port_param_driverinit_value_get(struct devlink_port *devlink_port,
7223 union devlink_param_value *init_val)
7225 struct devlink *devlink = devlink_port->devlink;
7227 if (!devlink_reload_supported(devlink))
7230 return __devlink_param_driverinit_value_get(&devlink_port->param_list,
7231 param_id, init_val);
7233 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_get);
7236 * devlink_port_param_driverinit_value_set - set value of configuration
7237 * parameter for driverinit
7238 * configuration mode
7240 * @devlink_port: devlink_port
7241 * @param_id: parameter ID
7242 * @init_val: value of parameter to set for driverinit configuration mode
7244 * This function should be used by the driver to set driverinit
7245 * configuration mode default value.
7247 int devlink_port_param_driverinit_value_set(struct devlink_port *devlink_port,
7249 union devlink_param_value init_val)
7251 return __devlink_param_driverinit_value_set(devlink_port->devlink,
7252 devlink_port->index,
7253 &devlink_port->param_list,
7255 DEVLINK_CMD_PORT_PARAM_NEW);
7257 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_set);
7260 * devlink_param_value_changed - notify devlink on a parameter's value
7261 * change. Should be called by the driver
7262 * right after the change.
7265 * @param_id: parameter ID
7267 * This function should be used by the driver to notify devlink on value
7268 * change, excluding driverinit configuration mode.
7269 * For driverinit configuration mode driver should use the function
7271 void devlink_param_value_changed(struct devlink *devlink, u32 param_id)
7273 struct devlink_param_item *param_item;
7275 param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
7276 WARN_ON(!param_item);
7278 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
7280 EXPORT_SYMBOL_GPL(devlink_param_value_changed);
7283 * devlink_port_param_value_changed - notify devlink on a parameter's value
7284 * change. Should be called by the driver
7285 * right after the change.
7287 * @devlink_port: devlink_port
7288 * @param_id: parameter ID
7290 * This function should be used by the driver to notify devlink on value
7291 * change, excluding driverinit configuration mode.
7292 * For driverinit configuration mode driver should use the function
7293 * devlink_port_param_driverinit_value_set() instead.
7295 void devlink_port_param_value_changed(struct devlink_port *devlink_port,
7298 struct devlink_param_item *param_item;
7300 param_item = devlink_param_find_by_id(&devlink_port->param_list,
7302 WARN_ON(!param_item);
7304 devlink_param_notify(devlink_port->devlink, devlink_port->index,
7305 param_item, DEVLINK_CMD_PORT_PARAM_NEW);
7307 EXPORT_SYMBOL_GPL(devlink_port_param_value_changed);
7310 * devlink_param_value_str_fill - Safely fill-up the string preventing
7311 * from overflow of the preallocated buffer
7313 * @dst_val: destination devlink_param_value
7314 * @src: source buffer
7316 void devlink_param_value_str_fill(union devlink_param_value *dst_val,
7321 len = strlcpy(dst_val->vstr, src, __DEVLINK_PARAM_MAX_STRING_VALUE);
7322 WARN_ON(len >= __DEVLINK_PARAM_MAX_STRING_VALUE);
7324 EXPORT_SYMBOL_GPL(devlink_param_value_str_fill);
7327 * devlink_region_create - create a new address region
7330 * @region_name: region name
7331 * @region_max_snapshots: Maximum supported number of snapshots for region
7332 * @region_size: size of region
7334 struct devlink_region *devlink_region_create(struct devlink *devlink,
7335 const char *region_name,
7336 u32 region_max_snapshots,
7339 struct devlink_region *region;
7342 mutex_lock(&devlink->lock);
7344 if (devlink_region_get_by_name(devlink, region_name)) {
7349 region = kzalloc(sizeof(*region), GFP_KERNEL);
7355 region->devlink = devlink;
7356 region->max_snapshots = region_max_snapshots;
7357 region->name = region_name;
7358 region->size = region_size;
7359 INIT_LIST_HEAD(®ion->snapshot_list);
7360 list_add_tail(®ion->list, &devlink->region_list);
7361 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
7363 mutex_unlock(&devlink->lock);
7367 mutex_unlock(&devlink->lock);
7368 return ERR_PTR(err);
7370 EXPORT_SYMBOL_GPL(devlink_region_create);
7373 * devlink_region_destroy - destroy address region
7375 * @region: devlink region to destroy
7377 void devlink_region_destroy(struct devlink_region *region)
7379 struct devlink *devlink = region->devlink;
7380 struct devlink_snapshot *snapshot, *ts;
7382 mutex_lock(&devlink->lock);
7384 /* Free all snapshots of region */
7385 list_for_each_entry_safe(snapshot, ts, ®ion->snapshot_list, list)
7386 devlink_region_snapshot_del(region, snapshot);
7388 list_del(®ion->list);
7390 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
7391 mutex_unlock(&devlink->lock);
7394 EXPORT_SYMBOL_GPL(devlink_region_destroy);
7397 * devlink_region_shapshot_id_get - get snapshot ID
7399 * This callback should be called when adding a new snapshot,
7400 * Driver should use the same id for multiple snapshots taken
7401 * on multiple regions at the same time/by the same trigger.
7405 u32 devlink_region_shapshot_id_get(struct devlink *devlink)
7409 mutex_lock(&devlink->lock);
7410 id = ++devlink->snapshot_id;
7411 mutex_unlock(&devlink->lock);
7415 EXPORT_SYMBOL_GPL(devlink_region_shapshot_id_get);
7418 * devlink_region_snapshot_create - create a new snapshot
7419 * This will add a new snapshot of a region. The snapshot
7420 * will be stored on the region struct and can be accessed
7421 * from devlink. This is useful for future analyses of snapshots.
7422 * Multiple snapshots can be created on a region.
7423 * The @snapshot_id should be obtained using the getter function.
7425 * @region: devlink region of the snapshot
7426 * @data: snapshot data
7427 * @snapshot_id: snapshot id to be created
7428 * @data_destructor: pointer to destructor function to free data
7430 int devlink_region_snapshot_create(struct devlink_region *region,
7431 u8 *data, u32 snapshot_id,
7432 devlink_snapshot_data_dest_t *data_destructor)
7434 struct devlink *devlink = region->devlink;
7435 struct devlink_snapshot *snapshot;
7438 mutex_lock(&devlink->lock);
7440 /* check if region can hold one more snapshot */
7441 if (region->cur_snapshots == region->max_snapshots) {
7446 if (devlink_region_snapshot_get_by_id(region, snapshot_id)) {
7451 snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL);
7457 snapshot->id = snapshot_id;
7458 snapshot->region = region;
7459 snapshot->data = data;
7460 snapshot->data_destructor = data_destructor;
7462 list_add_tail(&snapshot->list, ®ion->snapshot_list);
7464 region->cur_snapshots++;
7466 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW);
7467 mutex_unlock(&devlink->lock);
7471 mutex_unlock(&devlink->lock);
7474 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create);
7476 #define DEVLINK_TRAP(_id, _type) \
7478 .type = DEVLINK_TRAP_TYPE_##_type, \
7479 .id = DEVLINK_TRAP_GENERIC_ID_##_id, \
7480 .name = DEVLINK_TRAP_GENERIC_NAME_##_id, \
7483 static const struct devlink_trap devlink_trap_generic[] = {
7484 DEVLINK_TRAP(SMAC_MC, DROP),
7485 DEVLINK_TRAP(VLAN_TAG_MISMATCH, DROP),
7486 DEVLINK_TRAP(INGRESS_VLAN_FILTER, DROP),
7487 DEVLINK_TRAP(INGRESS_STP_FILTER, DROP),
7488 DEVLINK_TRAP(EMPTY_TX_LIST, DROP),
7489 DEVLINK_TRAP(PORT_LOOPBACK_FILTER, DROP),
7490 DEVLINK_TRAP(BLACKHOLE_ROUTE, DROP),
7491 DEVLINK_TRAP(TTL_ERROR, EXCEPTION),
7492 DEVLINK_TRAP(TAIL_DROP, DROP),
7495 #define DEVLINK_TRAP_GROUP(_id) \
7497 .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \
7498 .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \
7501 static const struct devlink_trap_group devlink_trap_group_generic[] = {
7502 DEVLINK_TRAP_GROUP(L2_DROPS),
7503 DEVLINK_TRAP_GROUP(L3_DROPS),
7504 DEVLINK_TRAP_GROUP(BUFFER_DROPS),
7507 static int devlink_trap_generic_verify(const struct devlink_trap *trap)
7509 if (trap->id > DEVLINK_TRAP_GENERIC_ID_MAX)
7512 if (strcmp(trap->name, devlink_trap_generic[trap->id].name))
7515 if (trap->type != devlink_trap_generic[trap->id].type)
7521 static int devlink_trap_driver_verify(const struct devlink_trap *trap)
7525 if (trap->id <= DEVLINK_TRAP_GENERIC_ID_MAX)
7528 for (i = 0; i < ARRAY_SIZE(devlink_trap_generic); i++) {
7529 if (!strcmp(trap->name, devlink_trap_generic[i].name))
7536 static int devlink_trap_verify(const struct devlink_trap *trap)
7538 if (!trap || !trap->name || !trap->group.name)
7542 return devlink_trap_generic_verify(trap);
7544 return devlink_trap_driver_verify(trap);
7548 devlink_trap_group_generic_verify(const struct devlink_trap_group *group)
7550 if (group->id > DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
7553 if (strcmp(group->name, devlink_trap_group_generic[group->id].name))
7560 devlink_trap_group_driver_verify(const struct devlink_trap_group *group)
7564 if (group->id <= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
7567 for (i = 0; i < ARRAY_SIZE(devlink_trap_group_generic); i++) {
7568 if (!strcmp(group->name, devlink_trap_group_generic[i].name))
7575 static int devlink_trap_group_verify(const struct devlink_trap_group *group)
7578 return devlink_trap_group_generic_verify(group);
7580 return devlink_trap_group_driver_verify(group);
7584 devlink_trap_group_notify(struct devlink *devlink,
7585 const struct devlink_trap_group_item *group_item,
7586 enum devlink_command cmd)
7588 struct sk_buff *msg;
7591 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_GROUP_NEW &&
7592 cmd != DEVLINK_CMD_TRAP_GROUP_DEL);
7594 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7598 err = devlink_nl_trap_group_fill(msg, devlink, group_item, cmd, 0, 0,
7605 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
7606 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
7609 static struct devlink_trap_group_item *
7610 devlink_trap_group_item_create(struct devlink *devlink,
7611 const struct devlink_trap_group *group)
7613 struct devlink_trap_group_item *group_item;
7616 err = devlink_trap_group_verify(group);
7618 return ERR_PTR(err);
7620 group_item = kzalloc(sizeof(*group_item), GFP_KERNEL);
7622 return ERR_PTR(-ENOMEM);
7624 group_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
7625 if (!group_item->stats) {
7627 goto err_stats_alloc;
7630 group_item->group = group;
7631 refcount_set(&group_item->refcount, 1);
7633 if (devlink->ops->trap_group_init) {
7634 err = devlink->ops->trap_group_init(devlink, group);
7636 goto err_group_init;
7639 list_add_tail(&group_item->list, &devlink->trap_group_list);
7640 devlink_trap_group_notify(devlink, group_item,
7641 DEVLINK_CMD_TRAP_GROUP_NEW);
7646 free_percpu(group_item->stats);
7649 return ERR_PTR(err);
7653 devlink_trap_group_item_destroy(struct devlink *devlink,
7654 struct devlink_trap_group_item *group_item)
7656 devlink_trap_group_notify(devlink, group_item,
7657 DEVLINK_CMD_TRAP_GROUP_DEL);
7658 list_del(&group_item->list);
7659 free_percpu(group_item->stats);
7663 static struct devlink_trap_group_item *
7664 devlink_trap_group_item_get(struct devlink *devlink,
7665 const struct devlink_trap_group *group)
7667 struct devlink_trap_group_item *group_item;
7669 group_item = devlink_trap_group_item_lookup(devlink, group->name);
7671 refcount_inc(&group_item->refcount);
7675 return devlink_trap_group_item_create(devlink, group);
7679 devlink_trap_group_item_put(struct devlink *devlink,
7680 struct devlink_trap_group_item *group_item)
7682 if (!refcount_dec_and_test(&group_item->refcount))
7685 devlink_trap_group_item_destroy(devlink, group_item);
7689 devlink_trap_item_group_link(struct devlink *devlink,
7690 struct devlink_trap_item *trap_item)
7692 struct devlink_trap_group_item *group_item;
7694 group_item = devlink_trap_group_item_get(devlink,
7695 &trap_item->trap->group);
7696 if (IS_ERR(group_item))
7697 return PTR_ERR(group_item);
7699 trap_item->group_item = group_item;
7705 devlink_trap_item_group_unlink(struct devlink *devlink,
7706 struct devlink_trap_item *trap_item)
7708 devlink_trap_group_item_put(devlink, trap_item->group_item);
7711 static void devlink_trap_notify(struct devlink *devlink,
7712 const struct devlink_trap_item *trap_item,
7713 enum devlink_command cmd)
7715 struct sk_buff *msg;
7718 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_NEW &&
7719 cmd != DEVLINK_CMD_TRAP_DEL);
7721 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7725 err = devlink_nl_trap_fill(msg, devlink, trap_item, cmd, 0, 0, 0);
7731 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
7732 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
7736 devlink_trap_register(struct devlink *devlink,
7737 const struct devlink_trap *trap, void *priv)
7739 struct devlink_trap_item *trap_item;
7742 if (devlink_trap_item_lookup(devlink, trap->name))
7745 trap_item = kzalloc(sizeof(*trap_item), GFP_KERNEL);
7749 trap_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
7750 if (!trap_item->stats) {
7752 goto err_stats_alloc;
7755 trap_item->trap = trap;
7756 trap_item->action = trap->init_action;
7757 trap_item->priv = priv;
7759 err = devlink_trap_item_group_link(devlink, trap_item);
7761 goto err_group_link;
7763 err = devlink->ops->trap_init(devlink, trap, trap_item);
7767 list_add_tail(&trap_item->list, &devlink->trap_list);
7768 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
7773 devlink_trap_item_group_unlink(devlink, trap_item);
7775 free_percpu(trap_item->stats);
7781 static void devlink_trap_unregister(struct devlink *devlink,
7782 const struct devlink_trap *trap)
7784 struct devlink_trap_item *trap_item;
7786 trap_item = devlink_trap_item_lookup(devlink, trap->name);
7787 if (WARN_ON_ONCE(!trap_item))
7790 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL);
7791 list_del(&trap_item->list);
7792 if (devlink->ops->trap_fini)
7793 devlink->ops->trap_fini(devlink, trap, trap_item);
7794 devlink_trap_item_group_unlink(devlink, trap_item);
7795 free_percpu(trap_item->stats);
7799 static void devlink_trap_disable(struct devlink *devlink,
7800 const struct devlink_trap *trap)
7802 struct devlink_trap_item *trap_item;
7804 trap_item = devlink_trap_item_lookup(devlink, trap->name);
7805 if (WARN_ON_ONCE(!trap_item))
7808 devlink->ops->trap_action_set(devlink, trap, DEVLINK_TRAP_ACTION_DROP);
7809 trap_item->action = DEVLINK_TRAP_ACTION_DROP;
7813 * devlink_traps_register - Register packet traps with devlink.
7814 * @devlink: devlink.
7815 * @traps: Packet traps.
7816 * @traps_count: Count of provided packet traps.
7817 * @priv: Driver private information.
7819 * Return: Non-zero value on failure.
7821 int devlink_traps_register(struct devlink *devlink,
7822 const struct devlink_trap *traps,
7823 size_t traps_count, void *priv)
7827 if (!devlink->ops->trap_init || !devlink->ops->trap_action_set)
7830 mutex_lock(&devlink->lock);
7831 for (i = 0; i < traps_count; i++) {
7832 const struct devlink_trap *trap = &traps[i];
7834 err = devlink_trap_verify(trap);
7836 goto err_trap_verify;
7838 err = devlink_trap_register(devlink, trap, priv);
7840 goto err_trap_register;
7842 mutex_unlock(&devlink->lock);
7848 for (i--; i >= 0; i--)
7849 devlink_trap_unregister(devlink, &traps[i]);
7850 mutex_unlock(&devlink->lock);
7853 EXPORT_SYMBOL_GPL(devlink_traps_register);
7856 * devlink_traps_unregister - Unregister packet traps from devlink.
7857 * @devlink: devlink.
7858 * @traps: Packet traps.
7859 * @traps_count: Count of provided packet traps.
7861 void devlink_traps_unregister(struct devlink *devlink,
7862 const struct devlink_trap *traps,
7867 mutex_lock(&devlink->lock);
7868 /* Make sure we do not have any packets in-flight while unregistering
7869 * traps by disabling all of them and waiting for a grace period.
7871 for (i = traps_count - 1; i >= 0; i--)
7872 devlink_trap_disable(devlink, &traps[i]);
7874 for (i = traps_count - 1; i >= 0; i--)
7875 devlink_trap_unregister(devlink, &traps[i]);
7876 mutex_unlock(&devlink->lock);
7878 EXPORT_SYMBOL_GPL(devlink_traps_unregister);
7881 devlink_trap_stats_update(struct devlink_stats __percpu *trap_stats,
7884 struct devlink_stats *stats;
7886 stats = this_cpu_ptr(trap_stats);
7887 u64_stats_update_begin(&stats->syncp);
7888 stats->rx_bytes += skb_len;
7889 stats->rx_packets++;
7890 u64_stats_update_end(&stats->syncp);
7894 devlink_trap_report_metadata_fill(struct net_dm_hw_metadata *hw_metadata,
7895 const struct devlink_trap_item *trap_item,
7896 struct devlink_port *in_devlink_port)
7898 struct devlink_trap_group_item *group_item = trap_item->group_item;
7900 hw_metadata->trap_group_name = group_item->group->name;
7901 hw_metadata->trap_name = trap_item->trap->name;
7903 spin_lock(&in_devlink_port->type_lock);
7904 if (in_devlink_port->type == DEVLINK_PORT_TYPE_ETH)
7905 hw_metadata->input_dev = in_devlink_port->type_dev;
7906 spin_unlock(&in_devlink_port->type_lock);
7910 * devlink_trap_report - Report trapped packet to drop monitor.
7911 * @devlink: devlink.
7912 * @skb: Trapped packet.
7913 * @trap_ctx: Trap context.
7914 * @in_devlink_port: Input devlink port.
7916 void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb,
7917 void *trap_ctx, struct devlink_port *in_devlink_port)
7919 struct devlink_trap_item *trap_item = trap_ctx;
7920 struct net_dm_hw_metadata hw_metadata = {};
7922 devlink_trap_stats_update(trap_item->stats, skb->len);
7923 devlink_trap_stats_update(trap_item->group_item->stats, skb->len);
7925 devlink_trap_report_metadata_fill(&hw_metadata, trap_item,
7927 net_dm_hw_report(skb, &hw_metadata);
7929 EXPORT_SYMBOL_GPL(devlink_trap_report);
7932 * devlink_trap_ctx_priv - Trap context to driver private information.
7933 * @trap_ctx: Trap context.
7935 * Return: Driver private information passed during registration.
7937 void *devlink_trap_ctx_priv(void *trap_ctx)
7939 struct devlink_trap_item *trap_item = trap_ctx;
7941 return trap_item->priv;
7943 EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv);
7945 static void __devlink_compat_running_version(struct devlink *devlink,
7946 char *buf, size_t len)
7948 const struct nlattr *nlattr;
7949 struct devlink_info_req req;
7950 struct sk_buff *msg;
7953 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7958 err = devlink->ops->info_get(devlink, &req, NULL);
7962 nla_for_each_attr(nlattr, (void *)msg->data, msg->len, rem) {
7963 const struct nlattr *kv;
7966 if (nla_type(nlattr) != DEVLINK_ATTR_INFO_VERSION_RUNNING)
7969 nla_for_each_nested(kv, nlattr, rem_kv) {
7970 if (nla_type(kv) != DEVLINK_ATTR_INFO_VERSION_VALUE)
7973 strlcat(buf, nla_data(kv), len);
7974 strlcat(buf, " ", len);
7981 void devlink_compat_running_version(struct net_device *dev,
7982 char *buf, size_t len)
7984 struct devlink *devlink;
7989 devlink = netdev_to_devlink(dev);
7990 if (!devlink || !devlink->ops->info_get)
7993 mutex_lock(&devlink->lock);
7994 __devlink_compat_running_version(devlink, buf, len);
7995 mutex_unlock(&devlink->lock);
8002 int devlink_compat_flash_update(struct net_device *dev, const char *file_name)
8004 struct devlink *devlink;
8010 devlink = netdev_to_devlink(dev);
8011 if (!devlink || !devlink->ops->flash_update) {
8016 mutex_lock(&devlink->lock);
8017 ret = devlink->ops->flash_update(devlink, file_name, NULL, NULL);
8018 mutex_unlock(&devlink->lock);
8027 int devlink_compat_phys_port_name_get(struct net_device *dev,
8028 char *name, size_t len)
8030 struct devlink_port *devlink_port;
8032 /* RTNL mutex is held here which ensures that devlink_port
8033 * instance cannot disappear in the middle. No need to take
8034 * any devlink lock as only permanent values are accessed.
8038 devlink_port = netdev_to_devlink_port(dev);
8042 return __devlink_port_phys_port_name_get(devlink_port, name, len);
8045 int devlink_compat_switch_id_get(struct net_device *dev,
8046 struct netdev_phys_item_id *ppid)
8048 struct devlink_port *devlink_port;
8050 /* Caller must hold RTNL mutex or reference to dev, which ensures that
8051 * devlink_port instance cannot disappear in the middle. No need to take
8052 * any devlink lock as only permanent values are accessed.
8054 devlink_port = netdev_to_devlink_port(dev);
8055 if (!devlink_port || !devlink_port->attrs.switch_port)
8058 memcpy(ppid, &devlink_port->attrs.switch_id, sizeof(*ppid));
8063 static int __init devlink_init(void)
8065 return genl_register_family(&devlink_nl_family);
8068 subsys_initcall(devlink_init);