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/etherdevice.h>
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/types.h>
14 #include <linux/slab.h>
15 #include <linux/gfp.h>
16 #include <linux/device.h>
17 #include <linux/list.h>
18 #include <linux/netdevice.h>
19 #include <linux/spinlock.h>
20 #include <linux/refcount.h>
21 #include <linux/workqueue.h>
22 #include <linux/u64_stats_sync.h>
23 #include <linux/timekeeping.h>
24 #include <rdma/ib_verbs.h>
25 #include <net/netlink.h>
26 #include <net/genetlink.h>
27 #include <net/rtnetlink.h>
28 #include <net/net_namespace.h>
30 #include <net/devlink.h>
31 #define CREATE_TRACE_POINTS
32 #include <trace/events/devlink.h>
34 #include "devl_internal.h"
36 struct devlink_linecard {
37 struct list_head list;
38 struct devlink *devlink;
40 const struct devlink_linecard_ops *ops;
42 enum devlink_linecard_state state;
43 struct mutex state_lock; /* Protects state */
45 struct devlink_linecard_type *types;
46 unsigned int types_count;
47 struct devlink *nested_devlink;
51 * struct devlink_resource - devlink resource
52 * @name: name of the resource
53 * @id: id, per devlink instance
54 * @size: size of the resource
55 * @size_new: updated size of the resource, reload is needed
56 * @size_valid: valid in case the total size of the resource is valid
57 * including its children
58 * @parent: parent resource
59 * @size_params: size parameters
61 * @resource_list: list of child resources
62 * @occ_get: occupancy getter callback
63 * @occ_get_priv: occupancy getter callback priv
65 struct devlink_resource {
71 struct devlink_resource *parent;
72 struct devlink_resource_size_params size_params;
73 struct list_head list;
74 struct list_head resource_list;
75 devlink_resource_occ_get_t *occ_get;
79 static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = {
81 .name = "destination mac",
82 .id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
87 struct devlink_dpipe_header devlink_dpipe_header_ethernet = {
89 .id = DEVLINK_DPIPE_HEADER_ETHERNET,
90 .fields = devlink_dpipe_fields_ethernet,
91 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet),
94 EXPORT_SYMBOL_GPL(devlink_dpipe_header_ethernet);
96 static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = {
98 .name = "destination ip",
99 .id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP,
104 struct devlink_dpipe_header devlink_dpipe_header_ipv4 = {
106 .id = DEVLINK_DPIPE_HEADER_IPV4,
107 .fields = devlink_dpipe_fields_ipv4,
108 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4),
111 EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv4);
113 static struct devlink_dpipe_field devlink_dpipe_fields_ipv6[] = {
115 .name = "destination ip",
116 .id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP,
121 struct devlink_dpipe_header devlink_dpipe_header_ipv6 = {
123 .id = DEVLINK_DPIPE_HEADER_IPV6,
124 .fields = devlink_dpipe_fields_ipv6,
125 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv6),
128 EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv6);
130 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg);
131 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwerr);
132 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_trap_report);
134 #define DEVLINK_PORT_FN_CAPS_VALID_MASK \
135 (_BITUL(__DEVLINK_PORT_FN_ATTR_CAPS_MAX) - 1)
137 static const struct nla_policy devlink_function_nl_policy[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1] = {
138 [DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] = { .type = NLA_BINARY },
139 [DEVLINK_PORT_FN_ATTR_STATE] =
140 NLA_POLICY_RANGE(NLA_U8, DEVLINK_PORT_FN_STATE_INACTIVE,
141 DEVLINK_PORT_FN_STATE_ACTIVE),
142 [DEVLINK_PORT_FN_ATTR_CAPS] =
143 NLA_POLICY_BITFIELD32(DEVLINK_PORT_FN_CAPS_VALID_MASK),
146 #define ASSERT_DEVLINK_PORT_REGISTERED(devlink_port) \
147 WARN_ON_ONCE(!(devlink_port)->registered)
148 #define ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port) \
149 WARN_ON_ONCE((devlink_port)->registered)
150 #define ASSERT_DEVLINK_PORT_INITIALIZED(devlink_port) \
151 WARN_ON_ONCE(!(devlink_port)->initialized)
153 static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
154 unsigned int port_index)
156 return xa_load(&devlink->ports, port_index);
159 static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
160 struct nlattr **attrs)
162 if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
163 u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
164 struct devlink_port *devlink_port;
166 devlink_port = devlink_port_get_by_index(devlink, port_index);
168 return ERR_PTR(-ENODEV);
171 return ERR_PTR(-EINVAL);
174 struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
175 struct genl_info *info)
177 return devlink_port_get_from_attrs(devlink, info->attrs);
181 devlink_rate_is_leaf(struct devlink_rate *devlink_rate)
183 return devlink_rate->type == DEVLINK_RATE_TYPE_LEAF;
187 devlink_rate_is_node(struct devlink_rate *devlink_rate)
189 return devlink_rate->type == DEVLINK_RATE_TYPE_NODE;
192 static struct devlink_rate *
193 devlink_rate_leaf_get_from_info(struct devlink *devlink, struct genl_info *info)
195 struct devlink_rate *devlink_rate;
196 struct devlink_port *devlink_port;
198 devlink_port = devlink_port_get_from_attrs(devlink, info->attrs);
199 if (IS_ERR(devlink_port))
200 return ERR_CAST(devlink_port);
201 devlink_rate = devlink_port->devlink_rate;
202 return devlink_rate ?: ERR_PTR(-ENODEV);
205 static struct devlink_rate *
206 devlink_rate_node_get_by_name(struct devlink *devlink, const char *node_name)
208 static struct devlink_rate *devlink_rate;
210 list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
211 if (devlink_rate_is_node(devlink_rate) &&
212 !strcmp(node_name, devlink_rate->name))
215 return ERR_PTR(-ENODEV);
218 static struct devlink_rate *
219 devlink_rate_node_get_from_attrs(struct devlink *devlink, struct nlattr **attrs)
221 const char *rate_node_name;
224 if (!attrs[DEVLINK_ATTR_RATE_NODE_NAME])
225 return ERR_PTR(-EINVAL);
226 rate_node_name = nla_data(attrs[DEVLINK_ATTR_RATE_NODE_NAME]);
227 len = strlen(rate_node_name);
228 /* Name cannot be empty or decimal number */
229 if (!len || strspn(rate_node_name, "0123456789") == len)
230 return ERR_PTR(-EINVAL);
232 return devlink_rate_node_get_by_name(devlink, rate_node_name);
235 struct devlink_rate *
236 devlink_rate_node_get_from_info(struct devlink *devlink, struct genl_info *info)
238 return devlink_rate_node_get_from_attrs(devlink, info->attrs);
241 struct devlink_rate *
242 devlink_rate_get_from_info(struct devlink *devlink, struct genl_info *info)
244 struct nlattr **attrs = info->attrs;
246 if (attrs[DEVLINK_ATTR_PORT_INDEX])
247 return devlink_rate_leaf_get_from_info(devlink, info);
248 else if (attrs[DEVLINK_ATTR_RATE_NODE_NAME])
249 return devlink_rate_node_get_from_info(devlink, info);
251 return ERR_PTR(-EINVAL);
254 static struct devlink_linecard *
255 devlink_linecard_get_by_index(struct devlink *devlink,
256 unsigned int linecard_index)
258 struct devlink_linecard *devlink_linecard;
260 list_for_each_entry(devlink_linecard, &devlink->linecard_list, list) {
261 if (devlink_linecard->index == linecard_index)
262 return devlink_linecard;
267 static bool devlink_linecard_index_exists(struct devlink *devlink,
268 unsigned int linecard_index)
270 return devlink_linecard_get_by_index(devlink, linecard_index);
273 static struct devlink_linecard *
274 devlink_linecard_get_from_attrs(struct devlink *devlink, struct nlattr **attrs)
276 if (attrs[DEVLINK_ATTR_LINECARD_INDEX]) {
277 u32 linecard_index = nla_get_u32(attrs[DEVLINK_ATTR_LINECARD_INDEX]);
278 struct devlink_linecard *linecard;
280 linecard = devlink_linecard_get_by_index(devlink, linecard_index);
282 return ERR_PTR(-ENODEV);
285 return ERR_PTR(-EINVAL);
288 struct devlink_linecard *
289 devlink_linecard_get_from_info(struct devlink *devlink, struct genl_info *info)
291 return devlink_linecard_get_from_attrs(devlink, info->attrs);
295 struct list_head list;
298 u16 ingress_pools_count;
299 u16 egress_pools_count;
300 u16 ingress_tc_count;
304 static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb)
306 return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count;
309 static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink,
310 unsigned int sb_index)
312 struct devlink_sb *devlink_sb;
314 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
315 if (devlink_sb->index == sb_index)
321 static bool devlink_sb_index_exists(struct devlink *devlink,
322 unsigned int sb_index)
324 return devlink_sb_get_by_index(devlink, sb_index);
327 static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink,
328 struct nlattr **attrs)
330 if (attrs[DEVLINK_ATTR_SB_INDEX]) {
331 u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]);
332 struct devlink_sb *devlink_sb;
334 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
336 return ERR_PTR(-ENODEV);
339 return ERR_PTR(-EINVAL);
342 static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink,
343 struct genl_info *info)
345 return devlink_sb_get_from_attrs(devlink, info->attrs);
348 static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb,
349 struct nlattr **attrs,
354 if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX])
357 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]);
358 if (val >= devlink_sb_pool_count(devlink_sb))
364 static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb,
365 struct genl_info *info,
368 return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs,
373 devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs,
374 enum devlink_sb_pool_type *p_pool_type)
378 if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE])
381 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]);
382 if (val != DEVLINK_SB_POOL_TYPE_INGRESS &&
383 val != DEVLINK_SB_POOL_TYPE_EGRESS)
390 devlink_sb_pool_type_get_from_info(struct genl_info *info,
391 enum devlink_sb_pool_type *p_pool_type)
393 return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type);
397 devlink_sb_th_type_get_from_attrs(struct nlattr **attrs,
398 enum devlink_sb_threshold_type *p_th_type)
402 if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])
405 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]);
406 if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC &&
407 val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC)
414 devlink_sb_th_type_get_from_info(struct genl_info *info,
415 enum devlink_sb_threshold_type *p_th_type)
417 return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type);
421 devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb,
422 struct nlattr **attrs,
423 enum devlink_sb_pool_type pool_type,
428 if (!attrs[DEVLINK_ATTR_SB_TC_INDEX])
431 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]);
432 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS &&
433 val >= devlink_sb->ingress_tc_count)
435 if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS &&
436 val >= devlink_sb->egress_tc_count)
442 static void devlink_port_fn_cap_fill(struct nla_bitfield32 *caps,
443 u32 cap, bool is_enable)
445 caps->selector |= cap;
450 static int devlink_port_fn_roce_fill(const struct devlink_ops *ops,
451 struct devlink_port *devlink_port,
452 struct nla_bitfield32 *caps,
453 struct netlink_ext_ack *extack)
458 if (!ops->port_fn_roce_get)
461 err = ops->port_fn_roce_get(devlink_port, &is_enable, extack);
463 if (err == -EOPNOTSUPP)
468 devlink_port_fn_cap_fill(caps, DEVLINK_PORT_FN_CAP_ROCE, is_enable);
472 static int devlink_port_fn_migratable_fill(const struct devlink_ops *ops,
473 struct devlink_port *devlink_port,
474 struct nla_bitfield32 *caps,
475 struct netlink_ext_ack *extack)
480 if (!ops->port_fn_migratable_get ||
481 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_PCI_VF)
484 err = ops->port_fn_migratable_get(devlink_port, &is_enable, extack);
486 if (err == -EOPNOTSUPP)
491 devlink_port_fn_cap_fill(caps, DEVLINK_PORT_FN_CAP_MIGRATABLE, is_enable);
495 static int devlink_port_fn_caps_fill(const struct devlink_ops *ops,
496 struct devlink_port *devlink_port,
498 struct netlink_ext_ack *extack,
501 struct nla_bitfield32 caps = {};
504 err = devlink_port_fn_roce_fill(ops, devlink_port, &caps, extack);
508 err = devlink_port_fn_migratable_fill(ops, devlink_port, &caps, extack);
514 err = nla_put_bitfield32(msg, DEVLINK_PORT_FN_ATTR_CAPS, caps.value,
524 devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
525 struct genl_info *info,
526 enum devlink_sb_pool_type pool_type,
529 return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs,
530 pool_type, p_tc_index);
533 struct devlink_region {
534 struct devlink *devlink;
535 struct devlink_port *port;
536 struct list_head list;
538 const struct devlink_region_ops *ops;
539 const struct devlink_port_region_ops *port_ops;
541 struct mutex snapshot_lock; /* protects snapshot_list,
542 * max_snapshots and cur_snapshots
545 struct list_head snapshot_list;
551 struct devlink_snapshot {
552 struct list_head list;
553 struct devlink_region *region;
558 static struct devlink_region *
559 devlink_region_get_by_name(struct devlink *devlink, const char *region_name)
561 struct devlink_region *region;
563 list_for_each_entry(region, &devlink->region_list, list)
564 if (!strcmp(region->ops->name, region_name))
570 static struct devlink_region *
571 devlink_port_region_get_by_name(struct devlink_port *port,
572 const char *region_name)
574 struct devlink_region *region;
576 list_for_each_entry(region, &port->region_list, list)
577 if (!strcmp(region->ops->name, region_name))
583 static struct devlink_snapshot *
584 devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id)
586 struct devlink_snapshot *snapshot;
588 list_for_each_entry(snapshot, ®ion->snapshot_list, list)
589 if (snapshot->id == id)
595 static int devlink_nl_put_nested_handle(struct sk_buff *msg, struct devlink *devlink)
597 struct nlattr *nested_attr;
599 nested_attr = nla_nest_start(msg, DEVLINK_ATTR_NESTED_DEVLINK);
602 if (devlink_nl_put_handle(msg, devlink))
603 goto nla_put_failure;
605 nla_nest_end(msg, nested_attr);
609 nla_nest_cancel(msg, nested_attr);
613 int devlink_nl_port_handle_fill(struct sk_buff *msg, struct devlink_port *devlink_port)
615 if (devlink_nl_put_handle(msg, devlink_port->devlink))
617 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
622 size_t devlink_nl_port_handle_size(struct devlink_port *devlink_port)
624 struct devlink *devlink = devlink_port->devlink;
626 return nla_total_size(strlen(devlink->dev->bus->name) + 1) /* DEVLINK_ATTR_BUS_NAME */
627 + nla_total_size(strlen(dev_name(devlink->dev)) + 1) /* DEVLINK_ATTR_DEV_NAME */
628 + nla_total_size(4); /* DEVLINK_ATTR_PORT_INDEX */
631 static int devlink_nl_port_attrs_put(struct sk_buff *msg,
632 struct devlink_port *devlink_port)
634 struct devlink_port_attrs *attrs = &devlink_port->attrs;
636 if (!devlink_port->attrs_set)
639 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_LANES, attrs->lanes))
642 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_SPLITTABLE, attrs->splittable))
644 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour))
646 switch (devlink_port->attrs.flavour) {
647 case DEVLINK_PORT_FLAVOUR_PCI_PF:
648 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
649 attrs->pci_pf.controller) ||
650 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_pf.pf))
652 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_pf.external))
655 case DEVLINK_PORT_FLAVOUR_PCI_VF:
656 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
657 attrs->pci_vf.controller) ||
658 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_vf.pf) ||
659 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_VF_NUMBER, attrs->pci_vf.vf))
661 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_vf.external))
664 case DEVLINK_PORT_FLAVOUR_PCI_SF:
665 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
666 attrs->pci_sf.controller) ||
667 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER,
669 nla_put_u32(msg, DEVLINK_ATTR_PORT_PCI_SF_NUMBER,
673 case DEVLINK_PORT_FLAVOUR_PHYSICAL:
674 case DEVLINK_PORT_FLAVOUR_CPU:
675 case DEVLINK_PORT_FLAVOUR_DSA:
676 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER,
677 attrs->phys.port_number))
681 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
682 attrs->phys.port_number))
684 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER,
685 attrs->phys.split_subport_number))
694 static int devlink_port_fn_hw_addr_fill(const struct devlink_ops *ops,
695 struct devlink_port *port,
697 struct netlink_ext_ack *extack,
700 u8 hw_addr[MAX_ADDR_LEN];
704 if (!ops->port_function_hw_addr_get)
707 err = ops->port_function_hw_addr_get(port, hw_addr, &hw_addr_len,
710 if (err == -EOPNOTSUPP)
714 err = nla_put(msg, DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR, hw_addr_len, hw_addr);
721 static int devlink_nl_rate_fill(struct sk_buff *msg,
722 struct devlink_rate *devlink_rate,
723 enum devlink_command cmd, u32 portid, u32 seq,
724 int flags, struct netlink_ext_ack *extack)
726 struct devlink *devlink = devlink_rate->devlink;
729 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
733 if (devlink_nl_put_handle(msg, devlink))
734 goto nla_put_failure;
736 if (nla_put_u16(msg, DEVLINK_ATTR_RATE_TYPE, devlink_rate->type))
737 goto nla_put_failure;
739 if (devlink_rate_is_leaf(devlink_rate)) {
740 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
741 devlink_rate->devlink_port->index))
742 goto nla_put_failure;
743 } else if (devlink_rate_is_node(devlink_rate)) {
744 if (nla_put_string(msg, DEVLINK_ATTR_RATE_NODE_NAME,
746 goto nla_put_failure;
749 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_RATE_TX_SHARE,
750 devlink_rate->tx_share, DEVLINK_ATTR_PAD))
751 goto nla_put_failure;
753 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_RATE_TX_MAX,
754 devlink_rate->tx_max, DEVLINK_ATTR_PAD))
755 goto nla_put_failure;
757 if (nla_put_u32(msg, DEVLINK_ATTR_RATE_TX_PRIORITY,
758 devlink_rate->tx_priority))
759 goto nla_put_failure;
761 if (nla_put_u32(msg, DEVLINK_ATTR_RATE_TX_WEIGHT,
762 devlink_rate->tx_weight))
763 goto nla_put_failure;
765 if (devlink_rate->parent)
766 if (nla_put_string(msg, DEVLINK_ATTR_RATE_PARENT_NODE_NAME,
767 devlink_rate->parent->name))
768 goto nla_put_failure;
770 genlmsg_end(msg, hdr);
774 genlmsg_cancel(msg, hdr);
779 devlink_port_fn_state_valid(enum devlink_port_fn_state state)
781 return state == DEVLINK_PORT_FN_STATE_INACTIVE ||
782 state == DEVLINK_PORT_FN_STATE_ACTIVE;
786 devlink_port_fn_opstate_valid(enum devlink_port_fn_opstate opstate)
788 return opstate == DEVLINK_PORT_FN_OPSTATE_DETACHED ||
789 opstate == DEVLINK_PORT_FN_OPSTATE_ATTACHED;
792 static int devlink_port_fn_state_fill(const struct devlink_ops *ops,
793 struct devlink_port *port,
795 struct netlink_ext_ack *extack,
798 enum devlink_port_fn_opstate opstate;
799 enum devlink_port_fn_state state;
802 if (!ops->port_fn_state_get)
805 err = ops->port_fn_state_get(port, &state, &opstate, extack);
807 if (err == -EOPNOTSUPP)
811 if (!devlink_port_fn_state_valid(state)) {
813 NL_SET_ERR_MSG(extack, "Invalid state read from driver");
816 if (!devlink_port_fn_opstate_valid(opstate)) {
818 NL_SET_ERR_MSG(extack, "Invalid operational state read from driver");
821 if (nla_put_u8(msg, DEVLINK_PORT_FN_ATTR_STATE, state) ||
822 nla_put_u8(msg, DEVLINK_PORT_FN_ATTR_OPSTATE, opstate))
829 devlink_port_fn_mig_set(struct devlink_port *devlink_port, bool enable,
830 struct netlink_ext_ack *extack)
832 const struct devlink_ops *ops = devlink_port->devlink->ops;
834 return ops->port_fn_migratable_set(devlink_port, enable, extack);
838 devlink_port_fn_roce_set(struct devlink_port *devlink_port, bool enable,
839 struct netlink_ext_ack *extack)
841 const struct devlink_ops *ops = devlink_port->devlink->ops;
843 return ops->port_fn_roce_set(devlink_port, enable, extack);
846 static int devlink_port_fn_caps_set(struct devlink_port *devlink_port,
847 const struct nlattr *attr,
848 struct netlink_ext_ack *extack)
850 struct nla_bitfield32 caps;
854 caps = nla_get_bitfield32(attr);
855 caps_value = caps.value & caps.selector;
856 if (caps.selector & DEVLINK_PORT_FN_CAP_ROCE) {
857 err = devlink_port_fn_roce_set(devlink_port,
858 caps_value & DEVLINK_PORT_FN_CAP_ROCE,
863 if (caps.selector & DEVLINK_PORT_FN_CAP_MIGRATABLE) {
864 err = devlink_port_fn_mig_set(devlink_port, caps_value &
865 DEVLINK_PORT_FN_CAP_MIGRATABLE,
874 devlink_nl_port_function_attrs_put(struct sk_buff *msg, struct devlink_port *port,
875 struct netlink_ext_ack *extack)
877 const struct devlink_ops *ops;
878 struct nlattr *function_attr;
879 bool msg_updated = false;
882 function_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PORT_FUNCTION);
886 ops = port->devlink->ops;
887 err = devlink_port_fn_hw_addr_fill(ops, port, msg, extack,
891 err = devlink_port_fn_caps_fill(ops, port, msg, extack,
895 err = devlink_port_fn_state_fill(ops, port, msg, extack, &msg_updated);
897 if (err || !msg_updated)
898 nla_nest_cancel(msg, function_attr);
900 nla_nest_end(msg, function_attr);
904 static int devlink_nl_port_fill(struct sk_buff *msg,
905 struct devlink_port *devlink_port,
906 enum devlink_command cmd, u32 portid, u32 seq,
907 int flags, struct netlink_ext_ack *extack)
909 struct devlink *devlink = devlink_port->devlink;
912 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
916 if (devlink_nl_put_handle(msg, devlink))
917 goto nla_put_failure;
918 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
919 goto nla_put_failure;
921 spin_lock_bh(&devlink_port->type_lock);
922 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
923 goto nla_put_failure_type_locked;
924 if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
925 nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
926 devlink_port->desired_type))
927 goto nla_put_failure_type_locked;
928 if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
929 if (devlink_port->type_eth.netdev &&
930 (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
931 devlink_port->type_eth.ifindex) ||
932 nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
933 devlink_port->type_eth.ifname)))
934 goto nla_put_failure_type_locked;
936 if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
937 struct ib_device *ibdev = devlink_port->type_ib.ibdev;
940 nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
942 goto nla_put_failure_type_locked;
944 spin_unlock_bh(&devlink_port->type_lock);
945 if (devlink_nl_port_attrs_put(msg, devlink_port))
946 goto nla_put_failure;
947 if (devlink_nl_port_function_attrs_put(msg, devlink_port, extack))
948 goto nla_put_failure;
949 if (devlink_port->linecard &&
950 nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX,
951 devlink_port->linecard->index))
952 goto nla_put_failure;
954 genlmsg_end(msg, hdr);
957 nla_put_failure_type_locked:
958 spin_unlock_bh(&devlink_port->type_lock);
960 genlmsg_cancel(msg, hdr);
964 static void devlink_port_notify(struct devlink_port *devlink_port,
965 enum devlink_command cmd)
967 struct devlink *devlink = devlink_port->devlink;
971 WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
973 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
976 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
980 err = devlink_nl_port_fill(msg, devlink_port, cmd, 0, 0, 0, NULL);
986 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
987 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
990 static void devlink_rate_notify(struct devlink_rate *devlink_rate,
991 enum devlink_command cmd)
993 struct devlink *devlink = devlink_rate->devlink;
997 WARN_ON(cmd != DEVLINK_CMD_RATE_NEW && cmd != DEVLINK_CMD_RATE_DEL);
999 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
1002 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1006 err = devlink_nl_rate_fill(msg, devlink_rate, cmd, 0, 0, 0, NULL);
1012 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
1013 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
1017 devlink_nl_cmd_rate_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
1018 struct netlink_callback *cb)
1020 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
1021 struct devlink_rate *devlink_rate;
1025 list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
1026 enum devlink_command cmd = DEVLINK_CMD_RATE_NEW;
1027 u32 id = NETLINK_CB(cb->skb).portid;
1029 if (idx < state->idx) {
1033 err = devlink_nl_rate_fill(msg, devlink_rate, cmd, id,
1046 const struct devlink_cmd devl_cmd_rate_get = {
1047 .dump_one = devlink_nl_cmd_rate_get_dump_one,
1050 static int devlink_nl_cmd_rate_get_doit(struct sk_buff *skb,
1051 struct genl_info *info)
1053 struct devlink_rate *devlink_rate = info->user_ptr[1];
1054 struct sk_buff *msg;
1057 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1061 err = devlink_nl_rate_fill(msg, devlink_rate, DEVLINK_CMD_RATE_NEW,
1062 info->snd_portid, info->snd_seq, 0,
1069 return genlmsg_reply(msg, info);
1073 devlink_rate_is_parent_node(struct devlink_rate *devlink_rate,
1074 struct devlink_rate *parent)
1077 if (parent == devlink_rate)
1079 parent = parent->parent;
1084 static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
1085 struct genl_info *info)
1087 struct devlink_port *devlink_port = info->user_ptr[1];
1088 struct sk_buff *msg;
1091 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1095 err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_PORT_NEW,
1096 info->snd_portid, info->snd_seq, 0,
1103 return genlmsg_reply(msg, info);
1107 devlink_nl_cmd_port_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
1108 struct netlink_callback *cb)
1110 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
1111 struct devlink_port *devlink_port;
1112 unsigned long port_index;
1116 xa_for_each(&devlink->ports, port_index, devlink_port) {
1117 if (idx < state->idx) {
1121 err = devlink_nl_port_fill(msg, devlink_port,
1123 NETLINK_CB(cb->skb).portid,
1125 NLM_F_MULTI, cb->extack);
1136 const struct devlink_cmd devl_cmd_port_get = {
1137 .dump_one = devlink_nl_cmd_port_get_dump_one,
1140 static int devlink_port_type_set(struct devlink_port *devlink_port,
1141 enum devlink_port_type port_type)
1146 if (!devlink_port->devlink->ops->port_type_set)
1149 if (port_type == devlink_port->type)
1152 err = devlink_port->devlink->ops->port_type_set(devlink_port,
1157 devlink_port->desired_type = port_type;
1158 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
1162 static int devlink_port_function_hw_addr_set(struct devlink_port *port,
1163 const struct nlattr *attr,
1164 struct netlink_ext_ack *extack)
1166 const struct devlink_ops *ops = port->devlink->ops;
1170 hw_addr = nla_data(attr);
1171 hw_addr_len = nla_len(attr);
1172 if (hw_addr_len > MAX_ADDR_LEN) {
1173 NL_SET_ERR_MSG(extack, "Port function hardware address too long");
1176 if (port->type == DEVLINK_PORT_TYPE_ETH) {
1177 if (hw_addr_len != ETH_ALEN) {
1178 NL_SET_ERR_MSG(extack, "Address must be 6 bytes for Ethernet device");
1181 if (!is_unicast_ether_addr(hw_addr)) {
1182 NL_SET_ERR_MSG(extack, "Non-unicast hardware address unsupported");
1187 return ops->port_function_hw_addr_set(port, hw_addr, hw_addr_len,
1191 static int devlink_port_fn_state_set(struct devlink_port *port,
1192 const struct nlattr *attr,
1193 struct netlink_ext_ack *extack)
1195 enum devlink_port_fn_state state;
1196 const struct devlink_ops *ops;
1198 state = nla_get_u8(attr);
1199 ops = port->devlink->ops;
1200 return ops->port_fn_state_set(port, state, extack);
1203 static int devlink_port_function_validate(struct devlink_port *devlink_port,
1205 struct netlink_ext_ack *extack)
1207 const struct devlink_ops *ops = devlink_port->devlink->ops;
1208 struct nlattr *attr;
1210 if (tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] &&
1211 !ops->port_function_hw_addr_set) {
1212 NL_SET_ERR_MSG_ATTR(extack, tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR],
1213 "Port doesn't support function attributes");
1216 if (tb[DEVLINK_PORT_FN_ATTR_STATE] && !ops->port_fn_state_set) {
1217 NL_SET_ERR_MSG_ATTR(extack, tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR],
1218 "Function does not support state setting");
1221 attr = tb[DEVLINK_PORT_FN_ATTR_CAPS];
1223 struct nla_bitfield32 caps;
1225 caps = nla_get_bitfield32(attr);
1226 if (caps.selector & DEVLINK_PORT_FN_CAP_ROCE &&
1227 !ops->port_fn_roce_set) {
1228 NL_SET_ERR_MSG_ATTR(extack, attr,
1229 "Port doesn't support RoCE function attribute");
1232 if (caps.selector & DEVLINK_PORT_FN_CAP_MIGRATABLE) {
1233 if (!ops->port_fn_migratable_set) {
1234 NL_SET_ERR_MSG_ATTR(extack, attr,
1235 "Port doesn't support migratable function attribute");
1238 if (devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_PCI_VF) {
1239 NL_SET_ERR_MSG_ATTR(extack, attr,
1240 "migratable function attribute supported for VFs only");
1248 static int devlink_port_function_set(struct devlink_port *port,
1249 const struct nlattr *attr,
1250 struct netlink_ext_ack *extack)
1252 struct nlattr *tb[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1];
1255 err = nla_parse_nested(tb, DEVLINK_PORT_FUNCTION_ATTR_MAX, attr,
1256 devlink_function_nl_policy, extack);
1258 NL_SET_ERR_MSG(extack, "Fail to parse port function attributes");
1262 err = devlink_port_function_validate(port, tb, extack);
1266 attr = tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR];
1268 err = devlink_port_function_hw_addr_set(port, attr, extack);
1273 attr = tb[DEVLINK_PORT_FN_ATTR_CAPS];
1275 err = devlink_port_fn_caps_set(port, attr, extack);
1280 /* Keep this as the last function attribute set, so that when
1281 * multiple port function attributes are set along with state,
1282 * Those can be applied first before activating the state.
1284 attr = tb[DEVLINK_PORT_FN_ATTR_STATE];
1286 err = devlink_port_fn_state_set(port, attr, extack);
1289 devlink_port_notify(port, DEVLINK_CMD_PORT_NEW);
1293 static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
1294 struct genl_info *info)
1296 struct devlink_port *devlink_port = info->user_ptr[1];
1299 if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
1300 enum devlink_port_type port_type;
1302 port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
1303 err = devlink_port_type_set(devlink_port, port_type);
1308 if (info->attrs[DEVLINK_ATTR_PORT_FUNCTION]) {
1309 struct nlattr *attr = info->attrs[DEVLINK_ATTR_PORT_FUNCTION];
1310 struct netlink_ext_ack *extack = info->extack;
1312 err = devlink_port_function_set(devlink_port, attr, extack);
1320 static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
1321 struct genl_info *info)
1323 struct devlink_port *devlink_port = info->user_ptr[1];
1324 struct devlink *devlink = info->user_ptr[0];
1327 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PORT_SPLIT_COUNT))
1329 if (!devlink->ops->port_split)
1332 count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
1334 if (!devlink_port->attrs.splittable) {
1335 /* Split ports cannot be split. */
1336 if (devlink_port->attrs.split)
1337 NL_SET_ERR_MSG(info->extack, "Port cannot be split further");
1339 NL_SET_ERR_MSG(info->extack, "Port cannot be split");
1343 if (count < 2 || !is_power_of_2(count) || count > devlink_port->attrs.lanes) {
1344 NL_SET_ERR_MSG(info->extack, "Invalid split count");
1348 return devlink->ops->port_split(devlink, devlink_port, count,
1352 static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
1353 struct genl_info *info)
1355 struct devlink_port *devlink_port = info->user_ptr[1];
1356 struct devlink *devlink = info->user_ptr[0];
1358 if (!devlink->ops->port_unsplit)
1360 return devlink->ops->port_unsplit(devlink, devlink_port, info->extack);
1363 static int devlink_port_new_notify(struct devlink *devlink,
1364 unsigned int port_index,
1365 struct genl_info *info)
1367 struct devlink_port *devlink_port;
1368 struct sk_buff *msg;
1371 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1375 lockdep_assert_held(&devlink->lock);
1376 devlink_port = devlink_port_get_by_index(devlink, port_index);
1377 if (!devlink_port) {
1382 err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_NEW,
1383 info->snd_portid, info->snd_seq, 0, NULL);
1387 return genlmsg_reply(msg, info);
1394 static int devlink_nl_cmd_port_new_doit(struct sk_buff *skb,
1395 struct genl_info *info)
1397 struct netlink_ext_ack *extack = info->extack;
1398 struct devlink_port_new_attrs new_attrs = {};
1399 struct devlink *devlink = info->user_ptr[0];
1400 unsigned int new_port_index;
1403 if (!devlink->ops->port_new || !devlink->ops->port_del)
1406 if (!info->attrs[DEVLINK_ATTR_PORT_FLAVOUR] ||
1407 !info->attrs[DEVLINK_ATTR_PORT_PCI_PF_NUMBER]) {
1408 NL_SET_ERR_MSG(extack, "Port flavour or PCI PF are not specified");
1411 new_attrs.flavour = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_FLAVOUR]);
1413 nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_PCI_PF_NUMBER]);
1415 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
1416 /* Port index of the new port being created by driver. */
1417 new_attrs.port_index =
1418 nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
1419 new_attrs.port_index_valid = true;
1421 if (info->attrs[DEVLINK_ATTR_PORT_CONTROLLER_NUMBER]) {
1422 new_attrs.controller =
1423 nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_CONTROLLER_NUMBER]);
1424 new_attrs.controller_valid = true;
1426 if (new_attrs.flavour == DEVLINK_PORT_FLAVOUR_PCI_SF &&
1427 info->attrs[DEVLINK_ATTR_PORT_PCI_SF_NUMBER]) {
1428 new_attrs.sfnum = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_PCI_SF_NUMBER]);
1429 new_attrs.sfnum_valid = true;
1432 err = devlink->ops->port_new(devlink, &new_attrs, extack,
1437 err = devlink_port_new_notify(devlink, new_port_index, info);
1438 if (err && err != -ENODEV) {
1439 /* Fail to send the response; destroy newly created port. */
1440 devlink->ops->port_del(devlink, new_port_index, extack);
1445 static int devlink_nl_cmd_port_del_doit(struct sk_buff *skb,
1446 struct genl_info *info)
1448 struct netlink_ext_ack *extack = info->extack;
1449 struct devlink *devlink = info->user_ptr[0];
1450 unsigned int port_index;
1452 if (!devlink->ops->port_del)
1455 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PORT_INDEX)) {
1456 NL_SET_ERR_MSG(extack, "Port index is not specified");
1459 port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
1461 return devlink->ops->port_del(devlink, port_index, extack);
1465 devlink_nl_rate_parent_node_set(struct devlink_rate *devlink_rate,
1466 struct genl_info *info,
1467 struct nlattr *nla_parent)
1469 struct devlink *devlink = devlink_rate->devlink;
1470 const char *parent_name = nla_data(nla_parent);
1471 const struct devlink_ops *ops = devlink->ops;
1472 size_t len = strlen(parent_name);
1473 struct devlink_rate *parent;
1474 int err = -EOPNOTSUPP;
1476 parent = devlink_rate->parent;
1478 if (parent && !len) {
1479 if (devlink_rate_is_leaf(devlink_rate))
1480 err = ops->rate_leaf_parent_set(devlink_rate, NULL,
1481 devlink_rate->priv, NULL,
1483 else if (devlink_rate_is_node(devlink_rate))
1484 err = ops->rate_node_parent_set(devlink_rate, NULL,
1485 devlink_rate->priv, NULL,
1490 refcount_dec(&parent->refcnt);
1491 devlink_rate->parent = NULL;
1493 parent = devlink_rate_node_get_by_name(devlink, parent_name);
1497 if (parent == devlink_rate) {
1498 NL_SET_ERR_MSG(info->extack, "Parent to self is not allowed");
1502 if (devlink_rate_is_node(devlink_rate) &&
1503 devlink_rate_is_parent_node(devlink_rate, parent->parent)) {
1504 NL_SET_ERR_MSG(info->extack, "Node is already a parent of parent node.");
1508 if (devlink_rate_is_leaf(devlink_rate))
1509 err = ops->rate_leaf_parent_set(devlink_rate, parent,
1510 devlink_rate->priv, parent->priv,
1512 else if (devlink_rate_is_node(devlink_rate))
1513 err = ops->rate_node_parent_set(devlink_rate, parent,
1514 devlink_rate->priv, parent->priv,
1519 if (devlink_rate->parent)
1520 /* we're reassigning to other parent in this case */
1521 refcount_dec(&devlink_rate->parent->refcnt);
1523 refcount_inc(&parent->refcnt);
1524 devlink_rate->parent = parent;
1530 static int devlink_nl_rate_set(struct devlink_rate *devlink_rate,
1531 const struct devlink_ops *ops,
1532 struct genl_info *info)
1534 struct nlattr *nla_parent, **attrs = info->attrs;
1535 int err = -EOPNOTSUPP;
1540 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE]) {
1541 rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_SHARE]);
1542 if (devlink_rate_is_leaf(devlink_rate))
1543 err = ops->rate_leaf_tx_share_set(devlink_rate, devlink_rate->priv,
1544 rate, info->extack);
1545 else if (devlink_rate_is_node(devlink_rate))
1546 err = ops->rate_node_tx_share_set(devlink_rate, devlink_rate->priv,
1547 rate, info->extack);
1550 devlink_rate->tx_share = rate;
1553 if (attrs[DEVLINK_ATTR_RATE_TX_MAX]) {
1554 rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_MAX]);
1555 if (devlink_rate_is_leaf(devlink_rate))
1556 err = ops->rate_leaf_tx_max_set(devlink_rate, devlink_rate->priv,
1557 rate, info->extack);
1558 else if (devlink_rate_is_node(devlink_rate))
1559 err = ops->rate_node_tx_max_set(devlink_rate, devlink_rate->priv,
1560 rate, info->extack);
1563 devlink_rate->tx_max = rate;
1566 if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY]) {
1567 priority = nla_get_u32(attrs[DEVLINK_ATTR_RATE_TX_PRIORITY]);
1568 if (devlink_rate_is_leaf(devlink_rate))
1569 err = ops->rate_leaf_tx_priority_set(devlink_rate, devlink_rate->priv,
1570 priority, info->extack);
1571 else if (devlink_rate_is_node(devlink_rate))
1572 err = ops->rate_node_tx_priority_set(devlink_rate, devlink_rate->priv,
1573 priority, info->extack);
1577 devlink_rate->tx_priority = priority;
1580 if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT]) {
1581 weight = nla_get_u32(attrs[DEVLINK_ATTR_RATE_TX_WEIGHT]);
1582 if (devlink_rate_is_leaf(devlink_rate))
1583 err = ops->rate_leaf_tx_weight_set(devlink_rate, devlink_rate->priv,
1584 weight, info->extack);
1585 else if (devlink_rate_is_node(devlink_rate))
1586 err = ops->rate_node_tx_weight_set(devlink_rate, devlink_rate->priv,
1587 weight, info->extack);
1591 devlink_rate->tx_weight = weight;
1594 nla_parent = attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME];
1596 err = devlink_nl_rate_parent_node_set(devlink_rate, info,
1605 static bool devlink_rate_set_ops_supported(const struct devlink_ops *ops,
1606 struct genl_info *info,
1607 enum devlink_rate_type type)
1609 struct nlattr **attrs = info->attrs;
1611 if (type == DEVLINK_RATE_TYPE_LEAF) {
1612 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_leaf_tx_share_set) {
1613 NL_SET_ERR_MSG(info->extack, "TX share set isn't supported for the leafs");
1616 if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_leaf_tx_max_set) {
1617 NL_SET_ERR_MSG(info->extack, "TX max set isn't supported for the leafs");
1620 if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] &&
1621 !ops->rate_leaf_parent_set) {
1622 NL_SET_ERR_MSG(info->extack, "Parent set isn't supported for the leafs");
1625 if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY] && !ops->rate_leaf_tx_priority_set) {
1626 NL_SET_ERR_MSG_ATTR(info->extack,
1627 attrs[DEVLINK_ATTR_RATE_TX_PRIORITY],
1628 "TX priority set isn't supported for the leafs");
1631 if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT] && !ops->rate_leaf_tx_weight_set) {
1632 NL_SET_ERR_MSG_ATTR(info->extack,
1633 attrs[DEVLINK_ATTR_RATE_TX_WEIGHT],
1634 "TX weight set isn't supported for the leafs");
1637 } else if (type == DEVLINK_RATE_TYPE_NODE) {
1638 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_node_tx_share_set) {
1639 NL_SET_ERR_MSG(info->extack, "TX share set isn't supported for the nodes");
1642 if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_node_tx_max_set) {
1643 NL_SET_ERR_MSG(info->extack, "TX max set isn't supported for the nodes");
1646 if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] &&
1647 !ops->rate_node_parent_set) {
1648 NL_SET_ERR_MSG(info->extack, "Parent set isn't supported for the nodes");
1651 if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY] && !ops->rate_node_tx_priority_set) {
1652 NL_SET_ERR_MSG_ATTR(info->extack,
1653 attrs[DEVLINK_ATTR_RATE_TX_PRIORITY],
1654 "TX priority set isn't supported for the nodes");
1657 if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT] && !ops->rate_node_tx_weight_set) {
1658 NL_SET_ERR_MSG_ATTR(info->extack,
1659 attrs[DEVLINK_ATTR_RATE_TX_WEIGHT],
1660 "TX weight set isn't supported for the nodes");
1664 WARN(1, "Unknown type of rate object");
1671 static int devlink_nl_cmd_rate_set_doit(struct sk_buff *skb,
1672 struct genl_info *info)
1674 struct devlink_rate *devlink_rate = info->user_ptr[1];
1675 struct devlink *devlink = devlink_rate->devlink;
1676 const struct devlink_ops *ops = devlink->ops;
1679 if (!ops || !devlink_rate_set_ops_supported(ops, info, devlink_rate->type))
1682 err = devlink_nl_rate_set(devlink_rate, ops, info);
1685 devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW);
1689 static int devlink_nl_cmd_rate_new_doit(struct sk_buff *skb,
1690 struct genl_info *info)
1692 struct devlink *devlink = info->user_ptr[0];
1693 struct devlink_rate *rate_node;
1694 const struct devlink_ops *ops;
1698 if (!ops || !ops->rate_node_new || !ops->rate_node_del) {
1699 NL_SET_ERR_MSG(info->extack, "Rate nodes aren't supported");
1703 if (!devlink_rate_set_ops_supported(ops, info, DEVLINK_RATE_TYPE_NODE))
1706 rate_node = devlink_rate_node_get_from_attrs(devlink, info->attrs);
1707 if (!IS_ERR(rate_node))
1709 else if (rate_node == ERR_PTR(-EINVAL))
1712 rate_node = kzalloc(sizeof(*rate_node), GFP_KERNEL);
1716 rate_node->devlink = devlink;
1717 rate_node->type = DEVLINK_RATE_TYPE_NODE;
1718 rate_node->name = nla_strdup(info->attrs[DEVLINK_ATTR_RATE_NODE_NAME], GFP_KERNEL);
1719 if (!rate_node->name) {
1724 err = ops->rate_node_new(rate_node, &rate_node->priv, info->extack);
1728 err = devlink_nl_rate_set(rate_node, ops, info);
1732 refcount_set(&rate_node->refcnt, 1);
1733 list_add(&rate_node->list, &devlink->rate_list);
1734 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
1738 ops->rate_node_del(rate_node, rate_node->priv, info->extack);
1740 kfree(rate_node->name);
1746 static int devlink_nl_cmd_rate_del_doit(struct sk_buff *skb,
1747 struct genl_info *info)
1749 struct devlink_rate *rate_node = info->user_ptr[1];
1750 struct devlink *devlink = rate_node->devlink;
1751 const struct devlink_ops *ops = devlink->ops;
1754 if (refcount_read(&rate_node->refcnt) > 1) {
1755 NL_SET_ERR_MSG(info->extack, "Node has children. Cannot delete node.");
1759 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL);
1760 err = ops->rate_node_del(rate_node, rate_node->priv, info->extack);
1761 if (rate_node->parent)
1762 refcount_dec(&rate_node->parent->refcnt);
1763 list_del(&rate_node->list);
1764 kfree(rate_node->name);
1769 struct devlink_linecard_type {
1774 static int devlink_nl_linecard_fill(struct sk_buff *msg,
1775 struct devlink *devlink,
1776 struct devlink_linecard *linecard,
1777 enum devlink_command cmd, u32 portid,
1779 struct netlink_ext_ack *extack)
1781 struct devlink_linecard_type *linecard_type;
1782 struct nlattr *attr;
1786 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1790 if (devlink_nl_put_handle(msg, devlink))
1791 goto nla_put_failure;
1792 if (nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX, linecard->index))
1793 goto nla_put_failure;
1794 if (nla_put_u8(msg, DEVLINK_ATTR_LINECARD_STATE, linecard->state))
1795 goto nla_put_failure;
1796 if (linecard->type &&
1797 nla_put_string(msg, DEVLINK_ATTR_LINECARD_TYPE, linecard->type))
1798 goto nla_put_failure;
1800 if (linecard->types_count) {
1801 attr = nla_nest_start(msg,
1802 DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES);
1804 goto nla_put_failure;
1805 for (i = 0; i < linecard->types_count; i++) {
1806 linecard_type = &linecard->types[i];
1807 if (nla_put_string(msg, DEVLINK_ATTR_LINECARD_TYPE,
1808 linecard_type->type)) {
1809 nla_nest_cancel(msg, attr);
1810 goto nla_put_failure;
1813 nla_nest_end(msg, attr);
1816 if (linecard->nested_devlink &&
1817 devlink_nl_put_nested_handle(msg, linecard->nested_devlink))
1818 goto nla_put_failure;
1820 genlmsg_end(msg, hdr);
1824 genlmsg_cancel(msg, hdr);
1828 static void devlink_linecard_notify(struct devlink_linecard *linecard,
1829 enum devlink_command cmd)
1831 struct devlink *devlink = linecard->devlink;
1832 struct sk_buff *msg;
1835 WARN_ON(cmd != DEVLINK_CMD_LINECARD_NEW &&
1836 cmd != DEVLINK_CMD_LINECARD_DEL);
1838 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
1841 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1845 err = devlink_nl_linecard_fill(msg, devlink, linecard, cmd, 0, 0, 0,
1852 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
1853 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
1856 static int devlink_nl_cmd_linecard_get_doit(struct sk_buff *skb,
1857 struct genl_info *info)
1859 struct devlink_linecard *linecard = info->user_ptr[1];
1860 struct devlink *devlink = linecard->devlink;
1861 struct sk_buff *msg;
1864 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1868 mutex_lock(&linecard->state_lock);
1869 err = devlink_nl_linecard_fill(msg, devlink, linecard,
1870 DEVLINK_CMD_LINECARD_NEW,
1871 info->snd_portid, info->snd_seq, 0,
1873 mutex_unlock(&linecard->state_lock);
1879 return genlmsg_reply(msg, info);
1882 static int devlink_nl_cmd_linecard_get_dump_one(struct sk_buff *msg,
1883 struct devlink *devlink,
1884 struct netlink_callback *cb)
1886 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
1887 struct devlink_linecard *linecard;
1891 list_for_each_entry(linecard, &devlink->linecard_list, list) {
1892 if (idx < state->idx) {
1896 mutex_lock(&linecard->state_lock);
1897 err = devlink_nl_linecard_fill(msg, devlink, linecard,
1898 DEVLINK_CMD_LINECARD_NEW,
1899 NETLINK_CB(cb->skb).portid,
1903 mutex_unlock(&linecard->state_lock);
1914 const struct devlink_cmd devl_cmd_linecard_get = {
1915 .dump_one = devlink_nl_cmd_linecard_get_dump_one,
1918 static struct devlink_linecard_type *
1919 devlink_linecard_type_lookup(struct devlink_linecard *linecard,
1922 struct devlink_linecard_type *linecard_type;
1925 for (i = 0; i < linecard->types_count; i++) {
1926 linecard_type = &linecard->types[i];
1927 if (!strcmp(type, linecard_type->type))
1928 return linecard_type;
1933 static int devlink_linecard_type_set(struct devlink_linecard *linecard,
1935 struct netlink_ext_ack *extack)
1937 const struct devlink_linecard_ops *ops = linecard->ops;
1938 struct devlink_linecard_type *linecard_type;
1941 mutex_lock(&linecard->state_lock);
1942 if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING) {
1943 NL_SET_ERR_MSG(extack, "Line card is currently being provisioned");
1947 if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONING) {
1948 NL_SET_ERR_MSG(extack, "Line card is currently being unprovisioned");
1953 linecard_type = devlink_linecard_type_lookup(linecard, type);
1954 if (!linecard_type) {
1955 NL_SET_ERR_MSG(extack, "Unsupported line card type provided");
1960 if (linecard->state != DEVLINK_LINECARD_STATE_UNPROVISIONED &&
1961 linecard->state != DEVLINK_LINECARD_STATE_PROVISIONING_FAILED) {
1962 NL_SET_ERR_MSG(extack, "Line card already provisioned");
1964 /* Check if the line card is provisioned in the same
1965 * way the user asks. In case it is, make the operation
1966 * to return success.
1968 if (ops->same_provision &&
1969 ops->same_provision(linecard, linecard->priv,
1970 linecard_type->type,
1971 linecard_type->priv))
1976 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING;
1977 linecard->type = linecard_type->type;
1978 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
1979 mutex_unlock(&linecard->state_lock);
1980 err = ops->provision(linecard, linecard->priv, linecard_type->type,
1981 linecard_type->priv, extack);
1983 /* Provisioning failed. Assume the linecard is unprovisioned
1984 * for future operations.
1986 mutex_lock(&linecard->state_lock);
1987 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
1988 linecard->type = NULL;
1989 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
1990 mutex_unlock(&linecard->state_lock);
1995 mutex_unlock(&linecard->state_lock);
1999 static int devlink_linecard_type_unset(struct devlink_linecard *linecard,
2000 struct netlink_ext_ack *extack)
2004 mutex_lock(&linecard->state_lock);
2005 if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING) {
2006 NL_SET_ERR_MSG(extack, "Line card is currently being provisioned");
2010 if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONING) {
2011 NL_SET_ERR_MSG(extack, "Line card is currently being unprovisioned");
2015 if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING_FAILED) {
2016 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
2017 linecard->type = NULL;
2018 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
2023 if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONED) {
2024 NL_SET_ERR_MSG(extack, "Line card is not provisioned");
2028 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONING;
2029 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
2030 mutex_unlock(&linecard->state_lock);
2031 err = linecard->ops->unprovision(linecard, linecard->priv,
2034 /* Unprovisioning failed. Assume the linecard is unprovisioned
2035 * for future operations.
2037 mutex_lock(&linecard->state_lock);
2038 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
2039 linecard->type = NULL;
2040 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
2041 mutex_unlock(&linecard->state_lock);
2046 mutex_unlock(&linecard->state_lock);
2050 static int devlink_nl_cmd_linecard_set_doit(struct sk_buff *skb,
2051 struct genl_info *info)
2053 struct devlink_linecard *linecard = info->user_ptr[1];
2054 struct netlink_ext_ack *extack = info->extack;
2057 if (info->attrs[DEVLINK_ATTR_LINECARD_TYPE]) {
2060 type = nla_data(info->attrs[DEVLINK_ATTR_LINECARD_TYPE]);
2061 if (strcmp(type, "")) {
2062 err = devlink_linecard_type_set(linecard, type, extack);
2066 err = devlink_linecard_type_unset(linecard, extack);
2075 static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
2076 struct devlink_sb *devlink_sb,
2077 enum devlink_command cmd, u32 portid,
2082 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2086 if (devlink_nl_put_handle(msg, devlink))
2087 goto nla_put_failure;
2088 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
2089 goto nla_put_failure;
2090 if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size))
2091 goto nla_put_failure;
2092 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT,
2093 devlink_sb->ingress_pools_count))
2094 goto nla_put_failure;
2095 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT,
2096 devlink_sb->egress_pools_count))
2097 goto nla_put_failure;
2098 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT,
2099 devlink_sb->ingress_tc_count))
2100 goto nla_put_failure;
2101 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT,
2102 devlink_sb->egress_tc_count))
2103 goto nla_put_failure;
2105 genlmsg_end(msg, hdr);
2109 genlmsg_cancel(msg, hdr);
2113 static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb,
2114 struct genl_info *info)
2116 struct devlink *devlink = info->user_ptr[0];
2117 struct devlink_sb *devlink_sb;
2118 struct sk_buff *msg;
2121 devlink_sb = devlink_sb_get_from_info(devlink, info);
2122 if (IS_ERR(devlink_sb))
2123 return PTR_ERR(devlink_sb);
2125 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2129 err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
2131 info->snd_portid, info->snd_seq, 0);
2137 return genlmsg_reply(msg, info);
2141 devlink_nl_cmd_sb_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
2142 struct netlink_callback *cb)
2144 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
2145 struct devlink_sb *devlink_sb;
2149 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
2150 if (idx < state->idx) {
2154 err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
2156 NETLINK_CB(cb->skb).portid,
2169 const struct devlink_cmd devl_cmd_sb_get = {
2170 .dump_one = devlink_nl_cmd_sb_get_dump_one,
2173 static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink,
2174 struct devlink_sb *devlink_sb,
2175 u16 pool_index, enum devlink_command cmd,
2176 u32 portid, u32 seq, int flags)
2178 struct devlink_sb_pool_info pool_info;
2182 err = devlink->ops->sb_pool_get(devlink, devlink_sb->index,
2183 pool_index, &pool_info);
2187 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2191 if (devlink_nl_put_handle(msg, devlink))
2192 goto nla_put_failure;
2193 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
2194 goto nla_put_failure;
2195 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
2196 goto nla_put_failure;
2197 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type))
2198 goto nla_put_failure;
2199 if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size))
2200 goto nla_put_failure;
2201 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE,
2202 pool_info.threshold_type))
2203 goto nla_put_failure;
2204 if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_CELL_SIZE,
2205 pool_info.cell_size))
2206 goto nla_put_failure;
2208 genlmsg_end(msg, hdr);
2212 genlmsg_cancel(msg, hdr);
2216 static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb,
2217 struct genl_info *info)
2219 struct devlink *devlink = info->user_ptr[0];
2220 struct devlink_sb *devlink_sb;
2221 struct sk_buff *msg;
2225 devlink_sb = devlink_sb_get_from_info(devlink, info);
2226 if (IS_ERR(devlink_sb))
2227 return PTR_ERR(devlink_sb);
2229 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2234 if (!devlink->ops->sb_pool_get)
2237 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2241 err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index,
2242 DEVLINK_CMD_SB_POOL_NEW,
2243 info->snd_portid, info->snd_seq, 0);
2249 return genlmsg_reply(msg, info);
2252 static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
2253 struct devlink *devlink,
2254 struct devlink_sb *devlink_sb,
2255 u32 portid, u32 seq)
2257 u16 pool_count = devlink_sb_pool_count(devlink_sb);
2261 for (pool_index = 0; pool_index < pool_count; pool_index++) {
2262 if (*p_idx < start) {
2266 err = devlink_nl_sb_pool_fill(msg, devlink,
2269 DEVLINK_CMD_SB_POOL_NEW,
2270 portid, seq, NLM_F_MULTI);
2279 devlink_nl_cmd_sb_pool_get_dump_one(struct sk_buff *msg,
2280 struct devlink *devlink,
2281 struct netlink_callback *cb)
2283 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
2284 struct devlink_sb *devlink_sb;
2288 if (!devlink->ops->sb_pool_get)
2291 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
2292 err = __sb_pool_get_dumpit(msg, state->idx, &idx,
2293 devlink, devlink_sb,
2294 NETLINK_CB(cb->skb).portid,
2295 cb->nlh->nlmsg_seq);
2296 if (err == -EOPNOTSUPP) {
2307 const struct devlink_cmd devl_cmd_sb_pool_get = {
2308 .dump_one = devlink_nl_cmd_sb_pool_get_dump_one,
2311 static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
2312 u16 pool_index, u32 size,
2313 enum devlink_sb_threshold_type threshold_type,
2314 struct netlink_ext_ack *extack)
2317 const struct devlink_ops *ops = devlink->ops;
2319 if (ops->sb_pool_set)
2320 return ops->sb_pool_set(devlink, sb_index, pool_index,
2321 size, threshold_type, extack);
2325 static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb,
2326 struct genl_info *info)
2328 struct devlink *devlink = info->user_ptr[0];
2329 enum devlink_sb_threshold_type threshold_type;
2330 struct devlink_sb *devlink_sb;
2335 devlink_sb = devlink_sb_get_from_info(devlink, info);
2336 if (IS_ERR(devlink_sb))
2337 return PTR_ERR(devlink_sb);
2339 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2344 err = devlink_sb_th_type_get_from_info(info, &threshold_type);
2348 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_POOL_SIZE))
2351 size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]);
2352 return devlink_sb_pool_set(devlink, devlink_sb->index,
2353 pool_index, size, threshold_type,
2357 static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg,
2358 struct devlink *devlink,
2359 struct devlink_port *devlink_port,
2360 struct devlink_sb *devlink_sb,
2362 enum devlink_command cmd,
2363 u32 portid, u32 seq, int flags)
2365 const struct devlink_ops *ops = devlink->ops;
2370 err = ops->sb_port_pool_get(devlink_port, devlink_sb->index,
2371 pool_index, &threshold);
2375 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2379 if (devlink_nl_put_handle(msg, devlink))
2380 goto nla_put_failure;
2381 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
2382 goto nla_put_failure;
2383 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
2384 goto nla_put_failure;
2385 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
2386 goto nla_put_failure;
2387 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
2388 goto nla_put_failure;
2390 if (ops->sb_occ_port_pool_get) {
2394 err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index,
2395 pool_index, &cur, &max);
2396 if (err && err != -EOPNOTSUPP)
2397 goto sb_occ_get_failure;
2399 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
2400 goto nla_put_failure;
2401 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
2402 goto nla_put_failure;
2406 genlmsg_end(msg, hdr);
2412 genlmsg_cancel(msg, hdr);
2416 static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,
2417 struct genl_info *info)
2419 struct devlink_port *devlink_port = info->user_ptr[1];
2420 struct devlink *devlink = devlink_port->devlink;
2421 struct devlink_sb *devlink_sb;
2422 struct sk_buff *msg;
2426 devlink_sb = devlink_sb_get_from_info(devlink, info);
2427 if (IS_ERR(devlink_sb))
2428 return PTR_ERR(devlink_sb);
2430 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2435 if (!devlink->ops->sb_port_pool_get)
2438 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2442 err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port,
2443 devlink_sb, pool_index,
2444 DEVLINK_CMD_SB_PORT_POOL_NEW,
2445 info->snd_portid, info->snd_seq, 0);
2451 return genlmsg_reply(msg, info);
2454 static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
2455 struct devlink *devlink,
2456 struct devlink_sb *devlink_sb,
2457 u32 portid, u32 seq)
2459 struct devlink_port *devlink_port;
2460 u16 pool_count = devlink_sb_pool_count(devlink_sb);
2461 unsigned long port_index;
2465 xa_for_each(&devlink->ports, port_index, devlink_port) {
2466 for (pool_index = 0; pool_index < pool_count; pool_index++) {
2467 if (*p_idx < start) {
2471 err = devlink_nl_sb_port_pool_fill(msg, devlink,
2475 DEVLINK_CMD_SB_PORT_POOL_NEW,
2487 devlink_nl_cmd_sb_port_pool_get_dump_one(struct sk_buff *msg,
2488 struct devlink *devlink,
2489 struct netlink_callback *cb)
2491 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
2492 struct devlink_sb *devlink_sb;
2496 if (!devlink->ops->sb_port_pool_get)
2499 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
2500 err = __sb_port_pool_get_dumpit(msg, state->idx, &idx,
2501 devlink, devlink_sb,
2502 NETLINK_CB(cb->skb).portid,
2503 cb->nlh->nlmsg_seq);
2504 if (err == -EOPNOTSUPP) {
2515 const struct devlink_cmd devl_cmd_sb_port_pool_get = {
2516 .dump_one = devlink_nl_cmd_sb_port_pool_get_dump_one,
2519 static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
2520 unsigned int sb_index, u16 pool_index,
2522 struct netlink_ext_ack *extack)
2525 const struct devlink_ops *ops = devlink_port->devlink->ops;
2527 if (ops->sb_port_pool_set)
2528 return ops->sb_port_pool_set(devlink_port, sb_index,
2529 pool_index, threshold, extack);
2533 static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb,
2534 struct genl_info *info)
2536 struct devlink_port *devlink_port = info->user_ptr[1];
2537 struct devlink *devlink = info->user_ptr[0];
2538 struct devlink_sb *devlink_sb;
2543 devlink_sb = devlink_sb_get_from_info(devlink, info);
2544 if (IS_ERR(devlink_sb))
2545 return PTR_ERR(devlink_sb);
2547 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2552 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_THRESHOLD))
2555 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
2556 return devlink_sb_port_pool_set(devlink_port, devlink_sb->index,
2557 pool_index, threshold, info->extack);
2561 devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink,
2562 struct devlink_port *devlink_port,
2563 struct devlink_sb *devlink_sb, u16 tc_index,
2564 enum devlink_sb_pool_type pool_type,
2565 enum devlink_command cmd,
2566 u32 portid, u32 seq, int flags)
2568 const struct devlink_ops *ops = devlink->ops;
2574 err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index,
2575 tc_index, pool_type,
2576 &pool_index, &threshold);
2580 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2584 if (devlink_nl_put_handle(msg, devlink))
2585 goto nla_put_failure;
2586 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
2587 goto nla_put_failure;
2588 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
2589 goto nla_put_failure;
2590 if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index))
2591 goto nla_put_failure;
2592 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type))
2593 goto nla_put_failure;
2594 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
2595 goto nla_put_failure;
2596 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
2597 goto nla_put_failure;
2599 if (ops->sb_occ_tc_port_bind_get) {
2603 err = ops->sb_occ_tc_port_bind_get(devlink_port,
2605 tc_index, pool_type,
2607 if (err && err != -EOPNOTSUPP)
2610 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
2611 goto nla_put_failure;
2612 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
2613 goto nla_put_failure;
2617 genlmsg_end(msg, hdr);
2621 genlmsg_cancel(msg, hdr);
2625 static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,
2626 struct genl_info *info)
2628 struct devlink_port *devlink_port = info->user_ptr[1];
2629 struct devlink *devlink = devlink_port->devlink;
2630 struct devlink_sb *devlink_sb;
2631 struct sk_buff *msg;
2632 enum devlink_sb_pool_type pool_type;
2636 devlink_sb = devlink_sb_get_from_info(devlink, info);
2637 if (IS_ERR(devlink_sb))
2638 return PTR_ERR(devlink_sb);
2640 err = devlink_sb_pool_type_get_from_info(info, &pool_type);
2644 err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
2645 pool_type, &tc_index);
2649 if (!devlink->ops->sb_tc_pool_bind_get)
2652 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2656 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port,
2657 devlink_sb, tc_index, pool_type,
2658 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
2666 return genlmsg_reply(msg, info);
2669 static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
2670 int start, int *p_idx,
2671 struct devlink *devlink,
2672 struct devlink_sb *devlink_sb,
2673 u32 portid, u32 seq)
2675 struct devlink_port *devlink_port;
2676 unsigned long port_index;
2680 xa_for_each(&devlink->ports, port_index, devlink_port) {
2682 tc_index < devlink_sb->ingress_tc_count; tc_index++) {
2683 if (*p_idx < start) {
2687 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
2691 DEVLINK_SB_POOL_TYPE_INGRESS,
2692 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
2700 tc_index < devlink_sb->egress_tc_count; tc_index++) {
2701 if (*p_idx < start) {
2705 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
2709 DEVLINK_SB_POOL_TYPE_EGRESS,
2710 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
2722 devlink_nl_cmd_sb_tc_pool_bind_get_dump_one(struct sk_buff *msg,
2723 struct devlink *devlink,
2724 struct netlink_callback *cb)
2726 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
2727 struct devlink_sb *devlink_sb;
2731 if (!devlink->ops->sb_tc_pool_bind_get)
2734 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
2735 err = __sb_tc_pool_bind_get_dumpit(msg, state->idx, &idx,
2736 devlink, devlink_sb,
2737 NETLINK_CB(cb->skb).portid,
2738 cb->nlh->nlmsg_seq);
2739 if (err == -EOPNOTSUPP) {
2750 const struct devlink_cmd devl_cmd_sb_tc_pool_bind_get = {
2751 .dump_one = devlink_nl_cmd_sb_tc_pool_bind_get_dump_one,
2754 static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port,
2755 unsigned int sb_index, u16 tc_index,
2756 enum devlink_sb_pool_type pool_type,
2757 u16 pool_index, u32 threshold,
2758 struct netlink_ext_ack *extack)
2761 const struct devlink_ops *ops = devlink_port->devlink->ops;
2763 if (ops->sb_tc_pool_bind_set)
2764 return ops->sb_tc_pool_bind_set(devlink_port, sb_index,
2765 tc_index, pool_type,
2766 pool_index, threshold, extack);
2770 static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb,
2771 struct genl_info *info)
2773 struct devlink_port *devlink_port = info->user_ptr[1];
2774 struct devlink *devlink = info->user_ptr[0];
2775 enum devlink_sb_pool_type pool_type;
2776 struct devlink_sb *devlink_sb;
2782 devlink_sb = devlink_sb_get_from_info(devlink, info);
2783 if (IS_ERR(devlink_sb))
2784 return PTR_ERR(devlink_sb);
2786 err = devlink_sb_pool_type_get_from_info(info, &pool_type);
2790 err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
2791 pool_type, &tc_index);
2795 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2800 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_THRESHOLD))
2803 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
2804 return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index,
2805 tc_index, pool_type,
2806 pool_index, threshold, info->extack);
2809 static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
2810 struct genl_info *info)
2812 struct devlink *devlink = info->user_ptr[0];
2813 const struct devlink_ops *ops = devlink->ops;
2814 struct devlink_sb *devlink_sb;
2816 devlink_sb = devlink_sb_get_from_info(devlink, info);
2817 if (IS_ERR(devlink_sb))
2818 return PTR_ERR(devlink_sb);
2820 if (ops->sb_occ_snapshot)
2821 return ops->sb_occ_snapshot(devlink, devlink_sb->index);
2825 static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
2826 struct genl_info *info)
2828 struct devlink *devlink = info->user_ptr[0];
2829 const struct devlink_ops *ops = devlink->ops;
2830 struct devlink_sb *devlink_sb;
2832 devlink_sb = devlink_sb_get_from_info(devlink, info);
2833 if (IS_ERR(devlink_sb))
2834 return PTR_ERR(devlink_sb);
2836 if (ops->sb_occ_max_clear)
2837 return ops->sb_occ_max_clear(devlink, devlink_sb->index);
2841 int devlink_rate_nodes_check(struct devlink *devlink, u16 mode,
2842 struct netlink_ext_ack *extack)
2844 struct devlink_rate *devlink_rate;
2846 list_for_each_entry(devlink_rate, &devlink->rate_list, list)
2847 if (devlink_rate_is_node(devlink_rate)) {
2848 NL_SET_ERR_MSG(extack, "Rate node(s) exists.");
2854 int devlink_dpipe_match_put(struct sk_buff *skb,
2855 struct devlink_dpipe_match *match)
2857 struct devlink_dpipe_header *header = match->header;
2858 struct devlink_dpipe_field *field = &header->fields[match->field_id];
2859 struct nlattr *match_attr;
2861 match_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_MATCH);
2865 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) ||
2866 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) ||
2867 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
2868 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
2869 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
2870 goto nla_put_failure;
2872 nla_nest_end(skb, match_attr);
2876 nla_nest_cancel(skb, match_attr);
2879 EXPORT_SYMBOL_GPL(devlink_dpipe_match_put);
2881 static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table,
2882 struct sk_buff *skb)
2884 struct nlattr *matches_attr;
2886 matches_attr = nla_nest_start_noflag(skb,
2887 DEVLINK_ATTR_DPIPE_TABLE_MATCHES);
2891 if (table->table_ops->matches_dump(table->priv, skb))
2892 goto nla_put_failure;
2894 nla_nest_end(skb, matches_attr);
2898 nla_nest_cancel(skb, matches_attr);
2902 int devlink_dpipe_action_put(struct sk_buff *skb,
2903 struct devlink_dpipe_action *action)
2905 struct devlink_dpipe_header *header = action->header;
2906 struct devlink_dpipe_field *field = &header->fields[action->field_id];
2907 struct nlattr *action_attr;
2909 action_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ACTION);
2913 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) ||
2914 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) ||
2915 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
2916 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
2917 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
2918 goto nla_put_failure;
2920 nla_nest_end(skb, action_attr);
2924 nla_nest_cancel(skb, action_attr);
2927 EXPORT_SYMBOL_GPL(devlink_dpipe_action_put);
2929 static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table,
2930 struct sk_buff *skb)
2932 struct nlattr *actions_attr;
2934 actions_attr = nla_nest_start_noflag(skb,
2935 DEVLINK_ATTR_DPIPE_TABLE_ACTIONS);
2939 if (table->table_ops->actions_dump(table->priv, skb))
2940 goto nla_put_failure;
2942 nla_nest_end(skb, actions_attr);
2946 nla_nest_cancel(skb, actions_attr);
2950 static int devlink_dpipe_table_put(struct sk_buff *skb,
2951 struct devlink_dpipe_table *table)
2953 struct nlattr *table_attr;
2956 table_size = table->table_ops->size_get(table->priv);
2957 table_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLE);
2961 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) ||
2962 nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size,
2964 goto nla_put_failure;
2965 if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
2966 table->counters_enabled))
2967 goto nla_put_failure;
2969 if (table->resource_valid) {
2970 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID,
2971 table->resource_id, DEVLINK_ATTR_PAD) ||
2972 nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS,
2973 table->resource_units, DEVLINK_ATTR_PAD))
2974 goto nla_put_failure;
2976 if (devlink_dpipe_matches_put(table, skb))
2977 goto nla_put_failure;
2979 if (devlink_dpipe_actions_put(table, skb))
2980 goto nla_put_failure;
2982 nla_nest_end(skb, table_attr);
2986 nla_nest_cancel(skb, table_attr);
2990 static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb,
2991 struct genl_info *info)
2996 err = genlmsg_reply(*pskb, info);
3000 *pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
3006 static int devlink_dpipe_tables_fill(struct genl_info *info,
3007 enum devlink_command cmd, int flags,
3008 struct list_head *dpipe_tables,
3009 const char *table_name)
3011 struct devlink *devlink = info->user_ptr[0];
3012 struct devlink_dpipe_table *table;
3013 struct nlattr *tables_attr;
3014 struct sk_buff *skb = NULL;
3015 struct nlmsghdr *nlh;
3021 table = list_first_entry(dpipe_tables,
3022 struct devlink_dpipe_table, list);
3024 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3028 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
3029 &devlink_nl_family, NLM_F_MULTI, cmd);
3035 if (devlink_nl_put_handle(skb, devlink))
3036 goto nla_put_failure;
3037 tables_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLES);
3039 goto nla_put_failure;
3043 list_for_each_entry_from(table, dpipe_tables, list) {
3045 err = devlink_dpipe_table_put(skb, table);
3053 if (!strcmp(table->name, table_name)) {
3054 err = devlink_dpipe_table_put(skb, table);
3062 nla_nest_end(skb, tables_attr);
3063 genlmsg_end(skb, hdr);
3068 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
3069 NLMSG_DONE, 0, flags | NLM_F_MULTI);
3071 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3077 return genlmsg_reply(skb, info);
3086 static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb,
3087 struct genl_info *info)
3089 struct devlink *devlink = info->user_ptr[0];
3090 const char *table_name = NULL;
3092 if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
3093 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
3095 return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0,
3096 &devlink->dpipe_table_list,
3100 static int devlink_dpipe_value_put(struct sk_buff *skb,
3101 struct devlink_dpipe_value *value)
3103 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE,
3104 value->value_size, value->value))
3107 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK,
3108 value->value_size, value->mask))
3110 if (value->mapping_valid)
3111 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING,
3112 value->mapping_value))
3117 static int devlink_dpipe_action_value_put(struct sk_buff *skb,
3118 struct devlink_dpipe_value *value)
3122 if (devlink_dpipe_action_put(skb, value->action))
3124 if (devlink_dpipe_value_put(skb, value))
3129 static int devlink_dpipe_action_values_put(struct sk_buff *skb,
3130 struct devlink_dpipe_value *values,
3131 unsigned int values_count)
3133 struct nlattr *action_attr;
3137 for (i = 0; i < values_count; i++) {
3138 action_attr = nla_nest_start_noflag(skb,
3139 DEVLINK_ATTR_DPIPE_ACTION_VALUE);
3142 err = devlink_dpipe_action_value_put(skb, &values[i]);
3144 goto err_action_value_put;
3145 nla_nest_end(skb, action_attr);
3149 err_action_value_put:
3150 nla_nest_cancel(skb, action_attr);
3154 static int devlink_dpipe_match_value_put(struct sk_buff *skb,
3155 struct devlink_dpipe_value *value)
3159 if (devlink_dpipe_match_put(skb, value->match))
3161 if (devlink_dpipe_value_put(skb, value))
3166 static int devlink_dpipe_match_values_put(struct sk_buff *skb,
3167 struct devlink_dpipe_value *values,
3168 unsigned int values_count)
3170 struct nlattr *match_attr;
3174 for (i = 0; i < values_count; i++) {
3175 match_attr = nla_nest_start_noflag(skb,
3176 DEVLINK_ATTR_DPIPE_MATCH_VALUE);
3179 err = devlink_dpipe_match_value_put(skb, &values[i]);
3181 goto err_match_value_put;
3182 nla_nest_end(skb, match_attr);
3186 err_match_value_put:
3187 nla_nest_cancel(skb, match_attr);
3191 static int devlink_dpipe_entry_put(struct sk_buff *skb,
3192 struct devlink_dpipe_entry *entry)
3194 struct nlattr *entry_attr, *matches_attr, *actions_attr;
3197 entry_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ENTRY);
3201 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index,
3203 goto nla_put_failure;
3204 if (entry->counter_valid)
3205 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER,
3206 entry->counter, DEVLINK_ATTR_PAD))
3207 goto nla_put_failure;
3209 matches_attr = nla_nest_start_noflag(skb,
3210 DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES);
3212 goto nla_put_failure;
3214 err = devlink_dpipe_match_values_put(skb, entry->match_values,
3215 entry->match_values_count);
3217 nla_nest_cancel(skb, matches_attr);
3218 goto err_match_values_put;
3220 nla_nest_end(skb, matches_attr);
3222 actions_attr = nla_nest_start_noflag(skb,
3223 DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES);
3225 goto nla_put_failure;
3227 err = devlink_dpipe_action_values_put(skb, entry->action_values,
3228 entry->action_values_count);
3230 nla_nest_cancel(skb, actions_attr);
3231 goto err_action_values_put;
3233 nla_nest_end(skb, actions_attr);
3235 nla_nest_end(skb, entry_attr);
3240 err_match_values_put:
3241 err_action_values_put:
3242 nla_nest_cancel(skb, entry_attr);
3246 static struct devlink_dpipe_table *
3247 devlink_dpipe_table_find(struct list_head *dpipe_tables,
3248 const char *table_name, struct devlink *devlink)
3250 struct devlink_dpipe_table *table;
3251 list_for_each_entry_rcu(table, dpipe_tables, list,
3252 lockdep_is_held(&devlink->lock)) {
3253 if (!strcmp(table->name, table_name))
3259 int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx)
3261 struct devlink *devlink;
3264 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb,
3269 dump_ctx->hdr = genlmsg_put(dump_ctx->skb,
3270 dump_ctx->info->snd_portid,
3271 dump_ctx->info->snd_seq,
3272 &devlink_nl_family, NLM_F_MULTI,
3275 goto nla_put_failure;
3277 devlink = dump_ctx->info->user_ptr[0];
3278 if (devlink_nl_put_handle(dump_ctx->skb, devlink))
3279 goto nla_put_failure;
3280 dump_ctx->nest = nla_nest_start_noflag(dump_ctx->skb,
3281 DEVLINK_ATTR_DPIPE_ENTRIES);
3282 if (!dump_ctx->nest)
3283 goto nla_put_failure;
3287 nlmsg_free(dump_ctx->skb);
3290 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare);
3292 int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx,
3293 struct devlink_dpipe_entry *entry)
3295 return devlink_dpipe_entry_put(dump_ctx->skb, entry);
3297 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append);
3299 int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx)
3301 nla_nest_end(dump_ctx->skb, dump_ctx->nest);
3302 genlmsg_end(dump_ctx->skb, dump_ctx->hdr);
3305 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close);
3307 void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry)
3310 unsigned int value_count, value_index;
3311 struct devlink_dpipe_value *value;
3313 value = entry->action_values;
3314 value_count = entry->action_values_count;
3315 for (value_index = 0; value_index < value_count; value_index++) {
3316 kfree(value[value_index].value);
3317 kfree(value[value_index].mask);
3320 value = entry->match_values;
3321 value_count = entry->match_values_count;
3322 for (value_index = 0; value_index < value_count; value_index++) {
3323 kfree(value[value_index].value);
3324 kfree(value[value_index].mask);
3327 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_clear);
3329 static int devlink_dpipe_entries_fill(struct genl_info *info,
3330 enum devlink_command cmd, int flags,
3331 struct devlink_dpipe_table *table)
3333 struct devlink_dpipe_dump_ctx dump_ctx;
3334 struct nlmsghdr *nlh;
3337 dump_ctx.skb = NULL;
3339 dump_ctx.info = info;
3341 err = table->table_ops->entries_dump(table->priv,
3342 table->counters_enabled,
3348 nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq,
3349 NLMSG_DONE, 0, flags | NLM_F_MULTI);
3351 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info);
3356 return genlmsg_reply(dump_ctx.skb, info);
3359 static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
3360 struct genl_info *info)
3362 struct devlink *devlink = info->user_ptr[0];
3363 struct devlink_dpipe_table *table;
3364 const char *table_name;
3366 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_DPIPE_TABLE_NAME))
3369 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
3370 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
3371 table_name, devlink);
3375 if (!table->table_ops->entries_dump)
3378 return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET,
3382 static int devlink_dpipe_fields_put(struct sk_buff *skb,
3383 const struct devlink_dpipe_header *header)
3385 struct devlink_dpipe_field *field;
3386 struct nlattr *field_attr;
3389 for (i = 0; i < header->fields_count; i++) {
3390 field = &header->fields[i];
3391 field_attr = nla_nest_start_noflag(skb,
3392 DEVLINK_ATTR_DPIPE_FIELD);
3395 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) ||
3396 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
3397 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) ||
3398 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type))
3399 goto nla_put_failure;
3400 nla_nest_end(skb, field_attr);
3405 nla_nest_cancel(skb, field_attr);
3409 static int devlink_dpipe_header_put(struct sk_buff *skb,
3410 struct devlink_dpipe_header *header)
3412 struct nlattr *fields_attr, *header_attr;
3415 header_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADER);
3419 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) ||
3420 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
3421 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
3422 goto nla_put_failure;
3424 fields_attr = nla_nest_start_noflag(skb,
3425 DEVLINK_ATTR_DPIPE_HEADER_FIELDS);
3427 goto nla_put_failure;
3429 err = devlink_dpipe_fields_put(skb, header);
3431 nla_nest_cancel(skb, fields_attr);
3432 goto nla_put_failure;
3434 nla_nest_end(skb, fields_attr);
3435 nla_nest_end(skb, header_attr);
3440 nla_nest_cancel(skb, header_attr);
3444 static int devlink_dpipe_headers_fill(struct genl_info *info,
3445 enum devlink_command cmd, int flags,
3446 struct devlink_dpipe_headers *
3449 struct devlink *devlink = info->user_ptr[0];
3450 struct nlattr *headers_attr;
3451 struct sk_buff *skb = NULL;
3452 struct nlmsghdr *nlh;
3459 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3463 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
3464 &devlink_nl_family, NLM_F_MULTI, cmd);
3470 if (devlink_nl_put_handle(skb, devlink))
3471 goto nla_put_failure;
3472 headers_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADERS);
3474 goto nla_put_failure;
3477 for (; i < dpipe_headers->headers_count; i++) {
3478 err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]);
3486 nla_nest_end(skb, headers_attr);
3487 genlmsg_end(skb, hdr);
3488 if (i != dpipe_headers->headers_count)
3492 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
3493 NLMSG_DONE, 0, flags | NLM_F_MULTI);
3495 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3500 return genlmsg_reply(skb, info);
3509 static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb,
3510 struct genl_info *info)
3512 struct devlink *devlink = info->user_ptr[0];
3514 if (!devlink->dpipe_headers)
3516 return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET,
3517 0, devlink->dpipe_headers);
3520 static int devlink_dpipe_table_counters_set(struct devlink *devlink,
3521 const char *table_name,
3524 struct devlink_dpipe_table *table;
3526 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
3527 table_name, devlink);
3531 if (table->counter_control_extern)
3534 if (!(table->counters_enabled ^ enable))
3537 table->counters_enabled = enable;
3538 if (table->table_ops->counters_set_update)
3539 table->table_ops->counters_set_update(table->priv, enable);
3543 static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb,
3544 struct genl_info *info)
3546 struct devlink *devlink = info->user_ptr[0];
3547 const char *table_name;
3548 bool counters_enable;
3550 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_DPIPE_TABLE_NAME) ||
3551 GENL_REQ_ATTR_CHECK(info,
3552 DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED))
3555 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
3556 counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]);
3558 return devlink_dpipe_table_counters_set(devlink, table_name,
3562 static struct devlink_resource *
3563 devlink_resource_find(struct devlink *devlink,
3564 struct devlink_resource *resource, u64 resource_id)
3566 struct list_head *resource_list;
3569 resource_list = &resource->resource_list;
3571 resource_list = &devlink->resource_list;
3573 list_for_each_entry(resource, resource_list, list) {
3574 struct devlink_resource *child_resource;
3576 if (resource->id == resource_id)
3579 child_resource = devlink_resource_find(devlink, resource,
3582 return child_resource;
3588 devlink_resource_validate_children(struct devlink_resource *resource)
3590 struct devlink_resource *child_resource;
3591 bool size_valid = true;
3594 if (list_empty(&resource->resource_list))
3597 list_for_each_entry(child_resource, &resource->resource_list, list)
3598 parts_size += child_resource->size_new;
3600 if (parts_size > resource->size_new)
3603 resource->size_valid = size_valid;
3607 devlink_resource_validate_size(struct devlink_resource *resource, u64 size,
3608 struct netlink_ext_ack *extack)
3613 if (size > resource->size_params.size_max) {
3614 NL_SET_ERR_MSG(extack, "Size larger than maximum");
3618 if (size < resource->size_params.size_min) {
3619 NL_SET_ERR_MSG(extack, "Size smaller than minimum");
3623 div64_u64_rem(size, resource->size_params.size_granularity, &reminder);
3625 NL_SET_ERR_MSG(extack, "Wrong granularity");
3632 static int devlink_nl_cmd_resource_set(struct sk_buff *skb,
3633 struct genl_info *info)
3635 struct devlink *devlink = info->user_ptr[0];
3636 struct devlink_resource *resource;
3641 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_RESOURCE_ID) ||
3642 GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_RESOURCE_SIZE))
3644 resource_id = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_ID]);
3646 resource = devlink_resource_find(devlink, NULL, resource_id);
3650 size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]);
3651 err = devlink_resource_validate_size(resource, size, info->extack);
3655 resource->size_new = size;
3656 devlink_resource_validate_children(resource);
3657 if (resource->parent)
3658 devlink_resource_validate_children(resource->parent);
3663 devlink_resource_size_params_put(struct devlink_resource *resource,
3664 struct sk_buff *skb)
3666 struct devlink_resource_size_params *size_params;
3668 size_params = &resource->size_params;
3669 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_GRAN,
3670 size_params->size_granularity, DEVLINK_ATTR_PAD) ||
3671 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MAX,
3672 size_params->size_max, DEVLINK_ATTR_PAD) ||
3673 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MIN,
3674 size_params->size_min, DEVLINK_ATTR_PAD) ||
3675 nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_UNIT, size_params->unit))
3680 static int devlink_resource_occ_put(struct devlink_resource *resource,
3681 struct sk_buff *skb)
3683 if (!resource->occ_get)
3685 return nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_OCC,
3686 resource->occ_get(resource->occ_get_priv),
3690 static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb,
3691 struct devlink_resource *resource)
3693 struct devlink_resource *child_resource;
3694 struct nlattr *child_resource_attr;
3695 struct nlattr *resource_attr;
3697 resource_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_RESOURCE);
3701 if (nla_put_string(skb, DEVLINK_ATTR_RESOURCE_NAME, resource->name) ||
3702 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE, resource->size,
3703 DEVLINK_ATTR_PAD) ||
3704 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_ID, resource->id,
3706 goto nla_put_failure;
3707 if (resource->size != resource->size_new &&
3708 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_NEW,
3709 resource->size_new, DEVLINK_ATTR_PAD))
3710 goto nla_put_failure;
3711 if (devlink_resource_occ_put(resource, skb))
3712 goto nla_put_failure;
3713 if (devlink_resource_size_params_put(resource, skb))
3714 goto nla_put_failure;
3715 if (list_empty(&resource->resource_list))
3718 if (nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_SIZE_VALID,
3719 resource->size_valid))
3720 goto nla_put_failure;
3722 child_resource_attr = nla_nest_start_noflag(skb,
3723 DEVLINK_ATTR_RESOURCE_LIST);
3724 if (!child_resource_attr)
3725 goto nla_put_failure;
3727 list_for_each_entry(child_resource, &resource->resource_list, list) {
3728 if (devlink_resource_put(devlink, skb, child_resource))
3729 goto resource_put_failure;
3732 nla_nest_end(skb, child_resource_attr);
3734 nla_nest_end(skb, resource_attr);
3737 resource_put_failure:
3738 nla_nest_cancel(skb, child_resource_attr);
3740 nla_nest_cancel(skb, resource_attr);
3744 static int devlink_resource_fill(struct genl_info *info,
3745 enum devlink_command cmd, int flags)
3747 struct devlink *devlink = info->user_ptr[0];
3748 struct devlink_resource *resource;
3749 struct nlattr *resources_attr;
3750 struct sk_buff *skb = NULL;
3751 struct nlmsghdr *nlh;
3757 resource = list_first_entry(&devlink->resource_list,
3758 struct devlink_resource, list);
3760 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3764 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
3765 &devlink_nl_family, NLM_F_MULTI, cmd);
3771 if (devlink_nl_put_handle(skb, devlink))
3772 goto nla_put_failure;
3774 resources_attr = nla_nest_start_noflag(skb,
3775 DEVLINK_ATTR_RESOURCE_LIST);
3776 if (!resources_attr)
3777 goto nla_put_failure;
3781 list_for_each_entry_from(resource, &devlink->resource_list, list) {
3782 err = devlink_resource_put(devlink, skb, resource);
3785 goto err_resource_put;
3791 nla_nest_end(skb, resources_attr);
3792 genlmsg_end(skb, hdr);
3796 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
3797 NLMSG_DONE, 0, flags | NLM_F_MULTI);
3799 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3804 return genlmsg_reply(skb, info);
3813 static int devlink_nl_cmd_resource_dump(struct sk_buff *skb,
3814 struct genl_info *info)
3816 struct devlink *devlink = info->user_ptr[0];
3818 if (list_empty(&devlink->resource_list))
3821 return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0);
3824 int devlink_resources_validate(struct devlink *devlink,
3825 struct devlink_resource *resource,
3826 struct genl_info *info)
3828 struct list_head *resource_list;
3832 resource_list = &resource->resource_list;
3834 resource_list = &devlink->resource_list;
3836 list_for_each_entry(resource, resource_list, list) {
3837 if (!resource->size_valid)
3839 err = devlink_resources_validate(devlink, resource, info);
3846 static const struct devlink_param devlink_param_generic[] = {
3848 .id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET,
3849 .name = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME,
3850 .type = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE,
3853 .id = DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
3854 .name = DEVLINK_PARAM_GENERIC_MAX_MACS_NAME,
3855 .type = DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE,
3858 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV,
3859 .name = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME,
3860 .type = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE,
3863 .id = DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT,
3864 .name = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME,
3865 .type = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE,
3868 .id = DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI,
3869 .name = DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME,
3870 .type = DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE,
3873 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX,
3874 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME,
3875 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE,
3878 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN,
3879 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME,
3880 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE,
3883 .id = DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY,
3884 .name = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME,
3885 .type = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE,
3888 .id = DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE,
3889 .name = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME,
3890 .type = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE,
3893 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE,
3894 .name = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_NAME,
3895 .type = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_TYPE,
3898 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_REMOTE_DEV_RESET,
3899 .name = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_NAME,
3900 .type = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_TYPE,
3903 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ETH,
3904 .name = DEVLINK_PARAM_GENERIC_ENABLE_ETH_NAME,
3905 .type = DEVLINK_PARAM_GENERIC_ENABLE_ETH_TYPE,
3908 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_RDMA,
3909 .name = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_NAME,
3910 .type = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_TYPE,
3913 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_VNET,
3914 .name = DEVLINK_PARAM_GENERIC_ENABLE_VNET_NAME,
3915 .type = DEVLINK_PARAM_GENERIC_ENABLE_VNET_TYPE,
3918 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_IWARP,
3919 .name = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_NAME,
3920 .type = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_TYPE,
3923 .id = DEVLINK_PARAM_GENERIC_ID_IO_EQ_SIZE,
3924 .name = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_NAME,
3925 .type = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_TYPE,
3928 .id = DEVLINK_PARAM_GENERIC_ID_EVENT_EQ_SIZE,
3929 .name = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_NAME,
3930 .type = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_TYPE,
3934 static int devlink_param_generic_verify(const struct devlink_param *param)
3936 /* verify it match generic parameter by id and name */
3937 if (param->id > DEVLINK_PARAM_GENERIC_ID_MAX)
3939 if (strcmp(param->name, devlink_param_generic[param->id].name))
3942 WARN_ON(param->type != devlink_param_generic[param->id].type);
3947 static int devlink_param_driver_verify(const struct devlink_param *param)
3951 if (param->id <= DEVLINK_PARAM_GENERIC_ID_MAX)
3953 /* verify no such name in generic params */
3954 for (i = 0; i <= DEVLINK_PARAM_GENERIC_ID_MAX; i++)
3955 if (!strcmp(param->name, devlink_param_generic[i].name))
3961 static struct devlink_param_item *
3962 devlink_param_find_by_name(struct list_head *param_list,
3963 const char *param_name)
3965 struct devlink_param_item *param_item;
3967 list_for_each_entry(param_item, param_list, list)
3968 if (!strcmp(param_item->param->name, param_name))
3973 static struct devlink_param_item *
3974 devlink_param_find_by_id(struct list_head *param_list, u32 param_id)
3976 struct devlink_param_item *param_item;
3978 list_for_each_entry(param_item, param_list, list)
3979 if (param_item->param->id == param_id)
3985 devlink_param_cmode_is_supported(const struct devlink_param *param,
3986 enum devlink_param_cmode cmode)
3988 return test_bit(cmode, ¶m->supported_cmodes);
3991 static int devlink_param_get(struct devlink *devlink,
3992 const struct devlink_param *param,
3993 struct devlink_param_gset_ctx *ctx)
3995 if (!param->get || devlink->reload_failed)
3997 return param->get(devlink, param->id, ctx);
4000 static int devlink_param_set(struct devlink *devlink,
4001 const struct devlink_param *param,
4002 struct devlink_param_gset_ctx *ctx)
4004 if (!param->set || devlink->reload_failed)
4006 return param->set(devlink, param->id, ctx);
4010 devlink_param_type_to_nla_type(enum devlink_param_type param_type)
4012 switch (param_type) {
4013 case DEVLINK_PARAM_TYPE_U8:
4015 case DEVLINK_PARAM_TYPE_U16:
4017 case DEVLINK_PARAM_TYPE_U32:
4019 case DEVLINK_PARAM_TYPE_STRING:
4021 case DEVLINK_PARAM_TYPE_BOOL:
4029 devlink_nl_param_value_fill_one(struct sk_buff *msg,
4030 enum devlink_param_type type,
4031 enum devlink_param_cmode cmode,
4032 union devlink_param_value val)
4034 struct nlattr *param_value_attr;
4036 param_value_attr = nla_nest_start_noflag(msg,
4037 DEVLINK_ATTR_PARAM_VALUE);
4038 if (!param_value_attr)
4039 goto nla_put_failure;
4041 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode))
4042 goto value_nest_cancel;
4045 case DEVLINK_PARAM_TYPE_U8:
4046 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu8))
4047 goto value_nest_cancel;
4049 case DEVLINK_PARAM_TYPE_U16:
4050 if (nla_put_u16(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu16))
4051 goto value_nest_cancel;
4053 case DEVLINK_PARAM_TYPE_U32:
4054 if (nla_put_u32(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu32))
4055 goto value_nest_cancel;
4057 case DEVLINK_PARAM_TYPE_STRING:
4058 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_VALUE_DATA,
4060 goto value_nest_cancel;
4062 case DEVLINK_PARAM_TYPE_BOOL:
4064 nla_put_flag(msg, DEVLINK_ATTR_PARAM_VALUE_DATA))
4065 goto value_nest_cancel;
4069 nla_nest_end(msg, param_value_attr);
4073 nla_nest_cancel(msg, param_value_attr);
4078 static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
4079 unsigned int port_index,
4080 struct devlink_param_item *param_item,
4081 enum devlink_command cmd,
4082 u32 portid, u32 seq, int flags)
4084 union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1];
4085 bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {};
4086 const struct devlink_param *param = param_item->param;
4087 struct devlink_param_gset_ctx ctx;
4088 struct nlattr *param_values_list;
4089 struct nlattr *param_attr;
4095 /* Get value from driver part to driverinit configuration mode */
4096 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
4097 if (!devlink_param_cmode_is_supported(param, i))
4099 if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) {
4100 if (!param_item->driverinit_value_valid)
4102 param_value[i] = param_item->driverinit_value;
4105 err = devlink_param_get(devlink, param, &ctx);
4108 param_value[i] = ctx.val;
4110 param_value_set[i] = true;
4113 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
4117 if (devlink_nl_put_handle(msg, devlink))
4118 goto genlmsg_cancel;
4120 if (cmd == DEVLINK_CMD_PORT_PARAM_GET ||
4121 cmd == DEVLINK_CMD_PORT_PARAM_NEW ||
4122 cmd == DEVLINK_CMD_PORT_PARAM_DEL)
4123 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index))
4124 goto genlmsg_cancel;
4126 param_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PARAM);
4128 goto genlmsg_cancel;
4129 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_NAME, param->name))
4130 goto param_nest_cancel;
4131 if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC))
4132 goto param_nest_cancel;
4134 nla_type = devlink_param_type_to_nla_type(param->type);
4136 goto param_nest_cancel;
4137 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, nla_type))
4138 goto param_nest_cancel;
4140 param_values_list = nla_nest_start_noflag(msg,
4141 DEVLINK_ATTR_PARAM_VALUES_LIST);
4142 if (!param_values_list)
4143 goto param_nest_cancel;
4145 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
4146 if (!param_value_set[i])
4148 err = devlink_nl_param_value_fill_one(msg, param->type,
4151 goto values_list_nest_cancel;
4154 nla_nest_end(msg, param_values_list);
4155 nla_nest_end(msg, param_attr);
4156 genlmsg_end(msg, hdr);
4159 values_list_nest_cancel:
4160 nla_nest_end(msg, param_values_list);
4162 nla_nest_cancel(msg, param_attr);
4164 genlmsg_cancel(msg, hdr);
4168 static void devlink_param_notify(struct devlink *devlink,
4169 unsigned int port_index,
4170 struct devlink_param_item *param_item,
4171 enum devlink_command cmd)
4173 struct sk_buff *msg;
4176 WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL &&
4177 cmd != DEVLINK_CMD_PORT_PARAM_NEW &&
4178 cmd != DEVLINK_CMD_PORT_PARAM_DEL);
4180 /* devlink_notify_register() / devlink_notify_unregister()
4181 * will replay the notifications if the params are added/removed
4182 * outside of the lifetime of the instance.
4184 if (!devl_is_registered(devlink))
4187 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4190 err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd,
4197 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
4198 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
4202 devlink_nl_cmd_param_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
4203 struct netlink_callback *cb)
4205 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
4206 struct devlink_param_item *param_item;
4210 list_for_each_entry(param_item, &devlink->param_list, list) {
4211 if (idx < state->idx) {
4215 err = devlink_nl_param_fill(msg, devlink, 0, param_item,
4216 DEVLINK_CMD_PARAM_GET,
4217 NETLINK_CB(cb->skb).portid,
4220 if (err == -EOPNOTSUPP) {
4232 const struct devlink_cmd devl_cmd_param_get = {
4233 .dump_one = devlink_nl_cmd_param_get_dump_one,
4237 devlink_param_type_get_from_info(struct genl_info *info,
4238 enum devlink_param_type *param_type)
4240 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_TYPE))
4243 switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) {
4245 *param_type = DEVLINK_PARAM_TYPE_U8;
4248 *param_type = DEVLINK_PARAM_TYPE_U16;
4251 *param_type = DEVLINK_PARAM_TYPE_U32;
4254 *param_type = DEVLINK_PARAM_TYPE_STRING;
4257 *param_type = DEVLINK_PARAM_TYPE_BOOL;
4267 devlink_param_value_get_from_info(const struct devlink_param *param,
4268 struct genl_info *info,
4269 union devlink_param_value *value)
4271 struct nlattr *param_data;
4274 param_data = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA];
4276 if (param->type != DEVLINK_PARAM_TYPE_BOOL && !param_data)
4279 switch (param->type) {
4280 case DEVLINK_PARAM_TYPE_U8:
4281 if (nla_len(param_data) != sizeof(u8))
4283 value->vu8 = nla_get_u8(param_data);
4285 case DEVLINK_PARAM_TYPE_U16:
4286 if (nla_len(param_data) != sizeof(u16))
4288 value->vu16 = nla_get_u16(param_data);
4290 case DEVLINK_PARAM_TYPE_U32:
4291 if (nla_len(param_data) != sizeof(u32))
4293 value->vu32 = nla_get_u32(param_data);
4295 case DEVLINK_PARAM_TYPE_STRING:
4296 len = strnlen(nla_data(param_data), nla_len(param_data));
4297 if (len == nla_len(param_data) ||
4298 len >= __DEVLINK_PARAM_MAX_STRING_VALUE)
4300 strcpy(value->vstr, nla_data(param_data));
4302 case DEVLINK_PARAM_TYPE_BOOL:
4303 if (param_data && nla_len(param_data))
4305 value->vbool = nla_get_flag(param_data);
4311 static struct devlink_param_item *
4312 devlink_param_get_from_info(struct list_head *param_list,
4313 struct genl_info *info)
4317 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_NAME))
4320 param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]);
4321 return devlink_param_find_by_name(param_list, param_name);
4324 static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb,
4325 struct genl_info *info)
4327 struct devlink *devlink = info->user_ptr[0];
4328 struct devlink_param_item *param_item;
4329 struct sk_buff *msg;
4332 param_item = devlink_param_get_from_info(&devlink->param_list, info);
4336 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4340 err = devlink_nl_param_fill(msg, devlink, 0, param_item,
4341 DEVLINK_CMD_PARAM_GET,
4342 info->snd_portid, info->snd_seq, 0);
4348 return genlmsg_reply(msg, info);
4351 static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink,
4352 unsigned int port_index,
4353 struct list_head *param_list,
4354 struct genl_info *info,
4355 enum devlink_command cmd)
4357 enum devlink_param_type param_type;
4358 struct devlink_param_gset_ctx ctx;
4359 enum devlink_param_cmode cmode;
4360 struct devlink_param_item *param_item;
4361 const struct devlink_param *param;
4362 union devlink_param_value value;
4365 param_item = devlink_param_get_from_info(param_list, info);
4368 param = param_item->param;
4369 err = devlink_param_type_get_from_info(info, ¶m_type);
4372 if (param_type != param->type)
4374 err = devlink_param_value_get_from_info(param, info, &value);
4377 if (param->validate) {
4378 err = param->validate(devlink, param->id, value, info->extack);
4383 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_VALUE_CMODE))
4385 cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]);
4386 if (!devlink_param_cmode_is_supported(param, cmode))
4389 if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) {
4390 if (param->type == DEVLINK_PARAM_TYPE_STRING)
4391 strcpy(param_item->driverinit_value.vstr, value.vstr);
4393 param_item->driverinit_value = value;
4394 param_item->driverinit_value_valid = true;
4400 err = devlink_param_set(devlink, param, &ctx);
4405 devlink_param_notify(devlink, port_index, param_item, cmd);
4409 static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb,
4410 struct genl_info *info)
4412 struct devlink *devlink = info->user_ptr[0];
4414 return __devlink_nl_cmd_param_set_doit(devlink, 0, &devlink->param_list,
4415 info, DEVLINK_CMD_PARAM_NEW);
4418 static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg,
4419 struct netlink_callback *cb)
4421 NL_SET_ERR_MSG(cb->extack, "Port params are not supported");
4425 static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb,
4426 struct genl_info *info)
4428 NL_SET_ERR_MSG(info->extack, "Port params are not supported");
4432 static int devlink_nl_cmd_port_param_set_doit(struct sk_buff *skb,
4433 struct genl_info *info)
4435 NL_SET_ERR_MSG(info->extack, "Port params are not supported");
4439 static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg,
4440 struct devlink *devlink,
4441 struct devlink_snapshot *snapshot)
4443 struct nlattr *snap_attr;
4446 snap_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_SNAPSHOT);
4450 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, snapshot->id);
4452 goto nla_put_failure;
4454 nla_nest_end(msg, snap_attr);
4458 nla_nest_cancel(msg, snap_attr);
4462 static int devlink_nl_region_snapshots_id_put(struct sk_buff *msg,
4463 struct devlink *devlink,
4464 struct devlink_region *region)
4466 struct devlink_snapshot *snapshot;
4467 struct nlattr *snapshots_attr;
4470 snapshots_attr = nla_nest_start_noflag(msg,
4471 DEVLINK_ATTR_REGION_SNAPSHOTS);
4472 if (!snapshots_attr)
4475 list_for_each_entry(snapshot, ®ion->snapshot_list, list) {
4476 err = devlink_nl_region_snapshot_id_put(msg, devlink, snapshot);
4478 goto nla_put_failure;
4481 nla_nest_end(msg, snapshots_attr);
4485 nla_nest_cancel(msg, snapshots_attr);
4489 static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink,
4490 enum devlink_command cmd, u32 portid,
4492 struct devlink_region *region)
4497 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
4501 err = devlink_nl_put_handle(msg, devlink);
4503 goto nla_put_failure;
4506 err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
4507 region->port->index);
4509 goto nla_put_failure;
4512 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->ops->name);
4514 goto nla_put_failure;
4516 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
4520 goto nla_put_failure;
4522 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_MAX_SNAPSHOTS,
4523 region->max_snapshots);
4525 goto nla_put_failure;
4527 err = devlink_nl_region_snapshots_id_put(msg, devlink, region);
4529 goto nla_put_failure;
4531 genlmsg_end(msg, hdr);
4535 genlmsg_cancel(msg, hdr);
4539 static struct sk_buff *
4540 devlink_nl_region_notify_build(struct devlink_region *region,
4541 struct devlink_snapshot *snapshot,
4542 enum devlink_command cmd, u32 portid, u32 seq)
4544 struct devlink *devlink = region->devlink;
4545 struct sk_buff *msg;
4550 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4552 return ERR_PTR(-ENOMEM);
4554 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, 0, cmd);
4560 err = devlink_nl_put_handle(msg, devlink);
4562 goto out_cancel_msg;
4565 err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
4566 region->port->index);
4568 goto out_cancel_msg;
4571 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME,
4574 goto out_cancel_msg;
4577 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID,
4580 goto out_cancel_msg;
4582 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
4583 region->size, DEVLINK_ATTR_PAD);
4585 goto out_cancel_msg;
4587 genlmsg_end(msg, hdr);
4592 genlmsg_cancel(msg, hdr);
4595 return ERR_PTR(err);
4598 static void devlink_nl_region_notify(struct devlink_region *region,
4599 struct devlink_snapshot *snapshot,
4600 enum devlink_command cmd)
4602 struct devlink *devlink = region->devlink;
4603 struct sk_buff *msg;
4605 WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL);
4606 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
4609 msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0);
4613 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
4614 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
4618 * __devlink_snapshot_id_increment - Increment number of snapshots using an id
4619 * @devlink: devlink instance
4620 * @id: the snapshot id
4622 * Track when a new snapshot begins using an id. Load the count for the
4623 * given id from the snapshot xarray, increment it, and store it back.
4625 * Called when a new snapshot is created with the given id.
4627 * The id *must* have been previously allocated by
4628 * devlink_region_snapshot_id_get().
4630 * Returns 0 on success, or an error on failure.
4632 static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id)
4634 unsigned long count;
4638 xa_lock(&devlink->snapshot_ids);
4639 p = xa_load(&devlink->snapshot_ids, id);
4645 if (WARN_ON(!xa_is_value(p))) {
4650 count = xa_to_value(p);
4653 err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
4656 xa_unlock(&devlink->snapshot_ids);
4661 * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id
4662 * @devlink: devlink instance
4663 * @id: the snapshot id
4665 * Track when a snapshot is deleted and stops using an id. Load the count
4666 * for the given id from the snapshot xarray, decrement it, and store it
4669 * If the count reaches zero, erase this id from the xarray, freeing it
4670 * up for future re-use by devlink_region_snapshot_id_get().
4672 * Called when a snapshot using the given id is deleted, and when the
4673 * initial allocator of the id is finished using it.
4675 static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id)
4677 unsigned long count;
4680 xa_lock(&devlink->snapshot_ids);
4681 p = xa_load(&devlink->snapshot_ids, id);
4685 if (WARN_ON(!xa_is_value(p)))
4688 count = xa_to_value(p);
4692 __xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
4695 /* If this was the last user, we can erase this id */
4696 __xa_erase(&devlink->snapshot_ids, id);
4699 xa_unlock(&devlink->snapshot_ids);
4703 * __devlink_snapshot_id_insert - Insert a specific snapshot ID
4704 * @devlink: devlink instance
4705 * @id: the snapshot id
4707 * Mark the given snapshot id as used by inserting a zero value into the
4710 * This must be called while holding the devlink instance lock. Unlike
4711 * devlink_snapshot_id_get, the initial reference count is zero, not one.
4712 * It is expected that the id will immediately be used before
4713 * releasing the devlink instance lock.
4715 * Returns zero on success, or an error code if the snapshot id could not
4718 static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id)
4722 xa_lock(&devlink->snapshot_ids);
4723 if (xa_load(&devlink->snapshot_ids, id)) {
4724 xa_unlock(&devlink->snapshot_ids);
4727 err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(0),
4729 xa_unlock(&devlink->snapshot_ids);
4734 * __devlink_region_snapshot_id_get - get snapshot ID
4735 * @devlink: devlink instance
4736 * @id: storage to return snapshot id
4738 * Allocates a new snapshot id. Returns zero on success, or a negative
4739 * error on failure. Must be called while holding the devlink instance
4742 * Snapshot IDs are tracked using an xarray which stores the number of
4743 * users of the snapshot id.
4745 * Note that the caller of this function counts as a 'user', in order to
4746 * avoid race conditions. The caller must release its hold on the
4747 * snapshot by using devlink_region_snapshot_id_put.
4749 static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
4751 return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1),
4752 xa_limit_32b, GFP_KERNEL);
4756 * __devlink_region_snapshot_create - create a new snapshot
4757 * This will add a new snapshot of a region. The snapshot
4758 * will be stored on the region struct and can be accessed
4759 * from devlink. This is useful for future analyses of snapshots.
4760 * Multiple snapshots can be created on a region.
4761 * The @snapshot_id should be obtained using the getter function.
4763 * Must be called only while holding the region snapshot lock.
4765 * @region: devlink region of the snapshot
4766 * @data: snapshot data
4767 * @snapshot_id: snapshot id to be created
4770 __devlink_region_snapshot_create(struct devlink_region *region,
4771 u8 *data, u32 snapshot_id)
4773 struct devlink *devlink = region->devlink;
4774 struct devlink_snapshot *snapshot;
4777 lockdep_assert_held(®ion->snapshot_lock);
4779 /* check if region can hold one more snapshot */
4780 if (region->cur_snapshots == region->max_snapshots)
4783 if (devlink_region_snapshot_get_by_id(region, snapshot_id))
4786 snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL);
4790 err = __devlink_snapshot_id_increment(devlink, snapshot_id);
4792 goto err_snapshot_id_increment;
4794 snapshot->id = snapshot_id;
4795 snapshot->region = region;
4796 snapshot->data = data;
4798 list_add_tail(&snapshot->list, ®ion->snapshot_list);
4800 region->cur_snapshots++;
4802 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW);
4805 err_snapshot_id_increment:
4810 static void devlink_region_snapshot_del(struct devlink_region *region,
4811 struct devlink_snapshot *snapshot)
4813 struct devlink *devlink = region->devlink;
4815 lockdep_assert_held(®ion->snapshot_lock);
4817 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL);
4818 region->cur_snapshots--;
4819 list_del(&snapshot->list);
4820 region->ops->destructor(snapshot->data);
4821 __devlink_snapshot_id_decrement(devlink, snapshot->id);
4825 static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb,
4826 struct genl_info *info)
4828 struct devlink *devlink = info->user_ptr[0];
4829 struct devlink_port *port = NULL;
4830 struct devlink_region *region;
4831 const char *region_name;
4832 struct sk_buff *msg;
4836 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME))
4839 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
4840 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
4842 port = devlink_port_get_by_index(devlink, index);
4847 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
4849 region = devlink_port_region_get_by_name(port, region_name);
4851 region = devlink_region_get_by_name(devlink, region_name);
4856 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4860 err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET,
4861 info->snd_portid, info->snd_seq, 0,
4868 return genlmsg_reply(msg, info);
4871 static int devlink_nl_cmd_region_get_port_dumpit(struct sk_buff *msg,
4872 struct netlink_callback *cb,
4873 struct devlink_port *port,
4877 struct devlink_region *region;
4880 list_for_each_entry(region, &port->region_list, list) {
4885 err = devlink_nl_region_fill(msg, port->devlink,
4886 DEVLINK_CMD_REGION_GET,
4887 NETLINK_CB(cb->skb).portid,
4889 NLM_F_MULTI, region);
4900 devlink_nl_cmd_region_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
4901 struct netlink_callback *cb)
4903 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
4904 struct devlink_region *region;
4905 struct devlink_port *port;
4906 unsigned long port_index;
4910 list_for_each_entry(region, &devlink->region_list, list) {
4911 if (idx < state->idx) {
4915 err = devlink_nl_region_fill(msg, devlink,
4916 DEVLINK_CMD_REGION_GET,
4917 NETLINK_CB(cb->skb).portid,
4919 NLM_F_MULTI, region);
4927 xa_for_each(&devlink->ports, port_index, port) {
4928 err = devlink_nl_cmd_region_get_port_dumpit(msg, cb, port, &idx,
4939 const struct devlink_cmd devl_cmd_region_get = {
4940 .dump_one = devlink_nl_cmd_region_get_dump_one,
4943 static int devlink_nl_cmd_region_del(struct sk_buff *skb,
4944 struct genl_info *info)
4946 struct devlink *devlink = info->user_ptr[0];
4947 struct devlink_snapshot *snapshot;
4948 struct devlink_port *port = NULL;
4949 struct devlink_region *region;
4950 const char *region_name;
4954 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME) ||
4955 GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_SNAPSHOT_ID))
4958 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
4959 snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
4961 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
4962 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
4964 port = devlink_port_get_by_index(devlink, index);
4970 region = devlink_port_region_get_by_name(port, region_name);
4972 region = devlink_region_get_by_name(devlink, region_name);
4977 mutex_lock(®ion->snapshot_lock);
4978 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
4980 mutex_unlock(®ion->snapshot_lock);
4984 devlink_region_snapshot_del(region, snapshot);
4985 mutex_unlock(®ion->snapshot_lock);
4990 devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
4992 struct devlink *devlink = info->user_ptr[0];
4993 struct devlink_snapshot *snapshot;
4994 struct devlink_port *port = NULL;
4995 struct nlattr *snapshot_id_attr;
4996 struct devlink_region *region;
4997 const char *region_name;
5003 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME)) {
5004 NL_SET_ERR_MSG(info->extack, "No region name provided");
5008 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
5010 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
5011 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
5013 port = devlink_port_get_by_index(devlink, index);
5019 region = devlink_port_region_get_by_name(port, region_name);
5021 region = devlink_region_get_by_name(devlink, region_name);
5024 NL_SET_ERR_MSG(info->extack, "The requested region does not exist");
5028 if (!region->ops->snapshot) {
5029 NL_SET_ERR_MSG(info->extack, "The requested region does not support taking an immediate snapshot");
5033 mutex_lock(®ion->snapshot_lock);
5035 if (region->cur_snapshots == region->max_snapshots) {
5036 NL_SET_ERR_MSG(info->extack, "The region has reached the maximum number of stored snapshots");
5041 snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID];
5042 if (snapshot_id_attr) {
5043 snapshot_id = nla_get_u32(snapshot_id_attr);
5045 if (devlink_region_snapshot_get_by_id(region, snapshot_id)) {
5046 NL_SET_ERR_MSG(info->extack, "The requested snapshot id is already in use");
5051 err = __devlink_snapshot_id_insert(devlink, snapshot_id);
5055 err = __devlink_region_snapshot_id_get(devlink, &snapshot_id);
5057 NL_SET_ERR_MSG(info->extack, "Failed to allocate a new snapshot id");
5063 err = region->port_ops->snapshot(port, region->port_ops,
5064 info->extack, &data);
5066 err = region->ops->snapshot(devlink, region->ops,
5067 info->extack, &data);
5069 goto err_snapshot_capture;
5071 err = __devlink_region_snapshot_create(region, data, snapshot_id);
5073 goto err_snapshot_create;
5075 if (!snapshot_id_attr) {
5076 struct sk_buff *msg;
5078 snapshot = devlink_region_snapshot_get_by_id(region,
5080 if (WARN_ON(!snapshot)) {
5085 msg = devlink_nl_region_notify_build(region, snapshot,
5086 DEVLINK_CMD_REGION_NEW,
5089 err = PTR_ERR_OR_ZERO(msg);
5093 err = genlmsg_reply(msg, info);
5098 mutex_unlock(®ion->snapshot_lock);
5101 err_snapshot_create:
5102 region->ops->destructor(data);
5103 err_snapshot_capture:
5104 __devlink_snapshot_id_decrement(devlink, snapshot_id);
5105 mutex_unlock(®ion->snapshot_lock);
5109 devlink_region_snapshot_del(region, snapshot);
5111 mutex_unlock(®ion->snapshot_lock);
5115 static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg,
5116 u8 *chunk, u32 chunk_size,
5119 struct nlattr *chunk_attr;
5122 chunk_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_CHUNK);
5126 err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk);
5128 goto nla_put_failure;
5130 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr,
5133 goto nla_put_failure;
5135 nla_nest_end(msg, chunk_attr);
5139 nla_nest_cancel(msg, chunk_attr);
5143 #define DEVLINK_REGION_READ_CHUNK_SIZE 256
5145 typedef int devlink_chunk_fill_t(void *cb_priv, u8 *chunk, u32 chunk_size,
5147 struct netlink_ext_ack *extack);
5150 devlink_nl_region_read_fill(struct sk_buff *skb, devlink_chunk_fill_t *cb,
5151 void *cb_priv, u64 start_offset, u64 end_offset,
5152 u64 *new_offset, struct netlink_ext_ack *extack)
5154 u64 curr_offset = start_offset;
5158 /* Allocate and re-use a single buffer */
5159 data = kmalloc(DEVLINK_REGION_READ_CHUNK_SIZE, GFP_KERNEL);
5163 *new_offset = start_offset;
5165 while (curr_offset < end_offset) {
5168 data_size = min_t(u32, end_offset - curr_offset,
5169 DEVLINK_REGION_READ_CHUNK_SIZE);
5171 err = cb(cb_priv, data, data_size, curr_offset, extack);
5175 err = devlink_nl_cmd_region_read_chunk_fill(skb, data, data_size, curr_offset);
5179 curr_offset += data_size;
5181 *new_offset = curr_offset;
5189 devlink_region_snapshot_fill(void *cb_priv, u8 *chunk, u32 chunk_size,
5191 struct netlink_ext_ack __always_unused *extack)
5193 struct devlink_snapshot *snapshot = cb_priv;
5195 memcpy(chunk, &snapshot->data[curr_offset], chunk_size);
5201 devlink_region_port_direct_fill(void *cb_priv, u8 *chunk, u32 chunk_size,
5202 u64 curr_offset, struct netlink_ext_ack *extack)
5204 struct devlink_region *region = cb_priv;
5206 return region->port_ops->read(region->port, region->port_ops, extack,
5207 curr_offset, chunk_size, chunk);
5211 devlink_region_direct_fill(void *cb_priv, u8 *chunk, u32 chunk_size,
5212 u64 curr_offset, struct netlink_ext_ack *extack)
5214 struct devlink_region *region = cb_priv;
5216 return region->ops->read(region->devlink, region->ops, extack,
5217 curr_offset, chunk_size, chunk);
5220 static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
5221 struct netlink_callback *cb)
5223 const struct genl_dumpit_info *info = genl_dumpit_info(cb);
5224 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
5225 struct nlattr *chunks_attr, *region_attr, *snapshot_attr;
5226 u64 ret_offset, start_offset, end_offset = U64_MAX;
5227 struct nlattr **attrs = info->attrs;
5228 struct devlink_port *port = NULL;
5229 devlink_chunk_fill_t *region_cb;
5230 struct devlink_region *region;
5231 const char *region_name;
5232 struct devlink *devlink;
5234 void *region_cb_priv;
5238 start_offset = state->start_offset;
5240 devlink = devlink_get_from_attrs_lock(sock_net(cb->skb->sk), attrs);
5241 if (IS_ERR(devlink))
5242 return PTR_ERR(devlink);
5244 if (!attrs[DEVLINK_ATTR_REGION_NAME]) {
5245 NL_SET_ERR_MSG(cb->extack, "No region name provided");
5250 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
5251 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
5253 port = devlink_port_get_by_index(devlink, index);
5260 region_attr = attrs[DEVLINK_ATTR_REGION_NAME];
5261 region_name = nla_data(region_attr);
5264 region = devlink_port_region_get_by_name(port, region_name);
5266 region = devlink_region_get_by_name(devlink, region_name);
5269 NL_SET_ERR_MSG_ATTR(cb->extack, region_attr, "Requested region does not exist");
5274 snapshot_attr = attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID];
5275 if (!snapshot_attr) {
5276 if (!nla_get_flag(attrs[DEVLINK_ATTR_REGION_DIRECT])) {
5277 NL_SET_ERR_MSG(cb->extack, "No snapshot id provided");
5282 if (!region->ops->read) {
5283 NL_SET_ERR_MSG(cb->extack, "Requested region does not support direct read");
5289 region_cb = &devlink_region_port_direct_fill;
5291 region_cb = &devlink_region_direct_fill;
5292 region_cb_priv = region;
5294 struct devlink_snapshot *snapshot;
5297 if (nla_get_flag(attrs[DEVLINK_ATTR_REGION_DIRECT])) {
5298 NL_SET_ERR_MSG_ATTR(cb->extack, snapshot_attr, "Direct region read does not use snapshot");
5303 snapshot_id = nla_get_u32(snapshot_attr);
5304 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
5306 NL_SET_ERR_MSG_ATTR(cb->extack, snapshot_attr, "Requested snapshot does not exist");
5310 region_cb = &devlink_region_snapshot_fill;
5311 region_cb_priv = snapshot;
5314 if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] &&
5315 attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) {
5318 nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
5320 end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
5321 end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]);
5324 if (end_offset > region->size)
5325 end_offset = region->size;
5327 /* return 0 if there is no further data to read */
5328 if (start_offset == end_offset) {
5333 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
5334 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI,
5335 DEVLINK_CMD_REGION_READ);
5341 err = devlink_nl_put_handle(skb, devlink);
5343 goto nla_put_failure;
5346 err = nla_put_u32(skb, DEVLINK_ATTR_PORT_INDEX,
5347 region->port->index);
5349 goto nla_put_failure;
5352 err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name);
5354 goto nla_put_failure;
5356 chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS);
5359 goto nla_put_failure;
5362 err = devlink_nl_region_read_fill(skb, region_cb, region_cb_priv,
5363 start_offset, end_offset, &ret_offset,
5366 if (err && err != -EMSGSIZE)
5367 goto nla_put_failure;
5369 /* Check if there was any progress done to prevent infinite loop */
5370 if (ret_offset == start_offset) {
5372 goto nla_put_failure;
5375 state->start_offset = ret_offset;
5377 nla_nest_end(skb, chunks_attr);
5378 genlmsg_end(skb, hdr);
5379 devl_unlock(devlink);
5380 devlink_put(devlink);
5384 genlmsg_cancel(skb, hdr);
5386 devl_unlock(devlink);
5387 devlink_put(devlink);
5391 struct devlink_fmsg_item {
5392 struct list_head list;
5399 struct devlink_fmsg {
5400 struct list_head item_list;
5401 bool putting_binary; /* This flag forces enclosing of binary data
5402 * in an array brackets. It forces using
5403 * of designated API:
5404 * devlink_fmsg_binary_pair_nest_start()
5405 * devlink_fmsg_binary_pair_nest_end()
5409 static struct devlink_fmsg *devlink_fmsg_alloc(void)
5411 struct devlink_fmsg *fmsg;
5413 fmsg = kzalloc(sizeof(*fmsg), GFP_KERNEL);
5417 INIT_LIST_HEAD(&fmsg->item_list);
5422 static void devlink_fmsg_free(struct devlink_fmsg *fmsg)
5424 struct devlink_fmsg_item *item, *tmp;
5426 list_for_each_entry_safe(item, tmp, &fmsg->item_list, list) {
5427 list_del(&item->list);
5433 static int devlink_fmsg_nest_common(struct devlink_fmsg *fmsg,
5436 struct devlink_fmsg_item *item;
5438 item = kzalloc(sizeof(*item), GFP_KERNEL);
5442 item->attrtype = attrtype;
5443 list_add_tail(&item->list, &fmsg->item_list);
5448 int devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg)
5450 if (fmsg->putting_binary)
5453 return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_OBJ_NEST_START);
5455 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start);
5457 static int devlink_fmsg_nest_end(struct devlink_fmsg *fmsg)
5459 if (fmsg->putting_binary)
5462 return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_NEST_END);
5465 int devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg)
5467 if (fmsg->putting_binary)
5470 return devlink_fmsg_nest_end(fmsg);
5472 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end);
5474 #define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN)
5476 static int devlink_fmsg_put_name(struct devlink_fmsg *fmsg, const char *name)
5478 struct devlink_fmsg_item *item;
5480 if (fmsg->putting_binary)
5483 if (strlen(name) + 1 > DEVLINK_FMSG_MAX_SIZE)
5486 item = kzalloc(sizeof(*item) + strlen(name) + 1, GFP_KERNEL);
5490 item->nla_type = NLA_NUL_STRING;
5491 item->len = strlen(name) + 1;
5492 item->attrtype = DEVLINK_ATTR_FMSG_OBJ_NAME;
5493 memcpy(&item->value, name, item->len);
5494 list_add_tail(&item->list, &fmsg->item_list);
5499 int devlink_fmsg_pair_nest_start(struct devlink_fmsg *fmsg, const char *name)
5503 if (fmsg->putting_binary)
5506 err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_PAIR_NEST_START);
5510 err = devlink_fmsg_put_name(fmsg, name);
5516 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start);
5518 int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg)
5520 if (fmsg->putting_binary)
5523 return devlink_fmsg_nest_end(fmsg);
5525 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end);
5527 int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg,
5532 if (fmsg->putting_binary)
5535 err = devlink_fmsg_pair_nest_start(fmsg, name);
5539 err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_ARR_NEST_START);
5545 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start);
5547 int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg)
5551 if (fmsg->putting_binary)
5554 err = devlink_fmsg_nest_end(fmsg);
5558 err = devlink_fmsg_nest_end(fmsg);
5564 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end);
5566 int devlink_fmsg_binary_pair_nest_start(struct devlink_fmsg *fmsg,
5571 err = devlink_fmsg_arr_pair_nest_start(fmsg, name);
5575 fmsg->putting_binary = true;
5578 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_start);
5580 int devlink_fmsg_binary_pair_nest_end(struct devlink_fmsg *fmsg)
5582 if (!fmsg->putting_binary)
5585 fmsg->putting_binary = false;
5586 return devlink_fmsg_arr_pair_nest_end(fmsg);
5588 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_end);
5590 static int devlink_fmsg_put_value(struct devlink_fmsg *fmsg,
5591 const void *value, u16 value_len,
5594 struct devlink_fmsg_item *item;
5596 if (value_len > DEVLINK_FMSG_MAX_SIZE)
5599 item = kzalloc(sizeof(*item) + value_len, GFP_KERNEL);
5603 item->nla_type = value_nla_type;
5604 item->len = value_len;
5605 item->attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
5606 memcpy(&item->value, value, item->len);
5607 list_add_tail(&item->list, &fmsg->item_list);
5612 static int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value)
5614 if (fmsg->putting_binary)
5617 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_FLAG);
5620 static int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value)
5622 if (fmsg->putting_binary)
5625 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U8);
5628 int devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value)
5630 if (fmsg->putting_binary)
5633 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U32);
5635 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put);
5637 static int devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value)
5639 if (fmsg->putting_binary)
5642 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U64);
5645 int devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value)
5647 if (fmsg->putting_binary)
5650 return devlink_fmsg_put_value(fmsg, value, strlen(value) + 1,
5653 EXPORT_SYMBOL_GPL(devlink_fmsg_string_put);
5655 int devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value,
5658 if (!fmsg->putting_binary)
5661 return devlink_fmsg_put_value(fmsg, value, value_len, NLA_BINARY);
5663 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put);
5665 int devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name,
5670 err = devlink_fmsg_pair_nest_start(fmsg, name);
5674 err = devlink_fmsg_bool_put(fmsg, value);
5678 err = devlink_fmsg_pair_nest_end(fmsg);
5684 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put);
5686 int devlink_fmsg_u8_pair_put(struct devlink_fmsg *fmsg, const char *name,
5691 err = devlink_fmsg_pair_nest_start(fmsg, name);
5695 err = devlink_fmsg_u8_put(fmsg, value);
5699 err = devlink_fmsg_pair_nest_end(fmsg);
5705 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put);
5707 int devlink_fmsg_u32_pair_put(struct devlink_fmsg *fmsg, const char *name,
5712 err = devlink_fmsg_pair_nest_start(fmsg, name);
5716 err = devlink_fmsg_u32_put(fmsg, value);
5720 err = devlink_fmsg_pair_nest_end(fmsg);
5726 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put);
5728 int devlink_fmsg_u64_pair_put(struct devlink_fmsg *fmsg, const char *name,
5733 err = devlink_fmsg_pair_nest_start(fmsg, name);
5737 err = devlink_fmsg_u64_put(fmsg, value);
5741 err = devlink_fmsg_pair_nest_end(fmsg);
5747 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put);
5749 int devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name,
5754 err = devlink_fmsg_pair_nest_start(fmsg, name);
5758 err = devlink_fmsg_string_put(fmsg, value);
5762 err = devlink_fmsg_pair_nest_end(fmsg);
5768 EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put);
5770 int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name,
5771 const void *value, u32 value_len)
5778 err = devlink_fmsg_binary_pair_nest_start(fmsg, name);
5782 for (offset = 0; offset < value_len; offset += data_size) {
5783 data_size = value_len - offset;
5784 if (data_size > DEVLINK_FMSG_MAX_SIZE)
5785 data_size = DEVLINK_FMSG_MAX_SIZE;
5786 err = devlink_fmsg_binary_put(fmsg, value + offset, data_size);
5789 /* Exit from loop with a break (instead of
5790 * return) to make sure putting_binary is turned off in
5791 * devlink_fmsg_binary_pair_nest_end
5795 end_err = devlink_fmsg_binary_pair_nest_end(fmsg);
5801 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put);
5804 devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb)
5806 switch (msg->nla_type) {
5811 case NLA_NUL_STRING:
5813 return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE,
5821 devlink_fmsg_item_fill_data(struct devlink_fmsg_item *msg, struct sk_buff *skb)
5823 int attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
5826 switch (msg->nla_type) {
5828 /* Always provide flag data, regardless of its value */
5829 tmp = *(bool *) msg->value;
5831 return nla_put_u8(skb, attrtype, tmp);
5833 return nla_put_u8(skb, attrtype, *(u8 *) msg->value);
5835 return nla_put_u32(skb, attrtype, *(u32 *) msg->value);
5837 return nla_put_u64_64bit(skb, attrtype, *(u64 *) msg->value,
5839 case NLA_NUL_STRING:
5840 return nla_put_string(skb, attrtype, (char *) &msg->value);
5842 return nla_put(skb, attrtype, msg->len, (void *) &msg->value);
5849 devlink_fmsg_prepare_skb(struct devlink_fmsg *fmsg, struct sk_buff *skb,
5852 struct devlink_fmsg_item *item;
5853 struct nlattr *fmsg_nlattr;
5857 fmsg_nlattr = nla_nest_start_noflag(skb, DEVLINK_ATTR_FMSG);
5861 list_for_each_entry(item, &fmsg->item_list, list) {
5867 switch (item->attrtype) {
5868 case DEVLINK_ATTR_FMSG_OBJ_NEST_START:
5869 case DEVLINK_ATTR_FMSG_PAIR_NEST_START:
5870 case DEVLINK_ATTR_FMSG_ARR_NEST_START:
5871 case DEVLINK_ATTR_FMSG_NEST_END:
5872 err = nla_put_flag(skb, item->attrtype);
5874 case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA:
5875 err = devlink_fmsg_item_fill_type(item, skb);
5878 err = devlink_fmsg_item_fill_data(item, skb);
5880 case DEVLINK_ATTR_FMSG_OBJ_NAME:
5881 err = nla_put_string(skb, item->attrtype,
5882 (char *) &item->value);
5894 nla_nest_end(skb, fmsg_nlattr);
5898 static int devlink_fmsg_snd(struct devlink_fmsg *fmsg,
5899 struct genl_info *info,
5900 enum devlink_command cmd, int flags)
5902 struct nlmsghdr *nlh;
5903 struct sk_buff *skb;
5910 int tmp_index = index;
5912 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
5916 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
5917 &devlink_nl_family, flags | NLM_F_MULTI, cmd);
5920 goto nla_put_failure;
5923 err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
5926 else if (err != -EMSGSIZE || tmp_index == index)
5927 goto nla_put_failure;
5929 genlmsg_end(skb, hdr);
5930 err = genlmsg_reply(skb, info);
5935 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
5938 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
5939 NLMSG_DONE, 0, flags | NLM_F_MULTI);
5942 goto nla_put_failure;
5945 return genlmsg_reply(skb, info);
5952 static int devlink_fmsg_dumpit(struct devlink_fmsg *fmsg, struct sk_buff *skb,
5953 struct netlink_callback *cb,
5954 enum devlink_command cmd)
5956 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
5957 int index = state->idx;
5958 int tmp_index = index;
5962 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
5963 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, cmd);
5966 goto nla_put_failure;
5969 err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
5970 if ((err && err != -EMSGSIZE) || tmp_index == index)
5971 goto nla_put_failure;
5974 genlmsg_end(skb, hdr);
5978 genlmsg_cancel(skb, hdr);
5982 struct devlink_health_reporter {
5983 struct list_head list;
5985 const struct devlink_health_reporter_ops *ops;
5986 struct devlink *devlink;
5987 struct devlink_port *devlink_port;
5988 struct devlink_fmsg *dump_fmsg;
5989 struct mutex dump_lock; /* lock parallel read/write from dump buffers */
5990 u64 graceful_period;
5998 u64 last_recovery_ts;
6002 devlink_health_reporter_priv(struct devlink_health_reporter *reporter)
6004 return reporter->priv;
6006 EXPORT_SYMBOL_GPL(devlink_health_reporter_priv);
6008 static struct devlink_health_reporter *
6009 __devlink_health_reporter_find_by_name(struct list_head *reporter_list,
6010 const char *reporter_name)
6012 struct devlink_health_reporter *reporter;
6014 list_for_each_entry(reporter, reporter_list, list)
6015 if (!strcmp(reporter->ops->name, reporter_name))
6020 static struct devlink_health_reporter *
6021 devlink_health_reporter_find_by_name(struct devlink *devlink,
6022 const char *reporter_name)
6024 return __devlink_health_reporter_find_by_name(&devlink->reporter_list,
6028 static struct devlink_health_reporter *
6029 devlink_port_health_reporter_find_by_name(struct devlink_port *devlink_port,
6030 const char *reporter_name)
6032 return __devlink_health_reporter_find_by_name(&devlink_port->reporter_list,
6036 static struct devlink_health_reporter *
6037 __devlink_health_reporter_create(struct devlink *devlink,
6038 const struct devlink_health_reporter_ops *ops,
6039 u64 graceful_period, void *priv)
6041 struct devlink_health_reporter *reporter;
6043 if (WARN_ON(graceful_period && !ops->recover))
6044 return ERR_PTR(-EINVAL);
6046 reporter = kzalloc(sizeof(*reporter), GFP_KERNEL);
6048 return ERR_PTR(-ENOMEM);
6050 reporter->priv = priv;
6051 reporter->ops = ops;
6052 reporter->devlink = devlink;
6053 reporter->graceful_period = graceful_period;
6054 reporter->auto_recover = !!ops->recover;
6055 reporter->auto_dump = !!ops->dump;
6056 mutex_init(&reporter->dump_lock);
6061 * devl_port_health_reporter_create - create devlink health reporter for
6062 * specified port instance
6064 * @port: devlink_port which should contain the new reporter
6066 * @graceful_period: to avoid recovery loops, in msecs
6069 struct devlink_health_reporter *
6070 devl_port_health_reporter_create(struct devlink_port *port,
6071 const struct devlink_health_reporter_ops *ops,
6072 u64 graceful_period, void *priv)
6074 struct devlink_health_reporter *reporter;
6076 devl_assert_locked(port->devlink);
6078 if (__devlink_health_reporter_find_by_name(&port->reporter_list,
6080 return ERR_PTR(-EEXIST);
6082 reporter = __devlink_health_reporter_create(port->devlink, ops,
6083 graceful_period, priv);
6084 if (IS_ERR(reporter))
6087 reporter->devlink_port = port;
6088 list_add_tail(&reporter->list, &port->reporter_list);
6091 EXPORT_SYMBOL_GPL(devl_port_health_reporter_create);
6093 struct devlink_health_reporter *
6094 devlink_port_health_reporter_create(struct devlink_port *port,
6095 const struct devlink_health_reporter_ops *ops,
6096 u64 graceful_period, void *priv)
6098 struct devlink_health_reporter *reporter;
6099 struct devlink *devlink = port->devlink;
6102 reporter = devl_port_health_reporter_create(port, ops,
6103 graceful_period, priv);
6104 devl_unlock(devlink);
6107 EXPORT_SYMBOL_GPL(devlink_port_health_reporter_create);
6110 * devl_health_reporter_create - create devlink health reporter
6114 * @graceful_period: to avoid recovery loops, in msecs
6117 struct devlink_health_reporter *
6118 devl_health_reporter_create(struct devlink *devlink,
6119 const struct devlink_health_reporter_ops *ops,
6120 u64 graceful_period, void *priv)
6122 struct devlink_health_reporter *reporter;
6124 devl_assert_locked(devlink);
6126 if (devlink_health_reporter_find_by_name(devlink, ops->name))
6127 return ERR_PTR(-EEXIST);
6129 reporter = __devlink_health_reporter_create(devlink, ops,
6130 graceful_period, priv);
6131 if (IS_ERR(reporter))
6134 list_add_tail(&reporter->list, &devlink->reporter_list);
6137 EXPORT_SYMBOL_GPL(devl_health_reporter_create);
6139 struct devlink_health_reporter *
6140 devlink_health_reporter_create(struct devlink *devlink,
6141 const struct devlink_health_reporter_ops *ops,
6142 u64 graceful_period, void *priv)
6144 struct devlink_health_reporter *reporter;
6147 reporter = devl_health_reporter_create(devlink, ops,
6148 graceful_period, priv);
6149 devl_unlock(devlink);
6152 EXPORT_SYMBOL_GPL(devlink_health_reporter_create);
6155 devlink_health_reporter_free(struct devlink_health_reporter *reporter)
6157 mutex_destroy(&reporter->dump_lock);
6158 if (reporter->dump_fmsg)
6159 devlink_fmsg_free(reporter->dump_fmsg);
6164 * devl_health_reporter_destroy - destroy devlink health reporter
6166 * @reporter: devlink health reporter to destroy
6169 devl_health_reporter_destroy(struct devlink_health_reporter *reporter)
6171 devl_assert_locked(reporter->devlink);
6173 list_del(&reporter->list);
6174 devlink_health_reporter_free(reporter);
6176 EXPORT_SYMBOL_GPL(devl_health_reporter_destroy);
6179 devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
6181 struct devlink *devlink = reporter->devlink;
6184 devl_health_reporter_destroy(reporter);
6185 devl_unlock(devlink);
6187 EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy);
6190 devlink_nl_health_reporter_fill(struct sk_buff *msg,
6191 struct devlink_health_reporter *reporter,
6192 enum devlink_command cmd, u32 portid,
6195 struct devlink *devlink = reporter->devlink;
6196 struct nlattr *reporter_attr;
6199 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
6203 if (devlink_nl_put_handle(msg, devlink))
6204 goto genlmsg_cancel;
6206 if (reporter->devlink_port) {
6207 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, reporter->devlink_port->index))
6208 goto genlmsg_cancel;
6210 reporter_attr = nla_nest_start_noflag(msg,
6211 DEVLINK_ATTR_HEALTH_REPORTER);
6213 goto genlmsg_cancel;
6214 if (nla_put_string(msg, DEVLINK_ATTR_HEALTH_REPORTER_NAME,
6215 reporter->ops->name))
6216 goto reporter_nest_cancel;
6217 if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_STATE,
6218 reporter->health_state))
6219 goto reporter_nest_cancel;
6220 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT,
6221 reporter->error_count, DEVLINK_ATTR_PAD))
6222 goto reporter_nest_cancel;
6223 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT,
6224 reporter->recovery_count, DEVLINK_ATTR_PAD))
6225 goto reporter_nest_cancel;
6226 if (reporter->ops->recover &&
6227 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD,
6228 reporter->graceful_period,
6230 goto reporter_nest_cancel;
6231 if (reporter->ops->recover &&
6232 nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER,
6233 reporter->auto_recover))
6234 goto reporter_nest_cancel;
6235 if (reporter->dump_fmsg &&
6236 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS,
6237 jiffies_to_msecs(reporter->dump_ts),
6239 goto reporter_nest_cancel;
6240 if (reporter->dump_fmsg &&
6241 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS,
6242 reporter->dump_real_ts, DEVLINK_ATTR_PAD))
6243 goto reporter_nest_cancel;
6244 if (reporter->ops->dump &&
6245 nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP,
6246 reporter->auto_dump))
6247 goto reporter_nest_cancel;
6249 nla_nest_end(msg, reporter_attr);
6250 genlmsg_end(msg, hdr);
6253 reporter_nest_cancel:
6254 nla_nest_end(msg, reporter_attr);
6256 genlmsg_cancel(msg, hdr);
6260 static void devlink_recover_notify(struct devlink_health_reporter *reporter,
6261 enum devlink_command cmd)
6263 struct devlink *devlink = reporter->devlink;
6264 struct sk_buff *msg;
6267 WARN_ON(cmd != DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
6268 WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED));
6270 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6274 err = devlink_nl_health_reporter_fill(msg, reporter, cmd, 0, 0, 0);
6280 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
6281 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
6285 devlink_health_reporter_recovery_done(struct devlink_health_reporter *reporter)
6287 reporter->recovery_count++;
6288 reporter->last_recovery_ts = jiffies;
6290 EXPORT_SYMBOL_GPL(devlink_health_reporter_recovery_done);
6293 devlink_health_reporter_recover(struct devlink_health_reporter *reporter,
6294 void *priv_ctx, struct netlink_ext_ack *extack)
6298 if (reporter->health_state == DEVLINK_HEALTH_REPORTER_STATE_HEALTHY)
6301 if (!reporter->ops->recover)
6304 err = reporter->ops->recover(reporter, priv_ctx, extack);
6308 devlink_health_reporter_recovery_done(reporter);
6309 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY;
6310 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
6316 devlink_health_dump_clear(struct devlink_health_reporter *reporter)
6318 if (!reporter->dump_fmsg)
6320 devlink_fmsg_free(reporter->dump_fmsg);
6321 reporter->dump_fmsg = NULL;
6324 static int devlink_health_do_dump(struct devlink_health_reporter *reporter,
6326 struct netlink_ext_ack *extack)
6330 if (!reporter->ops->dump)
6333 if (reporter->dump_fmsg)
6336 reporter->dump_fmsg = devlink_fmsg_alloc();
6337 if (!reporter->dump_fmsg) {
6342 err = devlink_fmsg_obj_nest_start(reporter->dump_fmsg);
6346 err = reporter->ops->dump(reporter, reporter->dump_fmsg,
6351 err = devlink_fmsg_obj_nest_end(reporter->dump_fmsg);
6355 reporter->dump_ts = jiffies;
6356 reporter->dump_real_ts = ktime_get_real_ns();
6361 devlink_health_dump_clear(reporter);
6365 int devlink_health_report(struct devlink_health_reporter *reporter,
6366 const char *msg, void *priv_ctx)
6368 enum devlink_health_reporter_state prev_health_state;
6369 struct devlink *devlink = reporter->devlink;
6370 unsigned long recover_ts_threshold;
6373 /* write a log message of the current error */
6375 trace_devlink_health_report(devlink, reporter->ops->name, msg);
6376 reporter->error_count++;
6377 prev_health_state = reporter->health_state;
6378 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
6379 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
6381 /* abort if the previous error wasn't recovered */
6382 recover_ts_threshold = reporter->last_recovery_ts +
6383 msecs_to_jiffies(reporter->graceful_period);
6384 if (reporter->auto_recover &&
6385 (prev_health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY ||
6386 (reporter->last_recovery_ts && reporter->recovery_count &&
6387 time_is_after_jiffies(recover_ts_threshold)))) {
6388 trace_devlink_health_recover_aborted(devlink,
6389 reporter->ops->name,
6390 reporter->health_state,
6392 reporter->last_recovery_ts);
6396 if (reporter->auto_dump) {
6397 mutex_lock(&reporter->dump_lock);
6398 /* store current dump of current error, for later analysis */
6399 devlink_health_do_dump(reporter, priv_ctx, NULL);
6400 mutex_unlock(&reporter->dump_lock);
6403 if (!reporter->auto_recover)
6407 ret = devlink_health_reporter_recover(reporter, priv_ctx, NULL);
6408 devl_unlock(devlink);
6412 EXPORT_SYMBOL_GPL(devlink_health_report);
6414 static struct devlink_health_reporter *
6415 devlink_health_reporter_get_from_attrs(struct devlink *devlink,
6416 struct nlattr **attrs)
6418 struct devlink_port *devlink_port;
6419 char *reporter_name;
6421 if (!attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME])
6424 reporter_name = nla_data(attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]);
6425 devlink_port = devlink_port_get_from_attrs(devlink, attrs);
6426 if (IS_ERR(devlink_port))
6427 return devlink_health_reporter_find_by_name(devlink,
6430 return devlink_port_health_reporter_find_by_name(devlink_port,
6434 static struct devlink_health_reporter *
6435 devlink_health_reporter_get_from_info(struct devlink *devlink,
6436 struct genl_info *info)
6438 return devlink_health_reporter_get_from_attrs(devlink, info->attrs);
6441 static struct devlink_health_reporter *
6442 devlink_health_reporter_get_from_cb(struct netlink_callback *cb)
6444 const struct genl_dumpit_info *info = genl_dumpit_info(cb);
6445 struct devlink_health_reporter *reporter;
6446 struct nlattr **attrs = info->attrs;
6447 struct devlink *devlink;
6449 devlink = devlink_get_from_attrs_lock(sock_net(cb->skb->sk), attrs);
6450 if (IS_ERR(devlink))
6452 devl_unlock(devlink);
6454 reporter = devlink_health_reporter_get_from_attrs(devlink, attrs);
6455 devlink_put(devlink);
6460 devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
6461 enum devlink_health_reporter_state state)
6463 if (WARN_ON(state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY &&
6464 state != DEVLINK_HEALTH_REPORTER_STATE_ERROR))
6467 if (reporter->health_state == state)
6470 reporter->health_state = state;
6471 trace_devlink_health_reporter_state_update(reporter->devlink,
6472 reporter->ops->name, state);
6473 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
6475 EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update);
6477 static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb,
6478 struct genl_info *info)
6480 struct devlink *devlink = info->user_ptr[0];
6481 struct devlink_health_reporter *reporter;
6482 struct sk_buff *msg;
6485 reporter = devlink_health_reporter_get_from_info(devlink, info);
6489 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6493 err = devlink_nl_health_reporter_fill(msg, reporter,
6494 DEVLINK_CMD_HEALTH_REPORTER_GET,
6495 info->snd_portid, info->snd_seq,
6502 return genlmsg_reply(msg, info);
6506 devlink_nl_cmd_health_reporter_get_dump_one(struct sk_buff *msg,
6507 struct devlink *devlink,
6508 struct netlink_callback *cb)
6510 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
6511 struct devlink_health_reporter *reporter;
6512 struct devlink_port *port;
6513 unsigned long port_index;
6517 list_for_each_entry(reporter, &devlink->reporter_list, list) {
6518 if (idx < state->idx) {
6522 err = devlink_nl_health_reporter_fill(msg, reporter,
6523 DEVLINK_CMD_HEALTH_REPORTER_GET,
6524 NETLINK_CB(cb->skb).portid,
6533 xa_for_each(&devlink->ports, port_index, port) {
6534 list_for_each_entry(reporter, &port->reporter_list, list) {
6535 if (idx < state->idx) {
6539 err = devlink_nl_health_reporter_fill(msg, reporter,
6540 DEVLINK_CMD_HEALTH_REPORTER_GET,
6541 NETLINK_CB(cb->skb).portid,
6555 const struct devlink_cmd devl_cmd_health_reporter_get = {
6556 .dump_one = devlink_nl_cmd_health_reporter_get_dump_one,
6560 devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb,
6561 struct genl_info *info)
6563 struct devlink *devlink = info->user_ptr[0];
6564 struct devlink_health_reporter *reporter;
6566 reporter = devlink_health_reporter_get_from_info(devlink, info);
6570 if (!reporter->ops->recover &&
6571 (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] ||
6572 info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]))
6575 if (!reporter->ops->dump &&
6576 info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP])
6579 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD])
6580 reporter->graceful_period =
6581 nla_get_u64(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]);
6583 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])
6584 reporter->auto_recover =
6585 nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]);
6587 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP])
6588 reporter->auto_dump =
6589 nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]);
6594 static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb,
6595 struct genl_info *info)
6597 struct devlink *devlink = info->user_ptr[0];
6598 struct devlink_health_reporter *reporter;
6600 reporter = devlink_health_reporter_get_from_info(devlink, info);
6604 return devlink_health_reporter_recover(reporter, NULL, info->extack);
6607 static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb,
6608 struct genl_info *info)
6610 struct devlink *devlink = info->user_ptr[0];
6611 struct devlink_health_reporter *reporter;
6612 struct devlink_fmsg *fmsg;
6615 reporter = devlink_health_reporter_get_from_info(devlink, info);
6619 if (!reporter->ops->diagnose)
6622 fmsg = devlink_fmsg_alloc();
6626 err = devlink_fmsg_obj_nest_start(fmsg);
6630 err = reporter->ops->diagnose(reporter, fmsg, info->extack);
6634 err = devlink_fmsg_obj_nest_end(fmsg);
6638 err = devlink_fmsg_snd(fmsg, info,
6639 DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 0);
6642 devlink_fmsg_free(fmsg);
6647 devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff *skb,
6648 struct netlink_callback *cb)
6650 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
6651 struct devlink_health_reporter *reporter;
6654 reporter = devlink_health_reporter_get_from_cb(cb);
6658 if (!reporter->ops->dump)
6661 mutex_lock(&reporter->dump_lock);
6663 err = devlink_health_do_dump(reporter, NULL, cb->extack);
6666 state->dump_ts = reporter->dump_ts;
6668 if (!reporter->dump_fmsg || state->dump_ts != reporter->dump_ts) {
6669 NL_SET_ERR_MSG(cb->extack, "Dump trampled, please retry");
6674 err = devlink_fmsg_dumpit(reporter->dump_fmsg, skb, cb,
6675 DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET);
6677 mutex_unlock(&reporter->dump_lock);
6682 devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb,
6683 struct genl_info *info)
6685 struct devlink *devlink = info->user_ptr[0];
6686 struct devlink_health_reporter *reporter;
6688 reporter = devlink_health_reporter_get_from_info(devlink, info);
6692 if (!reporter->ops->dump)
6695 mutex_lock(&reporter->dump_lock);
6696 devlink_health_dump_clear(reporter);
6697 mutex_unlock(&reporter->dump_lock);
6701 static int devlink_nl_cmd_health_reporter_test_doit(struct sk_buff *skb,
6702 struct genl_info *info)
6704 struct devlink *devlink = info->user_ptr[0];
6705 struct devlink_health_reporter *reporter;
6707 reporter = devlink_health_reporter_get_from_info(devlink, info);
6711 if (!reporter->ops->test)
6714 return reporter->ops->test(reporter, info->extack);
6717 struct devlink_stats {
6718 u64_stats_t rx_bytes;
6719 u64_stats_t rx_packets;
6720 struct u64_stats_sync syncp;
6724 * struct devlink_trap_policer_item - Packet trap policer attributes.
6725 * @policer: Immutable packet trap policer attributes.
6726 * @rate: Rate in packets / sec.
6727 * @burst: Burst size in packets.
6728 * @list: trap_policer_list member.
6730 * Describes packet trap policer attributes. Created by devlink during trap
6731 * policer registration.
6733 struct devlink_trap_policer_item {
6734 const struct devlink_trap_policer *policer;
6737 struct list_head list;
6741 * struct devlink_trap_group_item - Packet trap group attributes.
6742 * @group: Immutable packet trap group attributes.
6743 * @policer_item: Associated policer item. Can be NULL.
6744 * @list: trap_group_list member.
6745 * @stats: Trap group statistics.
6747 * Describes packet trap group attributes. Created by devlink during trap
6748 * group registration.
6750 struct devlink_trap_group_item {
6751 const struct devlink_trap_group *group;
6752 struct devlink_trap_policer_item *policer_item;
6753 struct list_head list;
6754 struct devlink_stats __percpu *stats;
6758 * struct devlink_trap_item - Packet trap attributes.
6759 * @trap: Immutable packet trap attributes.
6760 * @group_item: Associated group item.
6761 * @list: trap_list member.
6762 * @action: Trap action.
6763 * @stats: Trap statistics.
6764 * @priv: Driver private information.
6766 * Describes both mutable and immutable packet trap attributes. Created by
6767 * devlink during trap registration and used for all trap related operations.
6769 struct devlink_trap_item {
6770 const struct devlink_trap *trap;
6771 struct devlink_trap_group_item *group_item;
6772 struct list_head list;
6773 enum devlink_trap_action action;
6774 struct devlink_stats __percpu *stats;
6778 static struct devlink_trap_policer_item *
6779 devlink_trap_policer_item_lookup(struct devlink *devlink, u32 id)
6781 struct devlink_trap_policer_item *policer_item;
6783 list_for_each_entry(policer_item, &devlink->trap_policer_list, list) {
6784 if (policer_item->policer->id == id)
6785 return policer_item;
6791 static struct devlink_trap_item *
6792 devlink_trap_item_lookup(struct devlink *devlink, const char *name)
6794 struct devlink_trap_item *trap_item;
6796 list_for_each_entry(trap_item, &devlink->trap_list, list) {
6797 if (!strcmp(trap_item->trap->name, name))
6804 static struct devlink_trap_item *
6805 devlink_trap_item_get_from_info(struct devlink *devlink,
6806 struct genl_info *info)
6808 struct nlattr *attr;
6810 if (!info->attrs[DEVLINK_ATTR_TRAP_NAME])
6812 attr = info->attrs[DEVLINK_ATTR_TRAP_NAME];
6814 return devlink_trap_item_lookup(devlink, nla_data(attr));
6818 devlink_trap_action_get_from_info(struct genl_info *info,
6819 enum devlink_trap_action *p_trap_action)
6823 val = nla_get_u8(info->attrs[DEVLINK_ATTR_TRAP_ACTION]);
6825 case DEVLINK_TRAP_ACTION_DROP:
6826 case DEVLINK_TRAP_ACTION_TRAP:
6827 case DEVLINK_TRAP_ACTION_MIRROR:
6828 *p_trap_action = val;
6837 static int devlink_trap_metadata_put(struct sk_buff *msg,
6838 const struct devlink_trap *trap)
6840 struct nlattr *attr;
6842 attr = nla_nest_start(msg, DEVLINK_ATTR_TRAP_METADATA);
6846 if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT) &&
6847 nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT))
6848 goto nla_put_failure;
6849 if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE) &&
6850 nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE))
6851 goto nla_put_failure;
6853 nla_nest_end(msg, attr);
6858 nla_nest_cancel(msg, attr);
6862 static void devlink_trap_stats_read(struct devlink_stats __percpu *trap_stats,
6863 struct devlink_stats *stats)
6867 memset(stats, 0, sizeof(*stats));
6868 for_each_possible_cpu(i) {
6869 struct devlink_stats *cpu_stats;
6870 u64 rx_packets, rx_bytes;
6873 cpu_stats = per_cpu_ptr(trap_stats, i);
6875 start = u64_stats_fetch_begin(&cpu_stats->syncp);
6876 rx_packets = u64_stats_read(&cpu_stats->rx_packets);
6877 rx_bytes = u64_stats_read(&cpu_stats->rx_bytes);
6878 } while (u64_stats_fetch_retry(&cpu_stats->syncp, start));
6880 u64_stats_add(&stats->rx_packets, rx_packets);
6881 u64_stats_add(&stats->rx_bytes, rx_bytes);
6886 devlink_trap_group_stats_put(struct sk_buff *msg,
6887 struct devlink_stats __percpu *trap_stats)
6889 struct devlink_stats stats;
6890 struct nlattr *attr;
6892 devlink_trap_stats_read(trap_stats, &stats);
6894 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
6898 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS,
6899 u64_stats_read(&stats.rx_packets),
6901 goto nla_put_failure;
6903 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES,
6904 u64_stats_read(&stats.rx_bytes),
6906 goto nla_put_failure;
6908 nla_nest_end(msg, attr);
6913 nla_nest_cancel(msg, attr);
6917 static int devlink_trap_stats_put(struct sk_buff *msg, struct devlink *devlink,
6918 const struct devlink_trap_item *trap_item)
6920 struct devlink_stats stats;
6921 struct nlattr *attr;
6925 if (devlink->ops->trap_drop_counter_get) {
6926 err = devlink->ops->trap_drop_counter_get(devlink,
6933 devlink_trap_stats_read(trap_item->stats, &stats);
6935 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
6939 if (devlink->ops->trap_drop_counter_get &&
6940 nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops,
6942 goto nla_put_failure;
6944 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS,
6945 u64_stats_read(&stats.rx_packets),
6947 goto nla_put_failure;
6949 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES,
6950 u64_stats_read(&stats.rx_bytes),
6952 goto nla_put_failure;
6954 nla_nest_end(msg, attr);
6959 nla_nest_cancel(msg, attr);
6963 static int devlink_nl_trap_fill(struct sk_buff *msg, struct devlink *devlink,
6964 const struct devlink_trap_item *trap_item,
6965 enum devlink_command cmd, u32 portid, u32 seq,
6968 struct devlink_trap_group_item *group_item = trap_item->group_item;
6972 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
6976 if (devlink_nl_put_handle(msg, devlink))
6977 goto nla_put_failure;
6979 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
6980 group_item->group->name))
6981 goto nla_put_failure;
6983 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_NAME, trap_item->trap->name))
6984 goto nla_put_failure;
6986 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_TYPE, trap_item->trap->type))
6987 goto nla_put_failure;
6989 if (trap_item->trap->generic &&
6990 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
6991 goto nla_put_failure;
6993 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_ACTION, trap_item->action))
6994 goto nla_put_failure;
6996 err = devlink_trap_metadata_put(msg, trap_item->trap);
6998 goto nla_put_failure;
7000 err = devlink_trap_stats_put(msg, devlink, trap_item);
7002 goto nla_put_failure;
7004 genlmsg_end(msg, hdr);
7009 genlmsg_cancel(msg, hdr);
7013 static int devlink_nl_cmd_trap_get_doit(struct sk_buff *skb,
7014 struct genl_info *info)
7016 struct netlink_ext_ack *extack = info->extack;
7017 struct devlink *devlink = info->user_ptr[0];
7018 struct devlink_trap_item *trap_item;
7019 struct sk_buff *msg;
7022 if (list_empty(&devlink->trap_list))
7025 trap_item = devlink_trap_item_get_from_info(devlink, info);
7027 NL_SET_ERR_MSG(extack, "Device did not register this trap");
7031 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7035 err = devlink_nl_trap_fill(msg, devlink, trap_item,
7036 DEVLINK_CMD_TRAP_NEW, info->snd_portid,
7041 return genlmsg_reply(msg, info);
7049 devlink_nl_cmd_trap_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
7050 struct netlink_callback *cb)
7052 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
7053 struct devlink_trap_item *trap_item;
7057 list_for_each_entry(trap_item, &devlink->trap_list, list) {
7058 if (idx < state->idx) {
7062 err = devlink_nl_trap_fill(msg, devlink, trap_item,
7063 DEVLINK_CMD_TRAP_NEW,
7064 NETLINK_CB(cb->skb).portid,
7077 const struct devlink_cmd devl_cmd_trap_get = {
7078 .dump_one = devlink_nl_cmd_trap_get_dump_one,
7081 static int __devlink_trap_action_set(struct devlink *devlink,
7082 struct devlink_trap_item *trap_item,
7083 enum devlink_trap_action trap_action,
7084 struct netlink_ext_ack *extack)
7088 if (trap_item->action != trap_action &&
7089 trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) {
7090 NL_SET_ERR_MSG(extack, "Cannot change action of non-drop traps. Skipping");
7094 err = devlink->ops->trap_action_set(devlink, trap_item->trap,
7095 trap_action, extack);
7099 trap_item->action = trap_action;
7104 static int devlink_trap_action_set(struct devlink *devlink,
7105 struct devlink_trap_item *trap_item,
7106 struct genl_info *info)
7108 enum devlink_trap_action trap_action;
7111 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
7114 err = devlink_trap_action_get_from_info(info, &trap_action);
7116 NL_SET_ERR_MSG(info->extack, "Invalid trap action");
7120 return __devlink_trap_action_set(devlink, trap_item, trap_action,
7124 static int devlink_nl_cmd_trap_set_doit(struct sk_buff *skb,
7125 struct genl_info *info)
7127 struct netlink_ext_ack *extack = info->extack;
7128 struct devlink *devlink = info->user_ptr[0];
7129 struct devlink_trap_item *trap_item;
7131 if (list_empty(&devlink->trap_list))
7134 trap_item = devlink_trap_item_get_from_info(devlink, info);
7136 NL_SET_ERR_MSG(extack, "Device did not register this trap");
7140 return devlink_trap_action_set(devlink, trap_item, info);
7143 static struct devlink_trap_group_item *
7144 devlink_trap_group_item_lookup(struct devlink *devlink, const char *name)
7146 struct devlink_trap_group_item *group_item;
7148 list_for_each_entry(group_item, &devlink->trap_group_list, list) {
7149 if (!strcmp(group_item->group->name, name))
7156 static struct devlink_trap_group_item *
7157 devlink_trap_group_item_lookup_by_id(struct devlink *devlink, u16 id)
7159 struct devlink_trap_group_item *group_item;
7161 list_for_each_entry(group_item, &devlink->trap_group_list, list) {
7162 if (group_item->group->id == id)
7169 static struct devlink_trap_group_item *
7170 devlink_trap_group_item_get_from_info(struct devlink *devlink,
7171 struct genl_info *info)
7175 if (!info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME])
7177 name = nla_data(info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]);
7179 return devlink_trap_group_item_lookup(devlink, name);
7183 devlink_nl_trap_group_fill(struct sk_buff *msg, struct devlink *devlink,
7184 const struct devlink_trap_group_item *group_item,
7185 enum devlink_command cmd, u32 portid, u32 seq,
7191 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
7195 if (devlink_nl_put_handle(msg, devlink))
7196 goto nla_put_failure;
7198 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
7199 group_item->group->name))
7200 goto nla_put_failure;
7202 if (group_item->group->generic &&
7203 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
7204 goto nla_put_failure;
7206 if (group_item->policer_item &&
7207 nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
7208 group_item->policer_item->policer->id))
7209 goto nla_put_failure;
7211 err = devlink_trap_group_stats_put(msg, group_item->stats);
7213 goto nla_put_failure;
7215 genlmsg_end(msg, hdr);
7220 genlmsg_cancel(msg, hdr);
7224 static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff *skb,
7225 struct genl_info *info)
7227 struct netlink_ext_ack *extack = info->extack;
7228 struct devlink *devlink = info->user_ptr[0];
7229 struct devlink_trap_group_item *group_item;
7230 struct sk_buff *msg;
7233 if (list_empty(&devlink->trap_group_list))
7236 group_item = devlink_trap_group_item_get_from_info(devlink, info);
7238 NL_SET_ERR_MSG(extack, "Device did not register this trap group");
7242 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7246 err = devlink_nl_trap_group_fill(msg, devlink, group_item,
7247 DEVLINK_CMD_TRAP_GROUP_NEW,
7248 info->snd_portid, info->snd_seq, 0);
7250 goto err_trap_group_fill;
7252 return genlmsg_reply(msg, info);
7254 err_trap_group_fill:
7260 devlink_nl_cmd_trap_group_get_dump_one(struct sk_buff *msg,
7261 struct devlink *devlink,
7262 struct netlink_callback *cb)
7264 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
7265 struct devlink_trap_group_item *group_item;
7270 list_for_each_entry(group_item, &devlink->trap_group_list, list) {
7271 if (idx < state->idx) {
7275 err = devlink_nl_trap_group_fill(msg, devlink, group_item,
7276 DEVLINK_CMD_TRAP_GROUP_NEW,
7277 NETLINK_CB(cb->skb).portid,
7290 const struct devlink_cmd devl_cmd_trap_group_get = {
7291 .dump_one = devlink_nl_cmd_trap_group_get_dump_one,
7295 __devlink_trap_group_action_set(struct devlink *devlink,
7296 struct devlink_trap_group_item *group_item,
7297 enum devlink_trap_action trap_action,
7298 struct netlink_ext_ack *extack)
7300 const char *group_name = group_item->group->name;
7301 struct devlink_trap_item *trap_item;
7304 if (devlink->ops->trap_group_action_set) {
7305 err = devlink->ops->trap_group_action_set(devlink, group_item->group,
7306 trap_action, extack);
7310 list_for_each_entry(trap_item, &devlink->trap_list, list) {
7311 if (strcmp(trap_item->group_item->group->name, group_name))
7313 if (trap_item->action != trap_action &&
7314 trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP)
7316 trap_item->action = trap_action;
7322 list_for_each_entry(trap_item, &devlink->trap_list, list) {
7323 if (strcmp(trap_item->group_item->group->name, group_name))
7325 err = __devlink_trap_action_set(devlink, trap_item,
7326 trap_action, extack);
7335 devlink_trap_group_action_set(struct devlink *devlink,
7336 struct devlink_trap_group_item *group_item,
7337 struct genl_info *info, bool *p_modified)
7339 enum devlink_trap_action trap_action;
7342 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
7345 err = devlink_trap_action_get_from_info(info, &trap_action);
7347 NL_SET_ERR_MSG(info->extack, "Invalid trap action");
7351 err = __devlink_trap_group_action_set(devlink, group_item, trap_action,
7361 static int devlink_trap_group_set(struct devlink *devlink,
7362 struct devlink_trap_group_item *group_item,
7363 struct genl_info *info)
7365 struct devlink_trap_policer_item *policer_item;
7366 struct netlink_ext_ack *extack = info->extack;
7367 const struct devlink_trap_policer *policer;
7368 struct nlattr **attrs = info->attrs;
7372 if (!attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
7375 if (!devlink->ops->trap_group_set)
7378 policer_id = nla_get_u32(attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
7379 policer_item = devlink_trap_policer_item_lookup(devlink, policer_id);
7380 if (policer_id && !policer_item) {
7381 NL_SET_ERR_MSG(extack, "Device did not register this trap policer");
7384 policer = policer_item ? policer_item->policer : NULL;
7386 err = devlink->ops->trap_group_set(devlink, group_item->group, policer,
7391 group_item->policer_item = policer_item;
7396 static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff *skb,
7397 struct genl_info *info)
7399 struct netlink_ext_ack *extack = info->extack;
7400 struct devlink *devlink = info->user_ptr[0];
7401 struct devlink_trap_group_item *group_item;
7402 bool modified = false;
7405 if (list_empty(&devlink->trap_group_list))
7408 group_item = devlink_trap_group_item_get_from_info(devlink, info);
7410 NL_SET_ERR_MSG(extack, "Device did not register this trap group");
7414 err = devlink_trap_group_action_set(devlink, group_item, info,
7419 err = devlink_trap_group_set(devlink, group_item, info);
7421 goto err_trap_group_set;
7427 NL_SET_ERR_MSG(extack, "Trap group set failed, but some changes were committed already");
7431 static struct devlink_trap_policer_item *
7432 devlink_trap_policer_item_get_from_info(struct devlink *devlink,
7433 struct genl_info *info)
7437 if (!info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
7439 id = nla_get_u32(info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
7441 return devlink_trap_policer_item_lookup(devlink, id);
7445 devlink_trap_policer_stats_put(struct sk_buff *msg, struct devlink *devlink,
7446 const struct devlink_trap_policer *policer)
7448 struct nlattr *attr;
7452 if (!devlink->ops->trap_policer_counter_get)
7455 err = devlink->ops->trap_policer_counter_get(devlink, policer, &drops);
7459 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
7463 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops,
7465 goto nla_put_failure;
7467 nla_nest_end(msg, attr);
7472 nla_nest_cancel(msg, attr);
7477 devlink_nl_trap_policer_fill(struct sk_buff *msg, struct devlink *devlink,
7478 const struct devlink_trap_policer_item *policer_item,
7479 enum devlink_command cmd, u32 portid, u32 seq,
7485 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
7489 if (devlink_nl_put_handle(msg, devlink))
7490 goto nla_put_failure;
7492 if (nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
7493 policer_item->policer->id))
7494 goto nla_put_failure;
7496 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_RATE,
7497 policer_item->rate, DEVLINK_ATTR_PAD))
7498 goto nla_put_failure;
7500 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_BURST,
7501 policer_item->burst, DEVLINK_ATTR_PAD))
7502 goto nla_put_failure;
7504 err = devlink_trap_policer_stats_put(msg, devlink,
7505 policer_item->policer);
7507 goto nla_put_failure;
7509 genlmsg_end(msg, hdr);
7514 genlmsg_cancel(msg, hdr);
7518 static int devlink_nl_cmd_trap_policer_get_doit(struct sk_buff *skb,
7519 struct genl_info *info)
7521 struct devlink_trap_policer_item *policer_item;
7522 struct netlink_ext_ack *extack = info->extack;
7523 struct devlink *devlink = info->user_ptr[0];
7524 struct sk_buff *msg;
7527 if (list_empty(&devlink->trap_policer_list))
7530 policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
7531 if (!policer_item) {
7532 NL_SET_ERR_MSG(extack, "Device did not register this trap policer");
7536 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7540 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item,
7541 DEVLINK_CMD_TRAP_POLICER_NEW,
7542 info->snd_portid, info->snd_seq, 0);
7544 goto err_trap_policer_fill;
7546 return genlmsg_reply(msg, info);
7548 err_trap_policer_fill:
7554 devlink_nl_cmd_trap_policer_get_dump_one(struct sk_buff *msg,
7555 struct devlink *devlink,
7556 struct netlink_callback *cb)
7558 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
7559 struct devlink_trap_policer_item *policer_item;
7563 list_for_each_entry(policer_item, &devlink->trap_policer_list, list) {
7564 if (idx < state->idx) {
7568 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item,
7569 DEVLINK_CMD_TRAP_POLICER_NEW,
7570 NETLINK_CB(cb->skb).portid,
7583 const struct devlink_cmd devl_cmd_trap_policer_get = {
7584 .dump_one = devlink_nl_cmd_trap_policer_get_dump_one,
7588 devlink_trap_policer_set(struct devlink *devlink,
7589 struct devlink_trap_policer_item *policer_item,
7590 struct genl_info *info)
7592 struct netlink_ext_ack *extack = info->extack;
7593 struct nlattr **attrs = info->attrs;
7597 rate = policer_item->rate;
7598 burst = policer_item->burst;
7600 if (attrs[DEVLINK_ATTR_TRAP_POLICER_RATE])
7601 rate = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_RATE]);
7603 if (attrs[DEVLINK_ATTR_TRAP_POLICER_BURST])
7604 burst = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_BURST]);
7606 if (rate < policer_item->policer->min_rate) {
7607 NL_SET_ERR_MSG(extack, "Policer rate lower than limit");
7611 if (rate > policer_item->policer->max_rate) {
7612 NL_SET_ERR_MSG(extack, "Policer rate higher than limit");
7616 if (burst < policer_item->policer->min_burst) {
7617 NL_SET_ERR_MSG(extack, "Policer burst size lower than limit");
7621 if (burst > policer_item->policer->max_burst) {
7622 NL_SET_ERR_MSG(extack, "Policer burst size higher than limit");
7626 err = devlink->ops->trap_policer_set(devlink, policer_item->policer,
7627 rate, burst, info->extack);
7631 policer_item->rate = rate;
7632 policer_item->burst = burst;
7637 static int devlink_nl_cmd_trap_policer_set_doit(struct sk_buff *skb,
7638 struct genl_info *info)
7640 struct devlink_trap_policer_item *policer_item;
7641 struct netlink_ext_ack *extack = info->extack;
7642 struct devlink *devlink = info->user_ptr[0];
7644 if (list_empty(&devlink->trap_policer_list))
7647 if (!devlink->ops->trap_policer_set)
7650 policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
7651 if (!policer_item) {
7652 NL_SET_ERR_MSG(extack, "Device did not register this trap policer");
7656 return devlink_trap_policer_set(devlink, policer_item, info);
7659 const struct genl_small_ops devlink_nl_ops[56] = {
7661 .cmd = DEVLINK_CMD_GET,
7662 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7663 .doit = devlink_nl_cmd_get_doit,
7664 .dumpit = devlink_nl_instance_iter_dumpit,
7665 /* can be retrieved by unprivileged users */
7668 .cmd = DEVLINK_CMD_PORT_GET,
7669 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7670 .doit = devlink_nl_cmd_port_get_doit,
7671 .dumpit = devlink_nl_instance_iter_dumpit,
7672 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7673 /* can be retrieved by unprivileged users */
7676 .cmd = DEVLINK_CMD_PORT_SET,
7677 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7678 .doit = devlink_nl_cmd_port_set_doit,
7679 .flags = GENL_ADMIN_PERM,
7680 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7683 .cmd = DEVLINK_CMD_RATE_GET,
7684 .doit = devlink_nl_cmd_rate_get_doit,
7685 .dumpit = devlink_nl_instance_iter_dumpit,
7686 .internal_flags = DEVLINK_NL_FLAG_NEED_RATE,
7687 /* can be retrieved by unprivileged users */
7690 .cmd = DEVLINK_CMD_RATE_SET,
7691 .doit = devlink_nl_cmd_rate_set_doit,
7692 .flags = GENL_ADMIN_PERM,
7693 .internal_flags = DEVLINK_NL_FLAG_NEED_RATE,
7696 .cmd = DEVLINK_CMD_RATE_NEW,
7697 .doit = devlink_nl_cmd_rate_new_doit,
7698 .flags = GENL_ADMIN_PERM,
7701 .cmd = DEVLINK_CMD_RATE_DEL,
7702 .doit = devlink_nl_cmd_rate_del_doit,
7703 .flags = GENL_ADMIN_PERM,
7704 .internal_flags = DEVLINK_NL_FLAG_NEED_RATE_NODE,
7707 .cmd = DEVLINK_CMD_PORT_SPLIT,
7708 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7709 .doit = devlink_nl_cmd_port_split_doit,
7710 .flags = GENL_ADMIN_PERM,
7711 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7714 .cmd = DEVLINK_CMD_PORT_UNSPLIT,
7715 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7716 .doit = devlink_nl_cmd_port_unsplit_doit,
7717 .flags = GENL_ADMIN_PERM,
7718 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7721 .cmd = DEVLINK_CMD_PORT_NEW,
7722 .doit = devlink_nl_cmd_port_new_doit,
7723 .flags = GENL_ADMIN_PERM,
7726 .cmd = DEVLINK_CMD_PORT_DEL,
7727 .doit = devlink_nl_cmd_port_del_doit,
7728 .flags = GENL_ADMIN_PERM,
7731 .cmd = DEVLINK_CMD_LINECARD_GET,
7732 .doit = devlink_nl_cmd_linecard_get_doit,
7733 .dumpit = devlink_nl_instance_iter_dumpit,
7734 .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD,
7735 /* can be retrieved by unprivileged users */
7738 .cmd = DEVLINK_CMD_LINECARD_SET,
7739 .doit = devlink_nl_cmd_linecard_set_doit,
7740 .flags = GENL_ADMIN_PERM,
7741 .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD,
7744 .cmd = DEVLINK_CMD_SB_GET,
7745 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7746 .doit = devlink_nl_cmd_sb_get_doit,
7747 .dumpit = devlink_nl_instance_iter_dumpit,
7748 /* can be retrieved by unprivileged users */
7751 .cmd = DEVLINK_CMD_SB_POOL_GET,
7752 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7753 .doit = devlink_nl_cmd_sb_pool_get_doit,
7754 .dumpit = devlink_nl_instance_iter_dumpit,
7755 /* can be retrieved by unprivileged users */
7758 .cmd = DEVLINK_CMD_SB_POOL_SET,
7759 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7760 .doit = devlink_nl_cmd_sb_pool_set_doit,
7761 .flags = GENL_ADMIN_PERM,
7764 .cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
7765 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7766 .doit = devlink_nl_cmd_sb_port_pool_get_doit,
7767 .dumpit = devlink_nl_instance_iter_dumpit,
7768 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7769 /* can be retrieved by unprivileged users */
7772 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
7773 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7774 .doit = devlink_nl_cmd_sb_port_pool_set_doit,
7775 .flags = GENL_ADMIN_PERM,
7776 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7779 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
7780 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7781 .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
7782 .dumpit = devlink_nl_instance_iter_dumpit,
7783 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7784 /* can be retrieved by unprivileged users */
7787 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
7788 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7789 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
7790 .flags = GENL_ADMIN_PERM,
7791 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7794 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
7795 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7796 .doit = devlink_nl_cmd_sb_occ_snapshot_doit,
7797 .flags = GENL_ADMIN_PERM,
7800 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
7801 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7802 .doit = devlink_nl_cmd_sb_occ_max_clear_doit,
7803 .flags = GENL_ADMIN_PERM,
7806 .cmd = DEVLINK_CMD_ESWITCH_GET,
7807 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7808 .doit = devlink_nl_cmd_eswitch_get_doit,
7809 .flags = GENL_ADMIN_PERM,
7812 .cmd = DEVLINK_CMD_ESWITCH_SET,
7813 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7814 .doit = devlink_nl_cmd_eswitch_set_doit,
7815 .flags = GENL_ADMIN_PERM,
7818 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET,
7819 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7820 .doit = devlink_nl_cmd_dpipe_table_get,
7821 /* can be retrieved by unprivileged users */
7824 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET,
7825 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7826 .doit = devlink_nl_cmd_dpipe_entries_get,
7827 /* can be retrieved by unprivileged users */
7830 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET,
7831 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7832 .doit = devlink_nl_cmd_dpipe_headers_get,
7833 /* can be retrieved by unprivileged users */
7836 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
7837 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7838 .doit = devlink_nl_cmd_dpipe_table_counters_set,
7839 .flags = GENL_ADMIN_PERM,
7842 .cmd = DEVLINK_CMD_RESOURCE_SET,
7843 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7844 .doit = devlink_nl_cmd_resource_set,
7845 .flags = GENL_ADMIN_PERM,
7848 .cmd = DEVLINK_CMD_RESOURCE_DUMP,
7849 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7850 .doit = devlink_nl_cmd_resource_dump,
7851 /* can be retrieved by unprivileged users */
7854 .cmd = DEVLINK_CMD_RELOAD,
7855 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7856 .doit = devlink_nl_cmd_reload,
7857 .flags = GENL_ADMIN_PERM,
7860 .cmd = DEVLINK_CMD_PARAM_GET,
7861 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7862 .doit = devlink_nl_cmd_param_get_doit,
7863 .dumpit = devlink_nl_instance_iter_dumpit,
7864 /* can be retrieved by unprivileged users */
7867 .cmd = DEVLINK_CMD_PARAM_SET,
7868 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7869 .doit = devlink_nl_cmd_param_set_doit,
7870 .flags = GENL_ADMIN_PERM,
7873 .cmd = DEVLINK_CMD_PORT_PARAM_GET,
7874 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7875 .doit = devlink_nl_cmd_port_param_get_doit,
7876 .dumpit = devlink_nl_cmd_port_param_get_dumpit,
7877 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7878 /* can be retrieved by unprivileged users */
7881 .cmd = DEVLINK_CMD_PORT_PARAM_SET,
7882 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7883 .doit = devlink_nl_cmd_port_param_set_doit,
7884 .flags = GENL_ADMIN_PERM,
7885 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7888 .cmd = DEVLINK_CMD_REGION_GET,
7889 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7890 .doit = devlink_nl_cmd_region_get_doit,
7891 .dumpit = devlink_nl_instance_iter_dumpit,
7892 .flags = GENL_ADMIN_PERM,
7895 .cmd = DEVLINK_CMD_REGION_NEW,
7896 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7897 .doit = devlink_nl_cmd_region_new,
7898 .flags = GENL_ADMIN_PERM,
7901 .cmd = DEVLINK_CMD_REGION_DEL,
7902 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7903 .doit = devlink_nl_cmd_region_del,
7904 .flags = GENL_ADMIN_PERM,
7907 .cmd = DEVLINK_CMD_REGION_READ,
7908 .validate = GENL_DONT_VALIDATE_STRICT |
7909 GENL_DONT_VALIDATE_DUMP_STRICT,
7910 .dumpit = devlink_nl_cmd_region_read_dumpit,
7911 .flags = GENL_ADMIN_PERM,
7914 .cmd = DEVLINK_CMD_INFO_GET,
7915 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7916 .doit = devlink_nl_cmd_info_get_doit,
7917 .dumpit = devlink_nl_instance_iter_dumpit,
7918 /* can be retrieved by unprivileged users */
7921 .cmd = DEVLINK_CMD_HEALTH_REPORTER_GET,
7922 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7923 .doit = devlink_nl_cmd_health_reporter_get_doit,
7924 .dumpit = devlink_nl_instance_iter_dumpit,
7925 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
7926 /* can be retrieved by unprivileged users */
7929 .cmd = DEVLINK_CMD_HEALTH_REPORTER_SET,
7930 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7931 .doit = devlink_nl_cmd_health_reporter_set_doit,
7932 .flags = GENL_ADMIN_PERM,
7933 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
7936 .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER,
7937 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7938 .doit = devlink_nl_cmd_health_reporter_recover_doit,
7939 .flags = GENL_ADMIN_PERM,
7940 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
7943 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE,
7944 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7945 .doit = devlink_nl_cmd_health_reporter_diagnose_doit,
7946 .flags = GENL_ADMIN_PERM,
7947 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
7950 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET,
7951 .validate = GENL_DONT_VALIDATE_STRICT |
7952 GENL_DONT_VALIDATE_DUMP_STRICT,
7953 .dumpit = devlink_nl_cmd_health_reporter_dump_get_dumpit,
7954 .flags = GENL_ADMIN_PERM,
7957 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR,
7958 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7959 .doit = devlink_nl_cmd_health_reporter_dump_clear_doit,
7960 .flags = GENL_ADMIN_PERM,
7961 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
7964 .cmd = DEVLINK_CMD_HEALTH_REPORTER_TEST,
7965 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7966 .doit = devlink_nl_cmd_health_reporter_test_doit,
7967 .flags = GENL_ADMIN_PERM,
7968 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
7971 .cmd = DEVLINK_CMD_FLASH_UPDATE,
7972 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7973 .doit = devlink_nl_cmd_flash_update,
7974 .flags = GENL_ADMIN_PERM,
7977 .cmd = DEVLINK_CMD_TRAP_GET,
7978 .doit = devlink_nl_cmd_trap_get_doit,
7979 .dumpit = devlink_nl_instance_iter_dumpit,
7980 /* can be retrieved by unprivileged users */
7983 .cmd = DEVLINK_CMD_TRAP_SET,
7984 .doit = devlink_nl_cmd_trap_set_doit,
7985 .flags = GENL_ADMIN_PERM,
7988 .cmd = DEVLINK_CMD_TRAP_GROUP_GET,
7989 .doit = devlink_nl_cmd_trap_group_get_doit,
7990 .dumpit = devlink_nl_instance_iter_dumpit,
7991 /* can be retrieved by unprivileged users */
7994 .cmd = DEVLINK_CMD_TRAP_GROUP_SET,
7995 .doit = devlink_nl_cmd_trap_group_set_doit,
7996 .flags = GENL_ADMIN_PERM,
7999 .cmd = DEVLINK_CMD_TRAP_POLICER_GET,
8000 .doit = devlink_nl_cmd_trap_policer_get_doit,
8001 .dumpit = devlink_nl_instance_iter_dumpit,
8002 /* can be retrieved by unprivileged users */
8005 .cmd = DEVLINK_CMD_TRAP_POLICER_SET,
8006 .doit = devlink_nl_cmd_trap_policer_set_doit,
8007 .flags = GENL_ADMIN_PERM,
8010 .cmd = DEVLINK_CMD_SELFTESTS_GET,
8011 .doit = devlink_nl_cmd_selftests_get_doit,
8012 .dumpit = devlink_nl_instance_iter_dumpit,
8013 /* can be retrieved by unprivileged users */
8016 .cmd = DEVLINK_CMD_SELFTESTS_RUN,
8017 .doit = devlink_nl_cmd_selftests_run,
8018 .flags = GENL_ADMIN_PERM,
8020 /* -- No new ops here! Use split ops going forward! -- */
8024 devlink_trap_policer_notify(struct devlink *devlink,
8025 const struct devlink_trap_policer_item *policer_item,
8026 enum devlink_command cmd);
8028 devlink_trap_group_notify(struct devlink *devlink,
8029 const struct devlink_trap_group_item *group_item,
8030 enum devlink_command cmd);
8031 static void devlink_trap_notify(struct devlink *devlink,
8032 const struct devlink_trap_item *trap_item,
8033 enum devlink_command cmd);
8035 void devlink_notify_register(struct devlink *devlink)
8037 struct devlink_trap_policer_item *policer_item;
8038 struct devlink_trap_group_item *group_item;
8039 struct devlink_param_item *param_item;
8040 struct devlink_trap_item *trap_item;
8041 struct devlink_port *devlink_port;
8042 struct devlink_linecard *linecard;
8043 struct devlink_rate *rate_node;
8044 struct devlink_region *region;
8045 unsigned long port_index;
8047 devlink_notify(devlink, DEVLINK_CMD_NEW);
8048 list_for_each_entry(linecard, &devlink->linecard_list, list)
8049 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
8051 xa_for_each(&devlink->ports, port_index, devlink_port)
8052 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
8054 list_for_each_entry(policer_item, &devlink->trap_policer_list, list)
8055 devlink_trap_policer_notify(devlink, policer_item,
8056 DEVLINK_CMD_TRAP_POLICER_NEW);
8058 list_for_each_entry(group_item, &devlink->trap_group_list, list)
8059 devlink_trap_group_notify(devlink, group_item,
8060 DEVLINK_CMD_TRAP_GROUP_NEW);
8062 list_for_each_entry(trap_item, &devlink->trap_list, list)
8063 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
8065 list_for_each_entry(rate_node, &devlink->rate_list, list)
8066 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
8068 list_for_each_entry(region, &devlink->region_list, list)
8069 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
8071 list_for_each_entry(param_item, &devlink->param_list, list)
8072 devlink_param_notify(devlink, 0, param_item,
8073 DEVLINK_CMD_PARAM_NEW);
8076 void devlink_notify_unregister(struct devlink *devlink)
8078 struct devlink_trap_policer_item *policer_item;
8079 struct devlink_trap_group_item *group_item;
8080 struct devlink_param_item *param_item;
8081 struct devlink_trap_item *trap_item;
8082 struct devlink_port *devlink_port;
8083 struct devlink_rate *rate_node;
8084 struct devlink_region *region;
8085 unsigned long port_index;
8087 list_for_each_entry_reverse(param_item, &devlink->param_list, list)
8088 devlink_param_notify(devlink, 0, param_item,
8089 DEVLINK_CMD_PARAM_DEL);
8091 list_for_each_entry_reverse(region, &devlink->region_list, list)
8092 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
8094 list_for_each_entry_reverse(rate_node, &devlink->rate_list, list)
8095 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL);
8097 list_for_each_entry_reverse(trap_item, &devlink->trap_list, list)
8098 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL);
8100 list_for_each_entry_reverse(group_item, &devlink->trap_group_list, list)
8101 devlink_trap_group_notify(devlink, group_item,
8102 DEVLINK_CMD_TRAP_GROUP_DEL);
8103 list_for_each_entry_reverse(policer_item, &devlink->trap_policer_list,
8105 devlink_trap_policer_notify(devlink, policer_item,
8106 DEVLINK_CMD_TRAP_POLICER_DEL);
8108 xa_for_each(&devlink->ports, port_index, devlink_port)
8109 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
8110 devlink_notify(devlink, DEVLINK_CMD_DEL);
8113 static void devlink_port_type_warn(struct work_struct *work)
8115 WARN(true, "Type was not set for devlink port.");
8118 static bool devlink_port_type_should_warn(struct devlink_port *devlink_port)
8120 /* Ignore CPU and DSA flavours. */
8121 return devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_CPU &&
8122 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_DSA &&
8123 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_UNUSED;
8126 #define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 3600)
8128 static void devlink_port_type_warn_schedule(struct devlink_port *devlink_port)
8130 if (!devlink_port_type_should_warn(devlink_port))
8132 /* Schedule a work to WARN in case driver does not set port
8133 * type within timeout.
8135 schedule_delayed_work(&devlink_port->type_warn_dw,
8136 DEVLINK_PORT_TYPE_WARN_TIMEOUT);
8139 static void devlink_port_type_warn_cancel(struct devlink_port *devlink_port)
8141 if (!devlink_port_type_should_warn(devlink_port))
8143 cancel_delayed_work_sync(&devlink_port->type_warn_dw);
8147 * devlink_port_init() - Init devlink port
8150 * @devlink_port: devlink port
8152 * Initialize essencial stuff that is needed for functions
8153 * that may be called before devlink port registration.
8154 * Call to this function is optional and not needed
8155 * in case the driver does not use such functions.
8157 void devlink_port_init(struct devlink *devlink,
8158 struct devlink_port *devlink_port)
8160 if (devlink_port->initialized)
8162 devlink_port->devlink = devlink;
8163 INIT_LIST_HEAD(&devlink_port->region_list);
8164 devlink_port->initialized = true;
8166 EXPORT_SYMBOL_GPL(devlink_port_init);
8169 * devlink_port_fini() - Deinitialize devlink port
8171 * @devlink_port: devlink port
8173 * Deinitialize essencial stuff that is in use for functions
8174 * that may be called after devlink port unregistration.
8175 * Call to this function is optional and not needed
8176 * in case the driver does not use such functions.
8178 void devlink_port_fini(struct devlink_port *devlink_port)
8180 WARN_ON(!list_empty(&devlink_port->region_list));
8182 EXPORT_SYMBOL_GPL(devlink_port_fini);
8185 * devl_port_register() - Register devlink port
8188 * @devlink_port: devlink port
8189 * @port_index: driver-specific numerical identifier of the port
8191 * Register devlink port with provided port index. User can use
8192 * any indexing, even hw-related one. devlink_port structure
8193 * is convenient to be embedded inside user driver private structure.
8194 * Note that the caller should take care of zeroing the devlink_port
8197 int devl_port_register(struct devlink *devlink,
8198 struct devlink_port *devlink_port,
8199 unsigned int port_index)
8203 devl_assert_locked(devlink);
8205 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
8207 devlink_port_init(devlink, devlink_port);
8208 devlink_port->registered = true;
8209 devlink_port->index = port_index;
8210 spin_lock_init(&devlink_port->type_lock);
8211 INIT_LIST_HEAD(&devlink_port->reporter_list);
8212 err = xa_insert(&devlink->ports, port_index, devlink_port, GFP_KERNEL);
8216 INIT_DELAYED_WORK(&devlink_port->type_warn_dw, &devlink_port_type_warn);
8217 devlink_port_type_warn_schedule(devlink_port);
8218 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
8221 EXPORT_SYMBOL_GPL(devl_port_register);
8224 * devlink_port_register - Register devlink port
8227 * @devlink_port: devlink port
8228 * @port_index: driver-specific numerical identifier of the port
8230 * Register devlink port with provided port index. User can use
8231 * any indexing, even hw-related one. devlink_port structure
8232 * is convenient to be embedded inside user driver private structure.
8233 * Note that the caller should take care of zeroing the devlink_port
8236 * Context: Takes and release devlink->lock <mutex>.
8238 int devlink_port_register(struct devlink *devlink,
8239 struct devlink_port *devlink_port,
8240 unsigned int port_index)
8245 err = devl_port_register(devlink, devlink_port, port_index);
8246 devl_unlock(devlink);
8249 EXPORT_SYMBOL_GPL(devlink_port_register);
8252 * devl_port_unregister() - Unregister devlink port
8254 * @devlink_port: devlink port
8256 void devl_port_unregister(struct devlink_port *devlink_port)
8258 lockdep_assert_held(&devlink_port->devlink->lock);
8259 WARN_ON(devlink_port->type != DEVLINK_PORT_TYPE_NOTSET);
8261 devlink_port_type_warn_cancel(devlink_port);
8262 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
8263 xa_erase(&devlink_port->devlink->ports, devlink_port->index);
8264 WARN_ON(!list_empty(&devlink_port->reporter_list));
8265 devlink_port->registered = false;
8267 EXPORT_SYMBOL_GPL(devl_port_unregister);
8270 * devlink_port_unregister - Unregister devlink port
8272 * @devlink_port: devlink port
8274 * Context: Takes and release devlink->lock <mutex>.
8276 void devlink_port_unregister(struct devlink_port *devlink_port)
8278 struct devlink *devlink = devlink_port->devlink;
8281 devl_port_unregister(devlink_port);
8282 devl_unlock(devlink);
8284 EXPORT_SYMBOL_GPL(devlink_port_unregister);
8286 static void devlink_port_type_netdev_checks(struct devlink_port *devlink_port,
8287 struct net_device *netdev)
8289 const struct net_device_ops *ops = netdev->netdev_ops;
8291 /* If driver registers devlink port, it should set devlink port
8292 * attributes accordingly so the compat functions are called
8293 * and the original ops are not used.
8295 if (ops->ndo_get_phys_port_name) {
8296 /* Some drivers use the same set of ndos for netdevs
8297 * that have devlink_port registered and also for
8298 * those who don't. Make sure that ndo_get_phys_port_name
8299 * returns -EOPNOTSUPP here in case it is defined.
8302 char name[IFNAMSIZ];
8305 err = ops->ndo_get_phys_port_name(netdev, name, sizeof(name));
8306 WARN_ON(err != -EOPNOTSUPP);
8308 if (ops->ndo_get_port_parent_id) {
8309 /* Some drivers use the same set of ndos for netdevs
8310 * that have devlink_port registered and also for
8311 * those who don't. Make sure that ndo_get_port_parent_id
8312 * returns -EOPNOTSUPP here in case it is defined.
8315 struct netdev_phys_item_id ppid;
8318 err = ops->ndo_get_port_parent_id(netdev, &ppid);
8319 WARN_ON(err != -EOPNOTSUPP);
8323 static void __devlink_port_type_set(struct devlink_port *devlink_port,
8324 enum devlink_port_type type,
8327 struct net_device *netdev = type_dev;
8329 ASSERT_DEVLINK_PORT_REGISTERED(devlink_port);
8331 if (type == DEVLINK_PORT_TYPE_NOTSET) {
8332 devlink_port_type_warn_schedule(devlink_port);
8334 devlink_port_type_warn_cancel(devlink_port);
8335 if (type == DEVLINK_PORT_TYPE_ETH && netdev)
8336 devlink_port_type_netdev_checks(devlink_port, netdev);
8339 spin_lock_bh(&devlink_port->type_lock);
8340 devlink_port->type = type;
8342 case DEVLINK_PORT_TYPE_ETH:
8343 devlink_port->type_eth.netdev = netdev;
8346 devlink_port->type_eth.ifindex = netdev->ifindex;
8347 BUILD_BUG_ON(sizeof(devlink_port->type_eth.ifname) !=
8348 sizeof(netdev->name));
8349 strcpy(devlink_port->type_eth.ifname, netdev->name);
8352 case DEVLINK_PORT_TYPE_IB:
8353 devlink_port->type_ib.ibdev = type_dev;
8358 spin_unlock_bh(&devlink_port->type_lock);
8359 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
8363 * devlink_port_type_eth_set - Set port type to Ethernet
8365 * @devlink_port: devlink port
8367 * If driver is calling this, most likely it is doing something wrong.
8369 void devlink_port_type_eth_set(struct devlink_port *devlink_port)
8371 dev_warn(devlink_port->devlink->dev,
8372 "devlink port type for port %d set to Ethernet without a software interface reference, device type not supported by the kernel?\n",
8373 devlink_port->index);
8374 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, NULL);
8376 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
8379 * devlink_port_type_ib_set - Set port type to InfiniBand
8381 * @devlink_port: devlink port
8382 * @ibdev: related IB device
8384 void devlink_port_type_ib_set(struct devlink_port *devlink_port,
8385 struct ib_device *ibdev)
8387 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_IB, ibdev);
8389 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
8392 * devlink_port_type_clear - Clear port type
8394 * @devlink_port: devlink port
8396 * If driver is calling this for clearing Ethernet type, most likely
8397 * it is doing something wrong.
8399 void devlink_port_type_clear(struct devlink_port *devlink_port)
8401 if (devlink_port->type == DEVLINK_PORT_TYPE_ETH)
8402 dev_warn(devlink_port->devlink->dev,
8403 "devlink port type for port %d cleared without a software interface reference, device type not supported by the kernel?\n",
8404 devlink_port->index);
8405 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, NULL);
8407 EXPORT_SYMBOL_GPL(devlink_port_type_clear);
8409 int devlink_port_netdevice_event(struct notifier_block *nb,
8410 unsigned long event, void *ptr)
8412 struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
8413 struct devlink_port *devlink_port = netdev->devlink_port;
8414 struct devlink *devlink;
8416 devlink = container_of(nb, struct devlink, netdevice_nb);
8418 if (!devlink_port || devlink_port->devlink != devlink)
8422 case NETDEV_POST_INIT:
8423 /* Set the type but not netdev pointer. It is going to be set
8424 * later on by NETDEV_REGISTER event. Happens once during
8425 * netdevice register
8427 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH,
8430 case NETDEV_REGISTER:
8431 case NETDEV_CHANGENAME:
8432 if (devlink_net(devlink) != dev_net(netdev))
8434 /* Set the netdev on top of previously set type. Note this
8435 * event happens also during net namespace change so here
8436 * we take into account netdev pointer appearing in this
8439 __devlink_port_type_set(devlink_port, devlink_port->type,
8442 case NETDEV_UNREGISTER:
8443 if (devlink_net(devlink) != dev_net(netdev))
8445 /* Clear netdev pointer, but not the type. This event happens
8446 * also during net namespace change so we need to clear
8447 * pointer to netdev that is going to another net namespace.
8449 __devlink_port_type_set(devlink_port, devlink_port->type,
8452 case NETDEV_PRE_UNINIT:
8453 /* Clear the type and the netdev pointer. Happens one during
8454 * netdevice unregister.
8456 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET,
8464 static int __devlink_port_attrs_set(struct devlink_port *devlink_port,
8465 enum devlink_port_flavour flavour)
8467 struct devlink_port_attrs *attrs = &devlink_port->attrs;
8469 devlink_port->attrs_set = true;
8470 attrs->flavour = flavour;
8471 if (attrs->switch_id.id_len) {
8472 devlink_port->switch_port = true;
8473 if (WARN_ON(attrs->switch_id.id_len > MAX_PHYS_ITEM_ID_LEN))
8474 attrs->switch_id.id_len = MAX_PHYS_ITEM_ID_LEN;
8476 devlink_port->switch_port = false;
8482 * devlink_port_attrs_set - Set port attributes
8484 * @devlink_port: devlink port
8485 * @attrs: devlink port attrs
8487 void devlink_port_attrs_set(struct devlink_port *devlink_port,
8488 struct devlink_port_attrs *attrs)
8492 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
8494 devlink_port->attrs = *attrs;
8495 ret = __devlink_port_attrs_set(devlink_port, attrs->flavour);
8498 WARN_ON(attrs->splittable && attrs->split);
8500 EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
8503 * devlink_port_attrs_pci_pf_set - Set PCI PF port attributes
8505 * @devlink_port: devlink port
8506 * @controller: associated controller number for the devlink port instance
8507 * @pf: associated PF for the devlink port instance
8508 * @external: indicates if the port is for an external controller
8510 void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u32 controller,
8511 u16 pf, bool external)
8513 struct devlink_port_attrs *attrs = &devlink_port->attrs;
8516 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
8518 ret = __devlink_port_attrs_set(devlink_port,
8519 DEVLINK_PORT_FLAVOUR_PCI_PF);
8522 attrs->pci_pf.controller = controller;
8523 attrs->pci_pf.pf = pf;
8524 attrs->pci_pf.external = external;
8526 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set);
8529 * devlink_port_attrs_pci_vf_set - Set PCI VF port attributes
8531 * @devlink_port: devlink port
8532 * @controller: associated controller number for the devlink port instance
8533 * @pf: associated PF for the devlink port instance
8534 * @vf: associated VF of a PF for the devlink port instance
8535 * @external: indicates if the port is for an external controller
8537 void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port, u32 controller,
8538 u16 pf, u16 vf, bool external)
8540 struct devlink_port_attrs *attrs = &devlink_port->attrs;
8543 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
8545 ret = __devlink_port_attrs_set(devlink_port,
8546 DEVLINK_PORT_FLAVOUR_PCI_VF);
8549 attrs->pci_vf.controller = controller;
8550 attrs->pci_vf.pf = pf;
8551 attrs->pci_vf.vf = vf;
8552 attrs->pci_vf.external = external;
8554 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set);
8557 * devlink_port_attrs_pci_sf_set - Set PCI SF port attributes
8559 * @devlink_port: devlink port
8560 * @controller: associated controller number for the devlink port instance
8561 * @pf: associated PF for the devlink port instance
8562 * @sf: associated SF of a PF for the devlink port instance
8563 * @external: indicates if the port is for an external controller
8565 void devlink_port_attrs_pci_sf_set(struct devlink_port *devlink_port, u32 controller,
8566 u16 pf, u32 sf, bool external)
8568 struct devlink_port_attrs *attrs = &devlink_port->attrs;
8571 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
8573 ret = __devlink_port_attrs_set(devlink_port,
8574 DEVLINK_PORT_FLAVOUR_PCI_SF);
8577 attrs->pci_sf.controller = controller;
8578 attrs->pci_sf.pf = pf;
8579 attrs->pci_sf.sf = sf;
8580 attrs->pci_sf.external = external;
8582 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_sf_set);
8585 * devl_rate_node_create - create devlink rate node
8586 * @devlink: devlink instance
8587 * @priv: driver private data
8588 * @node_name: name of the resulting node
8589 * @parent: parent devlink_rate struct
8591 * Create devlink rate object of type node
8593 struct devlink_rate *
8594 devl_rate_node_create(struct devlink *devlink, void *priv, char *node_name,
8595 struct devlink_rate *parent)
8597 struct devlink_rate *rate_node;
8599 rate_node = devlink_rate_node_get_by_name(devlink, node_name);
8600 if (!IS_ERR(rate_node))
8601 return ERR_PTR(-EEXIST);
8603 rate_node = kzalloc(sizeof(*rate_node), GFP_KERNEL);
8605 return ERR_PTR(-ENOMEM);
8608 rate_node->parent = parent;
8609 refcount_inc(&rate_node->parent->refcnt);
8612 rate_node->type = DEVLINK_RATE_TYPE_NODE;
8613 rate_node->devlink = devlink;
8614 rate_node->priv = priv;
8616 rate_node->name = kstrdup(node_name, GFP_KERNEL);
8617 if (!rate_node->name) {
8619 return ERR_PTR(-ENOMEM);
8622 refcount_set(&rate_node->refcnt, 1);
8623 list_add(&rate_node->list, &devlink->rate_list);
8624 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
8627 EXPORT_SYMBOL_GPL(devl_rate_node_create);
8630 * devl_rate_leaf_create - create devlink rate leaf
8631 * @devlink_port: devlink port object to create rate object on
8632 * @priv: driver private data
8633 * @parent: parent devlink_rate struct
8635 * Create devlink rate object of type leaf on provided @devlink_port.
8637 int devl_rate_leaf_create(struct devlink_port *devlink_port, void *priv,
8638 struct devlink_rate *parent)
8640 struct devlink *devlink = devlink_port->devlink;
8641 struct devlink_rate *devlink_rate;
8643 devl_assert_locked(devlink_port->devlink);
8645 if (WARN_ON(devlink_port->devlink_rate))
8648 devlink_rate = kzalloc(sizeof(*devlink_rate), GFP_KERNEL);
8653 devlink_rate->parent = parent;
8654 refcount_inc(&devlink_rate->parent->refcnt);
8657 devlink_rate->type = DEVLINK_RATE_TYPE_LEAF;
8658 devlink_rate->devlink = devlink;
8659 devlink_rate->devlink_port = devlink_port;
8660 devlink_rate->priv = priv;
8661 list_add_tail(&devlink_rate->list, &devlink->rate_list);
8662 devlink_port->devlink_rate = devlink_rate;
8663 devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW);
8667 EXPORT_SYMBOL_GPL(devl_rate_leaf_create);
8670 * devl_rate_leaf_destroy - destroy devlink rate leaf
8672 * @devlink_port: devlink port linked to the rate object
8674 * Destroy the devlink rate object of type leaf on provided @devlink_port.
8676 void devl_rate_leaf_destroy(struct devlink_port *devlink_port)
8678 struct devlink_rate *devlink_rate = devlink_port->devlink_rate;
8680 devl_assert_locked(devlink_port->devlink);
8684 devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_DEL);
8685 if (devlink_rate->parent)
8686 refcount_dec(&devlink_rate->parent->refcnt);
8687 list_del(&devlink_rate->list);
8688 devlink_port->devlink_rate = NULL;
8689 kfree(devlink_rate);
8691 EXPORT_SYMBOL_GPL(devl_rate_leaf_destroy);
8694 * devl_rate_nodes_destroy - destroy all devlink rate nodes on device
8695 * @devlink: devlink instance
8697 * Unset parent for all rate objects and destroy all rate nodes
8698 * on specified device.
8700 void devl_rate_nodes_destroy(struct devlink *devlink)
8702 static struct devlink_rate *devlink_rate, *tmp;
8703 const struct devlink_ops *ops = devlink->ops;
8705 devl_assert_locked(devlink);
8707 list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
8708 if (!devlink_rate->parent)
8711 refcount_dec(&devlink_rate->parent->refcnt);
8712 if (devlink_rate_is_leaf(devlink_rate))
8713 ops->rate_leaf_parent_set(devlink_rate, NULL, devlink_rate->priv,
8715 else if (devlink_rate_is_node(devlink_rate))
8716 ops->rate_node_parent_set(devlink_rate, NULL, devlink_rate->priv,
8719 list_for_each_entry_safe(devlink_rate, tmp, &devlink->rate_list, list) {
8720 if (devlink_rate_is_node(devlink_rate)) {
8721 ops->rate_node_del(devlink_rate, devlink_rate->priv, NULL);
8722 list_del(&devlink_rate->list);
8723 kfree(devlink_rate->name);
8724 kfree(devlink_rate);
8728 EXPORT_SYMBOL_GPL(devl_rate_nodes_destroy);
8731 * devlink_port_linecard_set - Link port with a linecard
8733 * @devlink_port: devlink port
8734 * @linecard: devlink linecard
8736 void devlink_port_linecard_set(struct devlink_port *devlink_port,
8737 struct devlink_linecard *linecard)
8739 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
8741 devlink_port->linecard = linecard;
8743 EXPORT_SYMBOL_GPL(devlink_port_linecard_set);
8745 static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
8746 char *name, size_t len)
8748 struct devlink_port_attrs *attrs = &devlink_port->attrs;
8751 if (!devlink_port->attrs_set)
8754 switch (attrs->flavour) {
8755 case DEVLINK_PORT_FLAVOUR_PHYSICAL:
8756 if (devlink_port->linecard)
8757 n = snprintf(name, len, "l%u",
8758 devlink_port->linecard->index);
8760 n += snprintf(name + n, len - n, "p%u",
8761 attrs->phys.port_number);
8762 if (n < len && attrs->split)
8763 n += snprintf(name + n, len - n, "s%u",
8764 attrs->phys.split_subport_number);
8766 case DEVLINK_PORT_FLAVOUR_CPU:
8767 case DEVLINK_PORT_FLAVOUR_DSA:
8768 case DEVLINK_PORT_FLAVOUR_UNUSED:
8769 /* As CPU and DSA ports do not have a netdevice associated
8770 * case should not ever happen.
8774 case DEVLINK_PORT_FLAVOUR_PCI_PF:
8775 if (attrs->pci_pf.external) {
8776 n = snprintf(name, len, "c%u", attrs->pci_pf.controller);
8782 n = snprintf(name, len, "pf%u", attrs->pci_pf.pf);
8784 case DEVLINK_PORT_FLAVOUR_PCI_VF:
8785 if (attrs->pci_vf.external) {
8786 n = snprintf(name, len, "c%u", attrs->pci_vf.controller);
8792 n = snprintf(name, len, "pf%uvf%u",
8793 attrs->pci_vf.pf, attrs->pci_vf.vf);
8795 case DEVLINK_PORT_FLAVOUR_PCI_SF:
8796 if (attrs->pci_sf.external) {
8797 n = snprintf(name, len, "c%u", attrs->pci_sf.controller);
8803 n = snprintf(name, len, "pf%usf%u", attrs->pci_sf.pf,
8806 case DEVLINK_PORT_FLAVOUR_VIRTUAL:
8816 static int devlink_linecard_types_init(struct devlink_linecard *linecard)
8818 struct devlink_linecard_type *linecard_type;
8822 count = linecard->ops->types_count(linecard, linecard->priv);
8823 linecard->types = kmalloc_array(count, sizeof(*linecard_type),
8825 if (!linecard->types)
8827 linecard->types_count = count;
8829 for (i = 0; i < count; i++) {
8830 linecard_type = &linecard->types[i];
8831 linecard->ops->types_get(linecard, linecard->priv, i,
8832 &linecard_type->type,
8833 &linecard_type->priv);
8838 static void devlink_linecard_types_fini(struct devlink_linecard *linecard)
8840 kfree(linecard->types);
8844 * devl_linecard_create - Create devlink linecard
8847 * @linecard_index: driver-specific numerical identifier of the linecard
8848 * @ops: linecards ops
8849 * @priv: user priv pointer
8851 * Create devlink linecard instance with provided linecard index.
8852 * Caller can use any indexing, even hw-related one.
8854 * Return: Line card structure or an ERR_PTR() encoded error code.
8856 struct devlink_linecard *
8857 devl_linecard_create(struct devlink *devlink, unsigned int linecard_index,
8858 const struct devlink_linecard_ops *ops, void *priv)
8860 struct devlink_linecard *linecard;
8863 if (WARN_ON(!ops || !ops->provision || !ops->unprovision ||
8864 !ops->types_count || !ops->types_get))
8865 return ERR_PTR(-EINVAL);
8867 if (devlink_linecard_index_exists(devlink, linecard_index))
8868 return ERR_PTR(-EEXIST);
8870 linecard = kzalloc(sizeof(*linecard), GFP_KERNEL);
8872 return ERR_PTR(-ENOMEM);
8874 linecard->devlink = devlink;
8875 linecard->index = linecard_index;
8876 linecard->ops = ops;
8877 linecard->priv = priv;
8878 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
8879 mutex_init(&linecard->state_lock);
8881 err = devlink_linecard_types_init(linecard);
8883 mutex_destroy(&linecard->state_lock);
8885 return ERR_PTR(err);
8888 list_add_tail(&linecard->list, &devlink->linecard_list);
8889 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
8892 EXPORT_SYMBOL_GPL(devl_linecard_create);
8895 * devl_linecard_destroy - Destroy devlink linecard
8897 * @linecard: devlink linecard
8899 void devl_linecard_destroy(struct devlink_linecard *linecard)
8901 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_DEL);
8902 list_del(&linecard->list);
8903 devlink_linecard_types_fini(linecard);
8904 mutex_destroy(&linecard->state_lock);
8907 EXPORT_SYMBOL_GPL(devl_linecard_destroy);
8910 * devlink_linecard_provision_set - Set provisioning on linecard
8912 * @linecard: devlink linecard
8913 * @type: linecard type
8915 * This is either called directly from the provision() op call or
8916 * as a result of the provision() op call asynchronously.
8918 void devlink_linecard_provision_set(struct devlink_linecard *linecard,
8921 mutex_lock(&linecard->state_lock);
8922 WARN_ON(linecard->type && strcmp(linecard->type, type));
8923 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED;
8924 linecard->type = type;
8925 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
8926 mutex_unlock(&linecard->state_lock);
8928 EXPORT_SYMBOL_GPL(devlink_linecard_provision_set);
8931 * devlink_linecard_provision_clear - Clear provisioning on linecard
8933 * @linecard: devlink linecard
8935 * This is either called directly from the unprovision() op call or
8936 * as a result of the unprovision() op call asynchronously.
8938 void devlink_linecard_provision_clear(struct devlink_linecard *linecard)
8940 mutex_lock(&linecard->state_lock);
8941 WARN_ON(linecard->nested_devlink);
8942 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
8943 linecard->type = NULL;
8944 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
8945 mutex_unlock(&linecard->state_lock);
8947 EXPORT_SYMBOL_GPL(devlink_linecard_provision_clear);
8950 * devlink_linecard_provision_fail - Fail provisioning on linecard
8952 * @linecard: devlink linecard
8954 * This is either called directly from the provision() op call or
8955 * as a result of the provision() op call asynchronously.
8957 void devlink_linecard_provision_fail(struct devlink_linecard *linecard)
8959 mutex_lock(&linecard->state_lock);
8960 WARN_ON(linecard->nested_devlink);
8961 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING_FAILED;
8962 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
8963 mutex_unlock(&linecard->state_lock);
8965 EXPORT_SYMBOL_GPL(devlink_linecard_provision_fail);
8968 * devlink_linecard_activate - Set linecard active
8970 * @linecard: devlink linecard
8972 void devlink_linecard_activate(struct devlink_linecard *linecard)
8974 mutex_lock(&linecard->state_lock);
8975 WARN_ON(linecard->state != DEVLINK_LINECARD_STATE_PROVISIONED);
8976 linecard->state = DEVLINK_LINECARD_STATE_ACTIVE;
8977 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
8978 mutex_unlock(&linecard->state_lock);
8980 EXPORT_SYMBOL_GPL(devlink_linecard_activate);
8983 * devlink_linecard_deactivate - Set linecard inactive
8985 * @linecard: devlink linecard
8987 void devlink_linecard_deactivate(struct devlink_linecard *linecard)
8989 mutex_lock(&linecard->state_lock);
8990 switch (linecard->state) {
8991 case DEVLINK_LINECARD_STATE_ACTIVE:
8992 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED;
8993 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
8995 case DEVLINK_LINECARD_STATE_UNPROVISIONING:
8996 /* Line card is being deactivated as part
8997 * of unprovisioning flow.
9004 mutex_unlock(&linecard->state_lock);
9006 EXPORT_SYMBOL_GPL(devlink_linecard_deactivate);
9009 * devlink_linecard_nested_dl_set - Attach/detach nested devlink
9010 * instance to linecard.
9012 * @linecard: devlink linecard
9013 * @nested_devlink: devlink instance to attach or NULL to detach
9015 void devlink_linecard_nested_dl_set(struct devlink_linecard *linecard,
9016 struct devlink *nested_devlink)
9018 mutex_lock(&linecard->state_lock);
9019 linecard->nested_devlink = nested_devlink;
9020 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
9021 mutex_unlock(&linecard->state_lock);
9023 EXPORT_SYMBOL_GPL(devlink_linecard_nested_dl_set);
9025 int devl_sb_register(struct devlink *devlink, unsigned int sb_index,
9026 u32 size, u16 ingress_pools_count,
9027 u16 egress_pools_count, u16 ingress_tc_count,
9028 u16 egress_tc_count)
9030 struct devlink_sb *devlink_sb;
9032 lockdep_assert_held(&devlink->lock);
9034 if (devlink_sb_index_exists(devlink, sb_index))
9037 devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
9040 devlink_sb->index = sb_index;
9041 devlink_sb->size = size;
9042 devlink_sb->ingress_pools_count = ingress_pools_count;
9043 devlink_sb->egress_pools_count = egress_pools_count;
9044 devlink_sb->ingress_tc_count = ingress_tc_count;
9045 devlink_sb->egress_tc_count = egress_tc_count;
9046 list_add_tail(&devlink_sb->list, &devlink->sb_list);
9049 EXPORT_SYMBOL_GPL(devl_sb_register);
9051 int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
9052 u32 size, u16 ingress_pools_count,
9053 u16 egress_pools_count, u16 ingress_tc_count,
9054 u16 egress_tc_count)
9059 err = devl_sb_register(devlink, sb_index, size, ingress_pools_count,
9060 egress_pools_count, ingress_tc_count,
9062 devl_unlock(devlink);
9065 EXPORT_SYMBOL_GPL(devlink_sb_register);
9067 void devl_sb_unregister(struct devlink *devlink, unsigned int sb_index)
9069 struct devlink_sb *devlink_sb;
9071 lockdep_assert_held(&devlink->lock);
9073 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
9074 WARN_ON(!devlink_sb);
9075 list_del(&devlink_sb->list);
9078 EXPORT_SYMBOL_GPL(devl_sb_unregister);
9080 void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
9083 devl_sb_unregister(devlink, sb_index);
9084 devl_unlock(devlink);
9086 EXPORT_SYMBOL_GPL(devlink_sb_unregister);
9089 * devl_dpipe_headers_register - register dpipe headers
9092 * @dpipe_headers: dpipe header array
9094 * Register the headers supported by hardware.
9096 void devl_dpipe_headers_register(struct devlink *devlink,
9097 struct devlink_dpipe_headers *dpipe_headers)
9099 lockdep_assert_held(&devlink->lock);
9101 devlink->dpipe_headers = dpipe_headers;
9103 EXPORT_SYMBOL_GPL(devl_dpipe_headers_register);
9106 * devl_dpipe_headers_unregister - unregister dpipe headers
9110 * Unregister the headers supported by hardware.
9112 void devl_dpipe_headers_unregister(struct devlink *devlink)
9114 lockdep_assert_held(&devlink->lock);
9116 devlink->dpipe_headers = NULL;
9118 EXPORT_SYMBOL_GPL(devl_dpipe_headers_unregister);
9121 * devlink_dpipe_table_counter_enabled - check if counter allocation
9124 * @table_name: tables name
9126 * Used by driver to check if counter allocation is required.
9127 * After counter allocation is turned on the table entries
9128 * are updated to include counter statistics.
9130 * After that point on the driver must respect the counter
9131 * state so that each entry added to the table is added
9134 bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
9135 const char *table_name)
9137 struct devlink_dpipe_table *table;
9141 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
9142 table_name, devlink);
9145 enabled = table->counters_enabled;
9149 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled);
9152 * devl_dpipe_table_register - register dpipe table
9155 * @table_name: table name
9156 * @table_ops: table ops
9158 * @counter_control_extern: external control for counters
9160 int devl_dpipe_table_register(struct devlink *devlink,
9161 const char *table_name,
9162 struct devlink_dpipe_table_ops *table_ops,
9163 void *priv, bool counter_control_extern)
9165 struct devlink_dpipe_table *table;
9167 lockdep_assert_held(&devlink->lock);
9169 if (WARN_ON(!table_ops->size_get))
9172 if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name,
9176 table = kzalloc(sizeof(*table), GFP_KERNEL);
9180 table->name = table_name;
9181 table->table_ops = table_ops;
9183 table->counter_control_extern = counter_control_extern;
9185 list_add_tail_rcu(&table->list, &devlink->dpipe_table_list);
9189 EXPORT_SYMBOL_GPL(devl_dpipe_table_register);
9192 * devl_dpipe_table_unregister - unregister dpipe table
9195 * @table_name: table name
9197 void devl_dpipe_table_unregister(struct devlink *devlink,
9198 const char *table_name)
9200 struct devlink_dpipe_table *table;
9202 lockdep_assert_held(&devlink->lock);
9204 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
9205 table_name, devlink);
9208 list_del_rcu(&table->list);
9209 kfree_rcu(table, rcu);
9211 EXPORT_SYMBOL_GPL(devl_dpipe_table_unregister);
9214 * devl_resource_register - devlink resource register
9217 * @resource_name: resource's name
9218 * @resource_size: resource's size
9219 * @resource_id: resource's id
9220 * @parent_resource_id: resource's parent id
9221 * @size_params: size parameters
9223 * Generic resources should reuse the same names across drivers.
9224 * Please see the generic resources list at:
9225 * Documentation/networking/devlink/devlink-resource.rst
9227 int devl_resource_register(struct devlink *devlink,
9228 const char *resource_name,
9231 u64 parent_resource_id,
9232 const struct devlink_resource_size_params *size_params)
9234 struct devlink_resource *resource;
9235 struct list_head *resource_list;
9238 lockdep_assert_held(&devlink->lock);
9240 top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
9242 resource = devlink_resource_find(devlink, NULL, resource_id);
9246 resource = kzalloc(sizeof(*resource), GFP_KERNEL);
9250 if (top_hierarchy) {
9251 resource_list = &devlink->resource_list;
9253 struct devlink_resource *parent_resource;
9255 parent_resource = devlink_resource_find(devlink, NULL,
9256 parent_resource_id);
9257 if (parent_resource) {
9258 resource_list = &parent_resource->resource_list;
9259 resource->parent = parent_resource;
9266 resource->name = resource_name;
9267 resource->size = resource_size;
9268 resource->size_new = resource_size;
9269 resource->id = resource_id;
9270 resource->size_valid = true;
9271 memcpy(&resource->size_params, size_params,
9272 sizeof(resource->size_params));
9273 INIT_LIST_HEAD(&resource->resource_list);
9274 list_add_tail(&resource->list, resource_list);
9278 EXPORT_SYMBOL_GPL(devl_resource_register);
9281 * devlink_resource_register - devlink resource register
9284 * @resource_name: resource's name
9285 * @resource_size: resource's size
9286 * @resource_id: resource's id
9287 * @parent_resource_id: resource's parent id
9288 * @size_params: size parameters
9290 * Generic resources should reuse the same names across drivers.
9291 * Please see the generic resources list at:
9292 * Documentation/networking/devlink/devlink-resource.rst
9294 * Context: Takes and release devlink->lock <mutex>.
9296 int devlink_resource_register(struct devlink *devlink,
9297 const char *resource_name,
9300 u64 parent_resource_id,
9301 const struct devlink_resource_size_params *size_params)
9306 err = devl_resource_register(devlink, resource_name, resource_size,
9307 resource_id, parent_resource_id, size_params);
9308 devl_unlock(devlink);
9311 EXPORT_SYMBOL_GPL(devlink_resource_register);
9313 static void devlink_resource_unregister(struct devlink *devlink,
9314 struct devlink_resource *resource)
9316 struct devlink_resource *tmp, *child_resource;
9318 list_for_each_entry_safe(child_resource, tmp, &resource->resource_list,
9320 devlink_resource_unregister(devlink, child_resource);
9321 list_del(&child_resource->list);
9322 kfree(child_resource);
9327 * devl_resources_unregister - free all resources
9331 void devl_resources_unregister(struct devlink *devlink)
9333 struct devlink_resource *tmp, *child_resource;
9335 lockdep_assert_held(&devlink->lock);
9337 list_for_each_entry_safe(child_resource, tmp, &devlink->resource_list,
9339 devlink_resource_unregister(devlink, child_resource);
9340 list_del(&child_resource->list);
9341 kfree(child_resource);
9344 EXPORT_SYMBOL_GPL(devl_resources_unregister);
9347 * devlink_resources_unregister - free all resources
9351 * Context: Takes and release devlink->lock <mutex>.
9353 void devlink_resources_unregister(struct devlink *devlink)
9356 devl_resources_unregister(devlink);
9357 devl_unlock(devlink);
9359 EXPORT_SYMBOL_GPL(devlink_resources_unregister);
9362 * devl_resource_size_get - get and update size
9365 * @resource_id: the requested resource id
9366 * @p_resource_size: ptr to update
9368 int devl_resource_size_get(struct devlink *devlink,
9370 u64 *p_resource_size)
9372 struct devlink_resource *resource;
9374 lockdep_assert_held(&devlink->lock);
9376 resource = devlink_resource_find(devlink, NULL, resource_id);
9379 *p_resource_size = resource->size_new;
9380 resource->size = resource->size_new;
9383 EXPORT_SYMBOL_GPL(devl_resource_size_get);
9386 * devl_dpipe_table_resource_set - set the resource id
9389 * @table_name: table name
9390 * @resource_id: resource id
9391 * @resource_units: number of resource's units consumed per table's entry
9393 int devl_dpipe_table_resource_set(struct devlink *devlink,
9394 const char *table_name, u64 resource_id,
9397 struct devlink_dpipe_table *table;
9399 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
9400 table_name, devlink);
9404 table->resource_id = resource_id;
9405 table->resource_units = resource_units;
9406 table->resource_valid = true;
9409 EXPORT_SYMBOL_GPL(devl_dpipe_table_resource_set);
9412 * devl_resource_occ_get_register - register occupancy getter
9415 * @resource_id: resource id
9416 * @occ_get: occupancy getter callback
9417 * @occ_get_priv: occupancy getter callback priv
9419 void devl_resource_occ_get_register(struct devlink *devlink,
9421 devlink_resource_occ_get_t *occ_get,
9424 struct devlink_resource *resource;
9426 lockdep_assert_held(&devlink->lock);
9428 resource = devlink_resource_find(devlink, NULL, resource_id);
9429 if (WARN_ON(!resource))
9431 WARN_ON(resource->occ_get);
9433 resource->occ_get = occ_get;
9434 resource->occ_get_priv = occ_get_priv;
9436 EXPORT_SYMBOL_GPL(devl_resource_occ_get_register);
9439 * devlink_resource_occ_get_register - register occupancy getter
9442 * @resource_id: resource id
9443 * @occ_get: occupancy getter callback
9444 * @occ_get_priv: occupancy getter callback priv
9446 * Context: Takes and release devlink->lock <mutex>.
9448 void devlink_resource_occ_get_register(struct devlink *devlink,
9450 devlink_resource_occ_get_t *occ_get,
9454 devl_resource_occ_get_register(devlink, resource_id,
9455 occ_get, occ_get_priv);
9456 devl_unlock(devlink);
9458 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register);
9461 * devl_resource_occ_get_unregister - unregister occupancy getter
9464 * @resource_id: resource id
9466 void devl_resource_occ_get_unregister(struct devlink *devlink,
9469 struct devlink_resource *resource;
9471 lockdep_assert_held(&devlink->lock);
9473 resource = devlink_resource_find(devlink, NULL, resource_id);
9474 if (WARN_ON(!resource))
9476 WARN_ON(!resource->occ_get);
9478 resource->occ_get = NULL;
9479 resource->occ_get_priv = NULL;
9481 EXPORT_SYMBOL_GPL(devl_resource_occ_get_unregister);
9484 * devlink_resource_occ_get_unregister - unregister occupancy getter
9487 * @resource_id: resource id
9489 * Context: Takes and release devlink->lock <mutex>.
9491 void devlink_resource_occ_get_unregister(struct devlink *devlink,
9495 devl_resource_occ_get_unregister(devlink, resource_id);
9496 devl_unlock(devlink);
9498 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister);
9500 static int devlink_param_verify(const struct devlink_param *param)
9502 if (!param || !param->name || !param->supported_cmodes)
9505 return devlink_param_generic_verify(param);
9507 return devlink_param_driver_verify(param);
9510 static int devlink_param_register(struct devlink *devlink,
9511 const struct devlink_param *param)
9513 struct devlink_param_item *param_item;
9515 WARN_ON(devlink_param_verify(param));
9516 WARN_ON(devlink_param_find_by_name(&devlink->param_list, param->name));
9518 if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT))
9519 WARN_ON(param->get || param->set);
9521 WARN_ON(!param->get || !param->set);
9523 param_item = kzalloc(sizeof(*param_item), GFP_KERNEL);
9527 param_item->param = param;
9529 list_add_tail(¶m_item->list, &devlink->param_list);
9530 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
9534 static void devlink_param_unregister(struct devlink *devlink,
9535 const struct devlink_param *param)
9537 struct devlink_param_item *param_item;
9540 devlink_param_find_by_name(&devlink->param_list, param->name);
9541 if (WARN_ON(!param_item))
9543 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_DEL);
9544 list_del(¶m_item->list);
9549 * devl_params_register - register configuration parameters
9552 * @params: configuration parameters array
9553 * @params_count: number of parameters provided
9555 * Register the configuration parameters supported by the driver.
9557 int devl_params_register(struct devlink *devlink,
9558 const struct devlink_param *params,
9559 size_t params_count)
9561 const struct devlink_param *param = params;
9564 lockdep_assert_held(&devlink->lock);
9566 for (i = 0; i < params_count; i++, param++) {
9567 err = devlink_param_register(devlink, param);
9577 for (param--; i > 0; i--, param--)
9578 devlink_param_unregister(devlink, param);
9581 EXPORT_SYMBOL_GPL(devl_params_register);
9583 int devlink_params_register(struct devlink *devlink,
9584 const struct devlink_param *params,
9585 size_t params_count)
9590 err = devl_params_register(devlink, params, params_count);
9591 devl_unlock(devlink);
9594 EXPORT_SYMBOL_GPL(devlink_params_register);
9597 * devl_params_unregister - unregister configuration parameters
9599 * @params: configuration parameters to unregister
9600 * @params_count: number of parameters provided
9602 void devl_params_unregister(struct devlink *devlink,
9603 const struct devlink_param *params,
9604 size_t params_count)
9606 const struct devlink_param *param = params;
9609 lockdep_assert_held(&devlink->lock);
9611 for (i = 0; i < params_count; i++, param++)
9612 devlink_param_unregister(devlink, param);
9614 EXPORT_SYMBOL_GPL(devl_params_unregister);
9616 void devlink_params_unregister(struct devlink *devlink,
9617 const struct devlink_param *params,
9618 size_t params_count)
9621 devl_params_unregister(devlink, params, params_count);
9622 devl_unlock(devlink);
9624 EXPORT_SYMBOL_GPL(devlink_params_unregister);
9627 * devl_param_driverinit_value_get - get configuration parameter
9628 * value for driver initializing
9631 * @param_id: parameter ID
9632 * @init_val: value of parameter in driverinit configuration mode
9634 * This function should be used by the driver to get driverinit
9635 * configuration for initialization after reload command.
9637 int devl_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
9638 union devlink_param_value *init_val)
9640 struct devlink_param_item *param_item;
9642 lockdep_assert_held(&devlink->lock);
9644 if (WARN_ON(!devlink_reload_supported(devlink->ops)))
9647 param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
9651 if (!param_item->driverinit_value_valid)
9654 if (WARN_ON(!devlink_param_cmode_is_supported(param_item->param,
9655 DEVLINK_PARAM_CMODE_DRIVERINIT)))
9658 if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
9659 strcpy(init_val->vstr, param_item->driverinit_value.vstr);
9661 *init_val = param_item->driverinit_value;
9665 EXPORT_SYMBOL_GPL(devl_param_driverinit_value_get);
9668 * devl_param_driverinit_value_set - set value of configuration
9669 * parameter for driverinit
9670 * configuration mode
9673 * @param_id: parameter ID
9674 * @init_val: value of parameter to set for driverinit configuration mode
9676 * This function should be used by the driver to set driverinit
9677 * configuration mode default value.
9679 void devl_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
9680 union devlink_param_value init_val)
9682 struct devlink_param_item *param_item;
9684 param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
9685 if (WARN_ON(!param_item))
9688 if (WARN_ON(!devlink_param_cmode_is_supported(param_item->param,
9689 DEVLINK_PARAM_CMODE_DRIVERINIT)))
9692 if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
9693 strcpy(param_item->driverinit_value.vstr, init_val.vstr);
9695 param_item->driverinit_value = init_val;
9696 param_item->driverinit_value_valid = true;
9698 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
9700 EXPORT_SYMBOL_GPL(devl_param_driverinit_value_set);
9703 * devl_param_value_changed - notify devlink on a parameter's value
9704 * change. Should be called by the driver
9705 * right after the change.
9708 * @param_id: parameter ID
9710 * This function should be used by the driver to notify devlink on value
9711 * change, excluding driverinit configuration mode.
9712 * For driverinit configuration mode driver should use the function
9714 void devl_param_value_changed(struct devlink *devlink, u32 param_id)
9716 struct devlink_param_item *param_item;
9718 param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
9719 WARN_ON(!param_item);
9721 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
9723 EXPORT_SYMBOL_GPL(devl_param_value_changed);
9726 * devl_region_create - create a new address region
9729 * @ops: region operations and name
9730 * @region_max_snapshots: Maximum supported number of snapshots for region
9731 * @region_size: size of region
9733 struct devlink_region *devl_region_create(struct devlink *devlink,
9734 const struct devlink_region_ops *ops,
9735 u32 region_max_snapshots,
9738 struct devlink_region *region;
9740 devl_assert_locked(devlink);
9742 if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
9743 return ERR_PTR(-EINVAL);
9745 if (devlink_region_get_by_name(devlink, ops->name))
9746 return ERR_PTR(-EEXIST);
9748 region = kzalloc(sizeof(*region), GFP_KERNEL);
9750 return ERR_PTR(-ENOMEM);
9752 region->devlink = devlink;
9753 region->max_snapshots = region_max_snapshots;
9755 region->size = region_size;
9756 INIT_LIST_HEAD(®ion->snapshot_list);
9757 mutex_init(®ion->snapshot_lock);
9758 list_add_tail(®ion->list, &devlink->region_list);
9759 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
9763 EXPORT_SYMBOL_GPL(devl_region_create);
9766 * devlink_region_create - create a new address region
9769 * @ops: region operations and name
9770 * @region_max_snapshots: Maximum supported number of snapshots for region
9771 * @region_size: size of region
9773 * Context: Takes and release devlink->lock <mutex>.
9775 struct devlink_region *
9776 devlink_region_create(struct devlink *devlink,
9777 const struct devlink_region_ops *ops,
9778 u32 region_max_snapshots, u64 region_size)
9780 struct devlink_region *region;
9783 region = devl_region_create(devlink, ops, region_max_snapshots,
9785 devl_unlock(devlink);
9788 EXPORT_SYMBOL_GPL(devlink_region_create);
9791 * devlink_port_region_create - create a new address region for a port
9793 * @port: devlink port
9794 * @ops: region operations and name
9795 * @region_max_snapshots: Maximum supported number of snapshots for region
9796 * @region_size: size of region
9798 * Context: Takes and release devlink->lock <mutex>.
9800 struct devlink_region *
9801 devlink_port_region_create(struct devlink_port *port,
9802 const struct devlink_port_region_ops *ops,
9803 u32 region_max_snapshots, u64 region_size)
9805 struct devlink *devlink = port->devlink;
9806 struct devlink_region *region;
9809 ASSERT_DEVLINK_PORT_INITIALIZED(port);
9811 if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
9812 return ERR_PTR(-EINVAL);
9816 if (devlink_port_region_get_by_name(port, ops->name)) {
9821 region = kzalloc(sizeof(*region), GFP_KERNEL);
9827 region->devlink = devlink;
9828 region->port = port;
9829 region->max_snapshots = region_max_snapshots;
9830 region->port_ops = ops;
9831 region->size = region_size;
9832 INIT_LIST_HEAD(®ion->snapshot_list);
9833 mutex_init(®ion->snapshot_lock);
9834 list_add_tail(®ion->list, &port->region_list);
9835 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
9837 devl_unlock(devlink);
9841 devl_unlock(devlink);
9842 return ERR_PTR(err);
9844 EXPORT_SYMBOL_GPL(devlink_port_region_create);
9847 * devl_region_destroy - destroy address region
9849 * @region: devlink region to destroy
9851 void devl_region_destroy(struct devlink_region *region)
9853 struct devlink *devlink = region->devlink;
9854 struct devlink_snapshot *snapshot, *ts;
9856 devl_assert_locked(devlink);
9858 /* Free all snapshots of region */
9859 mutex_lock(®ion->snapshot_lock);
9860 list_for_each_entry_safe(snapshot, ts, ®ion->snapshot_list, list)
9861 devlink_region_snapshot_del(region, snapshot);
9862 mutex_unlock(®ion->snapshot_lock);
9864 list_del(®ion->list);
9865 mutex_destroy(®ion->snapshot_lock);
9867 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
9870 EXPORT_SYMBOL_GPL(devl_region_destroy);
9873 * devlink_region_destroy - destroy address region
9875 * @region: devlink region to destroy
9877 * Context: Takes and release devlink->lock <mutex>.
9879 void devlink_region_destroy(struct devlink_region *region)
9881 struct devlink *devlink = region->devlink;
9884 devl_region_destroy(region);
9885 devl_unlock(devlink);
9887 EXPORT_SYMBOL_GPL(devlink_region_destroy);
9890 * devlink_region_snapshot_id_get - get snapshot ID
9892 * This callback should be called when adding a new snapshot,
9893 * Driver should use the same id for multiple snapshots taken
9894 * on multiple regions at the same time/by the same trigger.
9896 * The caller of this function must use devlink_region_snapshot_id_put
9897 * when finished creating regions using this id.
9899 * Returns zero on success, or a negative error code on failure.
9902 * @id: storage to return id
9904 int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
9906 return __devlink_region_snapshot_id_get(devlink, id);
9908 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get);
9911 * devlink_region_snapshot_id_put - put snapshot ID reference
9913 * This should be called by a driver after finishing creating snapshots
9914 * with an id. Doing so ensures that the ID can later be released in the
9915 * event that all snapshots using it have been destroyed.
9918 * @id: id to release reference on
9920 void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id)
9922 __devlink_snapshot_id_decrement(devlink, id);
9924 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put);
9927 * devlink_region_snapshot_create - create a new snapshot
9928 * This will add a new snapshot of a region. The snapshot
9929 * will be stored on the region struct and can be accessed
9930 * from devlink. This is useful for future analyses of snapshots.
9931 * Multiple snapshots can be created on a region.
9932 * The @snapshot_id should be obtained using the getter function.
9934 * @region: devlink region of the snapshot
9935 * @data: snapshot data
9936 * @snapshot_id: snapshot id to be created
9938 int devlink_region_snapshot_create(struct devlink_region *region,
9939 u8 *data, u32 snapshot_id)
9943 mutex_lock(®ion->snapshot_lock);
9944 err = __devlink_region_snapshot_create(region, data, snapshot_id);
9945 mutex_unlock(®ion->snapshot_lock);
9948 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create);
9950 #define DEVLINK_TRAP(_id, _type) \
9952 .type = DEVLINK_TRAP_TYPE_##_type, \
9953 .id = DEVLINK_TRAP_GENERIC_ID_##_id, \
9954 .name = DEVLINK_TRAP_GENERIC_NAME_##_id, \
9957 static const struct devlink_trap devlink_trap_generic[] = {
9958 DEVLINK_TRAP(SMAC_MC, DROP),
9959 DEVLINK_TRAP(VLAN_TAG_MISMATCH, DROP),
9960 DEVLINK_TRAP(INGRESS_VLAN_FILTER, DROP),
9961 DEVLINK_TRAP(INGRESS_STP_FILTER, DROP),
9962 DEVLINK_TRAP(EMPTY_TX_LIST, DROP),
9963 DEVLINK_TRAP(PORT_LOOPBACK_FILTER, DROP),
9964 DEVLINK_TRAP(BLACKHOLE_ROUTE, DROP),
9965 DEVLINK_TRAP(TTL_ERROR, EXCEPTION),
9966 DEVLINK_TRAP(TAIL_DROP, DROP),
9967 DEVLINK_TRAP(NON_IP_PACKET, DROP),
9968 DEVLINK_TRAP(UC_DIP_MC_DMAC, DROP),
9969 DEVLINK_TRAP(DIP_LB, DROP),
9970 DEVLINK_TRAP(SIP_MC, DROP),
9971 DEVLINK_TRAP(SIP_LB, DROP),
9972 DEVLINK_TRAP(CORRUPTED_IP_HDR, DROP),
9973 DEVLINK_TRAP(IPV4_SIP_BC, DROP),
9974 DEVLINK_TRAP(IPV6_MC_DIP_RESERVED_SCOPE, DROP),
9975 DEVLINK_TRAP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE, DROP),
9976 DEVLINK_TRAP(MTU_ERROR, EXCEPTION),
9977 DEVLINK_TRAP(UNRESOLVED_NEIGH, EXCEPTION),
9978 DEVLINK_TRAP(RPF, EXCEPTION),
9979 DEVLINK_TRAP(REJECT_ROUTE, EXCEPTION),
9980 DEVLINK_TRAP(IPV4_LPM_UNICAST_MISS, EXCEPTION),
9981 DEVLINK_TRAP(IPV6_LPM_UNICAST_MISS, EXCEPTION),
9982 DEVLINK_TRAP(NON_ROUTABLE, DROP),
9983 DEVLINK_TRAP(DECAP_ERROR, EXCEPTION),
9984 DEVLINK_TRAP(OVERLAY_SMAC_MC, DROP),
9985 DEVLINK_TRAP(INGRESS_FLOW_ACTION_DROP, DROP),
9986 DEVLINK_TRAP(EGRESS_FLOW_ACTION_DROP, DROP),
9987 DEVLINK_TRAP(STP, CONTROL),
9988 DEVLINK_TRAP(LACP, CONTROL),
9989 DEVLINK_TRAP(LLDP, CONTROL),
9990 DEVLINK_TRAP(IGMP_QUERY, CONTROL),
9991 DEVLINK_TRAP(IGMP_V1_REPORT, CONTROL),
9992 DEVLINK_TRAP(IGMP_V2_REPORT, CONTROL),
9993 DEVLINK_TRAP(IGMP_V3_REPORT, CONTROL),
9994 DEVLINK_TRAP(IGMP_V2_LEAVE, CONTROL),
9995 DEVLINK_TRAP(MLD_QUERY, CONTROL),
9996 DEVLINK_TRAP(MLD_V1_REPORT, CONTROL),
9997 DEVLINK_TRAP(MLD_V2_REPORT, CONTROL),
9998 DEVLINK_TRAP(MLD_V1_DONE, CONTROL),
9999 DEVLINK_TRAP(IPV4_DHCP, CONTROL),
10000 DEVLINK_TRAP(IPV6_DHCP, CONTROL),
10001 DEVLINK_TRAP(ARP_REQUEST, CONTROL),
10002 DEVLINK_TRAP(ARP_RESPONSE, CONTROL),
10003 DEVLINK_TRAP(ARP_OVERLAY, CONTROL),
10004 DEVLINK_TRAP(IPV6_NEIGH_SOLICIT, CONTROL),
10005 DEVLINK_TRAP(IPV6_NEIGH_ADVERT, CONTROL),
10006 DEVLINK_TRAP(IPV4_BFD, CONTROL),
10007 DEVLINK_TRAP(IPV6_BFD, CONTROL),
10008 DEVLINK_TRAP(IPV4_OSPF, CONTROL),
10009 DEVLINK_TRAP(IPV6_OSPF, CONTROL),
10010 DEVLINK_TRAP(IPV4_BGP, CONTROL),
10011 DEVLINK_TRAP(IPV6_BGP, CONTROL),
10012 DEVLINK_TRAP(IPV4_VRRP, CONTROL),
10013 DEVLINK_TRAP(IPV6_VRRP, CONTROL),
10014 DEVLINK_TRAP(IPV4_PIM, CONTROL),
10015 DEVLINK_TRAP(IPV6_PIM, CONTROL),
10016 DEVLINK_TRAP(UC_LB, CONTROL),
10017 DEVLINK_TRAP(LOCAL_ROUTE, CONTROL),
10018 DEVLINK_TRAP(EXTERNAL_ROUTE, CONTROL),
10019 DEVLINK_TRAP(IPV6_UC_DIP_LINK_LOCAL_SCOPE, CONTROL),
10020 DEVLINK_TRAP(IPV6_DIP_ALL_NODES, CONTROL),
10021 DEVLINK_TRAP(IPV6_DIP_ALL_ROUTERS, CONTROL),
10022 DEVLINK_TRAP(IPV6_ROUTER_SOLICIT, CONTROL),
10023 DEVLINK_TRAP(IPV6_ROUTER_ADVERT, CONTROL),
10024 DEVLINK_TRAP(IPV6_REDIRECT, CONTROL),
10025 DEVLINK_TRAP(IPV4_ROUTER_ALERT, CONTROL),
10026 DEVLINK_TRAP(IPV6_ROUTER_ALERT, CONTROL),
10027 DEVLINK_TRAP(PTP_EVENT, CONTROL),
10028 DEVLINK_TRAP(PTP_GENERAL, CONTROL),
10029 DEVLINK_TRAP(FLOW_ACTION_SAMPLE, CONTROL),
10030 DEVLINK_TRAP(FLOW_ACTION_TRAP, CONTROL),
10031 DEVLINK_TRAP(EARLY_DROP, DROP),
10032 DEVLINK_TRAP(VXLAN_PARSING, DROP),
10033 DEVLINK_TRAP(LLC_SNAP_PARSING, DROP),
10034 DEVLINK_TRAP(VLAN_PARSING, DROP),
10035 DEVLINK_TRAP(PPPOE_PPP_PARSING, DROP),
10036 DEVLINK_TRAP(MPLS_PARSING, DROP),
10037 DEVLINK_TRAP(ARP_PARSING, DROP),
10038 DEVLINK_TRAP(IP_1_PARSING, DROP),
10039 DEVLINK_TRAP(IP_N_PARSING, DROP),
10040 DEVLINK_TRAP(GRE_PARSING, DROP),
10041 DEVLINK_TRAP(UDP_PARSING, DROP),
10042 DEVLINK_TRAP(TCP_PARSING, DROP),
10043 DEVLINK_TRAP(IPSEC_PARSING, DROP),
10044 DEVLINK_TRAP(SCTP_PARSING, DROP),
10045 DEVLINK_TRAP(DCCP_PARSING, DROP),
10046 DEVLINK_TRAP(GTP_PARSING, DROP),
10047 DEVLINK_TRAP(ESP_PARSING, DROP),
10048 DEVLINK_TRAP(BLACKHOLE_NEXTHOP, DROP),
10049 DEVLINK_TRAP(DMAC_FILTER, DROP),
10050 DEVLINK_TRAP(EAPOL, CONTROL),
10051 DEVLINK_TRAP(LOCKED_PORT, DROP),
10054 #define DEVLINK_TRAP_GROUP(_id) \
10056 .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \
10057 .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \
10060 static const struct devlink_trap_group devlink_trap_group_generic[] = {
10061 DEVLINK_TRAP_GROUP(L2_DROPS),
10062 DEVLINK_TRAP_GROUP(L3_DROPS),
10063 DEVLINK_TRAP_GROUP(L3_EXCEPTIONS),
10064 DEVLINK_TRAP_GROUP(BUFFER_DROPS),
10065 DEVLINK_TRAP_GROUP(TUNNEL_DROPS),
10066 DEVLINK_TRAP_GROUP(ACL_DROPS),
10067 DEVLINK_TRAP_GROUP(STP),
10068 DEVLINK_TRAP_GROUP(LACP),
10069 DEVLINK_TRAP_GROUP(LLDP),
10070 DEVLINK_TRAP_GROUP(MC_SNOOPING),
10071 DEVLINK_TRAP_GROUP(DHCP),
10072 DEVLINK_TRAP_GROUP(NEIGH_DISCOVERY),
10073 DEVLINK_TRAP_GROUP(BFD),
10074 DEVLINK_TRAP_GROUP(OSPF),
10075 DEVLINK_TRAP_GROUP(BGP),
10076 DEVLINK_TRAP_GROUP(VRRP),
10077 DEVLINK_TRAP_GROUP(PIM),
10078 DEVLINK_TRAP_GROUP(UC_LB),
10079 DEVLINK_TRAP_GROUP(LOCAL_DELIVERY),
10080 DEVLINK_TRAP_GROUP(EXTERNAL_DELIVERY),
10081 DEVLINK_TRAP_GROUP(IPV6),
10082 DEVLINK_TRAP_GROUP(PTP_EVENT),
10083 DEVLINK_TRAP_GROUP(PTP_GENERAL),
10084 DEVLINK_TRAP_GROUP(ACL_SAMPLE),
10085 DEVLINK_TRAP_GROUP(ACL_TRAP),
10086 DEVLINK_TRAP_GROUP(PARSER_ERROR_DROPS),
10087 DEVLINK_TRAP_GROUP(EAPOL),
10090 static int devlink_trap_generic_verify(const struct devlink_trap *trap)
10092 if (trap->id > DEVLINK_TRAP_GENERIC_ID_MAX)
10095 if (strcmp(trap->name, devlink_trap_generic[trap->id].name))
10098 if (trap->type != devlink_trap_generic[trap->id].type)
10104 static int devlink_trap_driver_verify(const struct devlink_trap *trap)
10108 if (trap->id <= DEVLINK_TRAP_GENERIC_ID_MAX)
10111 for (i = 0; i < ARRAY_SIZE(devlink_trap_generic); i++) {
10112 if (!strcmp(trap->name, devlink_trap_generic[i].name))
10119 static int devlink_trap_verify(const struct devlink_trap *trap)
10121 if (!trap || !trap->name)
10125 return devlink_trap_generic_verify(trap);
10127 return devlink_trap_driver_verify(trap);
10131 devlink_trap_group_generic_verify(const struct devlink_trap_group *group)
10133 if (group->id > DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
10136 if (strcmp(group->name, devlink_trap_group_generic[group->id].name))
10143 devlink_trap_group_driver_verify(const struct devlink_trap_group *group)
10147 if (group->id <= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
10150 for (i = 0; i < ARRAY_SIZE(devlink_trap_group_generic); i++) {
10151 if (!strcmp(group->name, devlink_trap_group_generic[i].name))
10158 static int devlink_trap_group_verify(const struct devlink_trap_group *group)
10160 if (group->generic)
10161 return devlink_trap_group_generic_verify(group);
10163 return devlink_trap_group_driver_verify(group);
10167 devlink_trap_group_notify(struct devlink *devlink,
10168 const struct devlink_trap_group_item *group_item,
10169 enum devlink_command cmd)
10171 struct sk_buff *msg;
10174 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_GROUP_NEW &&
10175 cmd != DEVLINK_CMD_TRAP_GROUP_DEL);
10176 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
10179 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
10183 err = devlink_nl_trap_group_fill(msg, devlink, group_item, cmd, 0, 0,
10190 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
10191 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
10195 devlink_trap_item_group_link(struct devlink *devlink,
10196 struct devlink_trap_item *trap_item)
10198 u16 group_id = trap_item->trap->init_group_id;
10199 struct devlink_trap_group_item *group_item;
10201 group_item = devlink_trap_group_item_lookup_by_id(devlink, group_id);
10202 if (WARN_ON_ONCE(!group_item))
10205 trap_item->group_item = group_item;
10210 static void devlink_trap_notify(struct devlink *devlink,
10211 const struct devlink_trap_item *trap_item,
10212 enum devlink_command cmd)
10214 struct sk_buff *msg;
10217 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_NEW &&
10218 cmd != DEVLINK_CMD_TRAP_DEL);
10219 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
10222 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
10226 err = devlink_nl_trap_fill(msg, devlink, trap_item, cmd, 0, 0, 0);
10232 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
10233 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
10237 devlink_trap_register(struct devlink *devlink,
10238 const struct devlink_trap *trap, void *priv)
10240 struct devlink_trap_item *trap_item;
10243 if (devlink_trap_item_lookup(devlink, trap->name))
10246 trap_item = kzalloc(sizeof(*trap_item), GFP_KERNEL);
10250 trap_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
10251 if (!trap_item->stats) {
10253 goto err_stats_alloc;
10256 trap_item->trap = trap;
10257 trap_item->action = trap->init_action;
10258 trap_item->priv = priv;
10260 err = devlink_trap_item_group_link(devlink, trap_item);
10262 goto err_group_link;
10264 err = devlink->ops->trap_init(devlink, trap, trap_item);
10266 goto err_trap_init;
10268 list_add_tail(&trap_item->list, &devlink->trap_list);
10269 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
10275 free_percpu(trap_item->stats);
10281 static void devlink_trap_unregister(struct devlink *devlink,
10282 const struct devlink_trap *trap)
10284 struct devlink_trap_item *trap_item;
10286 trap_item = devlink_trap_item_lookup(devlink, trap->name);
10287 if (WARN_ON_ONCE(!trap_item))
10290 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL);
10291 list_del(&trap_item->list);
10292 if (devlink->ops->trap_fini)
10293 devlink->ops->trap_fini(devlink, trap, trap_item);
10294 free_percpu(trap_item->stats);
10298 static void devlink_trap_disable(struct devlink *devlink,
10299 const struct devlink_trap *trap)
10301 struct devlink_trap_item *trap_item;
10303 trap_item = devlink_trap_item_lookup(devlink, trap->name);
10304 if (WARN_ON_ONCE(!trap_item))
10307 devlink->ops->trap_action_set(devlink, trap, DEVLINK_TRAP_ACTION_DROP,
10309 trap_item->action = DEVLINK_TRAP_ACTION_DROP;
10313 * devl_traps_register - Register packet traps with devlink.
10314 * @devlink: devlink.
10315 * @traps: Packet traps.
10316 * @traps_count: Count of provided packet traps.
10317 * @priv: Driver private information.
10319 * Return: Non-zero value on failure.
10321 int devl_traps_register(struct devlink *devlink,
10322 const struct devlink_trap *traps,
10323 size_t traps_count, void *priv)
10327 if (!devlink->ops->trap_init || !devlink->ops->trap_action_set)
10330 devl_assert_locked(devlink);
10331 for (i = 0; i < traps_count; i++) {
10332 const struct devlink_trap *trap = &traps[i];
10334 err = devlink_trap_verify(trap);
10336 goto err_trap_verify;
10338 err = devlink_trap_register(devlink, trap, priv);
10340 goto err_trap_register;
10347 for (i--; i >= 0; i--)
10348 devlink_trap_unregister(devlink, &traps[i]);
10351 EXPORT_SYMBOL_GPL(devl_traps_register);
10354 * devlink_traps_register - Register packet traps with devlink.
10355 * @devlink: devlink.
10356 * @traps: Packet traps.
10357 * @traps_count: Count of provided packet traps.
10358 * @priv: Driver private information.
10360 * Context: Takes and release devlink->lock <mutex>.
10362 * Return: Non-zero value on failure.
10364 int devlink_traps_register(struct devlink *devlink,
10365 const struct devlink_trap *traps,
10366 size_t traps_count, void *priv)
10370 devl_lock(devlink);
10371 err = devl_traps_register(devlink, traps, traps_count, priv);
10372 devl_unlock(devlink);
10375 EXPORT_SYMBOL_GPL(devlink_traps_register);
10378 * devl_traps_unregister - Unregister packet traps from devlink.
10379 * @devlink: devlink.
10380 * @traps: Packet traps.
10381 * @traps_count: Count of provided packet traps.
10383 void devl_traps_unregister(struct devlink *devlink,
10384 const struct devlink_trap *traps,
10385 size_t traps_count)
10389 devl_assert_locked(devlink);
10390 /* Make sure we do not have any packets in-flight while unregistering
10391 * traps by disabling all of them and waiting for a grace period.
10393 for (i = traps_count - 1; i >= 0; i--)
10394 devlink_trap_disable(devlink, &traps[i]);
10396 for (i = traps_count - 1; i >= 0; i--)
10397 devlink_trap_unregister(devlink, &traps[i]);
10399 EXPORT_SYMBOL_GPL(devl_traps_unregister);
10402 * devlink_traps_unregister - Unregister packet traps from devlink.
10403 * @devlink: devlink.
10404 * @traps: Packet traps.
10405 * @traps_count: Count of provided packet traps.
10407 * Context: Takes and release devlink->lock <mutex>.
10409 void devlink_traps_unregister(struct devlink *devlink,
10410 const struct devlink_trap *traps,
10411 size_t traps_count)
10413 devl_lock(devlink);
10414 devl_traps_unregister(devlink, traps, traps_count);
10415 devl_unlock(devlink);
10417 EXPORT_SYMBOL_GPL(devlink_traps_unregister);
10420 devlink_trap_stats_update(struct devlink_stats __percpu *trap_stats,
10423 struct devlink_stats *stats;
10425 stats = this_cpu_ptr(trap_stats);
10426 u64_stats_update_begin(&stats->syncp);
10427 u64_stats_add(&stats->rx_bytes, skb_len);
10428 u64_stats_inc(&stats->rx_packets);
10429 u64_stats_update_end(&stats->syncp);
10433 devlink_trap_report_metadata_set(struct devlink_trap_metadata *metadata,
10434 const struct devlink_trap_item *trap_item,
10435 struct devlink_port *in_devlink_port,
10436 const struct flow_action_cookie *fa_cookie)
10438 metadata->trap_name = trap_item->trap->name;
10439 metadata->trap_group_name = trap_item->group_item->group->name;
10440 metadata->fa_cookie = fa_cookie;
10441 metadata->trap_type = trap_item->trap->type;
10443 spin_lock(&in_devlink_port->type_lock);
10444 if (in_devlink_port->type == DEVLINK_PORT_TYPE_ETH)
10445 metadata->input_dev = in_devlink_port->type_eth.netdev;
10446 spin_unlock(&in_devlink_port->type_lock);
10450 * devlink_trap_report - Report trapped packet to drop monitor.
10451 * @devlink: devlink.
10452 * @skb: Trapped packet.
10453 * @trap_ctx: Trap context.
10454 * @in_devlink_port: Input devlink port.
10455 * @fa_cookie: Flow action cookie. Could be NULL.
10457 void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb,
10458 void *trap_ctx, struct devlink_port *in_devlink_port,
10459 const struct flow_action_cookie *fa_cookie)
10462 struct devlink_trap_item *trap_item = trap_ctx;
10464 devlink_trap_stats_update(trap_item->stats, skb->len);
10465 devlink_trap_stats_update(trap_item->group_item->stats, skb->len);
10467 if (trace_devlink_trap_report_enabled()) {
10468 struct devlink_trap_metadata metadata = {};
10470 devlink_trap_report_metadata_set(&metadata, trap_item,
10471 in_devlink_port, fa_cookie);
10472 trace_devlink_trap_report(devlink, skb, &metadata);
10475 EXPORT_SYMBOL_GPL(devlink_trap_report);
10478 * devlink_trap_ctx_priv - Trap context to driver private information.
10479 * @trap_ctx: Trap context.
10481 * Return: Driver private information passed during registration.
10483 void *devlink_trap_ctx_priv(void *trap_ctx)
10485 struct devlink_trap_item *trap_item = trap_ctx;
10487 return trap_item->priv;
10489 EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv);
10492 devlink_trap_group_item_policer_link(struct devlink *devlink,
10493 struct devlink_trap_group_item *group_item)
10495 u32 policer_id = group_item->group->init_policer_id;
10496 struct devlink_trap_policer_item *policer_item;
10498 if (policer_id == 0)
10501 policer_item = devlink_trap_policer_item_lookup(devlink, policer_id);
10502 if (WARN_ON_ONCE(!policer_item))
10505 group_item->policer_item = policer_item;
10511 devlink_trap_group_register(struct devlink *devlink,
10512 const struct devlink_trap_group *group)
10514 struct devlink_trap_group_item *group_item;
10517 if (devlink_trap_group_item_lookup(devlink, group->name))
10520 group_item = kzalloc(sizeof(*group_item), GFP_KERNEL);
10524 group_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
10525 if (!group_item->stats) {
10527 goto err_stats_alloc;
10530 group_item->group = group;
10532 err = devlink_trap_group_item_policer_link(devlink, group_item);
10534 goto err_policer_link;
10536 if (devlink->ops->trap_group_init) {
10537 err = devlink->ops->trap_group_init(devlink, group);
10539 goto err_group_init;
10542 list_add_tail(&group_item->list, &devlink->trap_group_list);
10543 devlink_trap_group_notify(devlink, group_item,
10544 DEVLINK_CMD_TRAP_GROUP_NEW);
10550 free_percpu(group_item->stats);
10557 devlink_trap_group_unregister(struct devlink *devlink,
10558 const struct devlink_trap_group *group)
10560 struct devlink_trap_group_item *group_item;
10562 group_item = devlink_trap_group_item_lookup(devlink, group->name);
10563 if (WARN_ON_ONCE(!group_item))
10566 devlink_trap_group_notify(devlink, group_item,
10567 DEVLINK_CMD_TRAP_GROUP_DEL);
10568 list_del(&group_item->list);
10569 free_percpu(group_item->stats);
10574 * devl_trap_groups_register - Register packet trap groups with devlink.
10575 * @devlink: devlink.
10576 * @groups: Packet trap groups.
10577 * @groups_count: Count of provided packet trap groups.
10579 * Return: Non-zero value on failure.
10581 int devl_trap_groups_register(struct devlink *devlink,
10582 const struct devlink_trap_group *groups,
10583 size_t groups_count)
10587 devl_assert_locked(devlink);
10588 for (i = 0; i < groups_count; i++) {
10589 const struct devlink_trap_group *group = &groups[i];
10591 err = devlink_trap_group_verify(group);
10593 goto err_trap_group_verify;
10595 err = devlink_trap_group_register(devlink, group);
10597 goto err_trap_group_register;
10602 err_trap_group_register:
10603 err_trap_group_verify:
10604 for (i--; i >= 0; i--)
10605 devlink_trap_group_unregister(devlink, &groups[i]);
10608 EXPORT_SYMBOL_GPL(devl_trap_groups_register);
10611 * devlink_trap_groups_register - Register packet trap groups with devlink.
10612 * @devlink: devlink.
10613 * @groups: Packet trap groups.
10614 * @groups_count: Count of provided packet trap groups.
10616 * Context: Takes and release devlink->lock <mutex>.
10618 * Return: Non-zero value on failure.
10620 int devlink_trap_groups_register(struct devlink *devlink,
10621 const struct devlink_trap_group *groups,
10622 size_t groups_count)
10626 devl_lock(devlink);
10627 err = devl_trap_groups_register(devlink, groups, groups_count);
10628 devl_unlock(devlink);
10631 EXPORT_SYMBOL_GPL(devlink_trap_groups_register);
10634 * devl_trap_groups_unregister - Unregister packet trap groups from devlink.
10635 * @devlink: devlink.
10636 * @groups: Packet trap groups.
10637 * @groups_count: Count of provided packet trap groups.
10639 void devl_trap_groups_unregister(struct devlink *devlink,
10640 const struct devlink_trap_group *groups,
10641 size_t groups_count)
10645 devl_assert_locked(devlink);
10646 for (i = groups_count - 1; i >= 0; i--)
10647 devlink_trap_group_unregister(devlink, &groups[i]);
10649 EXPORT_SYMBOL_GPL(devl_trap_groups_unregister);
10652 * devlink_trap_groups_unregister - Unregister packet trap groups from devlink.
10653 * @devlink: devlink.
10654 * @groups: Packet trap groups.
10655 * @groups_count: Count of provided packet trap groups.
10657 * Context: Takes and release devlink->lock <mutex>.
10659 void devlink_trap_groups_unregister(struct devlink *devlink,
10660 const struct devlink_trap_group *groups,
10661 size_t groups_count)
10663 devl_lock(devlink);
10664 devl_trap_groups_unregister(devlink, groups, groups_count);
10665 devl_unlock(devlink);
10667 EXPORT_SYMBOL_GPL(devlink_trap_groups_unregister);
10670 devlink_trap_policer_notify(struct devlink *devlink,
10671 const struct devlink_trap_policer_item *policer_item,
10672 enum devlink_command cmd)
10674 struct sk_buff *msg;
10677 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_POLICER_NEW &&
10678 cmd != DEVLINK_CMD_TRAP_POLICER_DEL);
10679 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
10682 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
10686 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, cmd, 0,
10693 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
10694 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
10698 devlink_trap_policer_register(struct devlink *devlink,
10699 const struct devlink_trap_policer *policer)
10701 struct devlink_trap_policer_item *policer_item;
10704 if (devlink_trap_policer_item_lookup(devlink, policer->id))
10707 policer_item = kzalloc(sizeof(*policer_item), GFP_KERNEL);
10711 policer_item->policer = policer;
10712 policer_item->rate = policer->init_rate;
10713 policer_item->burst = policer->init_burst;
10715 if (devlink->ops->trap_policer_init) {
10716 err = devlink->ops->trap_policer_init(devlink, policer);
10718 goto err_policer_init;
10721 list_add_tail(&policer_item->list, &devlink->trap_policer_list);
10722 devlink_trap_policer_notify(devlink, policer_item,
10723 DEVLINK_CMD_TRAP_POLICER_NEW);
10728 kfree(policer_item);
10733 devlink_trap_policer_unregister(struct devlink *devlink,
10734 const struct devlink_trap_policer *policer)
10736 struct devlink_trap_policer_item *policer_item;
10738 policer_item = devlink_trap_policer_item_lookup(devlink, policer->id);
10739 if (WARN_ON_ONCE(!policer_item))
10742 devlink_trap_policer_notify(devlink, policer_item,
10743 DEVLINK_CMD_TRAP_POLICER_DEL);
10744 list_del(&policer_item->list);
10745 if (devlink->ops->trap_policer_fini)
10746 devlink->ops->trap_policer_fini(devlink, policer);
10747 kfree(policer_item);
10751 * devl_trap_policers_register - Register packet trap policers with devlink.
10752 * @devlink: devlink.
10753 * @policers: Packet trap policers.
10754 * @policers_count: Count of provided packet trap policers.
10756 * Return: Non-zero value on failure.
10759 devl_trap_policers_register(struct devlink *devlink,
10760 const struct devlink_trap_policer *policers,
10761 size_t policers_count)
10765 devl_assert_locked(devlink);
10766 for (i = 0; i < policers_count; i++) {
10767 const struct devlink_trap_policer *policer = &policers[i];
10769 if (WARN_ON(policer->id == 0 ||
10770 policer->max_rate < policer->min_rate ||
10771 policer->max_burst < policer->min_burst)) {
10773 goto err_trap_policer_verify;
10776 err = devlink_trap_policer_register(devlink, policer);
10778 goto err_trap_policer_register;
10782 err_trap_policer_register:
10783 err_trap_policer_verify:
10784 for (i--; i >= 0; i--)
10785 devlink_trap_policer_unregister(devlink, &policers[i]);
10788 EXPORT_SYMBOL_GPL(devl_trap_policers_register);
10791 * devl_trap_policers_unregister - Unregister packet trap policers from devlink.
10792 * @devlink: devlink.
10793 * @policers: Packet trap policers.
10794 * @policers_count: Count of provided packet trap policers.
10797 devl_trap_policers_unregister(struct devlink *devlink,
10798 const struct devlink_trap_policer *policers,
10799 size_t policers_count)
10803 devl_assert_locked(devlink);
10804 for (i = policers_count - 1; i >= 0; i--)
10805 devlink_trap_policer_unregister(devlink, &policers[i]);
10807 EXPORT_SYMBOL_GPL(devl_trap_policers_unregister);
10809 int devlink_compat_phys_port_name_get(struct net_device *dev,
10810 char *name, size_t len)
10812 struct devlink_port *devlink_port;
10814 /* RTNL mutex is held here which ensures that devlink_port
10815 * instance cannot disappear in the middle. No need to take
10816 * any devlink lock as only permanent values are accessed.
10820 devlink_port = dev->devlink_port;
10822 return -EOPNOTSUPP;
10824 return __devlink_port_phys_port_name_get(devlink_port, name, len);
10827 int devlink_compat_switch_id_get(struct net_device *dev,
10828 struct netdev_phys_item_id *ppid)
10830 struct devlink_port *devlink_port;
10832 /* Caller must hold RTNL mutex or reference to dev, which ensures that
10833 * devlink_port instance cannot disappear in the middle. No need to take
10834 * any devlink lock as only permanent values are accessed.
10836 devlink_port = dev->devlink_port;
10837 if (!devlink_port || !devlink_port->switch_port)
10838 return -EOPNOTSUPP;
10840 memcpy(ppid, &devlink_port->attrs.switch_id, sizeof(*ppid));