1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * net/core/devlink.c - Network physical/parent device Netlink interface
5 * Heavily inspired by net/wireless/
6 * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
7 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/types.h>
13 #include <linux/slab.h>
14 #include <linux/gfp.h>
15 #include <linux/device.h>
16 #include <linux/list.h>
17 #include <linux/netdevice.h>
18 #include <linux/spinlock.h>
19 #include <linux/refcount.h>
20 #include <linux/workqueue.h>
21 #include <linux/u64_stats_sync.h>
22 #include <linux/timekeeping.h>
23 #include <rdma/ib_verbs.h>
24 #include <net/netlink.h>
25 #include <net/genetlink.h>
26 #include <net/rtnetlink.h>
27 #include <net/net_namespace.h>
29 #include <net/devlink.h>
30 #include <net/drop_monitor.h>
31 #define CREATE_TRACE_POINTS
32 #include <trace/events/devlink.h>
34 static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = {
36 .name = "destination mac",
37 .id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
42 struct devlink_dpipe_header devlink_dpipe_header_ethernet = {
44 .id = DEVLINK_DPIPE_HEADER_ETHERNET,
45 .fields = devlink_dpipe_fields_ethernet,
46 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet),
49 EXPORT_SYMBOL(devlink_dpipe_header_ethernet);
51 static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = {
53 .name = "destination ip",
54 .id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP,
59 struct devlink_dpipe_header devlink_dpipe_header_ipv4 = {
61 .id = DEVLINK_DPIPE_HEADER_IPV4,
62 .fields = devlink_dpipe_fields_ipv4,
63 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4),
66 EXPORT_SYMBOL(devlink_dpipe_header_ipv4);
68 static struct devlink_dpipe_field devlink_dpipe_fields_ipv6[] = {
70 .name = "destination ip",
71 .id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP,
76 struct devlink_dpipe_header devlink_dpipe_header_ipv6 = {
78 .id = DEVLINK_DPIPE_HEADER_IPV6,
79 .fields = devlink_dpipe_fields_ipv6,
80 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv6),
83 EXPORT_SYMBOL(devlink_dpipe_header_ipv6);
85 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg);
86 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwerr);
88 static const struct nla_policy devlink_function_nl_policy[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1] = {
89 [DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] = { .type = NLA_BINARY },
92 static LIST_HEAD(devlink_list);
96 * An overall lock guarding every operation coming from userspace.
97 * It also guards devlink devices list and it is taken when
98 * driver registers/unregisters it.
100 static DEFINE_MUTEX(devlink_mutex);
102 struct net *devlink_net(const struct devlink *devlink)
104 return read_pnet(&devlink->_net);
106 EXPORT_SYMBOL_GPL(devlink_net);
108 static void __devlink_net_set(struct devlink *devlink, struct net *net)
110 write_pnet(&devlink->_net, net);
113 void devlink_net_set(struct devlink *devlink, struct net *net)
115 if (WARN_ON(devlink->registered))
117 __devlink_net_set(devlink, net);
119 EXPORT_SYMBOL_GPL(devlink_net_set);
121 static struct devlink *devlink_get_from_attrs(struct net *net,
122 struct nlattr **attrs)
124 struct devlink *devlink;
128 if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME])
129 return ERR_PTR(-EINVAL);
131 busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]);
132 devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
134 lockdep_assert_held(&devlink_mutex);
136 list_for_each_entry(devlink, &devlink_list, list) {
137 if (strcmp(devlink->dev->bus->name, busname) == 0 &&
138 strcmp(dev_name(devlink->dev), devname) == 0 &&
139 net_eq(devlink_net(devlink), net))
143 return ERR_PTR(-ENODEV);
146 static struct devlink *devlink_get_from_info(struct genl_info *info)
148 return devlink_get_from_attrs(genl_info_net(info), info->attrs);
151 static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
152 unsigned int port_index)
154 struct devlink_port *devlink_port;
156 list_for_each_entry(devlink_port, &devlink->port_list, list) {
157 if (devlink_port->index == port_index)
163 static bool devlink_port_index_exists(struct devlink *devlink,
164 unsigned int port_index)
166 return devlink_port_get_by_index(devlink, port_index);
169 static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
170 struct nlattr **attrs)
172 if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
173 u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
174 struct devlink_port *devlink_port;
176 devlink_port = devlink_port_get_by_index(devlink, port_index);
178 return ERR_PTR(-ENODEV);
181 return ERR_PTR(-EINVAL);
184 static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
185 struct genl_info *info)
187 return devlink_port_get_from_attrs(devlink, info->attrs);
191 struct list_head list;
194 u16 ingress_pools_count;
195 u16 egress_pools_count;
196 u16 ingress_tc_count;
200 static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb)
202 return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count;
205 static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink,
206 unsigned int sb_index)
208 struct devlink_sb *devlink_sb;
210 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
211 if (devlink_sb->index == sb_index)
217 static bool devlink_sb_index_exists(struct devlink *devlink,
218 unsigned int sb_index)
220 return devlink_sb_get_by_index(devlink, sb_index);
223 static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink,
224 struct nlattr **attrs)
226 if (attrs[DEVLINK_ATTR_SB_INDEX]) {
227 u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]);
228 struct devlink_sb *devlink_sb;
230 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
232 return ERR_PTR(-ENODEV);
235 return ERR_PTR(-EINVAL);
238 static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink,
239 struct genl_info *info)
241 return devlink_sb_get_from_attrs(devlink, info->attrs);
244 static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb,
245 struct nlattr **attrs,
250 if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX])
253 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]);
254 if (val >= devlink_sb_pool_count(devlink_sb))
260 static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb,
261 struct genl_info *info,
264 return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs,
269 devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs,
270 enum devlink_sb_pool_type *p_pool_type)
274 if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE])
277 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]);
278 if (val != DEVLINK_SB_POOL_TYPE_INGRESS &&
279 val != DEVLINK_SB_POOL_TYPE_EGRESS)
286 devlink_sb_pool_type_get_from_info(struct genl_info *info,
287 enum devlink_sb_pool_type *p_pool_type)
289 return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type);
293 devlink_sb_th_type_get_from_attrs(struct nlattr **attrs,
294 enum devlink_sb_threshold_type *p_th_type)
298 if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])
301 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]);
302 if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC &&
303 val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC)
310 devlink_sb_th_type_get_from_info(struct genl_info *info,
311 enum devlink_sb_threshold_type *p_th_type)
313 return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type);
317 devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb,
318 struct nlattr **attrs,
319 enum devlink_sb_pool_type pool_type,
324 if (!attrs[DEVLINK_ATTR_SB_TC_INDEX])
327 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]);
328 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS &&
329 val >= devlink_sb->ingress_tc_count)
331 if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS &&
332 val >= devlink_sb->egress_tc_count)
339 devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
340 struct genl_info *info,
341 enum devlink_sb_pool_type pool_type,
344 return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs,
345 pool_type, p_tc_index);
348 struct devlink_region {
349 struct devlink *devlink;
350 struct list_head list;
351 const struct devlink_region_ops *ops;
352 struct list_head snapshot_list;
358 struct devlink_snapshot {
359 struct list_head list;
360 struct devlink_region *region;
365 static struct devlink_region *
366 devlink_region_get_by_name(struct devlink *devlink, const char *region_name)
368 struct devlink_region *region;
370 list_for_each_entry(region, &devlink->region_list, list)
371 if (!strcmp(region->ops->name, region_name))
377 static struct devlink_snapshot *
378 devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id)
380 struct devlink_snapshot *snapshot;
382 list_for_each_entry(snapshot, ®ion->snapshot_list, list)
383 if (snapshot->id == id)
389 #define DEVLINK_NL_FLAG_NEED_PORT BIT(0)
390 #define DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT BIT(1)
392 /* The per devlink instance lock is taken by default in the pre-doit
393 * operation, yet several commands do not require this. The global
394 * devlink lock is taken and protects from disruption by user-calls.
396 #define DEVLINK_NL_FLAG_NO_LOCK BIT(2)
398 static int devlink_nl_pre_doit(const struct genl_ops *ops,
399 struct sk_buff *skb, struct genl_info *info)
401 struct devlink_port *devlink_port;
402 struct devlink *devlink;
405 mutex_lock(&devlink_mutex);
406 devlink = devlink_get_from_info(info);
407 if (IS_ERR(devlink)) {
408 mutex_unlock(&devlink_mutex);
409 return PTR_ERR(devlink);
411 if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
412 mutex_lock(&devlink->lock);
413 info->user_ptr[0] = devlink;
414 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) {
415 devlink_port = devlink_port_get_from_info(devlink, info);
416 if (IS_ERR(devlink_port)) {
417 err = PTR_ERR(devlink_port);
420 info->user_ptr[1] = devlink_port;
421 } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT) {
422 devlink_port = devlink_port_get_from_info(devlink, info);
423 if (!IS_ERR(devlink_port))
424 info->user_ptr[1] = devlink_port;
429 if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
430 mutex_unlock(&devlink->lock);
431 mutex_unlock(&devlink_mutex);
435 static void devlink_nl_post_doit(const struct genl_ops *ops,
436 struct sk_buff *skb, struct genl_info *info)
438 struct devlink *devlink;
440 devlink = info->user_ptr[0];
441 if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
442 mutex_unlock(&devlink->lock);
443 mutex_unlock(&devlink_mutex);
446 static struct genl_family devlink_nl_family;
448 enum devlink_multicast_groups {
449 DEVLINK_MCGRP_CONFIG,
452 static const struct genl_multicast_group devlink_nl_mcgrps[] = {
453 [DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME },
456 static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
458 if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name))
460 if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev)))
465 static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
466 enum devlink_command cmd, u32 portid,
471 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
475 if (devlink_nl_put_handle(msg, devlink))
476 goto nla_put_failure;
477 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_FAILED, devlink->reload_failed))
478 goto nla_put_failure;
480 genlmsg_end(msg, hdr);
484 genlmsg_cancel(msg, hdr);
488 static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
493 WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
495 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
499 err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0);
505 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
506 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
509 static int devlink_nl_port_attrs_put(struct sk_buff *msg,
510 struct devlink_port *devlink_port)
512 struct devlink_port_attrs *attrs = &devlink_port->attrs;
514 if (!devlink_port->attrs_set)
517 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_LANES, attrs->lanes))
520 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_SPLITTABLE, attrs->splittable))
522 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour))
524 switch (devlink_port->attrs.flavour) {
525 case DEVLINK_PORT_FLAVOUR_PCI_PF:
526 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER,
530 case DEVLINK_PORT_FLAVOUR_PCI_VF:
531 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER,
533 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_VF_NUMBER,
537 case DEVLINK_PORT_FLAVOUR_PHYSICAL:
538 case DEVLINK_PORT_FLAVOUR_CPU:
539 case DEVLINK_PORT_FLAVOUR_DSA:
540 case DEVLINK_PORT_FLAVOUR_VIRTUAL:
541 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER,
542 attrs->phys.port_number))
546 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
547 attrs->phys.port_number))
549 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER,
550 attrs->phys.split_subport_number))
560 devlink_nl_port_function_attrs_put(struct sk_buff *msg, struct devlink_port *port,
561 struct netlink_ext_ack *extack)
563 struct devlink *devlink = port->devlink;
564 const struct devlink_ops *ops;
565 struct nlattr *function_attr;
566 bool empty_nest = true;
569 function_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PORT_FUNCTION);
574 if (ops->port_function_hw_addr_get) {
576 u8 hw_addr[MAX_ADDR_LEN];
578 err = ops->port_function_hw_addr_get(devlink, port, hw_addr, &hw_addr_len, extack);
579 if (err == -EOPNOTSUPP) {
580 /* Port function attributes are optional for a port. If port doesn't
581 * support function attribute, returning -EOPNOTSUPP is not an error.
588 err = nla_put(msg, DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR, hw_addr_len, hw_addr);
595 if (err || empty_nest)
596 nla_nest_cancel(msg, function_attr);
598 nla_nest_end(msg, function_attr);
602 static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
603 struct devlink_port *devlink_port,
604 enum devlink_command cmd, u32 portid,
606 struct netlink_ext_ack *extack)
610 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
614 if (devlink_nl_put_handle(msg, devlink))
615 goto nla_put_failure;
616 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
617 goto nla_put_failure;
619 spin_lock_bh(&devlink_port->type_lock);
620 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
621 goto nla_put_failure_type_locked;
622 if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
623 nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
624 devlink_port->desired_type))
625 goto nla_put_failure_type_locked;
626 if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
627 struct net_device *netdev = devlink_port->type_dev;
630 (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
632 nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
634 goto nla_put_failure_type_locked;
636 if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
637 struct ib_device *ibdev = devlink_port->type_dev;
640 nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
642 goto nla_put_failure_type_locked;
644 spin_unlock_bh(&devlink_port->type_lock);
645 if (devlink_nl_port_attrs_put(msg, devlink_port))
646 goto nla_put_failure;
647 if (devlink_nl_port_function_attrs_put(msg, devlink_port, extack))
648 goto nla_put_failure;
650 genlmsg_end(msg, hdr);
653 nla_put_failure_type_locked:
654 spin_unlock_bh(&devlink_port->type_lock);
656 genlmsg_cancel(msg, hdr);
660 static void devlink_port_notify(struct devlink_port *devlink_port,
661 enum devlink_command cmd)
663 struct devlink *devlink = devlink_port->devlink;
667 if (!devlink_port->registered)
670 WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
672 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
676 err = devlink_nl_port_fill(msg, devlink, devlink_port, cmd, 0, 0, 0,
683 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
684 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
687 static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
689 struct devlink *devlink = info->user_ptr[0];
693 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
697 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
698 info->snd_portid, info->snd_seq, 0);
704 return genlmsg_reply(msg, info);
707 static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
708 struct netlink_callback *cb)
710 struct devlink *devlink;
711 int start = cb->args[0];
715 mutex_lock(&devlink_mutex);
716 list_for_each_entry(devlink, &devlink_list, list) {
717 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
723 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
724 NETLINK_CB(cb->skb).portid,
725 cb->nlh->nlmsg_seq, NLM_F_MULTI);
731 mutex_unlock(&devlink_mutex);
737 static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
738 struct genl_info *info)
740 struct devlink_port *devlink_port = info->user_ptr[1];
741 struct devlink *devlink = devlink_port->devlink;
745 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
749 err = devlink_nl_port_fill(msg, devlink, devlink_port,
750 DEVLINK_CMD_PORT_NEW,
751 info->snd_portid, info->snd_seq, 0,
758 return genlmsg_reply(msg, info);
761 static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
762 struct netlink_callback *cb)
764 struct devlink *devlink;
765 struct devlink_port *devlink_port;
766 int start = cb->args[0];
770 mutex_lock(&devlink_mutex);
771 list_for_each_entry(devlink, &devlink_list, list) {
772 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
774 mutex_lock(&devlink->lock);
775 list_for_each_entry(devlink_port, &devlink->port_list, list) {
780 err = devlink_nl_port_fill(msg, devlink, devlink_port,
782 NETLINK_CB(cb->skb).portid,
787 mutex_unlock(&devlink->lock);
792 mutex_unlock(&devlink->lock);
795 mutex_unlock(&devlink_mutex);
801 static int devlink_port_type_set(struct devlink *devlink,
802 struct devlink_port *devlink_port,
803 enum devlink_port_type port_type)
808 if (devlink->ops->port_type_set) {
809 if (port_type == DEVLINK_PORT_TYPE_NOTSET)
811 if (port_type == devlink_port->type)
813 err = devlink->ops->port_type_set(devlink_port, port_type);
816 devlink_port->desired_type = port_type;
817 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
824 devlink_port_function_hw_addr_set(struct devlink *devlink, struct devlink_port *port,
825 const struct nlattr *attr, struct netlink_ext_ack *extack)
827 const struct devlink_ops *ops;
832 hw_addr = nla_data(attr);
833 hw_addr_len = nla_len(attr);
834 if (hw_addr_len > MAX_ADDR_LEN) {
835 NL_SET_ERR_MSG_MOD(extack, "Port function hardware address too long");
838 if (port->type == DEVLINK_PORT_TYPE_ETH) {
839 if (hw_addr_len != ETH_ALEN) {
840 NL_SET_ERR_MSG_MOD(extack, "Address must be 6 bytes for Ethernet device");
843 if (!is_unicast_ether_addr(hw_addr)) {
844 NL_SET_ERR_MSG_MOD(extack, "Non-unicast hardware address unsupported");
850 if (!ops->port_function_hw_addr_set) {
851 NL_SET_ERR_MSG_MOD(extack, "Port doesn't support function attributes");
855 err = ops->port_function_hw_addr_set(devlink, port, hw_addr, hw_addr_len, extack);
859 devlink_port_notify(port, DEVLINK_CMD_PORT_NEW);
864 devlink_port_function_set(struct devlink *devlink, struct devlink_port *port,
865 const struct nlattr *attr, struct netlink_ext_ack *extack)
867 struct nlattr *tb[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1];
870 err = nla_parse_nested(tb, DEVLINK_PORT_FUNCTION_ATTR_MAX, attr,
871 devlink_function_nl_policy, extack);
873 NL_SET_ERR_MSG_MOD(extack, "Fail to parse port function attributes");
877 attr = tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR];
879 err = devlink_port_function_hw_addr_set(devlink, port, attr, extack);
884 static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
885 struct genl_info *info)
887 struct devlink_port *devlink_port = info->user_ptr[1];
888 struct devlink *devlink = devlink_port->devlink;
891 if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
892 enum devlink_port_type port_type;
894 port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
895 err = devlink_port_type_set(devlink, devlink_port, port_type);
900 if (info->attrs[DEVLINK_ATTR_PORT_FUNCTION]) {
901 struct nlattr *attr = info->attrs[DEVLINK_ATTR_PORT_FUNCTION];
902 struct netlink_ext_ack *extack = info->extack;
904 err = devlink_port_function_set(devlink, devlink_port, attr, extack);
912 static int devlink_port_split(struct devlink *devlink, u32 port_index,
913 u32 count, struct netlink_ext_ack *extack)
916 if (devlink->ops->port_split)
917 return devlink->ops->port_split(devlink, port_index, count,
922 static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
923 struct genl_info *info)
925 struct devlink *devlink = info->user_ptr[0];
926 struct devlink_port *devlink_port;
930 if (!info->attrs[DEVLINK_ATTR_PORT_INDEX] ||
931 !info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT])
934 devlink_port = devlink_port_get_from_info(devlink, info);
935 port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
936 count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
938 if (IS_ERR(devlink_port))
941 if (!devlink_port->attrs.splittable) {
942 /* Split ports cannot be split. */
943 if (devlink_port->attrs.split)
944 NL_SET_ERR_MSG_MOD(info->extack, "Port cannot be split further");
946 NL_SET_ERR_MSG_MOD(info->extack, "Port cannot be split");
950 if (count < 2 || !is_power_of_2(count) || count > devlink_port->attrs.lanes) {
951 NL_SET_ERR_MSG_MOD(info->extack, "Invalid split count");
955 return devlink_port_split(devlink, port_index, count, info->extack);
958 static int devlink_port_unsplit(struct devlink *devlink, u32 port_index,
959 struct netlink_ext_ack *extack)
962 if (devlink->ops->port_unsplit)
963 return devlink->ops->port_unsplit(devlink, port_index, extack);
967 static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
968 struct genl_info *info)
970 struct devlink *devlink = info->user_ptr[0];
973 if (!info->attrs[DEVLINK_ATTR_PORT_INDEX])
976 port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
977 return devlink_port_unsplit(devlink, port_index, info->extack);
980 static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
981 struct devlink_sb *devlink_sb,
982 enum devlink_command cmd, u32 portid,
987 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
991 if (devlink_nl_put_handle(msg, devlink))
992 goto nla_put_failure;
993 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
994 goto nla_put_failure;
995 if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size))
996 goto nla_put_failure;
997 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT,
998 devlink_sb->ingress_pools_count))
999 goto nla_put_failure;
1000 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT,
1001 devlink_sb->egress_pools_count))
1002 goto nla_put_failure;
1003 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT,
1004 devlink_sb->ingress_tc_count))
1005 goto nla_put_failure;
1006 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT,
1007 devlink_sb->egress_tc_count))
1008 goto nla_put_failure;
1010 genlmsg_end(msg, hdr);
1014 genlmsg_cancel(msg, hdr);
1018 static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb,
1019 struct genl_info *info)
1021 struct devlink *devlink = info->user_ptr[0];
1022 struct devlink_sb *devlink_sb;
1023 struct sk_buff *msg;
1026 devlink_sb = devlink_sb_get_from_info(devlink, info);
1027 if (IS_ERR(devlink_sb))
1028 return PTR_ERR(devlink_sb);
1030 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1034 err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
1036 info->snd_portid, info->snd_seq, 0);
1042 return genlmsg_reply(msg, info);
1045 static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg,
1046 struct netlink_callback *cb)
1048 struct devlink *devlink;
1049 struct devlink_sb *devlink_sb;
1050 int start = cb->args[0];
1054 mutex_lock(&devlink_mutex);
1055 list_for_each_entry(devlink, &devlink_list, list) {
1056 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
1058 mutex_lock(&devlink->lock);
1059 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1064 err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
1066 NETLINK_CB(cb->skb).portid,
1070 mutex_unlock(&devlink->lock);
1075 mutex_unlock(&devlink->lock);
1078 mutex_unlock(&devlink_mutex);
1084 static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink,
1085 struct devlink_sb *devlink_sb,
1086 u16 pool_index, enum devlink_command cmd,
1087 u32 portid, u32 seq, int flags)
1089 struct devlink_sb_pool_info pool_info;
1093 err = devlink->ops->sb_pool_get(devlink, devlink_sb->index,
1094 pool_index, &pool_info);
1098 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1102 if (devlink_nl_put_handle(msg, devlink))
1103 goto nla_put_failure;
1104 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1105 goto nla_put_failure;
1106 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
1107 goto nla_put_failure;
1108 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type))
1109 goto nla_put_failure;
1110 if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size))
1111 goto nla_put_failure;
1112 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE,
1113 pool_info.threshold_type))
1114 goto nla_put_failure;
1115 if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_CELL_SIZE,
1116 pool_info.cell_size))
1117 goto nla_put_failure;
1119 genlmsg_end(msg, hdr);
1123 genlmsg_cancel(msg, hdr);
1127 static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb,
1128 struct genl_info *info)
1130 struct devlink *devlink = info->user_ptr[0];
1131 struct devlink_sb *devlink_sb;
1132 struct sk_buff *msg;
1136 devlink_sb = devlink_sb_get_from_info(devlink, info);
1137 if (IS_ERR(devlink_sb))
1138 return PTR_ERR(devlink_sb);
1140 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1145 if (!devlink->ops->sb_pool_get)
1148 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1152 err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index,
1153 DEVLINK_CMD_SB_POOL_NEW,
1154 info->snd_portid, info->snd_seq, 0);
1160 return genlmsg_reply(msg, info);
1163 static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
1164 struct devlink *devlink,
1165 struct devlink_sb *devlink_sb,
1166 u32 portid, u32 seq)
1168 u16 pool_count = devlink_sb_pool_count(devlink_sb);
1172 for (pool_index = 0; pool_index < pool_count; pool_index++) {
1173 if (*p_idx < start) {
1177 err = devlink_nl_sb_pool_fill(msg, devlink,
1180 DEVLINK_CMD_SB_POOL_NEW,
1181 portid, seq, NLM_F_MULTI);
1189 static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg,
1190 struct netlink_callback *cb)
1192 struct devlink *devlink;
1193 struct devlink_sb *devlink_sb;
1194 int start = cb->args[0];
1198 mutex_lock(&devlink_mutex);
1199 list_for_each_entry(devlink, &devlink_list, list) {
1200 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1201 !devlink->ops->sb_pool_get)
1203 mutex_lock(&devlink->lock);
1204 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1205 err = __sb_pool_get_dumpit(msg, start, &idx, devlink,
1207 NETLINK_CB(cb->skb).portid,
1208 cb->nlh->nlmsg_seq);
1209 if (err == -EOPNOTSUPP) {
1212 mutex_unlock(&devlink->lock);
1216 mutex_unlock(&devlink->lock);
1219 mutex_unlock(&devlink_mutex);
1221 if (err != -EMSGSIZE)
1228 static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
1229 u16 pool_index, u32 size,
1230 enum devlink_sb_threshold_type threshold_type,
1231 struct netlink_ext_ack *extack)
1234 const struct devlink_ops *ops = devlink->ops;
1236 if (ops->sb_pool_set)
1237 return ops->sb_pool_set(devlink, sb_index, pool_index,
1238 size, threshold_type, extack);
1242 static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb,
1243 struct genl_info *info)
1245 struct devlink *devlink = info->user_ptr[0];
1246 enum devlink_sb_threshold_type threshold_type;
1247 struct devlink_sb *devlink_sb;
1252 devlink_sb = devlink_sb_get_from_info(devlink, info);
1253 if (IS_ERR(devlink_sb))
1254 return PTR_ERR(devlink_sb);
1256 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1261 err = devlink_sb_th_type_get_from_info(info, &threshold_type);
1265 if (!info->attrs[DEVLINK_ATTR_SB_POOL_SIZE])
1268 size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]);
1269 return devlink_sb_pool_set(devlink, devlink_sb->index,
1270 pool_index, size, threshold_type,
1274 static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg,
1275 struct devlink *devlink,
1276 struct devlink_port *devlink_port,
1277 struct devlink_sb *devlink_sb,
1279 enum devlink_command cmd,
1280 u32 portid, u32 seq, int flags)
1282 const struct devlink_ops *ops = devlink->ops;
1287 err = ops->sb_port_pool_get(devlink_port, devlink_sb->index,
1288 pool_index, &threshold);
1292 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1296 if (devlink_nl_put_handle(msg, devlink))
1297 goto nla_put_failure;
1298 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1299 goto nla_put_failure;
1300 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1301 goto nla_put_failure;
1302 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
1303 goto nla_put_failure;
1304 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
1305 goto nla_put_failure;
1307 if (ops->sb_occ_port_pool_get) {
1311 err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index,
1312 pool_index, &cur, &max);
1313 if (err && err != -EOPNOTSUPP)
1316 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
1317 goto nla_put_failure;
1318 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
1319 goto nla_put_failure;
1323 genlmsg_end(msg, hdr);
1327 genlmsg_cancel(msg, hdr);
1331 static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,
1332 struct genl_info *info)
1334 struct devlink_port *devlink_port = info->user_ptr[1];
1335 struct devlink *devlink = devlink_port->devlink;
1336 struct devlink_sb *devlink_sb;
1337 struct sk_buff *msg;
1341 devlink_sb = devlink_sb_get_from_info(devlink, info);
1342 if (IS_ERR(devlink_sb))
1343 return PTR_ERR(devlink_sb);
1345 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1350 if (!devlink->ops->sb_port_pool_get)
1353 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1357 err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port,
1358 devlink_sb, pool_index,
1359 DEVLINK_CMD_SB_PORT_POOL_NEW,
1360 info->snd_portid, info->snd_seq, 0);
1366 return genlmsg_reply(msg, info);
1369 static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
1370 struct devlink *devlink,
1371 struct devlink_sb *devlink_sb,
1372 u32 portid, u32 seq)
1374 struct devlink_port *devlink_port;
1375 u16 pool_count = devlink_sb_pool_count(devlink_sb);
1379 list_for_each_entry(devlink_port, &devlink->port_list, list) {
1380 for (pool_index = 0; pool_index < pool_count; pool_index++) {
1381 if (*p_idx < start) {
1385 err = devlink_nl_sb_port_pool_fill(msg, devlink,
1389 DEVLINK_CMD_SB_PORT_POOL_NEW,
1400 static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg,
1401 struct netlink_callback *cb)
1403 struct devlink *devlink;
1404 struct devlink_sb *devlink_sb;
1405 int start = cb->args[0];
1409 mutex_lock(&devlink_mutex);
1410 list_for_each_entry(devlink, &devlink_list, list) {
1411 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1412 !devlink->ops->sb_port_pool_get)
1414 mutex_lock(&devlink->lock);
1415 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1416 err = __sb_port_pool_get_dumpit(msg, start, &idx,
1417 devlink, devlink_sb,
1418 NETLINK_CB(cb->skb).portid,
1419 cb->nlh->nlmsg_seq);
1420 if (err == -EOPNOTSUPP) {
1423 mutex_unlock(&devlink->lock);
1427 mutex_unlock(&devlink->lock);
1430 mutex_unlock(&devlink_mutex);
1432 if (err != -EMSGSIZE)
1439 static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
1440 unsigned int sb_index, u16 pool_index,
1442 struct netlink_ext_ack *extack)
1445 const struct devlink_ops *ops = devlink_port->devlink->ops;
1447 if (ops->sb_port_pool_set)
1448 return ops->sb_port_pool_set(devlink_port, sb_index,
1449 pool_index, threshold, extack);
1453 static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb,
1454 struct genl_info *info)
1456 struct devlink_port *devlink_port = info->user_ptr[1];
1457 struct devlink *devlink = info->user_ptr[0];
1458 struct devlink_sb *devlink_sb;
1463 devlink_sb = devlink_sb_get_from_info(devlink, info);
1464 if (IS_ERR(devlink_sb))
1465 return PTR_ERR(devlink_sb);
1467 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1472 if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1475 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1476 return devlink_sb_port_pool_set(devlink_port, devlink_sb->index,
1477 pool_index, threshold, info->extack);
1481 devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink,
1482 struct devlink_port *devlink_port,
1483 struct devlink_sb *devlink_sb, u16 tc_index,
1484 enum devlink_sb_pool_type pool_type,
1485 enum devlink_command cmd,
1486 u32 portid, u32 seq, int flags)
1488 const struct devlink_ops *ops = devlink->ops;
1494 err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index,
1495 tc_index, pool_type,
1496 &pool_index, &threshold);
1500 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1504 if (devlink_nl_put_handle(msg, devlink))
1505 goto nla_put_failure;
1506 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1507 goto nla_put_failure;
1508 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1509 goto nla_put_failure;
1510 if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index))
1511 goto nla_put_failure;
1512 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type))
1513 goto nla_put_failure;
1514 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
1515 goto nla_put_failure;
1516 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
1517 goto nla_put_failure;
1519 if (ops->sb_occ_tc_port_bind_get) {
1523 err = ops->sb_occ_tc_port_bind_get(devlink_port,
1525 tc_index, pool_type,
1527 if (err && err != -EOPNOTSUPP)
1530 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
1531 goto nla_put_failure;
1532 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
1533 goto nla_put_failure;
1537 genlmsg_end(msg, hdr);
1541 genlmsg_cancel(msg, hdr);
1545 static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,
1546 struct genl_info *info)
1548 struct devlink_port *devlink_port = info->user_ptr[1];
1549 struct devlink *devlink = devlink_port->devlink;
1550 struct devlink_sb *devlink_sb;
1551 struct sk_buff *msg;
1552 enum devlink_sb_pool_type pool_type;
1556 devlink_sb = devlink_sb_get_from_info(devlink, info);
1557 if (IS_ERR(devlink_sb))
1558 return PTR_ERR(devlink_sb);
1560 err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1564 err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1565 pool_type, &tc_index);
1569 if (!devlink->ops->sb_tc_pool_bind_get)
1572 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1576 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port,
1577 devlink_sb, tc_index, pool_type,
1578 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1586 return genlmsg_reply(msg, info);
1589 static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1590 int start, int *p_idx,
1591 struct devlink *devlink,
1592 struct devlink_sb *devlink_sb,
1593 u32 portid, u32 seq)
1595 struct devlink_port *devlink_port;
1599 list_for_each_entry(devlink_port, &devlink->port_list, list) {
1601 tc_index < devlink_sb->ingress_tc_count; tc_index++) {
1602 if (*p_idx < start) {
1606 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1610 DEVLINK_SB_POOL_TYPE_INGRESS,
1611 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1619 tc_index < devlink_sb->egress_tc_count; tc_index++) {
1620 if (*p_idx < start) {
1624 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1628 DEVLINK_SB_POOL_TYPE_EGRESS,
1629 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1641 devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1642 struct netlink_callback *cb)
1644 struct devlink *devlink;
1645 struct devlink_sb *devlink_sb;
1646 int start = cb->args[0];
1650 mutex_lock(&devlink_mutex);
1651 list_for_each_entry(devlink, &devlink_list, list) {
1652 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1653 !devlink->ops->sb_tc_pool_bind_get)
1656 mutex_lock(&devlink->lock);
1657 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1658 err = __sb_tc_pool_bind_get_dumpit(msg, start, &idx,
1661 NETLINK_CB(cb->skb).portid,
1662 cb->nlh->nlmsg_seq);
1663 if (err == -EOPNOTSUPP) {
1666 mutex_unlock(&devlink->lock);
1670 mutex_unlock(&devlink->lock);
1673 mutex_unlock(&devlink_mutex);
1675 if (err != -EMSGSIZE)
1682 static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port,
1683 unsigned int sb_index, u16 tc_index,
1684 enum devlink_sb_pool_type pool_type,
1685 u16 pool_index, u32 threshold,
1686 struct netlink_ext_ack *extack)
1689 const struct devlink_ops *ops = devlink_port->devlink->ops;
1691 if (ops->sb_tc_pool_bind_set)
1692 return ops->sb_tc_pool_bind_set(devlink_port, sb_index,
1693 tc_index, pool_type,
1694 pool_index, threshold, extack);
1698 static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb,
1699 struct genl_info *info)
1701 struct devlink_port *devlink_port = info->user_ptr[1];
1702 struct devlink *devlink = info->user_ptr[0];
1703 enum devlink_sb_pool_type pool_type;
1704 struct devlink_sb *devlink_sb;
1710 devlink_sb = devlink_sb_get_from_info(devlink, info);
1711 if (IS_ERR(devlink_sb))
1712 return PTR_ERR(devlink_sb);
1714 err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1718 err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1719 pool_type, &tc_index);
1723 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1728 if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1731 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1732 return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index,
1733 tc_index, pool_type,
1734 pool_index, threshold, info->extack);
1737 static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
1738 struct genl_info *info)
1740 struct devlink *devlink = info->user_ptr[0];
1741 const struct devlink_ops *ops = devlink->ops;
1742 struct devlink_sb *devlink_sb;
1744 devlink_sb = devlink_sb_get_from_info(devlink, info);
1745 if (IS_ERR(devlink_sb))
1746 return PTR_ERR(devlink_sb);
1748 if (ops->sb_occ_snapshot)
1749 return ops->sb_occ_snapshot(devlink, devlink_sb->index);
1753 static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
1754 struct genl_info *info)
1756 struct devlink *devlink = info->user_ptr[0];
1757 const struct devlink_ops *ops = devlink->ops;
1758 struct devlink_sb *devlink_sb;
1760 devlink_sb = devlink_sb_get_from_info(devlink, info);
1761 if (IS_ERR(devlink_sb))
1762 return PTR_ERR(devlink_sb);
1764 if (ops->sb_occ_max_clear)
1765 return ops->sb_occ_max_clear(devlink, devlink_sb->index);
1769 static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
1770 enum devlink_command cmd, u32 portid,
1773 const struct devlink_ops *ops = devlink->ops;
1774 enum devlink_eswitch_encap_mode encap_mode;
1780 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1784 err = devlink_nl_put_handle(msg, devlink);
1786 goto nla_put_failure;
1788 if (ops->eswitch_mode_get) {
1789 err = ops->eswitch_mode_get(devlink, &mode);
1791 goto nla_put_failure;
1792 err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode);
1794 goto nla_put_failure;
1797 if (ops->eswitch_inline_mode_get) {
1798 err = ops->eswitch_inline_mode_get(devlink, &inline_mode);
1800 goto nla_put_failure;
1801 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE,
1804 goto nla_put_failure;
1807 if (ops->eswitch_encap_mode_get) {
1808 err = ops->eswitch_encap_mode_get(devlink, &encap_mode);
1810 goto nla_put_failure;
1811 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode);
1813 goto nla_put_failure;
1816 genlmsg_end(msg, hdr);
1820 genlmsg_cancel(msg, hdr);
1824 static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb,
1825 struct genl_info *info)
1827 struct devlink *devlink = info->user_ptr[0];
1828 struct sk_buff *msg;
1831 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1835 err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET,
1836 info->snd_portid, info->snd_seq, 0);
1843 return genlmsg_reply(msg, info);
1846 static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb,
1847 struct genl_info *info)
1849 struct devlink *devlink = info->user_ptr[0];
1850 const struct devlink_ops *ops = devlink->ops;
1851 enum devlink_eswitch_encap_mode encap_mode;
1856 if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) {
1857 if (!ops->eswitch_mode_set)
1859 mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
1860 err = ops->eswitch_mode_set(devlink, mode, info->extack);
1865 if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) {
1866 if (!ops->eswitch_inline_mode_set)
1868 inline_mode = nla_get_u8(
1869 info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]);
1870 err = ops->eswitch_inline_mode_set(devlink, inline_mode,
1876 if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) {
1877 if (!ops->eswitch_encap_mode_set)
1879 encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]);
1880 err = ops->eswitch_encap_mode_set(devlink, encap_mode,
1889 int devlink_dpipe_match_put(struct sk_buff *skb,
1890 struct devlink_dpipe_match *match)
1892 struct devlink_dpipe_header *header = match->header;
1893 struct devlink_dpipe_field *field = &header->fields[match->field_id];
1894 struct nlattr *match_attr;
1896 match_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_MATCH);
1900 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) ||
1901 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) ||
1902 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
1903 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
1904 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
1905 goto nla_put_failure;
1907 nla_nest_end(skb, match_attr);
1911 nla_nest_cancel(skb, match_attr);
1914 EXPORT_SYMBOL_GPL(devlink_dpipe_match_put);
1916 static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table,
1917 struct sk_buff *skb)
1919 struct nlattr *matches_attr;
1921 matches_attr = nla_nest_start_noflag(skb,
1922 DEVLINK_ATTR_DPIPE_TABLE_MATCHES);
1926 if (table->table_ops->matches_dump(table->priv, skb))
1927 goto nla_put_failure;
1929 nla_nest_end(skb, matches_attr);
1933 nla_nest_cancel(skb, matches_attr);
1937 int devlink_dpipe_action_put(struct sk_buff *skb,
1938 struct devlink_dpipe_action *action)
1940 struct devlink_dpipe_header *header = action->header;
1941 struct devlink_dpipe_field *field = &header->fields[action->field_id];
1942 struct nlattr *action_attr;
1944 action_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ACTION);
1948 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) ||
1949 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) ||
1950 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
1951 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
1952 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
1953 goto nla_put_failure;
1955 nla_nest_end(skb, action_attr);
1959 nla_nest_cancel(skb, action_attr);
1962 EXPORT_SYMBOL_GPL(devlink_dpipe_action_put);
1964 static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table,
1965 struct sk_buff *skb)
1967 struct nlattr *actions_attr;
1969 actions_attr = nla_nest_start_noflag(skb,
1970 DEVLINK_ATTR_DPIPE_TABLE_ACTIONS);
1974 if (table->table_ops->actions_dump(table->priv, skb))
1975 goto nla_put_failure;
1977 nla_nest_end(skb, actions_attr);
1981 nla_nest_cancel(skb, actions_attr);
1985 static int devlink_dpipe_table_put(struct sk_buff *skb,
1986 struct devlink_dpipe_table *table)
1988 struct nlattr *table_attr;
1991 table_size = table->table_ops->size_get(table->priv);
1992 table_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLE);
1996 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) ||
1997 nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size,
1999 goto nla_put_failure;
2000 if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
2001 table->counters_enabled))
2002 goto nla_put_failure;
2004 if (table->resource_valid) {
2005 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID,
2006 table->resource_id, DEVLINK_ATTR_PAD) ||
2007 nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS,
2008 table->resource_units, DEVLINK_ATTR_PAD))
2009 goto nla_put_failure;
2011 if (devlink_dpipe_matches_put(table, skb))
2012 goto nla_put_failure;
2014 if (devlink_dpipe_actions_put(table, skb))
2015 goto nla_put_failure;
2017 nla_nest_end(skb, table_attr);
2021 nla_nest_cancel(skb, table_attr);
2025 static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb,
2026 struct genl_info *info)
2031 err = genlmsg_reply(*pskb, info);
2035 *pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
2041 static int devlink_dpipe_tables_fill(struct genl_info *info,
2042 enum devlink_command cmd, int flags,
2043 struct list_head *dpipe_tables,
2044 const char *table_name)
2046 struct devlink *devlink = info->user_ptr[0];
2047 struct devlink_dpipe_table *table;
2048 struct nlattr *tables_attr;
2049 struct sk_buff *skb = NULL;
2050 struct nlmsghdr *nlh;
2056 table = list_first_entry(dpipe_tables,
2057 struct devlink_dpipe_table, list);
2059 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2063 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
2064 &devlink_nl_family, NLM_F_MULTI, cmd);
2070 if (devlink_nl_put_handle(skb, devlink))
2071 goto nla_put_failure;
2072 tables_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLES);
2074 goto nla_put_failure;
2078 list_for_each_entry_from(table, dpipe_tables, list) {
2080 err = devlink_dpipe_table_put(skb, table);
2088 if (!strcmp(table->name, table_name)) {
2089 err = devlink_dpipe_table_put(skb, table);
2097 nla_nest_end(skb, tables_attr);
2098 genlmsg_end(skb, hdr);
2103 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
2104 NLMSG_DONE, 0, flags | NLM_F_MULTI);
2106 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2112 return genlmsg_reply(skb, info);
2121 static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb,
2122 struct genl_info *info)
2124 struct devlink *devlink = info->user_ptr[0];
2125 const char *table_name = NULL;
2127 if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
2128 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
2130 return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0,
2131 &devlink->dpipe_table_list,
2135 static int devlink_dpipe_value_put(struct sk_buff *skb,
2136 struct devlink_dpipe_value *value)
2138 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE,
2139 value->value_size, value->value))
2142 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK,
2143 value->value_size, value->mask))
2145 if (value->mapping_valid)
2146 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING,
2147 value->mapping_value))
2152 static int devlink_dpipe_action_value_put(struct sk_buff *skb,
2153 struct devlink_dpipe_value *value)
2157 if (devlink_dpipe_action_put(skb, value->action))
2159 if (devlink_dpipe_value_put(skb, value))
2164 static int devlink_dpipe_action_values_put(struct sk_buff *skb,
2165 struct devlink_dpipe_value *values,
2166 unsigned int values_count)
2168 struct nlattr *action_attr;
2172 for (i = 0; i < values_count; i++) {
2173 action_attr = nla_nest_start_noflag(skb,
2174 DEVLINK_ATTR_DPIPE_ACTION_VALUE);
2177 err = devlink_dpipe_action_value_put(skb, &values[i]);
2179 goto err_action_value_put;
2180 nla_nest_end(skb, action_attr);
2184 err_action_value_put:
2185 nla_nest_cancel(skb, action_attr);
2189 static int devlink_dpipe_match_value_put(struct sk_buff *skb,
2190 struct devlink_dpipe_value *value)
2194 if (devlink_dpipe_match_put(skb, value->match))
2196 if (devlink_dpipe_value_put(skb, value))
2201 static int devlink_dpipe_match_values_put(struct sk_buff *skb,
2202 struct devlink_dpipe_value *values,
2203 unsigned int values_count)
2205 struct nlattr *match_attr;
2209 for (i = 0; i < values_count; i++) {
2210 match_attr = nla_nest_start_noflag(skb,
2211 DEVLINK_ATTR_DPIPE_MATCH_VALUE);
2214 err = devlink_dpipe_match_value_put(skb, &values[i]);
2216 goto err_match_value_put;
2217 nla_nest_end(skb, match_attr);
2221 err_match_value_put:
2222 nla_nest_cancel(skb, match_attr);
2226 static int devlink_dpipe_entry_put(struct sk_buff *skb,
2227 struct devlink_dpipe_entry *entry)
2229 struct nlattr *entry_attr, *matches_attr, *actions_attr;
2232 entry_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ENTRY);
2236 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index,
2238 goto nla_put_failure;
2239 if (entry->counter_valid)
2240 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER,
2241 entry->counter, DEVLINK_ATTR_PAD))
2242 goto nla_put_failure;
2244 matches_attr = nla_nest_start_noflag(skb,
2245 DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES);
2247 goto nla_put_failure;
2249 err = devlink_dpipe_match_values_put(skb, entry->match_values,
2250 entry->match_values_count);
2252 nla_nest_cancel(skb, matches_attr);
2253 goto err_match_values_put;
2255 nla_nest_end(skb, matches_attr);
2257 actions_attr = nla_nest_start_noflag(skb,
2258 DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES);
2260 goto nla_put_failure;
2262 err = devlink_dpipe_action_values_put(skb, entry->action_values,
2263 entry->action_values_count);
2265 nla_nest_cancel(skb, actions_attr);
2266 goto err_action_values_put;
2268 nla_nest_end(skb, actions_attr);
2270 nla_nest_end(skb, entry_attr);
2275 err_match_values_put:
2276 err_action_values_put:
2277 nla_nest_cancel(skb, entry_attr);
2281 static struct devlink_dpipe_table *
2282 devlink_dpipe_table_find(struct list_head *dpipe_tables,
2283 const char *table_name, struct devlink *devlink)
2285 struct devlink_dpipe_table *table;
2286 list_for_each_entry_rcu(table, dpipe_tables, list,
2287 lockdep_is_held(&devlink->lock)) {
2288 if (!strcmp(table->name, table_name))
2294 int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx)
2296 struct devlink *devlink;
2299 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb,
2304 dump_ctx->hdr = genlmsg_put(dump_ctx->skb,
2305 dump_ctx->info->snd_portid,
2306 dump_ctx->info->snd_seq,
2307 &devlink_nl_family, NLM_F_MULTI,
2310 goto nla_put_failure;
2312 devlink = dump_ctx->info->user_ptr[0];
2313 if (devlink_nl_put_handle(dump_ctx->skb, devlink))
2314 goto nla_put_failure;
2315 dump_ctx->nest = nla_nest_start_noflag(dump_ctx->skb,
2316 DEVLINK_ATTR_DPIPE_ENTRIES);
2317 if (!dump_ctx->nest)
2318 goto nla_put_failure;
2322 nlmsg_free(dump_ctx->skb);
2325 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare);
2327 int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx,
2328 struct devlink_dpipe_entry *entry)
2330 return devlink_dpipe_entry_put(dump_ctx->skb, entry);
2332 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append);
2334 int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx)
2336 nla_nest_end(dump_ctx->skb, dump_ctx->nest);
2337 genlmsg_end(dump_ctx->skb, dump_ctx->hdr);
2340 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close);
2342 void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry)
2345 unsigned int value_count, value_index;
2346 struct devlink_dpipe_value *value;
2348 value = entry->action_values;
2349 value_count = entry->action_values_count;
2350 for (value_index = 0; value_index < value_count; value_index++) {
2351 kfree(value[value_index].value);
2352 kfree(value[value_index].mask);
2355 value = entry->match_values;
2356 value_count = entry->match_values_count;
2357 for (value_index = 0; value_index < value_count; value_index++) {
2358 kfree(value[value_index].value);
2359 kfree(value[value_index].mask);
2362 EXPORT_SYMBOL(devlink_dpipe_entry_clear);
2364 static int devlink_dpipe_entries_fill(struct genl_info *info,
2365 enum devlink_command cmd, int flags,
2366 struct devlink_dpipe_table *table)
2368 struct devlink_dpipe_dump_ctx dump_ctx;
2369 struct nlmsghdr *nlh;
2372 dump_ctx.skb = NULL;
2374 dump_ctx.info = info;
2376 err = table->table_ops->entries_dump(table->priv,
2377 table->counters_enabled,
2383 nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq,
2384 NLMSG_DONE, 0, flags | NLM_F_MULTI);
2386 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info);
2391 return genlmsg_reply(dump_ctx.skb, info);
2394 static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
2395 struct genl_info *info)
2397 struct devlink *devlink = info->user_ptr[0];
2398 struct devlink_dpipe_table *table;
2399 const char *table_name;
2401 if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
2404 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
2405 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2406 table_name, devlink);
2410 if (!table->table_ops->entries_dump)
2413 return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET,
2417 static int devlink_dpipe_fields_put(struct sk_buff *skb,
2418 const struct devlink_dpipe_header *header)
2420 struct devlink_dpipe_field *field;
2421 struct nlattr *field_attr;
2424 for (i = 0; i < header->fields_count; i++) {
2425 field = &header->fields[i];
2426 field_attr = nla_nest_start_noflag(skb,
2427 DEVLINK_ATTR_DPIPE_FIELD);
2430 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) ||
2431 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
2432 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) ||
2433 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type))
2434 goto nla_put_failure;
2435 nla_nest_end(skb, field_attr);
2440 nla_nest_cancel(skb, field_attr);
2444 static int devlink_dpipe_header_put(struct sk_buff *skb,
2445 struct devlink_dpipe_header *header)
2447 struct nlattr *fields_attr, *header_attr;
2450 header_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADER);
2454 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) ||
2455 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
2456 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
2457 goto nla_put_failure;
2459 fields_attr = nla_nest_start_noflag(skb,
2460 DEVLINK_ATTR_DPIPE_HEADER_FIELDS);
2462 goto nla_put_failure;
2464 err = devlink_dpipe_fields_put(skb, header);
2466 nla_nest_cancel(skb, fields_attr);
2467 goto nla_put_failure;
2469 nla_nest_end(skb, fields_attr);
2470 nla_nest_end(skb, header_attr);
2475 nla_nest_cancel(skb, header_attr);
2479 static int devlink_dpipe_headers_fill(struct genl_info *info,
2480 enum devlink_command cmd, int flags,
2481 struct devlink_dpipe_headers *
2484 struct devlink *devlink = info->user_ptr[0];
2485 struct nlattr *headers_attr;
2486 struct sk_buff *skb = NULL;
2487 struct nlmsghdr *nlh;
2494 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2498 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
2499 &devlink_nl_family, NLM_F_MULTI, cmd);
2505 if (devlink_nl_put_handle(skb, devlink))
2506 goto nla_put_failure;
2507 headers_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADERS);
2509 goto nla_put_failure;
2512 for (; i < dpipe_headers->headers_count; i++) {
2513 err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]);
2521 nla_nest_end(skb, headers_attr);
2522 genlmsg_end(skb, hdr);
2523 if (i != dpipe_headers->headers_count)
2527 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
2528 NLMSG_DONE, 0, flags | NLM_F_MULTI);
2530 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2535 return genlmsg_reply(skb, info);
2544 static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb,
2545 struct genl_info *info)
2547 struct devlink *devlink = info->user_ptr[0];
2549 if (!devlink->dpipe_headers)
2551 return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET,
2552 0, devlink->dpipe_headers);
2555 static int devlink_dpipe_table_counters_set(struct devlink *devlink,
2556 const char *table_name,
2559 struct devlink_dpipe_table *table;
2561 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2562 table_name, devlink);
2566 if (table->counter_control_extern)
2569 if (!(table->counters_enabled ^ enable))
2572 table->counters_enabled = enable;
2573 if (table->table_ops->counters_set_update)
2574 table->table_ops->counters_set_update(table->priv, enable);
2578 static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb,
2579 struct genl_info *info)
2581 struct devlink *devlink = info->user_ptr[0];
2582 const char *table_name;
2583 bool counters_enable;
2585 if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME] ||
2586 !info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED])
2589 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
2590 counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]);
2592 return devlink_dpipe_table_counters_set(devlink, table_name,
2596 static struct devlink_resource *
2597 devlink_resource_find(struct devlink *devlink,
2598 struct devlink_resource *resource, u64 resource_id)
2600 struct list_head *resource_list;
2603 resource_list = &resource->resource_list;
2605 resource_list = &devlink->resource_list;
2607 list_for_each_entry(resource, resource_list, list) {
2608 struct devlink_resource *child_resource;
2610 if (resource->id == resource_id)
2613 child_resource = devlink_resource_find(devlink, resource,
2616 return child_resource;
2622 devlink_resource_validate_children(struct devlink_resource *resource)
2624 struct devlink_resource *child_resource;
2625 bool size_valid = true;
2628 if (list_empty(&resource->resource_list))
2631 list_for_each_entry(child_resource, &resource->resource_list, list)
2632 parts_size += child_resource->size_new;
2634 if (parts_size > resource->size_new)
2637 resource->size_valid = size_valid;
2641 devlink_resource_validate_size(struct devlink_resource *resource, u64 size,
2642 struct netlink_ext_ack *extack)
2647 if (size > resource->size_params.size_max) {
2648 NL_SET_ERR_MSG_MOD(extack, "Size larger than maximum");
2652 if (size < resource->size_params.size_min) {
2653 NL_SET_ERR_MSG_MOD(extack, "Size smaller than minimum");
2657 div64_u64_rem(size, resource->size_params.size_granularity, &reminder);
2659 NL_SET_ERR_MSG_MOD(extack, "Wrong granularity");
2666 static int devlink_nl_cmd_resource_set(struct sk_buff *skb,
2667 struct genl_info *info)
2669 struct devlink *devlink = info->user_ptr[0];
2670 struct devlink_resource *resource;
2675 if (!info->attrs[DEVLINK_ATTR_RESOURCE_ID] ||
2676 !info->attrs[DEVLINK_ATTR_RESOURCE_SIZE])
2678 resource_id = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_ID]);
2680 resource = devlink_resource_find(devlink, NULL, resource_id);
2684 size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]);
2685 err = devlink_resource_validate_size(resource, size, info->extack);
2689 resource->size_new = size;
2690 devlink_resource_validate_children(resource);
2691 if (resource->parent)
2692 devlink_resource_validate_children(resource->parent);
2697 devlink_resource_size_params_put(struct devlink_resource *resource,
2698 struct sk_buff *skb)
2700 struct devlink_resource_size_params *size_params;
2702 size_params = &resource->size_params;
2703 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_GRAN,
2704 size_params->size_granularity, DEVLINK_ATTR_PAD) ||
2705 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MAX,
2706 size_params->size_max, DEVLINK_ATTR_PAD) ||
2707 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MIN,
2708 size_params->size_min, DEVLINK_ATTR_PAD) ||
2709 nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_UNIT, size_params->unit))
2714 static int devlink_resource_occ_put(struct devlink_resource *resource,
2715 struct sk_buff *skb)
2717 if (!resource->occ_get)
2719 return nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_OCC,
2720 resource->occ_get(resource->occ_get_priv),
2724 static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb,
2725 struct devlink_resource *resource)
2727 struct devlink_resource *child_resource;
2728 struct nlattr *child_resource_attr;
2729 struct nlattr *resource_attr;
2731 resource_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_RESOURCE);
2735 if (nla_put_string(skb, DEVLINK_ATTR_RESOURCE_NAME, resource->name) ||
2736 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE, resource->size,
2737 DEVLINK_ATTR_PAD) ||
2738 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_ID, resource->id,
2740 goto nla_put_failure;
2741 if (resource->size != resource->size_new)
2742 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_NEW,
2743 resource->size_new, DEVLINK_ATTR_PAD);
2744 if (devlink_resource_occ_put(resource, skb))
2745 goto nla_put_failure;
2746 if (devlink_resource_size_params_put(resource, skb))
2747 goto nla_put_failure;
2748 if (list_empty(&resource->resource_list))
2751 if (nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_SIZE_VALID,
2752 resource->size_valid))
2753 goto nla_put_failure;
2755 child_resource_attr = nla_nest_start_noflag(skb,
2756 DEVLINK_ATTR_RESOURCE_LIST);
2757 if (!child_resource_attr)
2758 goto nla_put_failure;
2760 list_for_each_entry(child_resource, &resource->resource_list, list) {
2761 if (devlink_resource_put(devlink, skb, child_resource))
2762 goto resource_put_failure;
2765 nla_nest_end(skb, child_resource_attr);
2767 nla_nest_end(skb, resource_attr);
2770 resource_put_failure:
2771 nla_nest_cancel(skb, child_resource_attr);
2773 nla_nest_cancel(skb, resource_attr);
2777 static int devlink_resource_fill(struct genl_info *info,
2778 enum devlink_command cmd, int flags)
2780 struct devlink *devlink = info->user_ptr[0];
2781 struct devlink_resource *resource;
2782 struct nlattr *resources_attr;
2783 struct sk_buff *skb = NULL;
2784 struct nlmsghdr *nlh;
2790 resource = list_first_entry(&devlink->resource_list,
2791 struct devlink_resource, list);
2793 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2797 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
2798 &devlink_nl_family, NLM_F_MULTI, cmd);
2804 if (devlink_nl_put_handle(skb, devlink))
2805 goto nla_put_failure;
2807 resources_attr = nla_nest_start_noflag(skb,
2808 DEVLINK_ATTR_RESOURCE_LIST);
2809 if (!resources_attr)
2810 goto nla_put_failure;
2814 list_for_each_entry_from(resource, &devlink->resource_list, list) {
2815 err = devlink_resource_put(devlink, skb, resource);
2818 goto err_resource_put;
2824 nla_nest_end(skb, resources_attr);
2825 genlmsg_end(skb, hdr);
2829 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
2830 NLMSG_DONE, 0, flags | NLM_F_MULTI);
2832 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2837 return genlmsg_reply(skb, info);
2846 static int devlink_nl_cmd_resource_dump(struct sk_buff *skb,
2847 struct genl_info *info)
2849 struct devlink *devlink = info->user_ptr[0];
2851 if (list_empty(&devlink->resource_list))
2854 return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0);
2858 devlink_resources_validate(struct devlink *devlink,
2859 struct devlink_resource *resource,
2860 struct genl_info *info)
2862 struct list_head *resource_list;
2866 resource_list = &resource->resource_list;
2868 resource_list = &devlink->resource_list;
2870 list_for_each_entry(resource, resource_list, list) {
2871 if (!resource->size_valid)
2873 err = devlink_resources_validate(devlink, resource, info);
2880 static struct net *devlink_netns_get(struct sk_buff *skb,
2881 struct genl_info *info)
2883 struct nlattr *netns_pid_attr = info->attrs[DEVLINK_ATTR_NETNS_PID];
2884 struct nlattr *netns_fd_attr = info->attrs[DEVLINK_ATTR_NETNS_FD];
2885 struct nlattr *netns_id_attr = info->attrs[DEVLINK_ATTR_NETNS_ID];
2888 if (!!netns_pid_attr + !!netns_fd_attr + !!netns_id_attr > 1) {
2889 NL_SET_ERR_MSG_MOD(info->extack, "multiple netns identifying attributes specified");
2890 return ERR_PTR(-EINVAL);
2893 if (netns_pid_attr) {
2894 net = get_net_ns_by_pid(nla_get_u32(netns_pid_attr));
2895 } else if (netns_fd_attr) {
2896 net = get_net_ns_by_fd(nla_get_u32(netns_fd_attr));
2897 } else if (netns_id_attr) {
2898 net = get_net_ns_by_id(sock_net(skb->sk),
2899 nla_get_u32(netns_id_attr));
2901 net = ERR_PTR(-EINVAL);
2904 net = ERR_PTR(-EINVAL);
2907 NL_SET_ERR_MSG_MOD(info->extack, "Unknown network namespace");
2908 return ERR_PTR(-EINVAL);
2910 if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) {
2912 return ERR_PTR(-EPERM);
2917 static void devlink_param_notify(struct devlink *devlink,
2918 unsigned int port_index,
2919 struct devlink_param_item *param_item,
2920 enum devlink_command cmd);
2922 static void devlink_reload_netns_change(struct devlink *devlink,
2923 struct net *dest_net)
2925 struct devlink_param_item *param_item;
2927 /* Userspace needs to be notified about devlink objects
2928 * removed from original and entering new network namespace.
2929 * The rest of the devlink objects are re-created during
2930 * reload process so the notifications are generated separatelly.
2933 list_for_each_entry(param_item, &devlink->param_list, list)
2934 devlink_param_notify(devlink, 0, param_item,
2935 DEVLINK_CMD_PARAM_DEL);
2936 devlink_notify(devlink, DEVLINK_CMD_DEL);
2938 __devlink_net_set(devlink, dest_net);
2940 devlink_notify(devlink, DEVLINK_CMD_NEW);
2941 list_for_each_entry(param_item, &devlink->param_list, list)
2942 devlink_param_notify(devlink, 0, param_item,
2943 DEVLINK_CMD_PARAM_NEW);
2946 static bool devlink_reload_supported(const struct devlink *devlink)
2948 return devlink->ops->reload_down && devlink->ops->reload_up;
2951 static void devlink_reload_failed_set(struct devlink *devlink,
2954 if (devlink->reload_failed == reload_failed)
2956 devlink->reload_failed = reload_failed;
2957 devlink_notify(devlink, DEVLINK_CMD_NEW);
2960 bool devlink_is_reload_failed(const struct devlink *devlink)
2962 return devlink->reload_failed;
2964 EXPORT_SYMBOL_GPL(devlink_is_reload_failed);
2966 static int devlink_reload(struct devlink *devlink, struct net *dest_net,
2967 struct netlink_ext_ack *extack)
2971 if (!devlink->reload_enabled)
2974 err = devlink->ops->reload_down(devlink, !!dest_net, extack);
2978 if (dest_net && !net_eq(dest_net, devlink_net(devlink)))
2979 devlink_reload_netns_change(devlink, dest_net);
2981 err = devlink->ops->reload_up(devlink, extack);
2982 devlink_reload_failed_set(devlink, !!err);
2986 static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
2988 struct devlink *devlink = info->user_ptr[0];
2989 struct net *dest_net = NULL;
2992 if (!devlink_reload_supported(devlink))
2995 err = devlink_resources_validate(devlink, NULL, info);
2997 NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed");
3001 if (info->attrs[DEVLINK_ATTR_NETNS_PID] ||
3002 info->attrs[DEVLINK_ATTR_NETNS_FD] ||
3003 info->attrs[DEVLINK_ATTR_NETNS_ID]) {
3004 dest_net = devlink_netns_get(skb, info);
3005 if (IS_ERR(dest_net))
3006 return PTR_ERR(dest_net);
3009 err = devlink_reload(devlink, dest_net, info->extack);
3017 static int devlink_nl_flash_update_fill(struct sk_buff *msg,
3018 struct devlink *devlink,
3019 enum devlink_command cmd,
3020 const char *status_msg,
3021 const char *component,
3022 unsigned long done, unsigned long total)
3026 hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd);
3030 if (devlink_nl_put_handle(msg, devlink))
3031 goto nla_put_failure;
3033 if (cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS)
3037 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG,
3039 goto nla_put_failure;
3041 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT,
3043 goto nla_put_failure;
3044 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE,
3045 done, DEVLINK_ATTR_PAD))
3046 goto nla_put_failure;
3047 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL,
3048 total, DEVLINK_ATTR_PAD))
3049 goto nla_put_failure;
3052 genlmsg_end(msg, hdr);
3056 genlmsg_cancel(msg, hdr);
3060 static void __devlink_flash_update_notify(struct devlink *devlink,
3061 enum devlink_command cmd,
3062 const char *status_msg,
3063 const char *component,
3065 unsigned long total)
3067 struct sk_buff *msg;
3070 WARN_ON(cmd != DEVLINK_CMD_FLASH_UPDATE &&
3071 cmd != DEVLINK_CMD_FLASH_UPDATE_END &&
3072 cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS);
3074 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3078 err = devlink_nl_flash_update_fill(msg, devlink, cmd, status_msg,
3079 component, done, total);
3083 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
3084 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
3091 void devlink_flash_update_begin_notify(struct devlink *devlink)
3093 __devlink_flash_update_notify(devlink,
3094 DEVLINK_CMD_FLASH_UPDATE,
3097 EXPORT_SYMBOL_GPL(devlink_flash_update_begin_notify);
3099 void devlink_flash_update_end_notify(struct devlink *devlink)
3101 __devlink_flash_update_notify(devlink,
3102 DEVLINK_CMD_FLASH_UPDATE_END,
3105 EXPORT_SYMBOL_GPL(devlink_flash_update_end_notify);
3107 void devlink_flash_update_status_notify(struct devlink *devlink,
3108 const char *status_msg,
3109 const char *component,
3111 unsigned long total)
3113 __devlink_flash_update_notify(devlink,
3114 DEVLINK_CMD_FLASH_UPDATE_STATUS,
3115 status_msg, component, done, total);
3117 EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify);
3119 static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
3120 struct genl_info *info)
3122 struct devlink *devlink = info->user_ptr[0];
3123 const char *file_name, *component;
3124 struct nlattr *nla_component;
3126 if (!devlink->ops->flash_update)
3129 if (!info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME])
3131 file_name = nla_data(info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]);
3133 nla_component = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT];
3134 component = nla_component ? nla_data(nla_component) : NULL;
3136 return devlink->ops->flash_update(devlink, file_name, component,
3140 static const struct devlink_param devlink_param_generic[] = {
3142 .id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET,
3143 .name = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME,
3144 .type = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE,
3147 .id = DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
3148 .name = DEVLINK_PARAM_GENERIC_MAX_MACS_NAME,
3149 .type = DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE,
3152 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV,
3153 .name = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME,
3154 .type = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE,
3157 .id = DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT,
3158 .name = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME,
3159 .type = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE,
3162 .id = DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI,
3163 .name = DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME,
3164 .type = DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE,
3167 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX,
3168 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME,
3169 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE,
3172 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN,
3173 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME,
3174 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE,
3177 .id = DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY,
3178 .name = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME,
3179 .type = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE,
3182 .id = DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE,
3183 .name = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME,
3184 .type = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE,
3187 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE,
3188 .name = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_NAME,
3189 .type = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_TYPE,
3193 static int devlink_param_generic_verify(const struct devlink_param *param)
3195 /* verify it match generic parameter by id and name */
3196 if (param->id > DEVLINK_PARAM_GENERIC_ID_MAX)
3198 if (strcmp(param->name, devlink_param_generic[param->id].name))
3201 WARN_ON(param->type != devlink_param_generic[param->id].type);
3206 static int devlink_param_driver_verify(const struct devlink_param *param)
3210 if (param->id <= DEVLINK_PARAM_GENERIC_ID_MAX)
3212 /* verify no such name in generic params */
3213 for (i = 0; i <= DEVLINK_PARAM_GENERIC_ID_MAX; i++)
3214 if (!strcmp(param->name, devlink_param_generic[i].name))
3220 static struct devlink_param_item *
3221 devlink_param_find_by_name(struct list_head *param_list,
3222 const char *param_name)
3224 struct devlink_param_item *param_item;
3226 list_for_each_entry(param_item, param_list, list)
3227 if (!strcmp(param_item->param->name, param_name))
3232 static struct devlink_param_item *
3233 devlink_param_find_by_id(struct list_head *param_list, u32 param_id)
3235 struct devlink_param_item *param_item;
3237 list_for_each_entry(param_item, param_list, list)
3238 if (param_item->param->id == param_id)
3244 devlink_param_cmode_is_supported(const struct devlink_param *param,
3245 enum devlink_param_cmode cmode)
3247 return test_bit(cmode, ¶m->supported_cmodes);
3250 static int devlink_param_get(struct devlink *devlink,
3251 const struct devlink_param *param,
3252 struct devlink_param_gset_ctx *ctx)
3256 return param->get(devlink, param->id, ctx);
3259 static int devlink_param_set(struct devlink *devlink,
3260 const struct devlink_param *param,
3261 struct devlink_param_gset_ctx *ctx)
3265 return param->set(devlink, param->id, ctx);
3269 devlink_param_type_to_nla_type(enum devlink_param_type param_type)
3271 switch (param_type) {
3272 case DEVLINK_PARAM_TYPE_U8:
3274 case DEVLINK_PARAM_TYPE_U16:
3276 case DEVLINK_PARAM_TYPE_U32:
3278 case DEVLINK_PARAM_TYPE_STRING:
3280 case DEVLINK_PARAM_TYPE_BOOL:
3288 devlink_nl_param_value_fill_one(struct sk_buff *msg,
3289 enum devlink_param_type type,
3290 enum devlink_param_cmode cmode,
3291 union devlink_param_value val)
3293 struct nlattr *param_value_attr;
3295 param_value_attr = nla_nest_start_noflag(msg,
3296 DEVLINK_ATTR_PARAM_VALUE);
3297 if (!param_value_attr)
3298 goto nla_put_failure;
3300 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode))
3301 goto value_nest_cancel;
3304 case DEVLINK_PARAM_TYPE_U8:
3305 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu8))
3306 goto value_nest_cancel;
3308 case DEVLINK_PARAM_TYPE_U16:
3309 if (nla_put_u16(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu16))
3310 goto value_nest_cancel;
3312 case DEVLINK_PARAM_TYPE_U32:
3313 if (nla_put_u32(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu32))
3314 goto value_nest_cancel;
3316 case DEVLINK_PARAM_TYPE_STRING:
3317 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_VALUE_DATA,
3319 goto value_nest_cancel;
3321 case DEVLINK_PARAM_TYPE_BOOL:
3323 nla_put_flag(msg, DEVLINK_ATTR_PARAM_VALUE_DATA))
3324 goto value_nest_cancel;
3328 nla_nest_end(msg, param_value_attr);
3332 nla_nest_cancel(msg, param_value_attr);
3337 static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
3338 unsigned int port_index,
3339 struct devlink_param_item *param_item,
3340 enum devlink_command cmd,
3341 u32 portid, u32 seq, int flags)
3343 union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1];
3344 bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {};
3345 const struct devlink_param *param = param_item->param;
3346 struct devlink_param_gset_ctx ctx;
3347 struct nlattr *param_values_list;
3348 struct nlattr *param_attr;
3354 /* Get value from driver part to driverinit configuration mode */
3355 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
3356 if (!devlink_param_cmode_is_supported(param, i))
3358 if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) {
3359 if (!param_item->driverinit_value_valid)
3361 param_value[i] = param_item->driverinit_value;
3363 if (!param_item->published)
3366 err = devlink_param_get(devlink, param, &ctx);
3369 param_value[i] = ctx.val;
3371 param_value_set[i] = true;
3374 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
3378 if (devlink_nl_put_handle(msg, devlink))
3379 goto genlmsg_cancel;
3381 if (cmd == DEVLINK_CMD_PORT_PARAM_GET ||
3382 cmd == DEVLINK_CMD_PORT_PARAM_NEW ||
3383 cmd == DEVLINK_CMD_PORT_PARAM_DEL)
3384 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index))
3385 goto genlmsg_cancel;
3387 param_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PARAM);
3389 goto genlmsg_cancel;
3390 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_NAME, param->name))
3391 goto param_nest_cancel;
3392 if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC))
3393 goto param_nest_cancel;
3395 nla_type = devlink_param_type_to_nla_type(param->type);
3397 goto param_nest_cancel;
3398 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, nla_type))
3399 goto param_nest_cancel;
3401 param_values_list = nla_nest_start_noflag(msg,
3402 DEVLINK_ATTR_PARAM_VALUES_LIST);
3403 if (!param_values_list)
3404 goto param_nest_cancel;
3406 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
3407 if (!param_value_set[i])
3409 err = devlink_nl_param_value_fill_one(msg, param->type,
3412 goto values_list_nest_cancel;
3415 nla_nest_end(msg, param_values_list);
3416 nla_nest_end(msg, param_attr);
3417 genlmsg_end(msg, hdr);
3420 values_list_nest_cancel:
3421 nla_nest_end(msg, param_values_list);
3423 nla_nest_cancel(msg, param_attr);
3425 genlmsg_cancel(msg, hdr);
3429 static void devlink_param_notify(struct devlink *devlink,
3430 unsigned int port_index,
3431 struct devlink_param_item *param_item,
3432 enum devlink_command cmd)
3434 struct sk_buff *msg;
3437 WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL &&
3438 cmd != DEVLINK_CMD_PORT_PARAM_NEW &&
3439 cmd != DEVLINK_CMD_PORT_PARAM_DEL);
3441 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3444 err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd,
3451 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
3452 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
3455 static int devlink_nl_cmd_param_get_dumpit(struct sk_buff *msg,
3456 struct netlink_callback *cb)
3458 struct devlink_param_item *param_item;
3459 struct devlink *devlink;
3460 int start = cb->args[0];
3464 mutex_lock(&devlink_mutex);
3465 list_for_each_entry(devlink, &devlink_list, list) {
3466 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
3468 mutex_lock(&devlink->lock);
3469 list_for_each_entry(param_item, &devlink->param_list, list) {
3474 err = devlink_nl_param_fill(msg, devlink, 0, param_item,
3475 DEVLINK_CMD_PARAM_GET,
3476 NETLINK_CB(cb->skb).portid,
3479 if (err == -EOPNOTSUPP) {
3482 mutex_unlock(&devlink->lock);
3487 mutex_unlock(&devlink->lock);
3490 mutex_unlock(&devlink_mutex);
3492 if (err != -EMSGSIZE)
3500 devlink_param_type_get_from_info(struct genl_info *info,
3501 enum devlink_param_type *param_type)
3503 if (!info->attrs[DEVLINK_ATTR_PARAM_TYPE])
3506 switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) {
3508 *param_type = DEVLINK_PARAM_TYPE_U8;
3511 *param_type = DEVLINK_PARAM_TYPE_U16;
3514 *param_type = DEVLINK_PARAM_TYPE_U32;
3517 *param_type = DEVLINK_PARAM_TYPE_STRING;
3520 *param_type = DEVLINK_PARAM_TYPE_BOOL;
3530 devlink_param_value_get_from_info(const struct devlink_param *param,
3531 struct genl_info *info,
3532 union devlink_param_value *value)
3534 struct nlattr *param_data;
3537 param_data = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA];
3539 if (param->type != DEVLINK_PARAM_TYPE_BOOL && !param_data)
3542 switch (param->type) {
3543 case DEVLINK_PARAM_TYPE_U8:
3544 if (nla_len(param_data) != sizeof(u8))
3546 value->vu8 = nla_get_u8(param_data);
3548 case DEVLINK_PARAM_TYPE_U16:
3549 if (nla_len(param_data) != sizeof(u16))
3551 value->vu16 = nla_get_u16(param_data);
3553 case DEVLINK_PARAM_TYPE_U32:
3554 if (nla_len(param_data) != sizeof(u32))
3556 value->vu32 = nla_get_u32(param_data);
3558 case DEVLINK_PARAM_TYPE_STRING:
3559 len = strnlen(nla_data(param_data), nla_len(param_data));
3560 if (len == nla_len(param_data) ||
3561 len >= __DEVLINK_PARAM_MAX_STRING_VALUE)
3563 strcpy(value->vstr, nla_data(param_data));
3565 case DEVLINK_PARAM_TYPE_BOOL:
3566 if (param_data && nla_len(param_data))
3568 value->vbool = nla_get_flag(param_data);
3574 static struct devlink_param_item *
3575 devlink_param_get_from_info(struct list_head *param_list,
3576 struct genl_info *info)
3580 if (!info->attrs[DEVLINK_ATTR_PARAM_NAME])
3583 param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]);
3584 return devlink_param_find_by_name(param_list, param_name);
3587 static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb,
3588 struct genl_info *info)
3590 struct devlink *devlink = info->user_ptr[0];
3591 struct devlink_param_item *param_item;
3592 struct sk_buff *msg;
3595 param_item = devlink_param_get_from_info(&devlink->param_list, info);
3599 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3603 err = devlink_nl_param_fill(msg, devlink, 0, param_item,
3604 DEVLINK_CMD_PARAM_GET,
3605 info->snd_portid, info->snd_seq, 0);
3611 return genlmsg_reply(msg, info);
3614 static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink,
3615 unsigned int port_index,
3616 struct list_head *param_list,
3617 struct genl_info *info,
3618 enum devlink_command cmd)
3620 enum devlink_param_type param_type;
3621 struct devlink_param_gset_ctx ctx;
3622 enum devlink_param_cmode cmode;
3623 struct devlink_param_item *param_item;
3624 const struct devlink_param *param;
3625 union devlink_param_value value;
3628 param_item = devlink_param_get_from_info(param_list, info);
3631 param = param_item->param;
3632 err = devlink_param_type_get_from_info(info, ¶m_type);
3635 if (param_type != param->type)
3637 err = devlink_param_value_get_from_info(param, info, &value);
3640 if (param->validate) {
3641 err = param->validate(devlink, param->id, value, info->extack);
3646 if (!info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE])
3648 cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]);
3649 if (!devlink_param_cmode_is_supported(param, cmode))
3652 if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) {
3653 if (param->type == DEVLINK_PARAM_TYPE_STRING)
3654 strcpy(param_item->driverinit_value.vstr, value.vstr);
3656 param_item->driverinit_value = value;
3657 param_item->driverinit_value_valid = true;
3663 err = devlink_param_set(devlink, param, &ctx);
3668 devlink_param_notify(devlink, port_index, param_item, cmd);
3672 static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb,
3673 struct genl_info *info)
3675 struct devlink *devlink = info->user_ptr[0];
3677 return __devlink_nl_cmd_param_set_doit(devlink, 0, &devlink->param_list,
3678 info, DEVLINK_CMD_PARAM_NEW);
3681 static int devlink_param_register_one(struct devlink *devlink,
3682 unsigned int port_index,
3683 struct list_head *param_list,
3684 const struct devlink_param *param,
3685 enum devlink_command cmd)
3687 struct devlink_param_item *param_item;
3689 if (devlink_param_find_by_name(param_list, param->name))
3692 if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT))
3693 WARN_ON(param->get || param->set);
3695 WARN_ON(!param->get || !param->set);
3697 param_item = kzalloc(sizeof(*param_item), GFP_KERNEL);
3700 param_item->param = param;
3702 list_add_tail(¶m_item->list, param_list);
3703 devlink_param_notify(devlink, port_index, param_item, cmd);
3707 static void devlink_param_unregister_one(struct devlink *devlink,
3708 unsigned int port_index,
3709 struct list_head *param_list,
3710 const struct devlink_param *param,
3711 enum devlink_command cmd)
3713 struct devlink_param_item *param_item;
3715 param_item = devlink_param_find_by_name(param_list, param->name);
3716 WARN_ON(!param_item);
3717 devlink_param_notify(devlink, port_index, param_item, cmd);
3718 list_del(¶m_item->list);
3722 static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg,
3723 struct netlink_callback *cb)
3725 struct devlink_param_item *param_item;
3726 struct devlink_port *devlink_port;
3727 struct devlink *devlink;
3728 int start = cb->args[0];
3732 mutex_lock(&devlink_mutex);
3733 list_for_each_entry(devlink, &devlink_list, list) {
3734 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
3736 mutex_lock(&devlink->lock);
3737 list_for_each_entry(devlink_port, &devlink->port_list, list) {
3738 list_for_each_entry(param_item,
3739 &devlink_port->param_list, list) {
3744 err = devlink_nl_param_fill(msg,
3745 devlink_port->devlink,
3746 devlink_port->index, param_item,
3747 DEVLINK_CMD_PORT_PARAM_GET,
3748 NETLINK_CB(cb->skb).portid,
3751 if (err == -EOPNOTSUPP) {
3754 mutex_unlock(&devlink->lock);
3760 mutex_unlock(&devlink->lock);
3763 mutex_unlock(&devlink_mutex);
3765 if (err != -EMSGSIZE)
3772 static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb,
3773 struct genl_info *info)
3775 struct devlink_port *devlink_port = info->user_ptr[0];
3776 struct devlink_param_item *param_item;
3777 struct sk_buff *msg;
3780 param_item = devlink_param_get_from_info(&devlink_port->param_list,
3785 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3789 err = devlink_nl_param_fill(msg, devlink_port->devlink,
3790 devlink_port->index, param_item,
3791 DEVLINK_CMD_PORT_PARAM_GET,
3792 info->snd_portid, info->snd_seq, 0);
3798 return genlmsg_reply(msg, info);
3801 static int devlink_nl_cmd_port_param_set_doit(struct sk_buff *skb,
3802 struct genl_info *info)
3804 struct devlink_port *devlink_port = info->user_ptr[0];
3806 return __devlink_nl_cmd_param_set_doit(devlink_port->devlink,
3807 devlink_port->index,
3808 &devlink_port->param_list, info,
3809 DEVLINK_CMD_PORT_PARAM_NEW);
3812 static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg,
3813 struct devlink *devlink,
3814 struct devlink_snapshot *snapshot)
3816 struct nlattr *snap_attr;
3819 snap_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_SNAPSHOT);
3823 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, snapshot->id);
3825 goto nla_put_failure;
3827 nla_nest_end(msg, snap_attr);
3831 nla_nest_cancel(msg, snap_attr);
3835 static int devlink_nl_region_snapshots_id_put(struct sk_buff *msg,
3836 struct devlink *devlink,
3837 struct devlink_region *region)
3839 struct devlink_snapshot *snapshot;
3840 struct nlattr *snapshots_attr;
3843 snapshots_attr = nla_nest_start_noflag(msg,
3844 DEVLINK_ATTR_REGION_SNAPSHOTS);
3845 if (!snapshots_attr)
3848 list_for_each_entry(snapshot, ®ion->snapshot_list, list) {
3849 err = devlink_nl_region_snapshot_id_put(msg, devlink, snapshot);
3851 goto nla_put_failure;
3854 nla_nest_end(msg, snapshots_attr);
3858 nla_nest_cancel(msg, snapshots_attr);
3862 static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink,
3863 enum devlink_command cmd, u32 portid,
3865 struct devlink_region *region)
3870 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
3874 err = devlink_nl_put_handle(msg, devlink);
3876 goto nla_put_failure;
3878 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->ops->name);
3880 goto nla_put_failure;
3882 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
3886 goto nla_put_failure;
3888 err = devlink_nl_region_snapshots_id_put(msg, devlink, region);
3890 goto nla_put_failure;
3892 genlmsg_end(msg, hdr);
3896 genlmsg_cancel(msg, hdr);
3900 static struct sk_buff *
3901 devlink_nl_region_notify_build(struct devlink_region *region,
3902 struct devlink_snapshot *snapshot,
3903 enum devlink_command cmd, u32 portid, u32 seq)
3905 struct devlink *devlink = region->devlink;
3906 struct sk_buff *msg;
3911 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3913 return ERR_PTR(-ENOMEM);
3915 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, 0, cmd);
3921 err = devlink_nl_put_handle(msg, devlink);
3923 goto out_cancel_msg;
3925 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME,
3928 goto out_cancel_msg;
3931 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID,
3934 goto out_cancel_msg;
3936 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
3937 region->size, DEVLINK_ATTR_PAD);
3939 goto out_cancel_msg;
3941 genlmsg_end(msg, hdr);
3946 genlmsg_cancel(msg, hdr);
3949 return ERR_PTR(err);
3952 static void devlink_nl_region_notify(struct devlink_region *region,
3953 struct devlink_snapshot *snapshot,
3954 enum devlink_command cmd)
3956 struct devlink *devlink = region->devlink;
3957 struct sk_buff *msg;
3959 WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL);
3961 msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0);
3965 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
3966 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
3970 * __devlink_snapshot_id_increment - Increment number of snapshots using an id
3971 * @devlink: devlink instance
3972 * @id: the snapshot id
3974 * Track when a new snapshot begins using an id. Load the count for the
3975 * given id from the snapshot xarray, increment it, and store it back.
3977 * Called when a new snapshot is created with the given id.
3979 * The id *must* have been previously allocated by
3980 * devlink_region_snapshot_id_get().
3982 * Returns 0 on success, or an error on failure.
3984 static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id)
3986 unsigned long count;
3989 lockdep_assert_held(&devlink->lock);
3991 p = xa_load(&devlink->snapshot_ids, id);
3995 if (WARN_ON(!xa_is_value(p)))
3998 count = xa_to_value(p);
4001 return xa_err(xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
4006 * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id
4007 * @devlink: devlink instance
4008 * @id: the snapshot id
4010 * Track when a snapshot is deleted and stops using an id. Load the count
4011 * for the given id from the snapshot xarray, decrement it, and store it
4014 * If the count reaches zero, erase this id from the xarray, freeing it
4015 * up for future re-use by devlink_region_snapshot_id_get().
4017 * Called when a snapshot using the given id is deleted, and when the
4018 * initial allocator of the id is finished using it.
4020 static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id)
4022 unsigned long count;
4025 lockdep_assert_held(&devlink->lock);
4027 p = xa_load(&devlink->snapshot_ids, id);
4031 if (WARN_ON(!xa_is_value(p)))
4034 count = xa_to_value(p);
4038 xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
4041 /* If this was the last user, we can erase this id */
4042 xa_erase(&devlink->snapshot_ids, id);
4047 * __devlink_snapshot_id_insert - Insert a specific snapshot ID
4048 * @devlink: devlink instance
4049 * @id: the snapshot id
4051 * Mark the given snapshot id as used by inserting a zero value into the
4054 * This must be called while holding the devlink instance lock. Unlike
4055 * devlink_snapshot_id_get, the initial reference count is zero, not one.
4056 * It is expected that the id will immediately be used before
4057 * releasing the devlink instance lock.
4059 * Returns zero on success, or an error code if the snapshot id could not
4062 static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id)
4064 lockdep_assert_held(&devlink->lock);
4066 if (xa_load(&devlink->snapshot_ids, id))
4069 return xa_err(xa_store(&devlink->snapshot_ids, id, xa_mk_value(0),
4074 * __devlink_region_snapshot_id_get - get snapshot ID
4075 * @devlink: devlink instance
4076 * @id: storage to return snapshot id
4078 * Allocates a new snapshot id. Returns zero on success, or a negative
4079 * error on failure. Must be called while holding the devlink instance
4082 * Snapshot IDs are tracked using an xarray which stores the number of
4083 * users of the snapshot id.
4085 * Note that the caller of this function counts as a 'user', in order to
4086 * avoid race conditions. The caller must release its hold on the
4087 * snapshot by using devlink_region_snapshot_id_put.
4089 static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
4091 lockdep_assert_held(&devlink->lock);
4093 return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1),
4094 xa_limit_32b, GFP_KERNEL);
4098 * __devlink_region_snapshot_create - create a new snapshot
4099 * This will add a new snapshot of a region. The snapshot
4100 * will be stored on the region struct and can be accessed
4101 * from devlink. This is useful for future analyses of snapshots.
4102 * Multiple snapshots can be created on a region.
4103 * The @snapshot_id should be obtained using the getter function.
4105 * Must be called only while holding the devlink instance lock.
4107 * @region: devlink region of the snapshot
4108 * @data: snapshot data
4109 * @snapshot_id: snapshot id to be created
4112 __devlink_region_snapshot_create(struct devlink_region *region,
4113 u8 *data, u32 snapshot_id)
4115 struct devlink *devlink = region->devlink;
4116 struct devlink_snapshot *snapshot;
4119 lockdep_assert_held(&devlink->lock);
4121 /* check if region can hold one more snapshot */
4122 if (region->cur_snapshots == region->max_snapshots)
4125 if (devlink_region_snapshot_get_by_id(region, snapshot_id))
4128 snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL);
4132 err = __devlink_snapshot_id_increment(devlink, snapshot_id);
4134 goto err_snapshot_id_increment;
4136 snapshot->id = snapshot_id;
4137 snapshot->region = region;
4138 snapshot->data = data;
4140 list_add_tail(&snapshot->list, ®ion->snapshot_list);
4142 region->cur_snapshots++;
4144 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW);
4147 err_snapshot_id_increment:
4152 static void devlink_region_snapshot_del(struct devlink_region *region,
4153 struct devlink_snapshot *snapshot)
4155 struct devlink *devlink = region->devlink;
4157 lockdep_assert_held(&devlink->lock);
4159 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL);
4160 region->cur_snapshots--;
4161 list_del(&snapshot->list);
4162 region->ops->destructor(snapshot->data);
4163 __devlink_snapshot_id_decrement(devlink, snapshot->id);
4167 static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb,
4168 struct genl_info *info)
4170 struct devlink *devlink = info->user_ptr[0];
4171 struct devlink_region *region;
4172 const char *region_name;
4173 struct sk_buff *msg;
4176 if (!info->attrs[DEVLINK_ATTR_REGION_NAME])
4179 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
4180 region = devlink_region_get_by_name(devlink, region_name);
4184 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4188 err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET,
4189 info->snd_portid, info->snd_seq, 0,
4196 return genlmsg_reply(msg, info);
4199 static int devlink_nl_cmd_region_get_dumpit(struct sk_buff *msg,
4200 struct netlink_callback *cb)
4202 struct devlink_region *region;
4203 struct devlink *devlink;
4204 int start = cb->args[0];
4208 mutex_lock(&devlink_mutex);
4209 list_for_each_entry(devlink, &devlink_list, list) {
4210 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
4213 mutex_lock(&devlink->lock);
4214 list_for_each_entry(region, &devlink->region_list, list) {
4219 err = devlink_nl_region_fill(msg, devlink,
4220 DEVLINK_CMD_REGION_GET,
4221 NETLINK_CB(cb->skb).portid,
4223 NLM_F_MULTI, region);
4225 mutex_unlock(&devlink->lock);
4230 mutex_unlock(&devlink->lock);
4233 mutex_unlock(&devlink_mutex);
4238 static int devlink_nl_cmd_region_del(struct sk_buff *skb,
4239 struct genl_info *info)
4241 struct devlink *devlink = info->user_ptr[0];
4242 struct devlink_snapshot *snapshot;
4243 struct devlink_region *region;
4244 const char *region_name;
4247 if (!info->attrs[DEVLINK_ATTR_REGION_NAME] ||
4248 !info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID])
4251 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
4252 snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
4254 region = devlink_region_get_by_name(devlink, region_name);
4258 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
4262 devlink_region_snapshot_del(region, snapshot);
4267 devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
4269 struct devlink *devlink = info->user_ptr[0];
4270 struct devlink_snapshot *snapshot;
4271 struct nlattr *snapshot_id_attr;
4272 struct devlink_region *region;
4273 const char *region_name;
4278 if (!info->attrs[DEVLINK_ATTR_REGION_NAME]) {
4279 NL_SET_ERR_MSG_MOD(info->extack, "No region name provided");
4283 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
4284 region = devlink_region_get_by_name(devlink, region_name);
4286 NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not exist");
4290 if (!region->ops->snapshot) {
4291 NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not support taking an immediate snapshot");
4295 if (region->cur_snapshots == region->max_snapshots) {
4296 NL_SET_ERR_MSG_MOD(info->extack, "The region has reached the maximum number of stored snapshots");
4300 snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID];
4301 if (snapshot_id_attr) {
4302 snapshot_id = nla_get_u32(snapshot_id_attr);
4304 if (devlink_region_snapshot_get_by_id(region, snapshot_id)) {
4305 NL_SET_ERR_MSG_MOD(info->extack, "The requested snapshot id is already in use");
4309 err = __devlink_snapshot_id_insert(devlink, snapshot_id);
4313 err = __devlink_region_snapshot_id_get(devlink, &snapshot_id);
4315 NL_SET_ERR_MSG_MOD(info->extack, "Failed to allocate a new snapshot id");
4320 err = region->ops->snapshot(devlink, info->extack, &data);
4322 goto err_snapshot_capture;
4324 err = __devlink_region_snapshot_create(region, data, snapshot_id);
4326 goto err_snapshot_create;
4328 if (!snapshot_id_attr) {
4329 struct sk_buff *msg;
4331 snapshot = devlink_region_snapshot_get_by_id(region,
4333 if (WARN_ON(!snapshot))
4336 msg = devlink_nl_region_notify_build(region, snapshot,
4337 DEVLINK_CMD_REGION_NEW,
4340 err = PTR_ERR_OR_ZERO(msg);
4344 err = genlmsg_reply(msg, info);
4351 err_snapshot_create:
4352 region->ops->destructor(data);
4353 err_snapshot_capture:
4354 __devlink_snapshot_id_decrement(devlink, snapshot_id);
4358 devlink_region_snapshot_del(region, snapshot);
4362 static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg,
4363 struct devlink *devlink,
4364 u8 *chunk, u32 chunk_size,
4367 struct nlattr *chunk_attr;
4370 chunk_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_CHUNK);
4374 err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk);
4376 goto nla_put_failure;
4378 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr,
4381 goto nla_put_failure;
4383 nla_nest_end(msg, chunk_attr);
4387 nla_nest_cancel(msg, chunk_attr);
4391 #define DEVLINK_REGION_READ_CHUNK_SIZE 256
4393 static int devlink_nl_region_read_snapshot_fill(struct sk_buff *skb,
4394 struct devlink *devlink,
4395 struct devlink_region *region,
4396 struct nlattr **attrs,
4401 struct devlink_snapshot *snapshot;
4402 u64 curr_offset = start_offset;
4406 *new_offset = start_offset;
4408 snapshot_id = nla_get_u32(attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
4409 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
4413 while (curr_offset < end_offset) {
4417 if (end_offset - curr_offset < DEVLINK_REGION_READ_CHUNK_SIZE)
4418 data_size = end_offset - curr_offset;
4420 data_size = DEVLINK_REGION_READ_CHUNK_SIZE;
4422 data = &snapshot->data[curr_offset];
4423 err = devlink_nl_cmd_region_read_chunk_fill(skb, devlink,
4429 curr_offset += data_size;
4431 *new_offset = curr_offset;
4436 static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
4437 struct netlink_callback *cb)
4439 const struct genl_dumpit_info *info = genl_dumpit_info(cb);
4440 u64 ret_offset, start_offset, end_offset = U64_MAX;
4441 struct nlattr **attrs = info->attrs;
4442 struct devlink_region *region;
4443 struct nlattr *chunks_attr;
4444 const char *region_name;
4445 struct devlink *devlink;
4449 start_offset = *((u64 *)&cb->args[0]);
4451 mutex_lock(&devlink_mutex);
4452 devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs);
4453 if (IS_ERR(devlink)) {
4454 err = PTR_ERR(devlink);
4458 mutex_lock(&devlink->lock);
4460 if (!attrs[DEVLINK_ATTR_REGION_NAME] ||
4461 !attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]) {
4466 region_name = nla_data(attrs[DEVLINK_ATTR_REGION_NAME]);
4467 region = devlink_region_get_by_name(devlink, region_name);
4473 if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] &&
4474 attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) {
4477 nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
4479 end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
4480 end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]);
4483 if (end_offset > region->size)
4484 end_offset = region->size;
4486 /* return 0 if there is no further data to read */
4487 if (start_offset == end_offset) {
4492 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
4493 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI,
4494 DEVLINK_CMD_REGION_READ);
4500 err = devlink_nl_put_handle(skb, devlink);
4502 goto nla_put_failure;
4504 err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name);
4506 goto nla_put_failure;
4508 chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS);
4511 goto nla_put_failure;
4514 err = devlink_nl_region_read_snapshot_fill(skb, devlink,
4517 end_offset, &ret_offset);
4519 if (err && err != -EMSGSIZE)
4520 goto nla_put_failure;
4522 /* Check if there was any progress done to prevent infinite loop */
4523 if (ret_offset == start_offset) {
4525 goto nla_put_failure;
4528 *((u64 *)&cb->args[0]) = ret_offset;
4530 nla_nest_end(skb, chunks_attr);
4531 genlmsg_end(skb, hdr);
4532 mutex_unlock(&devlink->lock);
4533 mutex_unlock(&devlink_mutex);
4538 genlmsg_cancel(skb, hdr);
4540 mutex_unlock(&devlink->lock);
4542 mutex_unlock(&devlink_mutex);
4546 struct devlink_info_req {
4547 struct sk_buff *msg;
4550 int devlink_info_driver_name_put(struct devlink_info_req *req, const char *name)
4552 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME, name);
4554 EXPORT_SYMBOL_GPL(devlink_info_driver_name_put);
4556 int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn)
4558 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn);
4560 EXPORT_SYMBOL_GPL(devlink_info_serial_number_put);
4562 int devlink_info_board_serial_number_put(struct devlink_info_req *req,
4565 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER,
4568 EXPORT_SYMBOL_GPL(devlink_info_board_serial_number_put);
4570 static int devlink_info_version_put(struct devlink_info_req *req, int attr,
4571 const char *version_name,
4572 const char *version_value)
4574 struct nlattr *nest;
4577 nest = nla_nest_start_noflag(req->msg, attr);
4581 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME,
4584 goto nla_put_failure;
4586 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE,
4589 goto nla_put_failure;
4591 nla_nest_end(req->msg, nest);
4596 nla_nest_cancel(req->msg, nest);
4600 int devlink_info_version_fixed_put(struct devlink_info_req *req,
4601 const char *version_name,
4602 const char *version_value)
4604 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED,
4605 version_name, version_value);
4607 EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put);
4609 int devlink_info_version_stored_put(struct devlink_info_req *req,
4610 const char *version_name,
4611 const char *version_value)
4613 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED,
4614 version_name, version_value);
4616 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put);
4618 int devlink_info_version_running_put(struct devlink_info_req *req,
4619 const char *version_name,
4620 const char *version_value)
4622 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING,
4623 version_name, version_value);
4625 EXPORT_SYMBOL_GPL(devlink_info_version_running_put);
4628 devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
4629 enum devlink_command cmd, u32 portid,
4630 u32 seq, int flags, struct netlink_ext_ack *extack)
4632 struct devlink_info_req req;
4636 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
4641 if (devlink_nl_put_handle(msg, devlink))
4642 goto err_cancel_msg;
4645 err = devlink->ops->info_get(devlink, &req, extack);
4647 goto err_cancel_msg;
4649 genlmsg_end(msg, hdr);
4653 genlmsg_cancel(msg, hdr);
4657 static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb,
4658 struct genl_info *info)
4660 struct devlink *devlink = info->user_ptr[0];
4661 struct sk_buff *msg;
4664 if (!devlink->ops->info_get)
4667 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4671 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
4672 info->snd_portid, info->snd_seq, 0,
4679 return genlmsg_reply(msg, info);
4682 static int devlink_nl_cmd_info_get_dumpit(struct sk_buff *msg,
4683 struct netlink_callback *cb)
4685 struct devlink *devlink;
4686 int start = cb->args[0];
4690 mutex_lock(&devlink_mutex);
4691 list_for_each_entry(devlink, &devlink_list, list) {
4692 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
4699 if (!devlink->ops->info_get) {
4704 mutex_lock(&devlink->lock);
4705 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
4706 NETLINK_CB(cb->skb).portid,
4707 cb->nlh->nlmsg_seq, NLM_F_MULTI,
4709 mutex_unlock(&devlink->lock);
4710 if (err == -EOPNOTSUPP)
4716 mutex_unlock(&devlink_mutex);
4718 if (err != -EMSGSIZE)
4725 struct devlink_fmsg_item {
4726 struct list_head list;
4733 struct devlink_fmsg {
4734 struct list_head item_list;
4735 bool putting_binary; /* This flag forces enclosing of binary data
4736 * in an array brackets. It forces using
4737 * of designated API:
4738 * devlink_fmsg_binary_pair_nest_start()
4739 * devlink_fmsg_binary_pair_nest_end()
4743 static struct devlink_fmsg *devlink_fmsg_alloc(void)
4745 struct devlink_fmsg *fmsg;
4747 fmsg = kzalloc(sizeof(*fmsg), GFP_KERNEL);
4751 INIT_LIST_HEAD(&fmsg->item_list);
4756 static void devlink_fmsg_free(struct devlink_fmsg *fmsg)
4758 struct devlink_fmsg_item *item, *tmp;
4760 list_for_each_entry_safe(item, tmp, &fmsg->item_list, list) {
4761 list_del(&item->list);
4767 static int devlink_fmsg_nest_common(struct devlink_fmsg *fmsg,
4770 struct devlink_fmsg_item *item;
4772 item = kzalloc(sizeof(*item), GFP_KERNEL);
4776 item->attrtype = attrtype;
4777 list_add_tail(&item->list, &fmsg->item_list);
4782 int devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg)
4784 if (fmsg->putting_binary)
4787 return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_OBJ_NEST_START);
4789 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start);
4791 static int devlink_fmsg_nest_end(struct devlink_fmsg *fmsg)
4793 if (fmsg->putting_binary)
4796 return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_NEST_END);
4799 int devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg)
4801 if (fmsg->putting_binary)
4804 return devlink_fmsg_nest_end(fmsg);
4806 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end);
4808 #define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN)
4810 static int devlink_fmsg_put_name(struct devlink_fmsg *fmsg, const char *name)
4812 struct devlink_fmsg_item *item;
4814 if (fmsg->putting_binary)
4817 if (strlen(name) + 1 > DEVLINK_FMSG_MAX_SIZE)
4820 item = kzalloc(sizeof(*item) + strlen(name) + 1, GFP_KERNEL);
4824 item->nla_type = NLA_NUL_STRING;
4825 item->len = strlen(name) + 1;
4826 item->attrtype = DEVLINK_ATTR_FMSG_OBJ_NAME;
4827 memcpy(&item->value, name, item->len);
4828 list_add_tail(&item->list, &fmsg->item_list);
4833 int devlink_fmsg_pair_nest_start(struct devlink_fmsg *fmsg, const char *name)
4837 if (fmsg->putting_binary)
4840 err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_PAIR_NEST_START);
4844 err = devlink_fmsg_put_name(fmsg, name);
4850 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start);
4852 int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg)
4854 if (fmsg->putting_binary)
4857 return devlink_fmsg_nest_end(fmsg);
4859 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end);
4861 int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg,
4866 if (fmsg->putting_binary)
4869 err = devlink_fmsg_pair_nest_start(fmsg, name);
4873 err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_ARR_NEST_START);
4879 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start);
4881 int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg)
4885 if (fmsg->putting_binary)
4888 err = devlink_fmsg_nest_end(fmsg);
4892 err = devlink_fmsg_nest_end(fmsg);
4898 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end);
4900 int devlink_fmsg_binary_pair_nest_start(struct devlink_fmsg *fmsg,
4905 err = devlink_fmsg_arr_pair_nest_start(fmsg, name);
4909 fmsg->putting_binary = true;
4912 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_start);
4914 int devlink_fmsg_binary_pair_nest_end(struct devlink_fmsg *fmsg)
4916 if (!fmsg->putting_binary)
4919 fmsg->putting_binary = false;
4920 return devlink_fmsg_arr_pair_nest_end(fmsg);
4922 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_end);
4924 static int devlink_fmsg_put_value(struct devlink_fmsg *fmsg,
4925 const void *value, u16 value_len,
4928 struct devlink_fmsg_item *item;
4930 if (value_len > DEVLINK_FMSG_MAX_SIZE)
4933 item = kzalloc(sizeof(*item) + value_len, GFP_KERNEL);
4937 item->nla_type = value_nla_type;
4938 item->len = value_len;
4939 item->attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
4940 memcpy(&item->value, value, item->len);
4941 list_add_tail(&item->list, &fmsg->item_list);
4946 int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value)
4948 if (fmsg->putting_binary)
4951 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_FLAG);
4953 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_put);
4955 int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value)
4957 if (fmsg->putting_binary)
4960 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U8);
4962 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_put);
4964 int devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value)
4966 if (fmsg->putting_binary)
4969 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U32);
4971 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put);
4973 int devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value)
4975 if (fmsg->putting_binary)
4978 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U64);
4980 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_put);
4982 int devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value)
4984 if (fmsg->putting_binary)
4987 return devlink_fmsg_put_value(fmsg, value, strlen(value) + 1,
4990 EXPORT_SYMBOL_GPL(devlink_fmsg_string_put);
4992 int devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value,
4995 if (!fmsg->putting_binary)
4998 return devlink_fmsg_put_value(fmsg, value, value_len, NLA_BINARY);
5000 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put);
5002 int devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name,
5007 err = devlink_fmsg_pair_nest_start(fmsg, name);
5011 err = devlink_fmsg_bool_put(fmsg, value);
5015 err = devlink_fmsg_pair_nest_end(fmsg);
5021 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put);
5023 int devlink_fmsg_u8_pair_put(struct devlink_fmsg *fmsg, const char *name,
5028 err = devlink_fmsg_pair_nest_start(fmsg, name);
5032 err = devlink_fmsg_u8_put(fmsg, value);
5036 err = devlink_fmsg_pair_nest_end(fmsg);
5042 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put);
5044 int devlink_fmsg_u32_pair_put(struct devlink_fmsg *fmsg, const char *name,
5049 err = devlink_fmsg_pair_nest_start(fmsg, name);
5053 err = devlink_fmsg_u32_put(fmsg, value);
5057 err = devlink_fmsg_pair_nest_end(fmsg);
5063 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put);
5065 int devlink_fmsg_u64_pair_put(struct devlink_fmsg *fmsg, const char *name,
5070 err = devlink_fmsg_pair_nest_start(fmsg, name);
5074 err = devlink_fmsg_u64_put(fmsg, value);
5078 err = devlink_fmsg_pair_nest_end(fmsg);
5084 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put);
5086 int devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name,
5091 err = devlink_fmsg_pair_nest_start(fmsg, name);
5095 err = devlink_fmsg_string_put(fmsg, value);
5099 err = devlink_fmsg_pair_nest_end(fmsg);
5105 EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put);
5107 int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name,
5108 const void *value, u32 value_len)
5115 err = devlink_fmsg_binary_pair_nest_start(fmsg, name);
5119 for (offset = 0; offset < value_len; offset += data_size) {
5120 data_size = value_len - offset;
5121 if (data_size > DEVLINK_FMSG_MAX_SIZE)
5122 data_size = DEVLINK_FMSG_MAX_SIZE;
5123 err = devlink_fmsg_binary_put(fmsg, value + offset, data_size);
5126 /* Exit from loop with a break (instead of
5127 * return) to make sure putting_binary is turned off in
5128 * devlink_fmsg_binary_pair_nest_end
5132 end_err = devlink_fmsg_binary_pair_nest_end(fmsg);
5138 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put);
5141 devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb)
5143 switch (msg->nla_type) {
5148 case NLA_NUL_STRING:
5150 return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE,
5158 devlink_fmsg_item_fill_data(struct devlink_fmsg_item *msg, struct sk_buff *skb)
5160 int attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
5163 switch (msg->nla_type) {
5165 /* Always provide flag data, regardless of its value */
5166 tmp = *(bool *) msg->value;
5168 return nla_put_u8(skb, attrtype, tmp);
5170 return nla_put_u8(skb, attrtype, *(u8 *) msg->value);
5172 return nla_put_u32(skb, attrtype, *(u32 *) msg->value);
5174 return nla_put_u64_64bit(skb, attrtype, *(u64 *) msg->value,
5176 case NLA_NUL_STRING:
5177 return nla_put_string(skb, attrtype, (char *) &msg->value);
5179 return nla_put(skb, attrtype, msg->len, (void *) &msg->value);
5186 devlink_fmsg_prepare_skb(struct devlink_fmsg *fmsg, struct sk_buff *skb,
5189 struct devlink_fmsg_item *item;
5190 struct nlattr *fmsg_nlattr;
5194 fmsg_nlattr = nla_nest_start_noflag(skb, DEVLINK_ATTR_FMSG);
5198 list_for_each_entry(item, &fmsg->item_list, list) {
5204 switch (item->attrtype) {
5205 case DEVLINK_ATTR_FMSG_OBJ_NEST_START:
5206 case DEVLINK_ATTR_FMSG_PAIR_NEST_START:
5207 case DEVLINK_ATTR_FMSG_ARR_NEST_START:
5208 case DEVLINK_ATTR_FMSG_NEST_END:
5209 err = nla_put_flag(skb, item->attrtype);
5211 case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA:
5212 err = devlink_fmsg_item_fill_type(item, skb);
5215 err = devlink_fmsg_item_fill_data(item, skb);
5217 case DEVLINK_ATTR_FMSG_OBJ_NAME:
5218 err = nla_put_string(skb, item->attrtype,
5219 (char *) &item->value);
5231 nla_nest_end(skb, fmsg_nlattr);
5235 static int devlink_fmsg_snd(struct devlink_fmsg *fmsg,
5236 struct genl_info *info,
5237 enum devlink_command cmd, int flags)
5239 struct nlmsghdr *nlh;
5240 struct sk_buff *skb;
5247 int tmp_index = index;
5249 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
5253 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
5254 &devlink_nl_family, flags | NLM_F_MULTI, cmd);
5257 goto nla_put_failure;
5260 err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
5263 else if (err != -EMSGSIZE || tmp_index == index)
5264 goto nla_put_failure;
5266 genlmsg_end(skb, hdr);
5267 err = genlmsg_reply(skb, info);
5272 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
5275 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
5276 NLMSG_DONE, 0, flags | NLM_F_MULTI);
5279 goto nla_put_failure;
5282 return genlmsg_reply(skb, info);
5289 static int devlink_fmsg_dumpit(struct devlink_fmsg *fmsg, struct sk_buff *skb,
5290 struct netlink_callback *cb,
5291 enum devlink_command cmd)
5293 int index = cb->args[0];
5294 int tmp_index = index;
5298 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
5299 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, cmd);
5302 goto nla_put_failure;
5305 err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
5306 if ((err && err != -EMSGSIZE) || tmp_index == index)
5307 goto nla_put_failure;
5309 cb->args[0] = index;
5310 genlmsg_end(skb, hdr);
5314 genlmsg_cancel(skb, hdr);
5318 struct devlink_health_reporter {
5319 struct list_head list;
5321 const struct devlink_health_reporter_ops *ops;
5322 struct devlink *devlink;
5323 struct devlink_port *devlink_port;
5324 struct devlink_fmsg *dump_fmsg;
5325 struct mutex dump_lock; /* lock parallel read/write from dump buffers */
5326 u64 graceful_period;
5334 u64 last_recovery_ts;
5335 refcount_t refcount;
5339 devlink_health_reporter_priv(struct devlink_health_reporter *reporter)
5341 return reporter->priv;
5343 EXPORT_SYMBOL_GPL(devlink_health_reporter_priv);
5345 static struct devlink_health_reporter *
5346 __devlink_health_reporter_find_by_name(struct list_head *reporter_list,
5347 struct mutex *list_lock,
5348 const char *reporter_name)
5350 struct devlink_health_reporter *reporter;
5352 lockdep_assert_held(list_lock);
5353 list_for_each_entry(reporter, reporter_list, list)
5354 if (!strcmp(reporter->ops->name, reporter_name))
5359 static struct devlink_health_reporter *
5360 devlink_health_reporter_find_by_name(struct devlink *devlink,
5361 const char *reporter_name)
5363 return __devlink_health_reporter_find_by_name(&devlink->reporter_list,
5364 &devlink->reporters_lock,
5368 static struct devlink_health_reporter *
5369 devlink_port_health_reporter_find_by_name(struct devlink_port *devlink_port,
5370 const char *reporter_name)
5372 return __devlink_health_reporter_find_by_name(&devlink_port->reporter_list,
5373 &devlink_port->reporters_lock,
5377 static struct devlink_health_reporter *
5378 __devlink_health_reporter_create(struct devlink *devlink,
5379 const struct devlink_health_reporter_ops *ops,
5380 u64 graceful_period, void *priv)
5382 struct devlink_health_reporter *reporter;
5384 if (WARN_ON(graceful_period && !ops->recover))
5385 return ERR_PTR(-EINVAL);
5387 reporter = kzalloc(sizeof(*reporter), GFP_KERNEL);
5389 return ERR_PTR(-ENOMEM);
5391 reporter->priv = priv;
5392 reporter->ops = ops;
5393 reporter->devlink = devlink;
5394 reporter->graceful_period = graceful_period;
5395 reporter->auto_recover = !!ops->recover;
5396 reporter->auto_dump = !!ops->dump;
5397 mutex_init(&reporter->dump_lock);
5398 refcount_set(&reporter->refcount, 1);
5403 * devlink_port_health_reporter_create - create devlink health reporter for
5404 * specified port instance
5406 * @port: devlink_port which should contain the new reporter
5408 * @graceful_period: to avoid recovery loops, in msecs
5411 struct devlink_health_reporter *
5412 devlink_port_health_reporter_create(struct devlink_port *port,
5413 const struct devlink_health_reporter_ops *ops,
5414 u64 graceful_period, void *priv)
5416 struct devlink_health_reporter *reporter;
5418 mutex_lock(&port->reporters_lock);
5419 if (__devlink_health_reporter_find_by_name(&port->reporter_list,
5420 &port->reporters_lock, ops->name)) {
5421 reporter = ERR_PTR(-EEXIST);
5425 reporter = __devlink_health_reporter_create(port->devlink, ops,
5426 graceful_period, priv);
5427 if (IS_ERR(reporter))
5430 reporter->devlink_port = port;
5431 list_add_tail(&reporter->list, &port->reporter_list);
5433 mutex_unlock(&port->reporters_lock);
5436 EXPORT_SYMBOL_GPL(devlink_port_health_reporter_create);
5439 * devlink_health_reporter_create - create devlink health reporter
5443 * @graceful_period: to avoid recovery loops, in msecs
5446 struct devlink_health_reporter *
5447 devlink_health_reporter_create(struct devlink *devlink,
5448 const struct devlink_health_reporter_ops *ops,
5449 u64 graceful_period, void *priv)
5451 struct devlink_health_reporter *reporter;
5453 mutex_lock(&devlink->reporters_lock);
5454 if (devlink_health_reporter_find_by_name(devlink, ops->name)) {
5455 reporter = ERR_PTR(-EEXIST);
5459 reporter = __devlink_health_reporter_create(devlink, ops,
5460 graceful_period, priv);
5461 if (IS_ERR(reporter))
5464 list_add_tail(&reporter->list, &devlink->reporter_list);
5466 mutex_unlock(&devlink->reporters_lock);
5469 EXPORT_SYMBOL_GPL(devlink_health_reporter_create);
5472 devlink_health_reporter_free(struct devlink_health_reporter *reporter)
5474 mutex_destroy(&reporter->dump_lock);
5475 if (reporter->dump_fmsg)
5476 devlink_fmsg_free(reporter->dump_fmsg);
5481 devlink_health_reporter_put(struct devlink_health_reporter *reporter)
5483 if (refcount_dec_and_test(&reporter->refcount))
5484 devlink_health_reporter_free(reporter);
5488 __devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
5490 list_del(&reporter->list);
5491 devlink_health_reporter_put(reporter);
5495 * devlink_health_reporter_destroy - destroy devlink health reporter
5497 * @reporter: devlink health reporter to destroy
5500 devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
5502 struct mutex *lock = &reporter->devlink->reporters_lock;
5505 __devlink_health_reporter_destroy(reporter);
5508 EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy);
5511 * devlink_port_health_reporter_destroy - destroy devlink port health reporter
5513 * @reporter: devlink health reporter to destroy
5516 devlink_port_health_reporter_destroy(struct devlink_health_reporter *reporter)
5518 struct mutex *lock = &reporter->devlink_port->reporters_lock;
5521 __devlink_health_reporter_destroy(reporter);
5524 EXPORT_SYMBOL_GPL(devlink_port_health_reporter_destroy);
5527 devlink_nl_health_reporter_fill(struct sk_buff *msg,
5528 struct devlink *devlink,
5529 struct devlink_health_reporter *reporter,
5530 enum devlink_command cmd, u32 portid,
5533 struct nlattr *reporter_attr;
5536 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
5540 if (devlink_nl_put_handle(msg, devlink))
5541 goto genlmsg_cancel;
5543 if (reporter->devlink_port) {
5544 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, reporter->devlink_port->index))
5545 goto genlmsg_cancel;
5547 reporter_attr = nla_nest_start_noflag(msg,
5548 DEVLINK_ATTR_HEALTH_REPORTER);
5550 goto genlmsg_cancel;
5551 if (nla_put_string(msg, DEVLINK_ATTR_HEALTH_REPORTER_NAME,
5552 reporter->ops->name))
5553 goto reporter_nest_cancel;
5554 if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_STATE,
5555 reporter->health_state))
5556 goto reporter_nest_cancel;
5557 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT,
5558 reporter->error_count, DEVLINK_ATTR_PAD))
5559 goto reporter_nest_cancel;
5560 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT,
5561 reporter->recovery_count, DEVLINK_ATTR_PAD))
5562 goto reporter_nest_cancel;
5563 if (reporter->ops->recover &&
5564 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD,
5565 reporter->graceful_period,
5567 goto reporter_nest_cancel;
5568 if (reporter->ops->recover &&
5569 nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER,
5570 reporter->auto_recover))
5571 goto reporter_nest_cancel;
5572 if (reporter->dump_fmsg &&
5573 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS,
5574 jiffies_to_msecs(reporter->dump_ts),
5576 goto reporter_nest_cancel;
5577 if (reporter->dump_fmsg &&
5578 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS,
5579 reporter->dump_real_ts, DEVLINK_ATTR_PAD))
5580 goto reporter_nest_cancel;
5581 if (reporter->ops->dump &&
5582 nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP,
5583 reporter->auto_dump))
5584 goto reporter_nest_cancel;
5586 nla_nest_end(msg, reporter_attr);
5587 genlmsg_end(msg, hdr);
5590 reporter_nest_cancel:
5591 nla_nest_end(msg, reporter_attr);
5593 genlmsg_cancel(msg, hdr);
5597 static void devlink_recover_notify(struct devlink_health_reporter *reporter,
5598 enum devlink_command cmd)
5600 struct sk_buff *msg;
5603 WARN_ON(cmd != DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
5605 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5609 err = devlink_nl_health_reporter_fill(msg, reporter->devlink,
5610 reporter, cmd, 0, 0, 0);
5616 genlmsg_multicast_netns(&devlink_nl_family,
5617 devlink_net(reporter->devlink),
5618 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
5622 devlink_health_reporter_recovery_done(struct devlink_health_reporter *reporter)
5624 reporter->recovery_count++;
5625 reporter->last_recovery_ts = jiffies;
5627 EXPORT_SYMBOL_GPL(devlink_health_reporter_recovery_done);
5630 devlink_health_reporter_recover(struct devlink_health_reporter *reporter,
5631 void *priv_ctx, struct netlink_ext_ack *extack)
5635 if (reporter->health_state == DEVLINK_HEALTH_REPORTER_STATE_HEALTHY)
5638 if (!reporter->ops->recover)
5641 err = reporter->ops->recover(reporter, priv_ctx, extack);
5645 devlink_health_reporter_recovery_done(reporter);
5646 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY;
5647 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
5653 devlink_health_dump_clear(struct devlink_health_reporter *reporter)
5655 if (!reporter->dump_fmsg)
5657 devlink_fmsg_free(reporter->dump_fmsg);
5658 reporter->dump_fmsg = NULL;
5661 static int devlink_health_do_dump(struct devlink_health_reporter *reporter,
5663 struct netlink_ext_ack *extack)
5667 if (!reporter->ops->dump)
5670 if (reporter->dump_fmsg)
5673 reporter->dump_fmsg = devlink_fmsg_alloc();
5674 if (!reporter->dump_fmsg) {
5679 err = devlink_fmsg_obj_nest_start(reporter->dump_fmsg);
5683 err = reporter->ops->dump(reporter, reporter->dump_fmsg,
5688 err = devlink_fmsg_obj_nest_end(reporter->dump_fmsg);
5692 reporter->dump_ts = jiffies;
5693 reporter->dump_real_ts = ktime_get_real_ns();
5698 devlink_health_dump_clear(reporter);
5702 int devlink_health_report(struct devlink_health_reporter *reporter,
5703 const char *msg, void *priv_ctx)
5705 enum devlink_health_reporter_state prev_health_state;
5706 struct devlink *devlink = reporter->devlink;
5707 unsigned long recover_ts_threshold;
5709 /* write a log message of the current error */
5711 trace_devlink_health_report(devlink, reporter->ops->name, msg);
5712 reporter->error_count++;
5713 prev_health_state = reporter->health_state;
5714 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
5715 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
5717 /* abort if the previous error wasn't recovered */
5718 recover_ts_threshold = reporter->last_recovery_ts +
5719 msecs_to_jiffies(reporter->graceful_period);
5720 if (reporter->auto_recover &&
5721 (prev_health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY ||
5722 (reporter->last_recovery_ts && reporter->recovery_count &&
5723 time_is_after_jiffies(recover_ts_threshold)))) {
5724 trace_devlink_health_recover_aborted(devlink,
5725 reporter->ops->name,
5726 reporter->health_state,
5728 reporter->last_recovery_ts);
5732 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
5734 if (reporter->auto_dump) {
5735 mutex_lock(&reporter->dump_lock);
5736 /* store current dump of current error, for later analysis */
5737 devlink_health_do_dump(reporter, priv_ctx, NULL);
5738 mutex_unlock(&reporter->dump_lock);
5741 if (reporter->auto_recover)
5742 return devlink_health_reporter_recover(reporter,
5747 EXPORT_SYMBOL_GPL(devlink_health_report);
5749 static struct devlink_health_reporter *
5750 devlink_health_reporter_get_from_attrs(struct devlink *devlink,
5751 struct nlattr **attrs)
5753 struct devlink_health_reporter *reporter;
5754 struct devlink_port *devlink_port;
5755 char *reporter_name;
5757 if (!attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME])
5760 reporter_name = nla_data(attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]);
5761 devlink_port = devlink_port_get_from_attrs(devlink, attrs);
5762 if (IS_ERR(devlink_port)) {
5763 mutex_lock(&devlink->reporters_lock);
5764 reporter = devlink_health_reporter_find_by_name(devlink, reporter_name);
5766 refcount_inc(&reporter->refcount);
5767 mutex_unlock(&devlink->reporters_lock);
5769 mutex_lock(&devlink_port->reporters_lock);
5770 reporter = devlink_port_health_reporter_find_by_name(devlink_port, reporter_name);
5772 refcount_inc(&reporter->refcount);
5773 mutex_unlock(&devlink_port->reporters_lock);
5779 static struct devlink_health_reporter *
5780 devlink_health_reporter_get_from_info(struct devlink *devlink,
5781 struct genl_info *info)
5783 return devlink_health_reporter_get_from_attrs(devlink, info->attrs);
5786 static struct devlink_health_reporter *
5787 devlink_health_reporter_get_from_cb(struct netlink_callback *cb)
5789 const struct genl_dumpit_info *info = genl_dumpit_info(cb);
5790 struct devlink_health_reporter *reporter;
5791 struct nlattr **attrs = info->attrs;
5792 struct devlink *devlink;
5794 mutex_lock(&devlink_mutex);
5795 devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs);
5796 if (IS_ERR(devlink))
5799 reporter = devlink_health_reporter_get_from_attrs(devlink, attrs);
5800 mutex_unlock(&devlink_mutex);
5803 mutex_unlock(&devlink_mutex);
5808 devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
5809 enum devlink_health_reporter_state state)
5811 if (WARN_ON(state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY &&
5812 state != DEVLINK_HEALTH_REPORTER_STATE_ERROR))
5815 if (reporter->health_state == state)
5818 reporter->health_state = state;
5819 trace_devlink_health_reporter_state_update(reporter->devlink,
5820 reporter->ops->name, state);
5821 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
5823 EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update);
5825 static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb,
5826 struct genl_info *info)
5828 struct devlink *devlink = info->user_ptr[0];
5829 struct devlink_health_reporter *reporter;
5830 struct sk_buff *msg;
5833 reporter = devlink_health_reporter_get_from_info(devlink, info);
5837 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5843 err = devlink_nl_health_reporter_fill(msg, devlink, reporter,
5844 DEVLINK_CMD_HEALTH_REPORTER_GET,
5845 info->snd_portid, info->snd_seq,
5852 err = genlmsg_reply(msg, info);
5854 devlink_health_reporter_put(reporter);
5859 devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff *msg,
5860 struct netlink_callback *cb)
5862 struct devlink_health_reporter *reporter;
5863 struct devlink_port *port;
5864 struct devlink *devlink;
5865 int start = cb->args[0];
5869 mutex_lock(&devlink_mutex);
5870 list_for_each_entry(devlink, &devlink_list, list) {
5871 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
5873 mutex_lock(&devlink->reporters_lock);
5874 list_for_each_entry(reporter, &devlink->reporter_list,
5880 err = devlink_nl_health_reporter_fill(msg, devlink,
5882 DEVLINK_CMD_HEALTH_REPORTER_GET,
5883 NETLINK_CB(cb->skb).portid,
5887 mutex_unlock(&devlink->reporters_lock);
5892 mutex_unlock(&devlink->reporters_lock);
5895 list_for_each_entry(devlink, &devlink_list, list) {
5896 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
5898 list_for_each_entry(port, &devlink->port_list, list) {
5899 mutex_lock(&port->reporters_lock);
5900 list_for_each_entry(reporter, &port->reporter_list, list) {
5905 err = devlink_nl_health_reporter_fill(msg, devlink, reporter,
5906 DEVLINK_CMD_HEALTH_REPORTER_GET,
5907 NETLINK_CB(cb->skb).portid,
5911 mutex_unlock(&port->reporters_lock);
5916 mutex_unlock(&port->reporters_lock);
5920 mutex_unlock(&devlink_mutex);
5927 devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb,
5928 struct genl_info *info)
5930 struct devlink *devlink = info->user_ptr[0];
5931 struct devlink_health_reporter *reporter;
5934 reporter = devlink_health_reporter_get_from_info(devlink, info);
5938 if (!reporter->ops->recover &&
5939 (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] ||
5940 info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])) {
5944 if (!reporter->ops->dump &&
5945 info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]) {
5950 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD])
5951 reporter->graceful_period =
5952 nla_get_u64(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]);
5954 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])
5955 reporter->auto_recover =
5956 nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]);
5958 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP])
5959 reporter->auto_dump =
5960 nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]);
5962 devlink_health_reporter_put(reporter);
5965 devlink_health_reporter_put(reporter);
5969 static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb,
5970 struct genl_info *info)
5972 struct devlink *devlink = info->user_ptr[0];
5973 struct devlink_health_reporter *reporter;
5976 reporter = devlink_health_reporter_get_from_info(devlink, info);
5980 err = devlink_health_reporter_recover(reporter, NULL, info->extack);
5982 devlink_health_reporter_put(reporter);
5986 static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb,
5987 struct genl_info *info)
5989 struct devlink *devlink = info->user_ptr[0];
5990 struct devlink_health_reporter *reporter;
5991 struct devlink_fmsg *fmsg;
5994 reporter = devlink_health_reporter_get_from_info(devlink, info);
5998 if (!reporter->ops->diagnose) {
5999 devlink_health_reporter_put(reporter);
6003 fmsg = devlink_fmsg_alloc();
6005 devlink_health_reporter_put(reporter);
6009 err = devlink_fmsg_obj_nest_start(fmsg);
6013 err = reporter->ops->diagnose(reporter, fmsg, info->extack);
6017 err = devlink_fmsg_obj_nest_end(fmsg);
6021 err = devlink_fmsg_snd(fmsg, info,
6022 DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 0);
6025 devlink_fmsg_free(fmsg);
6026 devlink_health_reporter_put(reporter);
6031 devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff *skb,
6032 struct netlink_callback *cb)
6034 struct devlink_health_reporter *reporter;
6035 u64 start = cb->args[0];
6038 reporter = devlink_health_reporter_get_from_cb(cb);
6042 if (!reporter->ops->dump) {
6046 mutex_lock(&reporter->dump_lock);
6048 err = devlink_health_do_dump(reporter, NULL, cb->extack);
6051 cb->args[1] = reporter->dump_ts;
6053 if (!reporter->dump_fmsg || cb->args[1] != reporter->dump_ts) {
6054 NL_SET_ERR_MSG_MOD(cb->extack, "Dump trampled, please retry");
6059 err = devlink_fmsg_dumpit(reporter->dump_fmsg, skb, cb,
6060 DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET);
6062 mutex_unlock(&reporter->dump_lock);
6064 devlink_health_reporter_put(reporter);
6069 devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb,
6070 struct genl_info *info)
6072 struct devlink *devlink = info->user_ptr[0];
6073 struct devlink_health_reporter *reporter;
6075 reporter = devlink_health_reporter_get_from_info(devlink, info);
6079 if (!reporter->ops->dump) {
6080 devlink_health_reporter_put(reporter);
6084 mutex_lock(&reporter->dump_lock);
6085 devlink_health_dump_clear(reporter);
6086 mutex_unlock(&reporter->dump_lock);
6087 devlink_health_reporter_put(reporter);
6091 struct devlink_stats {
6094 struct u64_stats_sync syncp;
6098 * struct devlink_trap_policer_item - Packet trap policer attributes.
6099 * @policer: Immutable packet trap policer attributes.
6100 * @rate: Rate in packets / sec.
6101 * @burst: Burst size in packets.
6102 * @list: trap_policer_list member.
6104 * Describes packet trap policer attributes. Created by devlink during trap
6105 * policer registration.
6107 struct devlink_trap_policer_item {
6108 const struct devlink_trap_policer *policer;
6111 struct list_head list;
6115 * struct devlink_trap_group_item - Packet trap group attributes.
6116 * @group: Immutable packet trap group attributes.
6117 * @policer_item: Associated policer item. Can be NULL.
6118 * @list: trap_group_list member.
6119 * @stats: Trap group statistics.
6121 * Describes packet trap group attributes. Created by devlink during trap
6122 * group registration.
6124 struct devlink_trap_group_item {
6125 const struct devlink_trap_group *group;
6126 struct devlink_trap_policer_item *policer_item;
6127 struct list_head list;
6128 struct devlink_stats __percpu *stats;
6132 * struct devlink_trap_item - Packet trap attributes.
6133 * @trap: Immutable packet trap attributes.
6134 * @group_item: Associated group item.
6135 * @list: trap_list member.
6136 * @action: Trap action.
6137 * @stats: Trap statistics.
6138 * @priv: Driver private information.
6140 * Describes both mutable and immutable packet trap attributes. Created by
6141 * devlink during trap registration and used for all trap related operations.
6143 struct devlink_trap_item {
6144 const struct devlink_trap *trap;
6145 struct devlink_trap_group_item *group_item;
6146 struct list_head list;
6147 enum devlink_trap_action action;
6148 struct devlink_stats __percpu *stats;
6152 static struct devlink_trap_policer_item *
6153 devlink_trap_policer_item_lookup(struct devlink *devlink, u32 id)
6155 struct devlink_trap_policer_item *policer_item;
6157 list_for_each_entry(policer_item, &devlink->trap_policer_list, list) {
6158 if (policer_item->policer->id == id)
6159 return policer_item;
6165 static struct devlink_trap_item *
6166 devlink_trap_item_lookup(struct devlink *devlink, const char *name)
6168 struct devlink_trap_item *trap_item;
6170 list_for_each_entry(trap_item, &devlink->trap_list, list) {
6171 if (!strcmp(trap_item->trap->name, name))
6178 static struct devlink_trap_item *
6179 devlink_trap_item_get_from_info(struct devlink *devlink,
6180 struct genl_info *info)
6182 struct nlattr *attr;
6184 if (!info->attrs[DEVLINK_ATTR_TRAP_NAME])
6186 attr = info->attrs[DEVLINK_ATTR_TRAP_NAME];
6188 return devlink_trap_item_lookup(devlink, nla_data(attr));
6192 devlink_trap_action_get_from_info(struct genl_info *info,
6193 enum devlink_trap_action *p_trap_action)
6197 val = nla_get_u8(info->attrs[DEVLINK_ATTR_TRAP_ACTION]);
6199 case DEVLINK_TRAP_ACTION_DROP: /* fall-through */
6200 case DEVLINK_TRAP_ACTION_TRAP: /* fall-through */
6201 case DEVLINK_TRAP_ACTION_MIRROR:
6202 *p_trap_action = val;
6211 static int devlink_trap_metadata_put(struct sk_buff *msg,
6212 const struct devlink_trap *trap)
6214 struct nlattr *attr;
6216 attr = nla_nest_start(msg, DEVLINK_ATTR_TRAP_METADATA);
6220 if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT) &&
6221 nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT))
6222 goto nla_put_failure;
6223 if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE) &&
6224 nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE))
6225 goto nla_put_failure;
6227 nla_nest_end(msg, attr);
6232 nla_nest_cancel(msg, attr);
6236 static void devlink_trap_stats_read(struct devlink_stats __percpu *trap_stats,
6237 struct devlink_stats *stats)
6241 memset(stats, 0, sizeof(*stats));
6242 for_each_possible_cpu(i) {
6243 struct devlink_stats *cpu_stats;
6244 u64 rx_packets, rx_bytes;
6247 cpu_stats = per_cpu_ptr(trap_stats, i);
6249 start = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
6250 rx_packets = cpu_stats->rx_packets;
6251 rx_bytes = cpu_stats->rx_bytes;
6252 } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start));
6254 stats->rx_packets += rx_packets;
6255 stats->rx_bytes += rx_bytes;
6259 static int devlink_trap_stats_put(struct sk_buff *msg,
6260 struct devlink_stats __percpu *trap_stats)
6262 struct devlink_stats stats;
6263 struct nlattr *attr;
6265 devlink_trap_stats_read(trap_stats, &stats);
6267 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
6271 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS,
6272 stats.rx_packets, DEVLINK_ATTR_PAD))
6273 goto nla_put_failure;
6275 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES,
6276 stats.rx_bytes, DEVLINK_ATTR_PAD))
6277 goto nla_put_failure;
6279 nla_nest_end(msg, attr);
6284 nla_nest_cancel(msg, attr);
6288 static int devlink_nl_trap_fill(struct sk_buff *msg, struct devlink *devlink,
6289 const struct devlink_trap_item *trap_item,
6290 enum devlink_command cmd, u32 portid, u32 seq,
6293 struct devlink_trap_group_item *group_item = trap_item->group_item;
6297 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
6301 if (devlink_nl_put_handle(msg, devlink))
6302 goto nla_put_failure;
6304 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
6305 group_item->group->name))
6306 goto nla_put_failure;
6308 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_NAME, trap_item->trap->name))
6309 goto nla_put_failure;
6311 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_TYPE, trap_item->trap->type))
6312 goto nla_put_failure;
6314 if (trap_item->trap->generic &&
6315 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
6316 goto nla_put_failure;
6318 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_ACTION, trap_item->action))
6319 goto nla_put_failure;
6321 err = devlink_trap_metadata_put(msg, trap_item->trap);
6323 goto nla_put_failure;
6325 err = devlink_trap_stats_put(msg, trap_item->stats);
6327 goto nla_put_failure;
6329 genlmsg_end(msg, hdr);
6334 genlmsg_cancel(msg, hdr);
6338 static int devlink_nl_cmd_trap_get_doit(struct sk_buff *skb,
6339 struct genl_info *info)
6341 struct netlink_ext_ack *extack = info->extack;
6342 struct devlink *devlink = info->user_ptr[0];
6343 struct devlink_trap_item *trap_item;
6344 struct sk_buff *msg;
6347 if (list_empty(&devlink->trap_list))
6350 trap_item = devlink_trap_item_get_from_info(devlink, info);
6352 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
6356 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6360 err = devlink_nl_trap_fill(msg, devlink, trap_item,
6361 DEVLINK_CMD_TRAP_NEW, info->snd_portid,
6366 return genlmsg_reply(msg, info);
6373 static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff *msg,
6374 struct netlink_callback *cb)
6376 struct devlink_trap_item *trap_item;
6377 struct devlink *devlink;
6378 int start = cb->args[0];
6382 mutex_lock(&devlink_mutex);
6383 list_for_each_entry(devlink, &devlink_list, list) {
6384 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
6386 mutex_lock(&devlink->lock);
6387 list_for_each_entry(trap_item, &devlink->trap_list, list) {
6392 err = devlink_nl_trap_fill(msg, devlink, trap_item,
6393 DEVLINK_CMD_TRAP_NEW,
6394 NETLINK_CB(cb->skb).portid,
6398 mutex_unlock(&devlink->lock);
6403 mutex_unlock(&devlink->lock);
6406 mutex_unlock(&devlink_mutex);
6412 static int __devlink_trap_action_set(struct devlink *devlink,
6413 struct devlink_trap_item *trap_item,
6414 enum devlink_trap_action trap_action,
6415 struct netlink_ext_ack *extack)
6419 if (trap_item->action != trap_action &&
6420 trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) {
6421 NL_SET_ERR_MSG_MOD(extack, "Cannot change action of non-drop traps. Skipping");
6425 err = devlink->ops->trap_action_set(devlink, trap_item->trap,
6426 trap_action, extack);
6430 trap_item->action = trap_action;
6435 static int devlink_trap_action_set(struct devlink *devlink,
6436 struct devlink_trap_item *trap_item,
6437 struct genl_info *info)
6439 enum devlink_trap_action trap_action;
6442 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
6445 err = devlink_trap_action_get_from_info(info, &trap_action);
6447 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
6451 return __devlink_trap_action_set(devlink, trap_item, trap_action,
6455 static int devlink_nl_cmd_trap_set_doit(struct sk_buff *skb,
6456 struct genl_info *info)
6458 struct netlink_ext_ack *extack = info->extack;
6459 struct devlink *devlink = info->user_ptr[0];
6460 struct devlink_trap_item *trap_item;
6463 if (list_empty(&devlink->trap_list))
6466 trap_item = devlink_trap_item_get_from_info(devlink, info);
6468 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
6472 err = devlink_trap_action_set(devlink, trap_item, info);
6479 static struct devlink_trap_group_item *
6480 devlink_trap_group_item_lookup(struct devlink *devlink, const char *name)
6482 struct devlink_trap_group_item *group_item;
6484 list_for_each_entry(group_item, &devlink->trap_group_list, list) {
6485 if (!strcmp(group_item->group->name, name))
6492 static struct devlink_trap_group_item *
6493 devlink_trap_group_item_lookup_by_id(struct devlink *devlink, u16 id)
6495 struct devlink_trap_group_item *group_item;
6497 list_for_each_entry(group_item, &devlink->trap_group_list, list) {
6498 if (group_item->group->id == id)
6505 static struct devlink_trap_group_item *
6506 devlink_trap_group_item_get_from_info(struct devlink *devlink,
6507 struct genl_info *info)
6511 if (!info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME])
6513 name = nla_data(info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]);
6515 return devlink_trap_group_item_lookup(devlink, name);
6519 devlink_nl_trap_group_fill(struct sk_buff *msg, struct devlink *devlink,
6520 const struct devlink_trap_group_item *group_item,
6521 enum devlink_command cmd, u32 portid, u32 seq,
6527 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
6531 if (devlink_nl_put_handle(msg, devlink))
6532 goto nla_put_failure;
6534 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
6535 group_item->group->name))
6536 goto nla_put_failure;
6538 if (group_item->group->generic &&
6539 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
6540 goto nla_put_failure;
6542 if (group_item->policer_item &&
6543 nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
6544 group_item->policer_item->policer->id))
6545 goto nla_put_failure;
6547 err = devlink_trap_stats_put(msg, group_item->stats);
6549 goto nla_put_failure;
6551 genlmsg_end(msg, hdr);
6556 genlmsg_cancel(msg, hdr);
6560 static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff *skb,
6561 struct genl_info *info)
6563 struct netlink_ext_ack *extack = info->extack;
6564 struct devlink *devlink = info->user_ptr[0];
6565 struct devlink_trap_group_item *group_item;
6566 struct sk_buff *msg;
6569 if (list_empty(&devlink->trap_group_list))
6572 group_item = devlink_trap_group_item_get_from_info(devlink, info);
6574 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
6578 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6582 err = devlink_nl_trap_group_fill(msg, devlink, group_item,
6583 DEVLINK_CMD_TRAP_GROUP_NEW,
6584 info->snd_portid, info->snd_seq, 0);
6586 goto err_trap_group_fill;
6588 return genlmsg_reply(msg, info);
6590 err_trap_group_fill:
6595 static int devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff *msg,
6596 struct netlink_callback *cb)
6598 enum devlink_command cmd = DEVLINK_CMD_TRAP_GROUP_NEW;
6599 struct devlink_trap_group_item *group_item;
6600 u32 portid = NETLINK_CB(cb->skb).portid;
6601 struct devlink *devlink;
6602 int start = cb->args[0];
6606 mutex_lock(&devlink_mutex);
6607 list_for_each_entry(devlink, &devlink_list, list) {
6608 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
6610 mutex_lock(&devlink->lock);
6611 list_for_each_entry(group_item, &devlink->trap_group_list,
6617 err = devlink_nl_trap_group_fill(msg, devlink,
6623 mutex_unlock(&devlink->lock);
6628 mutex_unlock(&devlink->lock);
6631 mutex_unlock(&devlink_mutex);
6638 __devlink_trap_group_action_set(struct devlink *devlink,
6639 struct devlink_trap_group_item *group_item,
6640 enum devlink_trap_action trap_action,
6641 struct netlink_ext_ack *extack)
6643 const char *group_name = group_item->group->name;
6644 struct devlink_trap_item *trap_item;
6647 list_for_each_entry(trap_item, &devlink->trap_list, list) {
6648 if (strcmp(trap_item->group_item->group->name, group_name))
6650 err = __devlink_trap_action_set(devlink, trap_item,
6651 trap_action, extack);
6660 devlink_trap_group_action_set(struct devlink *devlink,
6661 struct devlink_trap_group_item *group_item,
6662 struct genl_info *info, bool *p_modified)
6664 enum devlink_trap_action trap_action;
6667 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
6670 err = devlink_trap_action_get_from_info(info, &trap_action);
6672 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
6676 err = __devlink_trap_group_action_set(devlink, group_item, trap_action,
6686 static int devlink_trap_group_set(struct devlink *devlink,
6687 struct devlink_trap_group_item *group_item,
6688 struct genl_info *info)
6690 struct devlink_trap_policer_item *policer_item;
6691 struct netlink_ext_ack *extack = info->extack;
6692 const struct devlink_trap_policer *policer;
6693 struct nlattr **attrs = info->attrs;
6696 if (!attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
6699 if (!devlink->ops->trap_group_set)
6702 policer_item = group_item->policer_item;
6703 if (attrs[DEVLINK_ATTR_TRAP_POLICER_ID]) {
6706 policer_id = nla_get_u32(attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
6707 policer_item = devlink_trap_policer_item_lookup(devlink,
6709 if (policer_id && !policer_item) {
6710 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
6714 policer = policer_item ? policer_item->policer : NULL;
6716 err = devlink->ops->trap_group_set(devlink, group_item->group, policer,
6721 group_item->policer_item = policer_item;
6726 static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff *skb,
6727 struct genl_info *info)
6729 struct netlink_ext_ack *extack = info->extack;
6730 struct devlink *devlink = info->user_ptr[0];
6731 struct devlink_trap_group_item *group_item;
6732 bool modified = false;
6735 if (list_empty(&devlink->trap_group_list))
6738 group_item = devlink_trap_group_item_get_from_info(devlink, info);
6740 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
6744 err = devlink_trap_group_action_set(devlink, group_item, info,
6749 err = devlink_trap_group_set(devlink, group_item, info);
6751 goto err_trap_group_set;
6757 NL_SET_ERR_MSG_MOD(extack, "Trap group set failed, but some changes were committed already");
6761 static struct devlink_trap_policer_item *
6762 devlink_trap_policer_item_get_from_info(struct devlink *devlink,
6763 struct genl_info *info)
6767 if (!info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
6769 id = nla_get_u32(info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
6771 return devlink_trap_policer_item_lookup(devlink, id);
6775 devlink_trap_policer_stats_put(struct sk_buff *msg, struct devlink *devlink,
6776 const struct devlink_trap_policer *policer)
6778 struct nlattr *attr;
6782 if (!devlink->ops->trap_policer_counter_get)
6785 err = devlink->ops->trap_policer_counter_get(devlink, policer, &drops);
6789 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
6793 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops,
6795 goto nla_put_failure;
6797 nla_nest_end(msg, attr);
6802 nla_nest_cancel(msg, attr);
6807 devlink_nl_trap_policer_fill(struct sk_buff *msg, struct devlink *devlink,
6808 const struct devlink_trap_policer_item *policer_item,
6809 enum devlink_command cmd, u32 portid, u32 seq,
6815 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
6819 if (devlink_nl_put_handle(msg, devlink))
6820 goto nla_put_failure;
6822 if (nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
6823 policer_item->policer->id))
6824 goto nla_put_failure;
6826 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_RATE,
6827 policer_item->rate, DEVLINK_ATTR_PAD))
6828 goto nla_put_failure;
6830 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_BURST,
6831 policer_item->burst, DEVLINK_ATTR_PAD))
6832 goto nla_put_failure;
6834 err = devlink_trap_policer_stats_put(msg, devlink,
6835 policer_item->policer);
6837 goto nla_put_failure;
6839 genlmsg_end(msg, hdr);
6844 genlmsg_cancel(msg, hdr);
6848 static int devlink_nl_cmd_trap_policer_get_doit(struct sk_buff *skb,
6849 struct genl_info *info)
6851 struct devlink_trap_policer_item *policer_item;
6852 struct netlink_ext_ack *extack = info->extack;
6853 struct devlink *devlink = info->user_ptr[0];
6854 struct sk_buff *msg;
6857 if (list_empty(&devlink->trap_policer_list))
6860 policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
6861 if (!policer_item) {
6862 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
6866 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6870 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item,
6871 DEVLINK_CMD_TRAP_POLICER_NEW,
6872 info->snd_portid, info->snd_seq, 0);
6874 goto err_trap_policer_fill;
6876 return genlmsg_reply(msg, info);
6878 err_trap_policer_fill:
6883 static int devlink_nl_cmd_trap_policer_get_dumpit(struct sk_buff *msg,
6884 struct netlink_callback *cb)
6886 enum devlink_command cmd = DEVLINK_CMD_TRAP_POLICER_NEW;
6887 struct devlink_trap_policer_item *policer_item;
6888 u32 portid = NETLINK_CB(cb->skb).portid;
6889 struct devlink *devlink;
6890 int start = cb->args[0];
6894 mutex_lock(&devlink_mutex);
6895 list_for_each_entry(devlink, &devlink_list, list) {
6896 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
6898 mutex_lock(&devlink->lock);
6899 list_for_each_entry(policer_item, &devlink->trap_policer_list,
6905 err = devlink_nl_trap_policer_fill(msg, devlink,
6911 mutex_unlock(&devlink->lock);
6916 mutex_unlock(&devlink->lock);
6919 mutex_unlock(&devlink_mutex);
6926 devlink_trap_policer_set(struct devlink *devlink,
6927 struct devlink_trap_policer_item *policer_item,
6928 struct genl_info *info)
6930 struct netlink_ext_ack *extack = info->extack;
6931 struct nlattr **attrs = info->attrs;
6935 rate = policer_item->rate;
6936 burst = policer_item->burst;
6938 if (attrs[DEVLINK_ATTR_TRAP_POLICER_RATE])
6939 rate = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_RATE]);
6941 if (attrs[DEVLINK_ATTR_TRAP_POLICER_BURST])
6942 burst = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_BURST]);
6944 if (rate < policer_item->policer->min_rate) {
6945 NL_SET_ERR_MSG_MOD(extack, "Policer rate lower than limit");
6949 if (rate > policer_item->policer->max_rate) {
6950 NL_SET_ERR_MSG_MOD(extack, "Policer rate higher than limit");
6954 if (burst < policer_item->policer->min_burst) {
6955 NL_SET_ERR_MSG_MOD(extack, "Policer burst size lower than limit");
6959 if (burst > policer_item->policer->max_burst) {
6960 NL_SET_ERR_MSG_MOD(extack, "Policer burst size higher than limit");
6964 err = devlink->ops->trap_policer_set(devlink, policer_item->policer,
6965 rate, burst, info->extack);
6969 policer_item->rate = rate;
6970 policer_item->burst = burst;
6975 static int devlink_nl_cmd_trap_policer_set_doit(struct sk_buff *skb,
6976 struct genl_info *info)
6978 struct devlink_trap_policer_item *policer_item;
6979 struct netlink_ext_ack *extack = info->extack;
6980 struct devlink *devlink = info->user_ptr[0];
6982 if (list_empty(&devlink->trap_policer_list))
6985 if (!devlink->ops->trap_policer_set)
6988 policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
6989 if (!policer_item) {
6990 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
6994 return devlink_trap_policer_set(devlink, policer_item, info);
6997 static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
6998 [DEVLINK_ATTR_UNSPEC] = { .strict_start_type =
6999 DEVLINK_ATTR_TRAP_POLICER_ID },
7000 [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
7001 [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
7002 [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 },
7003 [DEVLINK_ATTR_PORT_TYPE] = { .type = NLA_U16 },
7004 [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 },
7005 [DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 },
7006 [DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 },
7007 [DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 },
7008 [DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 },
7009 [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 },
7010 [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
7011 [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
7012 [DEVLINK_ATTR_ESWITCH_MODE] = { .type = NLA_U16 },
7013 [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 },
7014 [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 },
7015 [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING },
7016 [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 },
7017 [DEVLINK_ATTR_RESOURCE_ID] = { .type = NLA_U64},
7018 [DEVLINK_ATTR_RESOURCE_SIZE] = { .type = NLA_U64},
7019 [DEVLINK_ATTR_PARAM_NAME] = { .type = NLA_NUL_STRING },
7020 [DEVLINK_ATTR_PARAM_TYPE] = { .type = NLA_U8 },
7021 [DEVLINK_ATTR_PARAM_VALUE_CMODE] = { .type = NLA_U8 },
7022 [DEVLINK_ATTR_REGION_NAME] = { .type = NLA_NUL_STRING },
7023 [DEVLINK_ATTR_REGION_SNAPSHOT_ID] = { .type = NLA_U32 },
7024 [DEVLINK_ATTR_REGION_CHUNK_ADDR] = { .type = NLA_U64 },
7025 [DEVLINK_ATTR_REGION_CHUNK_LEN] = { .type = NLA_U64 },
7026 [DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING },
7027 [DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] = { .type = NLA_U64 },
7028 [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER] = { .type = NLA_U8 },
7029 [DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME] = { .type = NLA_NUL_STRING },
7030 [DEVLINK_ATTR_FLASH_UPDATE_COMPONENT] = { .type = NLA_NUL_STRING },
7031 [DEVLINK_ATTR_TRAP_NAME] = { .type = NLA_NUL_STRING },
7032 [DEVLINK_ATTR_TRAP_ACTION] = { .type = NLA_U8 },
7033 [DEVLINK_ATTR_TRAP_GROUP_NAME] = { .type = NLA_NUL_STRING },
7034 [DEVLINK_ATTR_NETNS_PID] = { .type = NLA_U32 },
7035 [DEVLINK_ATTR_NETNS_FD] = { .type = NLA_U32 },
7036 [DEVLINK_ATTR_NETNS_ID] = { .type = NLA_U32 },
7037 [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP] = { .type = NLA_U8 },
7038 [DEVLINK_ATTR_TRAP_POLICER_ID] = { .type = NLA_U32 },
7039 [DEVLINK_ATTR_TRAP_POLICER_RATE] = { .type = NLA_U64 },
7040 [DEVLINK_ATTR_TRAP_POLICER_BURST] = { .type = NLA_U64 },
7041 [DEVLINK_ATTR_PORT_FUNCTION] = { .type = NLA_NESTED },
7044 static const struct genl_ops devlink_nl_ops[] = {
7046 .cmd = DEVLINK_CMD_GET,
7047 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7048 .doit = devlink_nl_cmd_get_doit,
7049 .dumpit = devlink_nl_cmd_get_dumpit,
7050 /* can be retrieved by unprivileged users */
7053 .cmd = DEVLINK_CMD_PORT_GET,
7054 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7055 .doit = devlink_nl_cmd_port_get_doit,
7056 .dumpit = devlink_nl_cmd_port_get_dumpit,
7057 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7058 /* can be retrieved by unprivileged users */
7061 .cmd = DEVLINK_CMD_PORT_SET,
7062 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7063 .doit = devlink_nl_cmd_port_set_doit,
7064 .flags = GENL_ADMIN_PERM,
7065 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7068 .cmd = DEVLINK_CMD_PORT_SPLIT,
7069 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7070 .doit = devlink_nl_cmd_port_split_doit,
7071 .flags = GENL_ADMIN_PERM,
7072 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK,
7075 .cmd = DEVLINK_CMD_PORT_UNSPLIT,
7076 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7077 .doit = devlink_nl_cmd_port_unsplit_doit,
7078 .flags = GENL_ADMIN_PERM,
7079 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK,
7082 .cmd = DEVLINK_CMD_SB_GET,
7083 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7084 .doit = devlink_nl_cmd_sb_get_doit,
7085 .dumpit = devlink_nl_cmd_sb_get_dumpit,
7086 /* can be retrieved by unprivileged users */
7089 .cmd = DEVLINK_CMD_SB_POOL_GET,
7090 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7091 .doit = devlink_nl_cmd_sb_pool_get_doit,
7092 .dumpit = devlink_nl_cmd_sb_pool_get_dumpit,
7093 /* can be retrieved by unprivileged users */
7096 .cmd = DEVLINK_CMD_SB_POOL_SET,
7097 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7098 .doit = devlink_nl_cmd_sb_pool_set_doit,
7099 .flags = GENL_ADMIN_PERM,
7102 .cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
7103 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7104 .doit = devlink_nl_cmd_sb_port_pool_get_doit,
7105 .dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit,
7106 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7107 /* can be retrieved by unprivileged users */
7110 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
7111 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7112 .doit = devlink_nl_cmd_sb_port_pool_set_doit,
7113 .flags = GENL_ADMIN_PERM,
7114 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7117 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
7118 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7119 .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
7120 .dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit,
7121 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7122 /* can be retrieved by unprivileged users */
7125 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
7126 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7127 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
7128 .flags = GENL_ADMIN_PERM,
7129 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7132 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
7133 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7134 .doit = devlink_nl_cmd_sb_occ_snapshot_doit,
7135 .flags = GENL_ADMIN_PERM,
7138 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
7139 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7140 .doit = devlink_nl_cmd_sb_occ_max_clear_doit,
7141 .flags = GENL_ADMIN_PERM,
7144 .cmd = DEVLINK_CMD_ESWITCH_GET,
7145 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7146 .doit = devlink_nl_cmd_eswitch_get_doit,
7147 .flags = GENL_ADMIN_PERM,
7148 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK,
7151 .cmd = DEVLINK_CMD_ESWITCH_SET,
7152 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7153 .doit = devlink_nl_cmd_eswitch_set_doit,
7154 .flags = GENL_ADMIN_PERM,
7155 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK,
7158 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET,
7159 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7160 .doit = devlink_nl_cmd_dpipe_table_get,
7161 /* can be retrieved by unprivileged users */
7164 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET,
7165 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7166 .doit = devlink_nl_cmd_dpipe_entries_get,
7167 /* can be retrieved by unprivileged users */
7170 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET,
7171 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7172 .doit = devlink_nl_cmd_dpipe_headers_get,
7173 /* can be retrieved by unprivileged users */
7176 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
7177 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7178 .doit = devlink_nl_cmd_dpipe_table_counters_set,
7179 .flags = GENL_ADMIN_PERM,
7182 .cmd = DEVLINK_CMD_RESOURCE_SET,
7183 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7184 .doit = devlink_nl_cmd_resource_set,
7185 .flags = GENL_ADMIN_PERM,
7188 .cmd = DEVLINK_CMD_RESOURCE_DUMP,
7189 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7190 .doit = devlink_nl_cmd_resource_dump,
7191 /* can be retrieved by unprivileged users */
7194 .cmd = DEVLINK_CMD_RELOAD,
7195 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7196 .doit = devlink_nl_cmd_reload,
7197 .flags = GENL_ADMIN_PERM,
7198 .internal_flags = DEVLINK_NL_FLAG_NO_LOCK,
7201 .cmd = DEVLINK_CMD_PARAM_GET,
7202 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7203 .doit = devlink_nl_cmd_param_get_doit,
7204 .dumpit = devlink_nl_cmd_param_get_dumpit,
7205 /* can be retrieved by unprivileged users */
7208 .cmd = DEVLINK_CMD_PARAM_SET,
7209 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7210 .doit = devlink_nl_cmd_param_set_doit,
7211 .flags = GENL_ADMIN_PERM,
7214 .cmd = DEVLINK_CMD_PORT_PARAM_GET,
7215 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7216 .doit = devlink_nl_cmd_port_param_get_doit,
7217 .dumpit = devlink_nl_cmd_port_param_get_dumpit,
7218 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7219 /* can be retrieved by unprivileged users */
7222 .cmd = DEVLINK_CMD_PORT_PARAM_SET,
7223 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7224 .doit = devlink_nl_cmd_port_param_set_doit,
7225 .flags = GENL_ADMIN_PERM,
7226 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7229 .cmd = DEVLINK_CMD_REGION_GET,
7230 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7231 .doit = devlink_nl_cmd_region_get_doit,
7232 .dumpit = devlink_nl_cmd_region_get_dumpit,
7233 .flags = GENL_ADMIN_PERM,
7236 .cmd = DEVLINK_CMD_REGION_NEW,
7237 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7238 .doit = devlink_nl_cmd_region_new,
7239 .flags = GENL_ADMIN_PERM,
7242 .cmd = DEVLINK_CMD_REGION_DEL,
7243 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7244 .doit = devlink_nl_cmd_region_del,
7245 .flags = GENL_ADMIN_PERM,
7248 .cmd = DEVLINK_CMD_REGION_READ,
7249 .validate = GENL_DONT_VALIDATE_STRICT |
7250 GENL_DONT_VALIDATE_DUMP_STRICT,
7251 .dumpit = devlink_nl_cmd_region_read_dumpit,
7252 .flags = GENL_ADMIN_PERM,
7255 .cmd = DEVLINK_CMD_INFO_GET,
7256 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7257 .doit = devlink_nl_cmd_info_get_doit,
7258 .dumpit = devlink_nl_cmd_info_get_dumpit,
7259 /* can be retrieved by unprivileged users */
7262 .cmd = DEVLINK_CMD_HEALTH_REPORTER_GET,
7263 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7264 .doit = devlink_nl_cmd_health_reporter_get_doit,
7265 .dumpit = devlink_nl_cmd_health_reporter_get_dumpit,
7266 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT |
7267 DEVLINK_NL_FLAG_NO_LOCK,
7268 /* can be retrieved by unprivileged users */
7271 .cmd = DEVLINK_CMD_HEALTH_REPORTER_SET,
7272 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7273 .doit = devlink_nl_cmd_health_reporter_set_doit,
7274 .flags = GENL_ADMIN_PERM,
7275 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT |
7276 DEVLINK_NL_FLAG_NO_LOCK,
7279 .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER,
7280 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7281 .doit = devlink_nl_cmd_health_reporter_recover_doit,
7282 .flags = GENL_ADMIN_PERM,
7283 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT |
7284 DEVLINK_NL_FLAG_NO_LOCK,
7287 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE,
7288 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7289 .doit = devlink_nl_cmd_health_reporter_diagnose_doit,
7290 .flags = GENL_ADMIN_PERM,
7291 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT |
7292 DEVLINK_NL_FLAG_NO_LOCK,
7295 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET,
7296 .validate = GENL_DONT_VALIDATE_STRICT |
7297 GENL_DONT_VALIDATE_DUMP_STRICT,
7298 .dumpit = devlink_nl_cmd_health_reporter_dump_get_dumpit,
7299 .flags = GENL_ADMIN_PERM,
7300 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT |
7301 DEVLINK_NL_FLAG_NO_LOCK,
7304 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR,
7305 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7306 .doit = devlink_nl_cmd_health_reporter_dump_clear_doit,
7307 .flags = GENL_ADMIN_PERM,
7308 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT |
7309 DEVLINK_NL_FLAG_NO_LOCK,
7312 .cmd = DEVLINK_CMD_FLASH_UPDATE,
7313 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7314 .doit = devlink_nl_cmd_flash_update,
7315 .flags = GENL_ADMIN_PERM,
7318 .cmd = DEVLINK_CMD_TRAP_GET,
7319 .doit = devlink_nl_cmd_trap_get_doit,
7320 .dumpit = devlink_nl_cmd_trap_get_dumpit,
7321 /* can be retrieved by unprivileged users */
7324 .cmd = DEVLINK_CMD_TRAP_SET,
7325 .doit = devlink_nl_cmd_trap_set_doit,
7326 .flags = GENL_ADMIN_PERM,
7329 .cmd = DEVLINK_CMD_TRAP_GROUP_GET,
7330 .doit = devlink_nl_cmd_trap_group_get_doit,
7331 .dumpit = devlink_nl_cmd_trap_group_get_dumpit,
7332 /* can be retrieved by unprivileged users */
7335 .cmd = DEVLINK_CMD_TRAP_GROUP_SET,
7336 .doit = devlink_nl_cmd_trap_group_set_doit,
7337 .flags = GENL_ADMIN_PERM,
7340 .cmd = DEVLINK_CMD_TRAP_POLICER_GET,
7341 .doit = devlink_nl_cmd_trap_policer_get_doit,
7342 .dumpit = devlink_nl_cmd_trap_policer_get_dumpit,
7343 /* can be retrieved by unprivileged users */
7346 .cmd = DEVLINK_CMD_TRAP_POLICER_SET,
7347 .doit = devlink_nl_cmd_trap_policer_set_doit,
7348 .flags = GENL_ADMIN_PERM,
7352 static struct genl_family devlink_nl_family __ro_after_init = {
7353 .name = DEVLINK_GENL_NAME,
7354 .version = DEVLINK_GENL_VERSION,
7355 .maxattr = DEVLINK_ATTR_MAX,
7356 .policy = devlink_nl_policy,
7358 .pre_doit = devlink_nl_pre_doit,
7359 .post_doit = devlink_nl_post_doit,
7360 .module = THIS_MODULE,
7361 .ops = devlink_nl_ops,
7362 .n_ops = ARRAY_SIZE(devlink_nl_ops),
7363 .mcgrps = devlink_nl_mcgrps,
7364 .n_mcgrps = ARRAY_SIZE(devlink_nl_mcgrps),
7368 * devlink_alloc - Allocate new devlink instance resources
7371 * @priv_size: size of user private data
7373 * Allocate new devlink instance resources, including devlink index
7376 struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
7378 struct devlink *devlink;
7383 devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
7387 xa_init_flags(&devlink->snapshot_ids, XA_FLAGS_ALLOC);
7388 __devlink_net_set(devlink, &init_net);
7389 INIT_LIST_HEAD(&devlink->port_list);
7390 INIT_LIST_HEAD(&devlink->sb_list);
7391 INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list);
7392 INIT_LIST_HEAD(&devlink->resource_list);
7393 INIT_LIST_HEAD(&devlink->param_list);
7394 INIT_LIST_HEAD(&devlink->region_list);
7395 INIT_LIST_HEAD(&devlink->reporter_list);
7396 INIT_LIST_HEAD(&devlink->trap_list);
7397 INIT_LIST_HEAD(&devlink->trap_group_list);
7398 INIT_LIST_HEAD(&devlink->trap_policer_list);
7399 mutex_init(&devlink->lock);
7400 mutex_init(&devlink->reporters_lock);
7403 EXPORT_SYMBOL_GPL(devlink_alloc);
7406 * devlink_register - Register devlink instance
7409 * @dev: parent device
7411 int devlink_register(struct devlink *devlink, struct device *dev)
7414 devlink->registered = true;
7415 mutex_lock(&devlink_mutex);
7416 list_add_tail(&devlink->list, &devlink_list);
7417 devlink_notify(devlink, DEVLINK_CMD_NEW);
7418 mutex_unlock(&devlink_mutex);
7421 EXPORT_SYMBOL_GPL(devlink_register);
7424 * devlink_unregister - Unregister devlink instance
7428 void devlink_unregister(struct devlink *devlink)
7430 mutex_lock(&devlink_mutex);
7431 WARN_ON(devlink_reload_supported(devlink) &&
7432 devlink->reload_enabled);
7433 devlink_notify(devlink, DEVLINK_CMD_DEL);
7434 list_del(&devlink->list);
7435 mutex_unlock(&devlink_mutex);
7437 EXPORT_SYMBOL_GPL(devlink_unregister);
7440 * devlink_reload_enable - Enable reload of devlink instance
7444 * Should be called at end of device initialization
7445 * process when reload operation is supported.
7447 void devlink_reload_enable(struct devlink *devlink)
7449 mutex_lock(&devlink_mutex);
7450 devlink->reload_enabled = true;
7451 mutex_unlock(&devlink_mutex);
7453 EXPORT_SYMBOL_GPL(devlink_reload_enable);
7456 * devlink_reload_disable - Disable reload of devlink instance
7460 * Should be called at the beginning of device cleanup
7461 * process when reload operation is supported.
7463 void devlink_reload_disable(struct devlink *devlink)
7465 mutex_lock(&devlink_mutex);
7466 /* Mutex is taken which ensures that no reload operation is in
7467 * progress while setting up forbidded flag.
7469 devlink->reload_enabled = false;
7470 mutex_unlock(&devlink_mutex);
7472 EXPORT_SYMBOL_GPL(devlink_reload_disable);
7475 * devlink_free - Free devlink instance resources
7479 void devlink_free(struct devlink *devlink)
7481 mutex_destroy(&devlink->reporters_lock);
7482 mutex_destroy(&devlink->lock);
7483 WARN_ON(!list_empty(&devlink->trap_policer_list));
7484 WARN_ON(!list_empty(&devlink->trap_group_list));
7485 WARN_ON(!list_empty(&devlink->trap_list));
7486 WARN_ON(!list_empty(&devlink->reporter_list));
7487 WARN_ON(!list_empty(&devlink->region_list));
7488 WARN_ON(!list_empty(&devlink->param_list));
7489 WARN_ON(!list_empty(&devlink->resource_list));
7490 WARN_ON(!list_empty(&devlink->dpipe_table_list));
7491 WARN_ON(!list_empty(&devlink->sb_list));
7492 WARN_ON(!list_empty(&devlink->port_list));
7494 xa_destroy(&devlink->snapshot_ids);
7498 EXPORT_SYMBOL_GPL(devlink_free);
7500 static void devlink_port_type_warn(struct work_struct *work)
7502 WARN(true, "Type was not set for devlink port.");
7505 static bool devlink_port_type_should_warn(struct devlink_port *devlink_port)
7507 /* Ignore CPU and DSA flavours. */
7508 return devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_CPU &&
7509 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_DSA;
7512 #define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 3600)
7514 static void devlink_port_type_warn_schedule(struct devlink_port *devlink_port)
7516 if (!devlink_port_type_should_warn(devlink_port))
7518 /* Schedule a work to WARN in case driver does not set port
7519 * type within timeout.
7521 schedule_delayed_work(&devlink_port->type_warn_dw,
7522 DEVLINK_PORT_TYPE_WARN_TIMEOUT);
7525 static void devlink_port_type_warn_cancel(struct devlink_port *devlink_port)
7527 if (!devlink_port_type_should_warn(devlink_port))
7529 cancel_delayed_work_sync(&devlink_port->type_warn_dw);
7533 * devlink_port_register - Register devlink port
7536 * @devlink_port: devlink port
7537 * @port_index: driver-specific numerical identifier of the port
7539 * Register devlink port with provided port index. User can use
7540 * any indexing, even hw-related one. devlink_port structure
7541 * is convenient to be embedded inside user driver private structure.
7542 * Note that the caller should take care of zeroing the devlink_port
7545 int devlink_port_register(struct devlink *devlink,
7546 struct devlink_port *devlink_port,
7547 unsigned int port_index)
7549 mutex_lock(&devlink->lock);
7550 if (devlink_port_index_exists(devlink, port_index)) {
7551 mutex_unlock(&devlink->lock);
7554 devlink_port->devlink = devlink;
7555 devlink_port->index = port_index;
7556 devlink_port->registered = true;
7557 spin_lock_init(&devlink_port->type_lock);
7558 list_add_tail(&devlink_port->list, &devlink->port_list);
7559 INIT_LIST_HEAD(&devlink_port->param_list);
7560 mutex_unlock(&devlink->lock);
7561 INIT_LIST_HEAD(&devlink_port->reporter_list);
7562 mutex_init(&devlink_port->reporters_lock);
7563 INIT_DELAYED_WORK(&devlink_port->type_warn_dw, &devlink_port_type_warn);
7564 devlink_port_type_warn_schedule(devlink_port);
7565 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
7568 EXPORT_SYMBOL_GPL(devlink_port_register);
7571 * devlink_port_unregister - Unregister devlink port
7573 * @devlink_port: devlink port
7575 void devlink_port_unregister(struct devlink_port *devlink_port)
7577 struct devlink *devlink = devlink_port->devlink;
7579 WARN_ON(!list_empty(&devlink_port->reporter_list));
7580 mutex_destroy(&devlink_port->reporters_lock);
7581 devlink_port_type_warn_cancel(devlink_port);
7582 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
7583 mutex_lock(&devlink->lock);
7584 list_del(&devlink_port->list);
7585 mutex_unlock(&devlink->lock);
7587 EXPORT_SYMBOL_GPL(devlink_port_unregister);
7589 static void __devlink_port_type_set(struct devlink_port *devlink_port,
7590 enum devlink_port_type type,
7593 if (WARN_ON(!devlink_port->registered))
7595 devlink_port_type_warn_cancel(devlink_port);
7596 spin_lock_bh(&devlink_port->type_lock);
7597 devlink_port->type = type;
7598 devlink_port->type_dev = type_dev;
7599 spin_unlock_bh(&devlink_port->type_lock);
7600 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
7604 * devlink_port_type_eth_set - Set port type to Ethernet
7606 * @devlink_port: devlink port
7607 * @netdev: related netdevice
7609 void devlink_port_type_eth_set(struct devlink_port *devlink_port,
7610 struct net_device *netdev)
7612 const struct net_device_ops *ops = netdev->netdev_ops;
7614 /* If driver registers devlink port, it should set devlink port
7615 * attributes accordingly so the compat functions are called
7616 * and the original ops are not used.
7618 if (ops->ndo_get_phys_port_name) {
7619 /* Some drivers use the same set of ndos for netdevs
7620 * that have devlink_port registered and also for
7621 * those who don't. Make sure that ndo_get_phys_port_name
7622 * returns -EOPNOTSUPP here in case it is defined.
7625 char name[IFNAMSIZ];
7628 err = ops->ndo_get_phys_port_name(netdev, name, sizeof(name));
7629 WARN_ON(err != -EOPNOTSUPP);
7631 if (ops->ndo_get_port_parent_id) {
7632 /* Some drivers use the same set of ndos for netdevs
7633 * that have devlink_port registered and also for
7634 * those who don't. Make sure that ndo_get_port_parent_id
7635 * returns -EOPNOTSUPP here in case it is defined.
7638 struct netdev_phys_item_id ppid;
7641 err = ops->ndo_get_port_parent_id(netdev, &ppid);
7642 WARN_ON(err != -EOPNOTSUPP);
7644 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, netdev);
7646 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
7649 * devlink_port_type_ib_set - Set port type to InfiniBand
7651 * @devlink_port: devlink port
7652 * @ibdev: related IB device
7654 void devlink_port_type_ib_set(struct devlink_port *devlink_port,
7655 struct ib_device *ibdev)
7657 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_IB, ibdev);
7659 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
7662 * devlink_port_type_clear - Clear port type
7664 * @devlink_port: devlink port
7666 void devlink_port_type_clear(struct devlink_port *devlink_port)
7668 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, NULL);
7669 devlink_port_type_warn_schedule(devlink_port);
7671 EXPORT_SYMBOL_GPL(devlink_port_type_clear);
7673 static int __devlink_port_attrs_set(struct devlink_port *devlink_port,
7674 enum devlink_port_flavour flavour)
7676 struct devlink_port_attrs *attrs = &devlink_port->attrs;
7678 if (WARN_ON(devlink_port->registered))
7680 devlink_port->attrs_set = true;
7681 attrs->flavour = flavour;
7682 if (attrs->switch_id.id_len) {
7683 devlink_port->switch_port = true;
7684 if (WARN_ON(attrs->switch_id.id_len > MAX_PHYS_ITEM_ID_LEN))
7685 attrs->switch_id.id_len = MAX_PHYS_ITEM_ID_LEN;
7687 devlink_port->switch_port = false;
7693 * devlink_port_attrs_set - Set port attributes
7695 * @devlink_port: devlink port
7696 * @attrs: devlink port attrs
7698 void devlink_port_attrs_set(struct devlink_port *devlink_port,
7699 struct devlink_port_attrs *attrs)
7703 devlink_port->attrs = *attrs;
7704 ret = __devlink_port_attrs_set(devlink_port, attrs->flavour);
7707 WARN_ON(attrs->splittable && attrs->split);
7709 EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
7712 * devlink_port_attrs_pci_pf_set - Set PCI PF port attributes
7714 * @devlink_port: devlink port
7715 * @pf: associated PF for the devlink port instance
7717 void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u16 pf)
7719 struct devlink_port_attrs *attrs = &devlink_port->attrs;
7722 ret = __devlink_port_attrs_set(devlink_port,
7723 DEVLINK_PORT_FLAVOUR_PCI_PF);
7727 attrs->pci_pf.pf = pf;
7729 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set);
7732 * devlink_port_attrs_pci_vf_set - Set PCI VF port attributes
7734 * @devlink_port: devlink port
7735 * @pf: associated PF for the devlink port instance
7736 * @vf: associated VF of a PF for the devlink port instance
7738 void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port,
7741 struct devlink_port_attrs *attrs = &devlink_port->attrs;
7744 ret = __devlink_port_attrs_set(devlink_port,
7745 DEVLINK_PORT_FLAVOUR_PCI_VF);
7748 attrs->pci_vf.pf = pf;
7749 attrs->pci_vf.vf = vf;
7751 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set);
7753 static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
7754 char *name, size_t len)
7756 struct devlink_port_attrs *attrs = &devlink_port->attrs;
7759 if (!devlink_port->attrs_set)
7762 switch (attrs->flavour) {
7763 case DEVLINK_PORT_FLAVOUR_PHYSICAL:
7764 case DEVLINK_PORT_FLAVOUR_VIRTUAL:
7766 n = snprintf(name, len, "p%u", attrs->phys.port_number);
7768 n = snprintf(name, len, "p%us%u",
7769 attrs->phys.port_number,
7770 attrs->phys.split_subport_number);
7772 case DEVLINK_PORT_FLAVOUR_CPU:
7773 case DEVLINK_PORT_FLAVOUR_DSA:
7774 /* As CPU and DSA ports do not have a netdevice associated
7775 * case should not ever happen.
7779 case DEVLINK_PORT_FLAVOUR_PCI_PF:
7780 n = snprintf(name, len, "pf%u", attrs->pci_pf.pf);
7782 case DEVLINK_PORT_FLAVOUR_PCI_VF:
7783 n = snprintf(name, len, "pf%uvf%u",
7784 attrs->pci_vf.pf, attrs->pci_vf.vf);
7794 int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
7795 u32 size, u16 ingress_pools_count,
7796 u16 egress_pools_count, u16 ingress_tc_count,
7797 u16 egress_tc_count)
7799 struct devlink_sb *devlink_sb;
7802 mutex_lock(&devlink->lock);
7803 if (devlink_sb_index_exists(devlink, sb_index)) {
7808 devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
7813 devlink_sb->index = sb_index;
7814 devlink_sb->size = size;
7815 devlink_sb->ingress_pools_count = ingress_pools_count;
7816 devlink_sb->egress_pools_count = egress_pools_count;
7817 devlink_sb->ingress_tc_count = ingress_tc_count;
7818 devlink_sb->egress_tc_count = egress_tc_count;
7819 list_add_tail(&devlink_sb->list, &devlink->sb_list);
7821 mutex_unlock(&devlink->lock);
7824 EXPORT_SYMBOL_GPL(devlink_sb_register);
7826 void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
7828 struct devlink_sb *devlink_sb;
7830 mutex_lock(&devlink->lock);
7831 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
7832 WARN_ON(!devlink_sb);
7833 list_del(&devlink_sb->list);
7834 mutex_unlock(&devlink->lock);
7837 EXPORT_SYMBOL_GPL(devlink_sb_unregister);
7840 * devlink_dpipe_headers_register - register dpipe headers
7843 * @dpipe_headers: dpipe header array
7845 * Register the headers supported by hardware.
7847 int devlink_dpipe_headers_register(struct devlink *devlink,
7848 struct devlink_dpipe_headers *dpipe_headers)
7850 mutex_lock(&devlink->lock);
7851 devlink->dpipe_headers = dpipe_headers;
7852 mutex_unlock(&devlink->lock);
7855 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register);
7858 * devlink_dpipe_headers_unregister - unregister dpipe headers
7862 * Unregister the headers supported by hardware.
7864 void devlink_dpipe_headers_unregister(struct devlink *devlink)
7866 mutex_lock(&devlink->lock);
7867 devlink->dpipe_headers = NULL;
7868 mutex_unlock(&devlink->lock);
7870 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister);
7873 * devlink_dpipe_table_counter_enabled - check if counter allocation
7876 * @table_name: tables name
7878 * Used by driver to check if counter allocation is required.
7879 * After counter allocation is turned on the table entries
7880 * are updated to include counter statistics.
7882 * After that point on the driver must respect the counter
7883 * state so that each entry added to the table is added
7886 bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
7887 const char *table_name)
7889 struct devlink_dpipe_table *table;
7893 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
7894 table_name, devlink);
7897 enabled = table->counters_enabled;
7901 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled);
7904 * devlink_dpipe_table_register - register dpipe table
7907 * @table_name: table name
7908 * @table_ops: table ops
7910 * @counter_control_extern: external control for counters
7912 int devlink_dpipe_table_register(struct devlink *devlink,
7913 const char *table_name,
7914 struct devlink_dpipe_table_ops *table_ops,
7915 void *priv, bool counter_control_extern)
7917 struct devlink_dpipe_table *table;
7920 if (WARN_ON(!table_ops->size_get))
7923 mutex_lock(&devlink->lock);
7925 if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name,
7931 table = kzalloc(sizeof(*table), GFP_KERNEL);
7937 table->name = table_name;
7938 table->table_ops = table_ops;
7940 table->counter_control_extern = counter_control_extern;
7942 list_add_tail_rcu(&table->list, &devlink->dpipe_table_list);
7944 mutex_unlock(&devlink->lock);
7947 EXPORT_SYMBOL_GPL(devlink_dpipe_table_register);
7950 * devlink_dpipe_table_unregister - unregister dpipe table
7953 * @table_name: table name
7955 void devlink_dpipe_table_unregister(struct devlink *devlink,
7956 const char *table_name)
7958 struct devlink_dpipe_table *table;
7960 mutex_lock(&devlink->lock);
7961 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
7962 table_name, devlink);
7965 list_del_rcu(&table->list);
7966 mutex_unlock(&devlink->lock);
7967 kfree_rcu(table, rcu);
7970 mutex_unlock(&devlink->lock);
7972 EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister);
7975 * devlink_resource_register - devlink resource register
7978 * @resource_name: resource's name
7979 * @resource_size: resource's size
7980 * @resource_id: resource's id
7981 * @parent_resource_id: resource's parent id
7982 * @size_params: size parameters
7984 int devlink_resource_register(struct devlink *devlink,
7985 const char *resource_name,
7988 u64 parent_resource_id,
7989 const struct devlink_resource_size_params *size_params)
7991 struct devlink_resource *resource;
7992 struct list_head *resource_list;
7996 top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
7998 mutex_lock(&devlink->lock);
7999 resource = devlink_resource_find(devlink, NULL, resource_id);
8005 resource = kzalloc(sizeof(*resource), GFP_KERNEL);
8011 if (top_hierarchy) {
8012 resource_list = &devlink->resource_list;
8014 struct devlink_resource *parent_resource;
8016 parent_resource = devlink_resource_find(devlink, NULL,
8017 parent_resource_id);
8018 if (parent_resource) {
8019 resource_list = &parent_resource->resource_list;
8020 resource->parent = parent_resource;
8028 resource->name = resource_name;
8029 resource->size = resource_size;
8030 resource->size_new = resource_size;
8031 resource->id = resource_id;
8032 resource->size_valid = true;
8033 memcpy(&resource->size_params, size_params,
8034 sizeof(resource->size_params));
8035 INIT_LIST_HEAD(&resource->resource_list);
8036 list_add_tail(&resource->list, resource_list);
8038 mutex_unlock(&devlink->lock);
8041 EXPORT_SYMBOL_GPL(devlink_resource_register);
8044 * devlink_resources_unregister - free all resources
8047 * @resource: resource
8049 void devlink_resources_unregister(struct devlink *devlink,
8050 struct devlink_resource *resource)
8052 struct devlink_resource *tmp, *child_resource;
8053 struct list_head *resource_list;
8056 resource_list = &resource->resource_list;
8058 resource_list = &devlink->resource_list;
8061 mutex_lock(&devlink->lock);
8063 list_for_each_entry_safe(child_resource, tmp, resource_list, list) {
8064 devlink_resources_unregister(devlink, child_resource);
8065 list_del(&child_resource->list);
8066 kfree(child_resource);
8070 mutex_unlock(&devlink->lock);
8072 EXPORT_SYMBOL_GPL(devlink_resources_unregister);
8075 * devlink_resource_size_get - get and update size
8078 * @resource_id: the requested resource id
8079 * @p_resource_size: ptr to update
8081 int devlink_resource_size_get(struct devlink *devlink,
8083 u64 *p_resource_size)
8085 struct devlink_resource *resource;
8088 mutex_lock(&devlink->lock);
8089 resource = devlink_resource_find(devlink, NULL, resource_id);
8094 *p_resource_size = resource->size_new;
8095 resource->size = resource->size_new;
8097 mutex_unlock(&devlink->lock);
8100 EXPORT_SYMBOL_GPL(devlink_resource_size_get);
8103 * devlink_dpipe_table_resource_set - set the resource id
8106 * @table_name: table name
8107 * @resource_id: resource id
8108 * @resource_units: number of resource's units consumed per table's entry
8110 int devlink_dpipe_table_resource_set(struct devlink *devlink,
8111 const char *table_name, u64 resource_id,
8114 struct devlink_dpipe_table *table;
8117 mutex_lock(&devlink->lock);
8118 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
8119 table_name, devlink);
8124 table->resource_id = resource_id;
8125 table->resource_units = resource_units;
8126 table->resource_valid = true;
8128 mutex_unlock(&devlink->lock);
8131 EXPORT_SYMBOL_GPL(devlink_dpipe_table_resource_set);
8134 * devlink_resource_occ_get_register - register occupancy getter
8137 * @resource_id: resource id
8138 * @occ_get: occupancy getter callback
8139 * @occ_get_priv: occupancy getter callback priv
8141 void devlink_resource_occ_get_register(struct devlink *devlink,
8143 devlink_resource_occ_get_t *occ_get,
8146 struct devlink_resource *resource;
8148 mutex_lock(&devlink->lock);
8149 resource = devlink_resource_find(devlink, NULL, resource_id);
8150 if (WARN_ON(!resource))
8152 WARN_ON(resource->occ_get);
8154 resource->occ_get = occ_get;
8155 resource->occ_get_priv = occ_get_priv;
8157 mutex_unlock(&devlink->lock);
8159 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register);
8162 * devlink_resource_occ_get_unregister - unregister occupancy getter
8165 * @resource_id: resource id
8167 void devlink_resource_occ_get_unregister(struct devlink *devlink,
8170 struct devlink_resource *resource;
8172 mutex_lock(&devlink->lock);
8173 resource = devlink_resource_find(devlink, NULL, resource_id);
8174 if (WARN_ON(!resource))
8176 WARN_ON(!resource->occ_get);
8178 resource->occ_get = NULL;
8179 resource->occ_get_priv = NULL;
8181 mutex_unlock(&devlink->lock);
8183 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister);
8185 static int devlink_param_verify(const struct devlink_param *param)
8187 if (!param || !param->name || !param->supported_cmodes)
8190 return devlink_param_generic_verify(param);
8192 return devlink_param_driver_verify(param);
8195 static int __devlink_params_register(struct devlink *devlink,
8196 unsigned int port_index,
8197 struct list_head *param_list,
8198 const struct devlink_param *params,
8199 size_t params_count,
8200 enum devlink_command reg_cmd,
8201 enum devlink_command unreg_cmd)
8203 const struct devlink_param *param = params;
8207 mutex_lock(&devlink->lock);
8208 for (i = 0; i < params_count; i++, param++) {
8209 err = devlink_param_verify(param);
8213 err = devlink_param_register_one(devlink, port_index,
8214 param_list, param, reg_cmd);
8219 mutex_unlock(&devlink->lock);
8225 for (param--; i > 0; i--, param--)
8226 devlink_param_unregister_one(devlink, port_index, param_list,
8229 mutex_unlock(&devlink->lock);
8233 static void __devlink_params_unregister(struct devlink *devlink,
8234 unsigned int port_index,
8235 struct list_head *param_list,
8236 const struct devlink_param *params,
8237 size_t params_count,
8238 enum devlink_command cmd)
8240 const struct devlink_param *param = params;
8243 mutex_lock(&devlink->lock);
8244 for (i = 0; i < params_count; i++, param++)
8245 devlink_param_unregister_one(devlink, 0, param_list, param,
8247 mutex_unlock(&devlink->lock);
8251 * devlink_params_register - register configuration parameters
8254 * @params: configuration parameters array
8255 * @params_count: number of parameters provided
8257 * Register the configuration parameters supported by the driver.
8259 int devlink_params_register(struct devlink *devlink,
8260 const struct devlink_param *params,
8261 size_t params_count)
8263 return __devlink_params_register(devlink, 0, &devlink->param_list,
8264 params, params_count,
8265 DEVLINK_CMD_PARAM_NEW,
8266 DEVLINK_CMD_PARAM_DEL);
8268 EXPORT_SYMBOL_GPL(devlink_params_register);
8271 * devlink_params_unregister - unregister configuration parameters
8273 * @params: configuration parameters to unregister
8274 * @params_count: number of parameters provided
8276 void devlink_params_unregister(struct devlink *devlink,
8277 const struct devlink_param *params,
8278 size_t params_count)
8280 return __devlink_params_unregister(devlink, 0, &devlink->param_list,
8281 params, params_count,
8282 DEVLINK_CMD_PARAM_DEL);
8284 EXPORT_SYMBOL_GPL(devlink_params_unregister);
8287 * devlink_params_publish - publish configuration parameters
8291 * Publish previously registered configuration parameters.
8293 void devlink_params_publish(struct devlink *devlink)
8295 struct devlink_param_item *param_item;
8297 list_for_each_entry(param_item, &devlink->param_list, list) {
8298 if (param_item->published)
8300 param_item->published = true;
8301 devlink_param_notify(devlink, 0, param_item,
8302 DEVLINK_CMD_PARAM_NEW);
8305 EXPORT_SYMBOL_GPL(devlink_params_publish);
8308 * devlink_params_unpublish - unpublish configuration parameters
8312 * Unpublish previously registered configuration parameters.
8314 void devlink_params_unpublish(struct devlink *devlink)
8316 struct devlink_param_item *param_item;
8318 list_for_each_entry(param_item, &devlink->param_list, list) {
8319 if (!param_item->published)
8321 param_item->published = false;
8322 devlink_param_notify(devlink, 0, param_item,
8323 DEVLINK_CMD_PARAM_DEL);
8326 EXPORT_SYMBOL_GPL(devlink_params_unpublish);
8329 * devlink_port_params_register - register port configuration parameters
8331 * @devlink_port: devlink port
8332 * @params: configuration parameters array
8333 * @params_count: number of parameters provided
8335 * Register the configuration parameters supported by the port.
8337 int devlink_port_params_register(struct devlink_port *devlink_port,
8338 const struct devlink_param *params,
8339 size_t params_count)
8341 return __devlink_params_register(devlink_port->devlink,
8342 devlink_port->index,
8343 &devlink_port->param_list, params,
8345 DEVLINK_CMD_PORT_PARAM_NEW,
8346 DEVLINK_CMD_PORT_PARAM_DEL);
8348 EXPORT_SYMBOL_GPL(devlink_port_params_register);
8351 * devlink_port_params_unregister - unregister port configuration
8354 * @devlink_port: devlink port
8355 * @params: configuration parameters array
8356 * @params_count: number of parameters provided
8358 void devlink_port_params_unregister(struct devlink_port *devlink_port,
8359 const struct devlink_param *params,
8360 size_t params_count)
8362 return __devlink_params_unregister(devlink_port->devlink,
8363 devlink_port->index,
8364 &devlink_port->param_list,
8365 params, params_count,
8366 DEVLINK_CMD_PORT_PARAM_DEL);
8368 EXPORT_SYMBOL_GPL(devlink_port_params_unregister);
8371 __devlink_param_driverinit_value_get(struct list_head *param_list, u32 param_id,
8372 union devlink_param_value *init_val)
8374 struct devlink_param_item *param_item;
8376 param_item = devlink_param_find_by_id(param_list, param_id);
8380 if (!param_item->driverinit_value_valid ||
8381 !devlink_param_cmode_is_supported(param_item->param,
8382 DEVLINK_PARAM_CMODE_DRIVERINIT))
8385 if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
8386 strcpy(init_val->vstr, param_item->driverinit_value.vstr);
8388 *init_val = param_item->driverinit_value;
8394 __devlink_param_driverinit_value_set(struct devlink *devlink,
8395 unsigned int port_index,
8396 struct list_head *param_list, u32 param_id,
8397 union devlink_param_value init_val,
8398 enum devlink_command cmd)
8400 struct devlink_param_item *param_item;
8402 param_item = devlink_param_find_by_id(param_list, param_id);
8406 if (!devlink_param_cmode_is_supported(param_item->param,
8407 DEVLINK_PARAM_CMODE_DRIVERINIT))
8410 if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
8411 strcpy(param_item->driverinit_value.vstr, init_val.vstr);
8413 param_item->driverinit_value = init_val;
8414 param_item->driverinit_value_valid = true;
8416 devlink_param_notify(devlink, port_index, param_item, cmd);
8421 * devlink_param_driverinit_value_get - get configuration parameter
8422 * value for driver initializing
8425 * @param_id: parameter ID
8426 * @init_val: value of parameter in driverinit configuration mode
8428 * This function should be used by the driver to get driverinit
8429 * configuration for initialization after reload command.
8431 int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
8432 union devlink_param_value *init_val)
8434 if (!devlink_reload_supported(devlink))
8437 return __devlink_param_driverinit_value_get(&devlink->param_list,
8438 param_id, init_val);
8440 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_get);
8443 * devlink_param_driverinit_value_set - set value of configuration
8444 * parameter for driverinit
8445 * configuration mode
8448 * @param_id: parameter ID
8449 * @init_val: value of parameter to set for driverinit configuration mode
8451 * This function should be used by the driver to set driverinit
8452 * configuration mode default value.
8454 int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
8455 union devlink_param_value init_val)
8457 return __devlink_param_driverinit_value_set(devlink, 0,
8458 &devlink->param_list,
8460 DEVLINK_CMD_PARAM_NEW);
8462 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set);
8465 * devlink_port_param_driverinit_value_get - get configuration parameter
8466 * value for driver initializing
8468 * @devlink_port: devlink_port
8469 * @param_id: parameter ID
8470 * @init_val: value of parameter in driverinit configuration mode
8472 * This function should be used by the driver to get driverinit
8473 * configuration for initialization after reload command.
8475 int devlink_port_param_driverinit_value_get(struct devlink_port *devlink_port,
8477 union devlink_param_value *init_val)
8479 struct devlink *devlink = devlink_port->devlink;
8481 if (!devlink_reload_supported(devlink))
8484 return __devlink_param_driverinit_value_get(&devlink_port->param_list,
8485 param_id, init_val);
8487 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_get);
8490 * devlink_port_param_driverinit_value_set - set value of configuration
8491 * parameter for driverinit
8492 * configuration mode
8494 * @devlink_port: devlink_port
8495 * @param_id: parameter ID
8496 * @init_val: value of parameter to set for driverinit configuration mode
8498 * This function should be used by the driver to set driverinit
8499 * configuration mode default value.
8501 int devlink_port_param_driverinit_value_set(struct devlink_port *devlink_port,
8503 union devlink_param_value init_val)
8505 return __devlink_param_driverinit_value_set(devlink_port->devlink,
8506 devlink_port->index,
8507 &devlink_port->param_list,
8509 DEVLINK_CMD_PORT_PARAM_NEW);
8511 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_set);
8514 * devlink_param_value_changed - notify devlink on a parameter's value
8515 * change. Should be called by the driver
8516 * right after the change.
8519 * @param_id: parameter ID
8521 * This function should be used by the driver to notify devlink on value
8522 * change, excluding driverinit configuration mode.
8523 * For driverinit configuration mode driver should use the function
8525 void devlink_param_value_changed(struct devlink *devlink, u32 param_id)
8527 struct devlink_param_item *param_item;
8529 param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
8530 WARN_ON(!param_item);
8532 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
8534 EXPORT_SYMBOL_GPL(devlink_param_value_changed);
8537 * devlink_port_param_value_changed - notify devlink on a parameter's value
8538 * change. Should be called by the driver
8539 * right after the change.
8541 * @devlink_port: devlink_port
8542 * @param_id: parameter ID
8544 * This function should be used by the driver to notify devlink on value
8545 * change, excluding driverinit configuration mode.
8546 * For driverinit configuration mode driver should use the function
8547 * devlink_port_param_driverinit_value_set() instead.
8549 void devlink_port_param_value_changed(struct devlink_port *devlink_port,
8552 struct devlink_param_item *param_item;
8554 param_item = devlink_param_find_by_id(&devlink_port->param_list,
8556 WARN_ON(!param_item);
8558 devlink_param_notify(devlink_port->devlink, devlink_port->index,
8559 param_item, DEVLINK_CMD_PORT_PARAM_NEW);
8561 EXPORT_SYMBOL_GPL(devlink_port_param_value_changed);
8564 * devlink_param_value_str_fill - Safely fill-up the string preventing
8565 * from overflow of the preallocated buffer
8567 * @dst_val: destination devlink_param_value
8568 * @src: source buffer
8570 void devlink_param_value_str_fill(union devlink_param_value *dst_val,
8575 len = strlcpy(dst_val->vstr, src, __DEVLINK_PARAM_MAX_STRING_VALUE);
8576 WARN_ON(len >= __DEVLINK_PARAM_MAX_STRING_VALUE);
8578 EXPORT_SYMBOL_GPL(devlink_param_value_str_fill);
8581 * devlink_region_create - create a new address region
8584 * @ops: region operations and name
8585 * @region_max_snapshots: Maximum supported number of snapshots for region
8586 * @region_size: size of region
8588 struct devlink_region *
8589 devlink_region_create(struct devlink *devlink,
8590 const struct devlink_region_ops *ops,
8591 u32 region_max_snapshots, u64 region_size)
8593 struct devlink_region *region;
8596 if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
8597 return ERR_PTR(-EINVAL);
8599 mutex_lock(&devlink->lock);
8601 if (devlink_region_get_by_name(devlink, ops->name)) {
8606 region = kzalloc(sizeof(*region), GFP_KERNEL);
8612 region->devlink = devlink;
8613 region->max_snapshots = region_max_snapshots;
8615 region->size = region_size;
8616 INIT_LIST_HEAD(®ion->snapshot_list);
8617 list_add_tail(®ion->list, &devlink->region_list);
8618 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
8620 mutex_unlock(&devlink->lock);
8624 mutex_unlock(&devlink->lock);
8625 return ERR_PTR(err);
8627 EXPORT_SYMBOL_GPL(devlink_region_create);
8630 * devlink_region_destroy - destroy address region
8632 * @region: devlink region to destroy
8634 void devlink_region_destroy(struct devlink_region *region)
8636 struct devlink *devlink = region->devlink;
8637 struct devlink_snapshot *snapshot, *ts;
8639 mutex_lock(&devlink->lock);
8641 /* Free all snapshots of region */
8642 list_for_each_entry_safe(snapshot, ts, ®ion->snapshot_list, list)
8643 devlink_region_snapshot_del(region, snapshot);
8645 list_del(®ion->list);
8647 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
8648 mutex_unlock(&devlink->lock);
8651 EXPORT_SYMBOL_GPL(devlink_region_destroy);
8654 * devlink_region_snapshot_id_get - get snapshot ID
8656 * This callback should be called when adding a new snapshot,
8657 * Driver should use the same id for multiple snapshots taken
8658 * on multiple regions at the same time/by the same trigger.
8660 * The caller of this function must use devlink_region_snapshot_id_put
8661 * when finished creating regions using this id.
8663 * Returns zero on success, or a negative error code on failure.
8666 * @id: storage to return id
8668 int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
8672 mutex_lock(&devlink->lock);
8673 err = __devlink_region_snapshot_id_get(devlink, id);
8674 mutex_unlock(&devlink->lock);
8678 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get);
8681 * devlink_region_snapshot_id_put - put snapshot ID reference
8683 * This should be called by a driver after finishing creating snapshots
8684 * with an id. Doing so ensures that the ID can later be released in the
8685 * event that all snapshots using it have been destroyed.
8688 * @id: id to release reference on
8690 void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id)
8692 mutex_lock(&devlink->lock);
8693 __devlink_snapshot_id_decrement(devlink, id);
8694 mutex_unlock(&devlink->lock);
8696 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put);
8699 * devlink_region_snapshot_create - create a new snapshot
8700 * This will add a new snapshot of a region. The snapshot
8701 * will be stored on the region struct and can be accessed
8702 * from devlink. This is useful for future analyses of snapshots.
8703 * Multiple snapshots can be created on a region.
8704 * The @snapshot_id should be obtained using the getter function.
8706 * @region: devlink region of the snapshot
8707 * @data: snapshot data
8708 * @snapshot_id: snapshot id to be created
8710 int devlink_region_snapshot_create(struct devlink_region *region,
8711 u8 *data, u32 snapshot_id)
8713 struct devlink *devlink = region->devlink;
8716 mutex_lock(&devlink->lock);
8717 err = __devlink_region_snapshot_create(region, data, snapshot_id);
8718 mutex_unlock(&devlink->lock);
8722 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create);
8724 #define DEVLINK_TRAP(_id, _type) \
8726 .type = DEVLINK_TRAP_TYPE_##_type, \
8727 .id = DEVLINK_TRAP_GENERIC_ID_##_id, \
8728 .name = DEVLINK_TRAP_GENERIC_NAME_##_id, \
8731 static const struct devlink_trap devlink_trap_generic[] = {
8732 DEVLINK_TRAP(SMAC_MC, DROP),
8733 DEVLINK_TRAP(VLAN_TAG_MISMATCH, DROP),
8734 DEVLINK_TRAP(INGRESS_VLAN_FILTER, DROP),
8735 DEVLINK_TRAP(INGRESS_STP_FILTER, DROP),
8736 DEVLINK_TRAP(EMPTY_TX_LIST, DROP),
8737 DEVLINK_TRAP(PORT_LOOPBACK_FILTER, DROP),
8738 DEVLINK_TRAP(BLACKHOLE_ROUTE, DROP),
8739 DEVLINK_TRAP(TTL_ERROR, EXCEPTION),
8740 DEVLINK_TRAP(TAIL_DROP, DROP),
8741 DEVLINK_TRAP(NON_IP_PACKET, DROP),
8742 DEVLINK_TRAP(UC_DIP_MC_DMAC, DROP),
8743 DEVLINK_TRAP(DIP_LB, DROP),
8744 DEVLINK_TRAP(SIP_MC, DROP),
8745 DEVLINK_TRAP(SIP_LB, DROP),
8746 DEVLINK_TRAP(CORRUPTED_IP_HDR, DROP),
8747 DEVLINK_TRAP(IPV4_SIP_BC, DROP),
8748 DEVLINK_TRAP(IPV6_MC_DIP_RESERVED_SCOPE, DROP),
8749 DEVLINK_TRAP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE, DROP),
8750 DEVLINK_TRAP(MTU_ERROR, EXCEPTION),
8751 DEVLINK_TRAP(UNRESOLVED_NEIGH, EXCEPTION),
8752 DEVLINK_TRAP(RPF, EXCEPTION),
8753 DEVLINK_TRAP(REJECT_ROUTE, EXCEPTION),
8754 DEVLINK_TRAP(IPV4_LPM_UNICAST_MISS, EXCEPTION),
8755 DEVLINK_TRAP(IPV6_LPM_UNICAST_MISS, EXCEPTION),
8756 DEVLINK_TRAP(NON_ROUTABLE, DROP),
8757 DEVLINK_TRAP(DECAP_ERROR, EXCEPTION),
8758 DEVLINK_TRAP(OVERLAY_SMAC_MC, DROP),
8759 DEVLINK_TRAP(INGRESS_FLOW_ACTION_DROP, DROP),
8760 DEVLINK_TRAP(EGRESS_FLOW_ACTION_DROP, DROP),
8761 DEVLINK_TRAP(STP, CONTROL),
8762 DEVLINK_TRAP(LACP, CONTROL),
8763 DEVLINK_TRAP(LLDP, CONTROL),
8764 DEVLINK_TRAP(IGMP_QUERY, CONTROL),
8765 DEVLINK_TRAP(IGMP_V1_REPORT, CONTROL),
8766 DEVLINK_TRAP(IGMP_V2_REPORT, CONTROL),
8767 DEVLINK_TRAP(IGMP_V3_REPORT, CONTROL),
8768 DEVLINK_TRAP(IGMP_V2_LEAVE, CONTROL),
8769 DEVLINK_TRAP(MLD_QUERY, CONTROL),
8770 DEVLINK_TRAP(MLD_V1_REPORT, CONTROL),
8771 DEVLINK_TRAP(MLD_V2_REPORT, CONTROL),
8772 DEVLINK_TRAP(MLD_V1_DONE, CONTROL),
8773 DEVLINK_TRAP(IPV4_DHCP, CONTROL),
8774 DEVLINK_TRAP(IPV6_DHCP, CONTROL),
8775 DEVLINK_TRAP(ARP_REQUEST, CONTROL),
8776 DEVLINK_TRAP(ARP_RESPONSE, CONTROL),
8777 DEVLINK_TRAP(ARP_OVERLAY, CONTROL),
8778 DEVLINK_TRAP(IPV6_NEIGH_SOLICIT, CONTROL),
8779 DEVLINK_TRAP(IPV6_NEIGH_ADVERT, CONTROL),
8780 DEVLINK_TRAP(IPV4_BFD, CONTROL),
8781 DEVLINK_TRAP(IPV6_BFD, CONTROL),
8782 DEVLINK_TRAP(IPV4_OSPF, CONTROL),
8783 DEVLINK_TRAP(IPV6_OSPF, CONTROL),
8784 DEVLINK_TRAP(IPV4_BGP, CONTROL),
8785 DEVLINK_TRAP(IPV6_BGP, CONTROL),
8786 DEVLINK_TRAP(IPV4_VRRP, CONTROL),
8787 DEVLINK_TRAP(IPV6_VRRP, CONTROL),
8788 DEVLINK_TRAP(IPV4_PIM, CONTROL),
8789 DEVLINK_TRAP(IPV6_PIM, CONTROL),
8790 DEVLINK_TRAP(UC_LB, CONTROL),
8791 DEVLINK_TRAP(LOCAL_ROUTE, CONTROL),
8792 DEVLINK_TRAP(EXTERNAL_ROUTE, CONTROL),
8793 DEVLINK_TRAP(IPV6_UC_DIP_LINK_LOCAL_SCOPE, CONTROL),
8794 DEVLINK_TRAP(IPV6_DIP_ALL_NODES, CONTROL),
8795 DEVLINK_TRAP(IPV6_DIP_ALL_ROUTERS, CONTROL),
8796 DEVLINK_TRAP(IPV6_ROUTER_SOLICIT, CONTROL),
8797 DEVLINK_TRAP(IPV6_ROUTER_ADVERT, CONTROL),
8798 DEVLINK_TRAP(IPV6_REDIRECT, CONTROL),
8799 DEVLINK_TRAP(IPV4_ROUTER_ALERT, CONTROL),
8800 DEVLINK_TRAP(IPV6_ROUTER_ALERT, CONTROL),
8801 DEVLINK_TRAP(PTP_EVENT, CONTROL),
8802 DEVLINK_TRAP(PTP_GENERAL, CONTROL),
8803 DEVLINK_TRAP(FLOW_ACTION_SAMPLE, CONTROL),
8804 DEVLINK_TRAP(FLOW_ACTION_TRAP, CONTROL),
8805 DEVLINK_TRAP(EARLY_DROP, DROP),
8808 #define DEVLINK_TRAP_GROUP(_id) \
8810 .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \
8811 .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \
8814 static const struct devlink_trap_group devlink_trap_group_generic[] = {
8815 DEVLINK_TRAP_GROUP(L2_DROPS),
8816 DEVLINK_TRAP_GROUP(L3_DROPS),
8817 DEVLINK_TRAP_GROUP(L3_EXCEPTIONS),
8818 DEVLINK_TRAP_GROUP(BUFFER_DROPS),
8819 DEVLINK_TRAP_GROUP(TUNNEL_DROPS),
8820 DEVLINK_TRAP_GROUP(ACL_DROPS),
8821 DEVLINK_TRAP_GROUP(STP),
8822 DEVLINK_TRAP_GROUP(LACP),
8823 DEVLINK_TRAP_GROUP(LLDP),
8824 DEVLINK_TRAP_GROUP(MC_SNOOPING),
8825 DEVLINK_TRAP_GROUP(DHCP),
8826 DEVLINK_TRAP_GROUP(NEIGH_DISCOVERY),
8827 DEVLINK_TRAP_GROUP(BFD),
8828 DEVLINK_TRAP_GROUP(OSPF),
8829 DEVLINK_TRAP_GROUP(BGP),
8830 DEVLINK_TRAP_GROUP(VRRP),
8831 DEVLINK_TRAP_GROUP(PIM),
8832 DEVLINK_TRAP_GROUP(UC_LB),
8833 DEVLINK_TRAP_GROUP(LOCAL_DELIVERY),
8834 DEVLINK_TRAP_GROUP(EXTERNAL_DELIVERY),
8835 DEVLINK_TRAP_GROUP(IPV6),
8836 DEVLINK_TRAP_GROUP(PTP_EVENT),
8837 DEVLINK_TRAP_GROUP(PTP_GENERAL),
8838 DEVLINK_TRAP_GROUP(ACL_SAMPLE),
8839 DEVLINK_TRAP_GROUP(ACL_TRAP),
8842 static int devlink_trap_generic_verify(const struct devlink_trap *trap)
8844 if (trap->id > DEVLINK_TRAP_GENERIC_ID_MAX)
8847 if (strcmp(trap->name, devlink_trap_generic[trap->id].name))
8850 if (trap->type != devlink_trap_generic[trap->id].type)
8856 static int devlink_trap_driver_verify(const struct devlink_trap *trap)
8860 if (trap->id <= DEVLINK_TRAP_GENERIC_ID_MAX)
8863 for (i = 0; i < ARRAY_SIZE(devlink_trap_generic); i++) {
8864 if (!strcmp(trap->name, devlink_trap_generic[i].name))
8871 static int devlink_trap_verify(const struct devlink_trap *trap)
8873 if (!trap || !trap->name)
8877 return devlink_trap_generic_verify(trap);
8879 return devlink_trap_driver_verify(trap);
8883 devlink_trap_group_generic_verify(const struct devlink_trap_group *group)
8885 if (group->id > DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
8888 if (strcmp(group->name, devlink_trap_group_generic[group->id].name))
8895 devlink_trap_group_driver_verify(const struct devlink_trap_group *group)
8899 if (group->id <= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
8902 for (i = 0; i < ARRAY_SIZE(devlink_trap_group_generic); i++) {
8903 if (!strcmp(group->name, devlink_trap_group_generic[i].name))
8910 static int devlink_trap_group_verify(const struct devlink_trap_group *group)
8913 return devlink_trap_group_generic_verify(group);
8915 return devlink_trap_group_driver_verify(group);
8919 devlink_trap_group_notify(struct devlink *devlink,
8920 const struct devlink_trap_group_item *group_item,
8921 enum devlink_command cmd)
8923 struct sk_buff *msg;
8926 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_GROUP_NEW &&
8927 cmd != DEVLINK_CMD_TRAP_GROUP_DEL);
8929 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8933 err = devlink_nl_trap_group_fill(msg, devlink, group_item, cmd, 0, 0,
8940 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
8941 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
8945 devlink_trap_item_group_link(struct devlink *devlink,
8946 struct devlink_trap_item *trap_item)
8948 u16 group_id = trap_item->trap->init_group_id;
8949 struct devlink_trap_group_item *group_item;
8951 group_item = devlink_trap_group_item_lookup_by_id(devlink, group_id);
8952 if (WARN_ON_ONCE(!group_item))
8955 trap_item->group_item = group_item;
8960 static void devlink_trap_notify(struct devlink *devlink,
8961 const struct devlink_trap_item *trap_item,
8962 enum devlink_command cmd)
8964 struct sk_buff *msg;
8967 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_NEW &&
8968 cmd != DEVLINK_CMD_TRAP_DEL);
8970 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8974 err = devlink_nl_trap_fill(msg, devlink, trap_item, cmd, 0, 0, 0);
8980 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
8981 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
8985 devlink_trap_register(struct devlink *devlink,
8986 const struct devlink_trap *trap, void *priv)
8988 struct devlink_trap_item *trap_item;
8991 if (devlink_trap_item_lookup(devlink, trap->name))
8994 trap_item = kzalloc(sizeof(*trap_item), GFP_KERNEL);
8998 trap_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
8999 if (!trap_item->stats) {
9001 goto err_stats_alloc;
9004 trap_item->trap = trap;
9005 trap_item->action = trap->init_action;
9006 trap_item->priv = priv;
9008 err = devlink_trap_item_group_link(devlink, trap_item);
9010 goto err_group_link;
9012 err = devlink->ops->trap_init(devlink, trap, trap_item);
9016 list_add_tail(&trap_item->list, &devlink->trap_list);
9017 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
9023 free_percpu(trap_item->stats);
9029 static void devlink_trap_unregister(struct devlink *devlink,
9030 const struct devlink_trap *trap)
9032 struct devlink_trap_item *trap_item;
9034 trap_item = devlink_trap_item_lookup(devlink, trap->name);
9035 if (WARN_ON_ONCE(!trap_item))
9038 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL);
9039 list_del(&trap_item->list);
9040 if (devlink->ops->trap_fini)
9041 devlink->ops->trap_fini(devlink, trap, trap_item);
9042 free_percpu(trap_item->stats);
9046 static void devlink_trap_disable(struct devlink *devlink,
9047 const struct devlink_trap *trap)
9049 struct devlink_trap_item *trap_item;
9051 trap_item = devlink_trap_item_lookup(devlink, trap->name);
9052 if (WARN_ON_ONCE(!trap_item))
9055 devlink->ops->trap_action_set(devlink, trap, DEVLINK_TRAP_ACTION_DROP,
9057 trap_item->action = DEVLINK_TRAP_ACTION_DROP;
9061 * devlink_traps_register - Register packet traps with devlink.
9062 * @devlink: devlink.
9063 * @traps: Packet traps.
9064 * @traps_count: Count of provided packet traps.
9065 * @priv: Driver private information.
9067 * Return: Non-zero value on failure.
9069 int devlink_traps_register(struct devlink *devlink,
9070 const struct devlink_trap *traps,
9071 size_t traps_count, void *priv)
9075 if (!devlink->ops->trap_init || !devlink->ops->trap_action_set)
9078 mutex_lock(&devlink->lock);
9079 for (i = 0; i < traps_count; i++) {
9080 const struct devlink_trap *trap = &traps[i];
9082 err = devlink_trap_verify(trap);
9084 goto err_trap_verify;
9086 err = devlink_trap_register(devlink, trap, priv);
9088 goto err_trap_register;
9090 mutex_unlock(&devlink->lock);
9096 for (i--; i >= 0; i--)
9097 devlink_trap_unregister(devlink, &traps[i]);
9098 mutex_unlock(&devlink->lock);
9101 EXPORT_SYMBOL_GPL(devlink_traps_register);
9104 * devlink_traps_unregister - Unregister packet traps from devlink.
9105 * @devlink: devlink.
9106 * @traps: Packet traps.
9107 * @traps_count: Count of provided packet traps.
9109 void devlink_traps_unregister(struct devlink *devlink,
9110 const struct devlink_trap *traps,
9115 mutex_lock(&devlink->lock);
9116 /* Make sure we do not have any packets in-flight while unregistering
9117 * traps by disabling all of them and waiting for a grace period.
9119 for (i = traps_count - 1; i >= 0; i--)
9120 devlink_trap_disable(devlink, &traps[i]);
9122 for (i = traps_count - 1; i >= 0; i--)
9123 devlink_trap_unregister(devlink, &traps[i]);
9124 mutex_unlock(&devlink->lock);
9126 EXPORT_SYMBOL_GPL(devlink_traps_unregister);
9129 devlink_trap_stats_update(struct devlink_stats __percpu *trap_stats,
9132 struct devlink_stats *stats;
9134 stats = this_cpu_ptr(trap_stats);
9135 u64_stats_update_begin(&stats->syncp);
9136 stats->rx_bytes += skb_len;
9137 stats->rx_packets++;
9138 u64_stats_update_end(&stats->syncp);
9142 devlink_trap_report_metadata_fill(struct net_dm_hw_metadata *hw_metadata,
9143 const struct devlink_trap_item *trap_item,
9144 struct devlink_port *in_devlink_port,
9145 const struct flow_action_cookie *fa_cookie)
9147 struct devlink_trap_group_item *group_item = trap_item->group_item;
9149 hw_metadata->trap_group_name = group_item->group->name;
9150 hw_metadata->trap_name = trap_item->trap->name;
9151 hw_metadata->fa_cookie = fa_cookie;
9153 spin_lock(&in_devlink_port->type_lock);
9154 if (in_devlink_port->type == DEVLINK_PORT_TYPE_ETH)
9155 hw_metadata->input_dev = in_devlink_port->type_dev;
9156 spin_unlock(&in_devlink_port->type_lock);
9160 * devlink_trap_report - Report trapped packet to drop monitor.
9161 * @devlink: devlink.
9162 * @skb: Trapped packet.
9163 * @trap_ctx: Trap context.
9164 * @in_devlink_port: Input devlink port.
9165 * @fa_cookie: Flow action cookie. Could be NULL.
9167 void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb,
9168 void *trap_ctx, struct devlink_port *in_devlink_port,
9169 const struct flow_action_cookie *fa_cookie)
9172 struct devlink_trap_item *trap_item = trap_ctx;
9173 struct net_dm_hw_metadata hw_metadata = {};
9175 devlink_trap_stats_update(trap_item->stats, skb->len);
9176 devlink_trap_stats_update(trap_item->group_item->stats, skb->len);
9178 /* Control packets were not dropped by the device or encountered an
9179 * exception during forwarding and therefore should not be reported to
9180 * the kernel's drop monitor.
9182 if (trap_item->trap->type == DEVLINK_TRAP_TYPE_CONTROL)
9185 devlink_trap_report_metadata_fill(&hw_metadata, trap_item,
9186 in_devlink_port, fa_cookie);
9187 net_dm_hw_report(skb, &hw_metadata);
9189 EXPORT_SYMBOL_GPL(devlink_trap_report);
9192 * devlink_trap_ctx_priv - Trap context to driver private information.
9193 * @trap_ctx: Trap context.
9195 * Return: Driver private information passed during registration.
9197 void *devlink_trap_ctx_priv(void *trap_ctx)
9199 struct devlink_trap_item *trap_item = trap_ctx;
9201 return trap_item->priv;
9203 EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv);
9206 devlink_trap_group_item_policer_link(struct devlink *devlink,
9207 struct devlink_trap_group_item *group_item)
9209 u32 policer_id = group_item->group->init_policer_id;
9210 struct devlink_trap_policer_item *policer_item;
9212 if (policer_id == 0)
9215 policer_item = devlink_trap_policer_item_lookup(devlink, policer_id);
9216 if (WARN_ON_ONCE(!policer_item))
9219 group_item->policer_item = policer_item;
9225 devlink_trap_group_register(struct devlink *devlink,
9226 const struct devlink_trap_group *group)
9228 struct devlink_trap_group_item *group_item;
9231 if (devlink_trap_group_item_lookup(devlink, group->name))
9234 group_item = kzalloc(sizeof(*group_item), GFP_KERNEL);
9238 group_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
9239 if (!group_item->stats) {
9241 goto err_stats_alloc;
9244 group_item->group = group;
9246 err = devlink_trap_group_item_policer_link(devlink, group_item);
9248 goto err_policer_link;
9250 if (devlink->ops->trap_group_init) {
9251 err = devlink->ops->trap_group_init(devlink, group);
9253 goto err_group_init;
9256 list_add_tail(&group_item->list, &devlink->trap_group_list);
9257 devlink_trap_group_notify(devlink, group_item,
9258 DEVLINK_CMD_TRAP_GROUP_NEW);
9264 free_percpu(group_item->stats);
9271 devlink_trap_group_unregister(struct devlink *devlink,
9272 const struct devlink_trap_group *group)
9274 struct devlink_trap_group_item *group_item;
9276 group_item = devlink_trap_group_item_lookup(devlink, group->name);
9277 if (WARN_ON_ONCE(!group_item))
9280 devlink_trap_group_notify(devlink, group_item,
9281 DEVLINK_CMD_TRAP_GROUP_DEL);
9282 list_del(&group_item->list);
9283 free_percpu(group_item->stats);
9288 * devlink_trap_groups_register - Register packet trap groups with devlink.
9289 * @devlink: devlink.
9290 * @groups: Packet trap groups.
9291 * @groups_count: Count of provided packet trap groups.
9293 * Return: Non-zero value on failure.
9295 int devlink_trap_groups_register(struct devlink *devlink,
9296 const struct devlink_trap_group *groups,
9297 size_t groups_count)
9301 mutex_lock(&devlink->lock);
9302 for (i = 0; i < groups_count; i++) {
9303 const struct devlink_trap_group *group = &groups[i];
9305 err = devlink_trap_group_verify(group);
9307 goto err_trap_group_verify;
9309 err = devlink_trap_group_register(devlink, group);
9311 goto err_trap_group_register;
9313 mutex_unlock(&devlink->lock);
9317 err_trap_group_register:
9318 err_trap_group_verify:
9319 for (i--; i >= 0; i--)
9320 devlink_trap_group_unregister(devlink, &groups[i]);
9321 mutex_unlock(&devlink->lock);
9324 EXPORT_SYMBOL_GPL(devlink_trap_groups_register);
9327 * devlink_trap_groups_unregister - Unregister packet trap groups from devlink.
9328 * @devlink: devlink.
9329 * @groups: Packet trap groups.
9330 * @groups_count: Count of provided packet trap groups.
9332 void devlink_trap_groups_unregister(struct devlink *devlink,
9333 const struct devlink_trap_group *groups,
9334 size_t groups_count)
9338 mutex_lock(&devlink->lock);
9339 for (i = groups_count - 1; i >= 0; i--)
9340 devlink_trap_group_unregister(devlink, &groups[i]);
9341 mutex_unlock(&devlink->lock);
9343 EXPORT_SYMBOL_GPL(devlink_trap_groups_unregister);
9346 devlink_trap_policer_notify(struct devlink *devlink,
9347 const struct devlink_trap_policer_item *policer_item,
9348 enum devlink_command cmd)
9350 struct sk_buff *msg;
9353 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_POLICER_NEW &&
9354 cmd != DEVLINK_CMD_TRAP_POLICER_DEL);
9356 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
9360 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, cmd, 0,
9367 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
9368 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
9372 devlink_trap_policer_register(struct devlink *devlink,
9373 const struct devlink_trap_policer *policer)
9375 struct devlink_trap_policer_item *policer_item;
9378 if (devlink_trap_policer_item_lookup(devlink, policer->id))
9381 policer_item = kzalloc(sizeof(*policer_item), GFP_KERNEL);
9385 policer_item->policer = policer;
9386 policer_item->rate = policer->init_rate;
9387 policer_item->burst = policer->init_burst;
9389 if (devlink->ops->trap_policer_init) {
9390 err = devlink->ops->trap_policer_init(devlink, policer);
9392 goto err_policer_init;
9395 list_add_tail(&policer_item->list, &devlink->trap_policer_list);
9396 devlink_trap_policer_notify(devlink, policer_item,
9397 DEVLINK_CMD_TRAP_POLICER_NEW);
9402 kfree(policer_item);
9407 devlink_trap_policer_unregister(struct devlink *devlink,
9408 const struct devlink_trap_policer *policer)
9410 struct devlink_trap_policer_item *policer_item;
9412 policer_item = devlink_trap_policer_item_lookup(devlink, policer->id);
9413 if (WARN_ON_ONCE(!policer_item))
9416 devlink_trap_policer_notify(devlink, policer_item,
9417 DEVLINK_CMD_TRAP_POLICER_DEL);
9418 list_del(&policer_item->list);
9419 if (devlink->ops->trap_policer_fini)
9420 devlink->ops->trap_policer_fini(devlink, policer);
9421 kfree(policer_item);
9425 * devlink_trap_policers_register - Register packet trap policers with devlink.
9426 * @devlink: devlink.
9427 * @policers: Packet trap policers.
9428 * @policers_count: Count of provided packet trap policers.
9430 * Return: Non-zero value on failure.
9433 devlink_trap_policers_register(struct devlink *devlink,
9434 const struct devlink_trap_policer *policers,
9435 size_t policers_count)
9439 mutex_lock(&devlink->lock);
9440 for (i = 0; i < policers_count; i++) {
9441 const struct devlink_trap_policer *policer = &policers[i];
9443 if (WARN_ON(policer->id == 0 ||
9444 policer->max_rate < policer->min_rate ||
9445 policer->max_burst < policer->min_burst)) {
9447 goto err_trap_policer_verify;
9450 err = devlink_trap_policer_register(devlink, policer);
9452 goto err_trap_policer_register;
9454 mutex_unlock(&devlink->lock);
9458 err_trap_policer_register:
9459 err_trap_policer_verify:
9460 for (i--; i >= 0; i--)
9461 devlink_trap_policer_unregister(devlink, &policers[i]);
9462 mutex_unlock(&devlink->lock);
9465 EXPORT_SYMBOL_GPL(devlink_trap_policers_register);
9468 * devlink_trap_policers_unregister - Unregister packet trap policers from devlink.
9469 * @devlink: devlink.
9470 * @policers: Packet trap policers.
9471 * @policers_count: Count of provided packet trap policers.
9474 devlink_trap_policers_unregister(struct devlink *devlink,
9475 const struct devlink_trap_policer *policers,
9476 size_t policers_count)
9480 mutex_lock(&devlink->lock);
9481 for (i = policers_count - 1; i >= 0; i--)
9482 devlink_trap_policer_unregister(devlink, &policers[i]);
9483 mutex_unlock(&devlink->lock);
9485 EXPORT_SYMBOL_GPL(devlink_trap_policers_unregister);
9487 static void __devlink_compat_running_version(struct devlink *devlink,
9488 char *buf, size_t len)
9490 const struct nlattr *nlattr;
9491 struct devlink_info_req req;
9492 struct sk_buff *msg;
9495 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
9500 err = devlink->ops->info_get(devlink, &req, NULL);
9504 nla_for_each_attr(nlattr, (void *)msg->data, msg->len, rem) {
9505 const struct nlattr *kv;
9508 if (nla_type(nlattr) != DEVLINK_ATTR_INFO_VERSION_RUNNING)
9511 nla_for_each_nested(kv, nlattr, rem_kv) {
9512 if (nla_type(kv) != DEVLINK_ATTR_INFO_VERSION_VALUE)
9515 strlcat(buf, nla_data(kv), len);
9516 strlcat(buf, " ", len);
9523 void devlink_compat_running_version(struct net_device *dev,
9524 char *buf, size_t len)
9526 struct devlink *devlink;
9531 devlink = netdev_to_devlink(dev);
9532 if (!devlink || !devlink->ops->info_get)
9535 mutex_lock(&devlink->lock);
9536 __devlink_compat_running_version(devlink, buf, len);
9537 mutex_unlock(&devlink->lock);
9544 int devlink_compat_flash_update(struct net_device *dev, const char *file_name)
9546 struct devlink *devlink;
9552 devlink = netdev_to_devlink(dev);
9553 if (!devlink || !devlink->ops->flash_update) {
9558 mutex_lock(&devlink->lock);
9559 ret = devlink->ops->flash_update(devlink, file_name, NULL, NULL);
9560 mutex_unlock(&devlink->lock);
9569 int devlink_compat_phys_port_name_get(struct net_device *dev,
9570 char *name, size_t len)
9572 struct devlink_port *devlink_port;
9574 /* RTNL mutex is held here which ensures that devlink_port
9575 * instance cannot disappear in the middle. No need to take
9576 * any devlink lock as only permanent values are accessed.
9580 devlink_port = netdev_to_devlink_port(dev);
9584 return __devlink_port_phys_port_name_get(devlink_port, name, len);
9587 int devlink_compat_switch_id_get(struct net_device *dev,
9588 struct netdev_phys_item_id *ppid)
9590 struct devlink_port *devlink_port;
9592 /* Caller must hold RTNL mutex or reference to dev, which ensures that
9593 * devlink_port instance cannot disappear in the middle. No need to take
9594 * any devlink lock as only permanent values are accessed.
9596 devlink_port = netdev_to_devlink_port(dev);
9597 if (!devlink_port || !devlink_port->switch_port)
9600 memcpy(ppid, &devlink_port->attrs.switch_id, sizeof(*ppid));
9605 static void __net_exit devlink_pernet_pre_exit(struct net *net)
9607 struct devlink *devlink;
9610 /* In case network namespace is getting destroyed, reload
9611 * all devlink instances from this namespace into init_net.
9613 mutex_lock(&devlink_mutex);
9614 list_for_each_entry(devlink, &devlink_list, list) {
9615 if (net_eq(devlink_net(devlink), net)) {
9616 if (WARN_ON(!devlink_reload_supported(devlink)))
9618 err = devlink_reload(devlink, &init_net, NULL);
9619 if (err && err != -EOPNOTSUPP)
9620 pr_warn("Failed to reload devlink instance into init_net\n");
9623 mutex_unlock(&devlink_mutex);
9626 static struct pernet_operations devlink_pernet_ops __net_initdata = {
9627 .pre_exit = devlink_pernet_pre_exit,
9630 static int __init devlink_init(void)
9634 err = genl_register_family(&devlink_nl_family);
9637 err = register_pernet_subsys(&devlink_pernet_ops);
9644 subsys_initcall(devlink_init);